Page MenuHomeHEPForge

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 590b423..0154ce4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,228 +1,232 @@
# 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/>.
################################################################################
-cmake_minimum_required (VERSION 2.6 FATAL_ERROR)
+cmake_minimum_required (VERSION 2.8 FATAL_ERROR)
+
+#Use the compilers found in the path
+find_program(CMAKE_C_COMPILER NAMES $ENV{CC} gcc PATHS ENV PATH NO_DEFAULT_PATH)
+find_program(CMAKE_CXX_COMPILER NAMES $ENV{CXX} g++ PATHS ENV PATH NO_DEFAULT_PATH)
project(NUISANCE)
include(ExternalProject)
enable_language(Fortran)
set (NUISANCE_VERSION_MAJOR 2)
set (NUISANCE_VERSION_MINOR 7)
set (NUISANCE_VERSION_REVISION 0)
set (NUISANCE_VERSION_STRING "v${NUISANCE_VERSION_MAJOR}r${NUISANCE_VERSION_MINOR}")
if(${NUISANCE_VERSION_REVISION} STRGREATER "0")
set (NUISANCE_VERSION_STRING "${NUISANCE_VERSION_STRING}p${NUISANCE_VERSION_REVISION}")
endif()
#Set this to TRUE to enable build debugging messages
set(BUILD_DEBUG_MSGS TRUE)
include(${CMAKE_SOURCE_DIR}/cmake/cmessage.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/cacheVariables.cmake)
cmessage(STATUS "CMAKE_INSTALL_PREFIX: \"${CMAKE_INSTALL_PREFIX}\"")
cmessage(STATUS "CMAKE_BUILD_TYPE: \"${CMAKE_BUILD_TYPE}\"")
################################################################################
# Check Dependencies
################################################################################
################################## ROOT ######################################
include(${CMAKE_SOURCE_DIR}/cmake/ROOTSetup.cmake)
################################# HEPMC ######################################
include(${CMAKE_SOURCE_DIR}/cmake/HepMC.cmake)
############################ Reweight Engines ################################
include(${CMAKE_SOURCE_DIR}/cmake/ReweightEnginesSetup.cmake)
############################ Other Generators ################################
include(${CMAKE_SOURCE_DIR}/cmake/GiBUUSetup.cmake)
if(USE_NUANCE)
LIST(APPEND EXTRA_CXX_FLAGS -D__NUANCE_ENABLED__)
endif()
################################# Pythia6/8 ####################################
include(${CMAKE_SOURCE_DIR}/cmake/pythia6Setup.cmake)
include(${CMAKE_SOURCE_DIR}/cmake/pythia8Setup.cmake)
################################# gperftools ###################################
include(${CMAKE_SOURCE_DIR}/cmake/gperfSetup.cmake)
if(NOT NOTEST)
enable_testing()
endif()
SET(GENERATOR_SUPPORT)
foreach(gen NEUT;NuWro;GENIE;GiBUU;NUANCE)
if(USE_${gen})
SET(GENERATOR_SUPPORT "${GENERATOR_SUPPORT}${gen} ")
endif()
endforeach(gen)
cmessage(STATUS "Generator Input Support: ${GENERATOR_SUPPORT}")
set(MINCODE
Routines
FCN)
set(CORE
MCStudies
Genie
FitBase
Config
Logger
InputHandler
Splines
Reweight
Utils
Statistical
#Devel
Smearceptance
)
LIST(APPEND ALLEXPERIMENTS
ANL
ArgoNeuT
BEBC
BNL
Electron
FNAL
GGM
K2K
MINERvA
MiniBooNE
SciBooNE
T2K)
foreach(exp ${ALLEXPERIMENTS})
if(NOT NO_${exp})
LIST(APPEND EXPERIMENTS_TO_BUILD ${exp})
else()
LIST(REVERSE EXTRA_CXX_FLAGS)
LIST(APPEND EXTRA_CXX_FLAGS -D__NO_${exp}__)
LIST(REVERSE EXTRA_CXX_FLAGS)
endif()
endforeach()
################################## COMPILER ####################################
include(${CMAKE_SOURCE_DIR}/cmake/c++CompilerSetup.cmake)
################################### doxygen ###################################
include(${CMAKE_SOURCE_DIR}/cmake/docsSetup.cmake)
################################################################################
set(MINIMUM_INCLUDE_DIRECTORIES)
LIST(APPEND MINIMUM_INCLUDE_DIRECTORIES
${RWENGINE_INCLUDE_DIRECTORIES}
${CMAKE_SOURCE_DIR}/src/FitBase
${CMAKE_SOURCE_DIR}/src/Reweight
${CMAKE_SOURCE_DIR}/src/InputHandler
${CMAKE_SOURCE_DIR}/src/Config
${CMAKE_SOURCE_DIR}/src/Logger
${CMAKE_SOURCE_DIR}/src/Statistical
${CMAKE_SOURCE_DIR}/src/Splines
${CMAKE_SOURCE_DIR}/src/Utils
${CMAKE_SOURCE_DIR}/src/Genie)
cmessage(DEBUG "Base include directories: ${MINIMUM_INCLUDE_DIRECTORIES}")
set(EXP_INCLUDE_DIRECTORIES)
foreach(edir ${EXPERIMENTS_TO_BUILD})
LIST(APPEND EXP_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/src/${edir})
endforeach()
cmessage(DEBUG "Included experiments: ${EXP_INCLUDE_DIRECTORIES}")
foreach(mdir ${MINCODE})
cmessage (DEBUG "Configuring directory: src/${mdir}")
add_subdirectory(src/${mdir})
endforeach()
foreach(edir ${EXPERIMENTS_TO_BUILD})
cmessage (DEBUG "Configuring directory: src/${edir}")
add_subdirectory(src/${edir})
endforeach()
foreach(cdir ${CORE})
cmessage (DEBUG "Configuring directory: src/${cdir}")
add_subdirectory(src/${cdir})
endforeach()
cmessage(DEBUG "Module targets: ${MODULETargets}")
add_subdirectory(app)
add_subdirectory(src/Tests)
configure_file(cmake/setup.sh.in
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/setup.sh" @ONLY)
install(FILES
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/setup.sh" DESTINATION
${CMAKE_INSTALL_PREFIX})
configure_file(cmake/MakeBinaryBlob.in
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/MakeBinaryBlob" @ONLY)
install(PROGRAMS
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/MakeBinaryBlob" DESTINATION
bin)
if(USE_DYNSAMPLES)
SET(ALL_INCLUDES ${MINIMUM_INCLUDE_DIRECTORIES})
LIST(APPEND ALL_INCLUDES ${CMAKE_SOURCE_DIR}/src/Smearceptance)
LIST(APPEND ALL_INCLUDES ${EXP_INCLUDE_DIRECTORIES})
string(REPLACE ";" " -I" ALL_INCLUDES_STR "${ALL_INCLUDES}")
cmessage(DEBUG ${CMAKE_DEPENDLIB_FLAGS})
string(REPLACE "-levent " "" CMAKE_DEPENDLIB_FLAGS_NEW ${CMAKE_DEPENDLIB_FLAGS})
set(CMAKE_DEPENDLIB_FLAGS ${CMAKE_DEPENDLIB_FLAGS_NEW})
cmessage(DEBUG ${CMAKE_DEPENDLIB_FLAGS})
string(REPLACE ";" " -l" ALL_MODULETARGETS_STR "${MODULETargets}")
configure_file(cmake/BuildDynamicSample.in
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/BuildDynamicSample" @ONLY)
install(PROGRAMS
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/BuildDynamicSample" DESTINATION
bin)
configure_file(cmake/BuildDynamicSmearcepter.in
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/BuildDynamicSmearcepter" @ONLY)
install(PROGRAMS
"${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/BuildDynamicSmearcepter" DESTINATION
bin)
endif()
install(PROGRAMS
"${PROJECT_SOURCE_DIR}/scripts/nuiscardgen" DESTINATION
bin)
install(PROGRAMS
"${PROJECT_SOURCE_DIR}/scripts/nuissamples" DESTINATION
bin)
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index 1d488e3..1afec7d 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -1,217 +1,225 @@
# 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/>.
################################################################################
set(TARGETS_TO_BUILD)
if(USE_MINIMIZER)
add_executable(nuismin nuismin.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuismin)
target_link_libraries(nuismin ${MODULETargets})
target_link_libraries(nuismin ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(nuismin ${ROOT_LIBS})
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(nuismin PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
add_executable(nuissplines nuissplines.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuissplines)
target_link_libraries(nuissplines ${MODULETargets})
target_link_libraries(nuissplines ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(nuissplines ${ROOT_LIBS})
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(nuissplines PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
endif()
include_directories(${RWENGINE_INCLUDE_DIRECTORIES})
include_directories(${CMAKE_SOURCE_DIR}/src/Routines)
include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler)
include_directories(${CMAKE_SOURCE_DIR}/src/Genie)
include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
include_directories(${CMAKE_SOURCE_DIR}/src/Statistical)
include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
include_directories(${CMAKE_SOURCE_DIR}/src/Config)
include_directories(${CMAKE_SOURCE_DIR}/src/Logger)
include_directories(${CMAKE_SOURCE_DIR}/src/Splines)
include_directories(${CMAKE_SOURCE_DIR}/src/Reweight)
include_directories(${CMAKE_SOURCE_DIR}/src/FCN)
include_directories(${CMAKE_SOURCE_DIR}/src/MCStudies)
include_directories(${CMAKE_SOURCE_DIR}/src/Smearceptance)
include_directories(${EXP_INCLUDE_DIRECTORIES})
if (USE_NuWro AND NOT NUWRO_BUILT_FROM_FILE)
add_executable(nuwro_nuisance nuwro_NUISANCE.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuwro_nuisance)
target_link_libraries(nuwro_nuisance ${MODULETargets})
target_link_libraries(nuwro_nuisance ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(nuwro_nuisance ${ROOT_LIBS})
include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(nuwro_nuisance PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
endif()
if (USE_NEUT)
add_executable(neut_nuisance neut_NUISANCE.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};neut_nuisance)
target_link_libraries(neut_nuisance ${MODULETargets})
target_link_libraries(neut_nuisance ${CMAKE_DEPENDLIB_FLAGS})
target_link_libraries(neut_nuisance ${ROOT_LIBS})
include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(neut_nuisance PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
endif()
if (BUILD_GEVGEN)
add_executable(gevgen_nuisance gEvGen_NUISANCE.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};gevgen_nuisance)
target_link_libraries(gevgen_nuisance ${MODULETargets})
target_link_libraries(gevgen_nuisance ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(gevgen_nuisance ${ROOT_LIBS})
include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
include_directories(${GENIE_INCLUDES}/Apps)
include_directories(${GENIE_INCLUDES}/FluxDrivers)
include_directories(${GENIE_INCLUDES}/EVGDrivers)
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(gevgen_nuisance PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
add_executable(gevgen_nuisance_mixed gEvGen_NUISANCE_MIXED.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};gevgen_nuisance_mixed)
target_link_libraries(gevgen_nuisance_mixed ${MODULETargets})
target_link_libraries(gevgen_nuisance_mixed ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(gevgen_nuisance_mixed ${ROOT_LIBS})
include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
include_directories(${GENIE_INCLUDES}/Apps)
include_directories(${GENIE_INCLUDES}/FluxDrivers)
include_directories(${GENIE_INCLUDES}/EVGDrivers)
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(gevgen_nuisance_mixed PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
endif()
if (USE_GiBUU)
add_executable(DumpGiBUUEvents DumpGiBUUEvents.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};DumpGiBUUEvents)
target_link_libraries(DumpGiBUUEvents ${MODULETargets})
target_link_libraries(DumpGiBUUEvents ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(DumpGiBUUEvents ${ROOT_LIBS})
include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(DumpGiBUUEvents PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
endif()
add_executable(nuiscomp nuiscomp.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuiscomp)
target_link_libraries(nuiscomp ${MODULETargets})
target_link_libraries(nuiscomp ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(nuiscomp ${ROOT_LIBS})
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(nuiscomp PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
add_executable(nuisflat nuisflat.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuisflat)
target_link_libraries(nuisflat ${MODULETargets})
target_link_libraries(nuisflat ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(nuisflat ${ROOT_LIBS})
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(nuisflat PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
add_executable(nuissmear nuissmear.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuissmear)
target_link_libraries(nuissmear ${MODULETargets})
target_link_libraries(nuissmear ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(nuissmear ${ROOT_LIBS})
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(nuissmear PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
add_executable(nuissyst nuissyst.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuissyst)
target_link_libraries(nuissyst ${MODULETargets})
target_link_libraries(nuissyst ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(nuissyst ${ROOT_LIBS})
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(nuissyst PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
add_executable(nuisbayes nuisbayes.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuisbayes)
target_link_libraries(nuisbayes ${MODULETargets})
target_link_libraries(nuisbayes ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(nuisbayes ${ROOT_LIBS})
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(nuisbayes PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
if(USE_GENIE)
add_executable(PrepareGENIE PrepareGENIE.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};PrepareGENIE)
target_link_libraries(PrepareGENIE ${MODULETargets})
target_link_libraries(PrepareGENIE ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(PrepareGENIE ${ROOT_LIBS})
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(PrepareGENIE PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
endif()
if(USE_NEUT)
add_executable(PrepareNEUT PrepareNEUT.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};PrepareNEUT)
target_link_libraries(PrepareNEUT ${MODULETargets})
target_link_libraries(PrepareNEUT ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(PrepareNEUT ${ROOT_LIBS})
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(PrepareNEUT PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
endif()
# PREPARE NUWRO
# Commented out for the time being until it is finished..
if(USE_NuWro)
add_executable(PrepareNuwro PrepareNuwroEvents.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};PrepareNuwro)
target_link_libraries(PrepareNuwro ${MODULETargets})
target_link_libraries(PrepareNuwro ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(PrepareNuwro ${ROOT_LIBS})
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(PrepareNuwro PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
endif()
+add_executable(nuisbac nuisbac.cxx)
+set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuisbac)
+target_link_libraries(nuisbac ${MODULETargets})
+target_link_libraries(nuisbac ${CMAKE_DEPENDLIB_FLAGS})
+if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
+ set_target_properties(nuisbac PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
+endif()
+
install(TARGETS ${TARGETS_TO_BUILD} DESTINATION bin)
#add_executable(DumpROOTClassesFromVector DumpROOTClassesFromVector.cxx)
# #Strip out -lNuWro_event1
# string(REPLACE "-lNuWro_event1" "" NWEVSTRIPPED_CDF ${CMAKE_DEPENDLIB_FLAGS})
# cmessage(DEBUG "Attempted to strip out nuwro library: \"${CMAKE_DEPENDLIB_FLAGS}\" -> \"${NWEVSTRIPPED_CDF}\"")
# add_executable(PrepareNEUT PrepareNEUT.cxx)
# target_link_libraries(DumpROOTClassesFromVector ${MODULETargets})
# target_link_libraries(DumpROOTClassesFromVector ${NWEVSTRIPPED_CDF})
# if(NOT CMAKE_LINK_FLAGS STREQUAL "")
# set_target_properties(DumpROOTClassesFromVector PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
# endif()
#install(TARGETS DumpROOTClassesFromVector DESTINATION bin)
diff --git a/app/PrepareGENIE.cxx b/app/PrepareGENIE.cxx
index 9c4c895..745beb3 100644
--- a/app/PrepareGENIE.cxx
+++ b/app/PrepareGENIE.cxx
@@ -1,798 +1,775 @@
#include <stdio.h>
#include <stdlib.h>
#include "FitLogger.h"
#include "PlotUtils.h"
#include "TFile.h"
#include "TH1D.h"
#include "TTree.h"
#ifdef __GENIE_ENABLED__
#include "Conventions/Units.h"
#include "GHEP/GHepParticle.h"
#include "PDG/PDGUtils.h"
#endif
std::string gInputFiles = "";
std::string gOutputFile = "";
std::string gFluxFile = "";
std::string gTarget = "";
double MonoEnergy;
int gNEvents = -999;
bool IsMonoE = false;
void PrintOptions();
void ParseOptions(int argc, char* argv[]);
void RunGENIEPrepareMono(std::string input, std::string target,
std::string output);
void RunGENIEPrepare(std::string input, std::string flux, std::string target,
std::string output);
int main(int argc, char* argv[]) {
ParseOptions(argc, argv);
if (IsMonoE) {
RunGENIEPrepareMono(gInputFiles, gTarget, gOutputFile);
} else {
RunGENIEPrepare(gInputFiles, gFluxFile, gTarget, gOutputFile);
}
}
void RunGENIEPrepareMono(std::string input, std::string target,
std::string output) {
LOG(FIT) << "Running GENIE Prepare in mono energetic with E = " << MonoEnergy << " GeV" << std::endl;
// Setup TTree
TChain* tn = new TChain("gtree");
tn->AddFile(input.c_str());
int nevt = tn->GetEntries();
if (gNEvents != -999) {
LOG(FIT) << "Overriding number of events by user from " << nevt << " to " << gNEvents << std::endl;
nevt = gNEvents;
}
NtpMCEventRecord* genientpl = NULL;
tn->SetBranchAddress("gmcrec", &genientpl);
// Have the TH1D go from MonoEnergy/2 to MonoEnergy/2
TH1D* fluxhist = new TH1D("flux", "flux", 1000, MonoEnergy/2., MonoEnergy*2.);
fluxhist->Fill(MonoEnergy);
fluxhist->Scale(1, "width");
// Make Event Hist
TH1D* eventhist = (TH1D*)fluxhist->Clone();
eventhist->Reset();
TH1D* xsechist = (TH1D*)eventhist->Clone();
// Create maps
std::map<std::string, TH1D*> modexsec;
std::map<std::string, TH1D*> modecount;
std::vector<std::string> genieids;
std::vector<std::string> targetids;
std::vector<std::string> interids;
// Loop over all events
for (int i = 0; i < nevt; i++) {
tn->GetEntry(i);
StopTalking();
EventRecord& event = *(genientpl->event);
GHepParticle* neu = event.Probe();
StartTalking();
// Get XSec From Spline
GHepRecord genie_record = static_cast<GHepRecord>(event);
double xsec = (genie_record.XSec() / (1E-38 * genie::units::cm2));
// Parse Interaction String
std::string mode = genie_record.Summary()->AsString();
std::vector<std::string> modevec = GeneralUtils::ParseToStr(mode, ";");
std::string targ = (modevec[0] + ";" + modevec[1]);
std::string inter = mode;
// Fill lists of Unique IDS
if (std::find(targetids.begin(), targetids.end(), targ) ==
targetids.end()) {
targetids.push_back(targ);
}
if (std::find(interids.begin(), interids.end(), inter) == interids.end()) {
interids.push_back(inter);
}
// Create entries Mode Maps
if (modexsec.find(mode) == modexsec.end()) {
genieids.push_back(mode);
modexsec[mode] = (TH1D*)xsechist->Clone();
modecount[mode] = (TH1D*)xsechist->Clone();
modexsec[mode]->GetYaxis()->SetTitle("d#sigma/dE_{#nu} #times 10^{-38} (events weighted by #sigma)");
modecount[mode]->GetYaxis()->SetTitle("Number of events in file");
}
// Fill XSec Histograms
modexsec[mode]->Fill(neu->E(), xsec);
modecount[mode]->Fill(neu->E());
// Fill total event hist
eventhist->Fill(neu->E());
- if (i % (nevt / 20) == 0) {
+ // Clear Event
+ genientpl->Clear();
+
+ size_t freq = nevt / 20;
+ if (freq && !(i % freq)) {
LOG(FIT) << "Processed " << i << "/" << nevt
<< " GENIE events (E: " << neu->E()
<< " GeV, xsec: " << xsec << " E-38 cm^2/nucleon)" << std::endl;
}
-
- // Clear Event
- genientpl->Clear();
}
LOG(FIT) << "Processed all events" << std::endl;
TFile* outputfile;
// If no output is specified just append to the file
if (!gOutputFile.length()) {
tn->GetEntry(0);
outputfile = tn->GetFile();
outputfile->cd();
} else {
outputfile = new TFile(gOutputFile.c_str(), "RECREATE");
outputfile->cd();
QLOG(FIT, "Cloning input vector to output file: " << gOutputFile);
TTree* cloneTree = tn->CloneTree();
cloneTree->SetDirectory(outputfile);
cloneTree->Write();
QLOG(FIT, "Cloning input nova_wgts to output file: " << gOutputFile);
+ // ***********************************
+ // ***********************************
+ // FUDGE FOR NOVA MINERVA WORKSHOP
// Also check for the nova_wgts tree from Jeremy
TChain *nova_chain = new TChain("nova_wgts");
nova_chain->AddFile(input.c_str());
TTree* nova_tree = nova_chain->GetTree();
if (!nova_tree) {
QLOG(FIT, "Could not find nova_wgts tree in " << gOutputFile);
} else {
QLOG(FIT, "Found nova_wgts tree in " << gOutputFile);
}
if (nova_tree) {
nova_tree->SetDirectory(outputfile);
nova_tree->Write();
}
QLOG(FIT, "Done cloning tree.");
}
LOG(FIT) << "Getting splines in mono-energetic..." << std::endl;
// Save each of the reconstructed splines to file
std::map<std::string, TH1D*> modeavg;
TDirectory* inddir = (TDirectory*)outputfile->Get("IndividualGENIESplines");
if (!inddir) inddir = (TDirectory*)outputfile->mkdir("IndividualGENIESplines");
inddir->cd();
// Loop over GENIE ID's and get MEC count
int MECcount = 0;
bool MECcorrect = FitPar::Config().GetParB("CorrectGENIEMECNorm");
for (UInt_t i = 0; i < genieids.size(); i++) {
if (genieids[i].find("MEC") != std::string::npos) {
MECcount++;
}
}
LOG(FIT) << "Found " << MECcount << " repeated MEC instances." << std::endl;
for (UInt_t i = 0; i < genieids.size(); i++) {
std::string mode = genieids[i];
modexsec[mode]->Write((mode + "_summed_xsec").c_str(), TObject::kOverwrite);
modecount[mode]->Write((mode + "_summed_evt").c_str(), TObject::kOverwrite);
// Form extra avg xsec map -> Reconstructed spline
modeavg[mode] = (TH1D*)modexsec[mode]->Clone();
modeavg[mode]->GetYaxis()->SetTitle("#sigma (E_{#nu}) #times 10^{-38} (cm^{2}/target)");
modeavg[mode]->Divide(modecount[mode]);
if (MECcorrect && (mode.find("MEC") != std::string::npos)) {
modeavg[mode]->Scale(1.0 / double(MECcount));
}
modeavg[mode]->Write((mode + "_rec_spline").c_str(), TObject::kOverwrite);
}
TDirectory* targdir = (TDirectory*)outputfile->Get("TargetGENIESplines");
if (!targdir) targdir = (TDirectory*)outputfile->mkdir("TargetGENIESplines");
targdir->cd();
LOG(FIT) << "Getting Target Splines" << std::endl;
// For each target save a total spline
std::map<std::string, TH1D*> targetsplines;
for (uint i = 0; i < targetids.size(); i++) {
std::string targ = targetids[i];
LOG(FIT) << "Getting target " << i << ": " << targ << std::endl;
targetsplines[targ] = (TH1D*)xsechist->Clone();
targetsplines[targ]->GetYaxis()->SetTitle("#sigma (E_{#nu}) #times 10^{-38} (cm^{2}/target)");
LOG(FIT) << "Created target spline for " << targ << std::endl;
for (uint j = 0; j < genieids.size(); j++) {
std::string mode = genieids[j];
if (mode.find(targ) != std::string::npos) {
LOG(FIT) << " Mode " << mode << " contains " << targ << " target" << std::endl;
targetsplines[targ]->Add(modeavg[mode]);
+ LOG(FIT) << "Finished with Mode " << mode << " " << modeavg[mode]->Integral() << std::endl;
}
}
LOG(FIT) << "Saving target spline:" << targ << std::endl;
targetsplines[targ]->Write(("Total_" + targ).c_str(), TObject::kOverwrite);
}
LOG(FIT) << "Getting total splines" << std::endl;
// Now we have each of the targets we need to create a total cross-section.
int totalnucl = 0;
// Get the targets specified by the user, separated by commas
std::vector<std::string> targprs = GeneralUtils::ParseToStr(target, ",");
TH1D* totalxsec = (TH1D*)xsechist->Clone();
for (uint i = 0; i < targprs.size(); i++) {
std::string targpdg = targprs[i];
// Check that we found the user requested target in GENIE
bool FoundTarget = false;
for (std::map<std::string, TH1D*>::iterator iter = targetsplines.begin();
iter != targetsplines.end(); iter++) {
std::string targstr = iter->first;
TH1D* xsec = iter->second;
if (targstr.find(targpdg) != std::string::npos) {
FoundTarget = true;
LOG(FIT) << "Adding target spline " << targstr << " Integral = " << xsec->Integral("width") << std::endl;
totalxsec->Add(xsec);
int nucl = atoi(targpdg.c_str());
totalnucl += int((nucl % 10000) / 10);
}
}
// Check that targets were all found
if (!FoundTarget) {
ERR(WRN) << "Didn't find target " << targpdg << " in the list of targets recorded by GENIE" << std::endl;
ERR(WRN) << " The list of targets you requested is: " << std::endl;
for (uint i = 0; i < targprs.size(); ++i) ERR(WRN) << " " << targprs[i] << std::endl;
ERR(WRN) << " The list of targets found in GENIE is: " << std::endl;
for (std::map<std::string, TH1D*>::iterator iter = targetsplines.begin(); iter != targetsplines.end(); iter++) ERR(WRN) << " " << iter->first<< std::endl;
}
}
outputfile->cd();
totalxsec->GetYaxis()->SetTitle("#sigma (E_{#nu}) #times 10^{-38} (cm^{2}/nucleon)");
totalxsec->Write("nuisance_xsec", TObject::kOverwrite);
eventhist = (TH1D*)fluxhist->Clone();
eventhist->Multiply(totalxsec);
eventhist->GetYaxis()->SetTitle((std::string("Event rate (N = #sigma #times #Phi) #times 10^{-38} (cm^{2}/nucleon) #times ")+eventhist->GetYaxis()->GetTitle()).c_str());
LOG(FIT) << "Dividing by Total Nucl = " << totalnucl << std::endl;
eventhist->Scale(1.0 / double(totalnucl));
eventhist->Write("nuisance_events", TObject::kOverwrite);
fluxhist->Write("nuisance_flux", TObject::kOverwrite);
LOG(FIT) << "Inclusive XSec Per Nucleon = " << eventhist->Integral("width") * 1E-38 / fluxhist->Integral("width") << std::endl;
LOG(FIT) << "XSec Hist Integral = " << totalxsec->Integral("width") << std::endl;
outputfile->Close();
return;
}
void RunGENIEPrepare(std::string input, std::string flux, std::string target,
std::string output) {
LOG(FIT) << "Running GENIE Prepare with flux..." << std::endl;
// Get Flux Hist
std::vector<std::string> fluxvect = GeneralUtils::ParseToStr(flux, ",");
- TH1D* fluxhist = NULL;
+ TH1* fluxhist = NULL;
if (fluxvect.size() == 3) {
double from = GeneralUtils::StrToDbl(fluxvect[0]);
double to = GeneralUtils::StrToDbl(fluxvect[1]);
double step = GeneralUtils::StrToDbl(fluxvect[2]);
int nstep = ceil((to - from) / step);
to = from + step * nstep;
QLOG(FIT, "Generating flat flux histogram from "
<< from << " to " << to << " with bins " << step
<< " wide (NBins = " << nstep << ").");
fluxhist = new TH1D("spectrum", ";E_{#nu} (GeV);Count (A.U.)", nstep, from, to);
for (Int_t bi_it = 1; bi_it < fluxhist->GetXaxis()->GetNbins(); ++bi_it) {
fluxhist->SetBinContent(bi_it, 1.0 / double(step * nstep));
}
fluxhist->SetDirectory(0);
} else if (fluxvect.size() == 2) {
TFile* fluxfile = new TFile(fluxvect[0].c_str(), "READ");
if (!fluxfile->IsZombie()) {
- fluxhist = (TH1D*)(fluxfile->Get(fluxvect[1].c_str()));
+ fluxhist = dynamic_cast<TH1D*>(fluxfile->Get(fluxvect[1].c_str()));
if (!fluxhist) {
ERR(FTL) << "Couldn't find histogram named: \"" << fluxvect[1]
<< "\" in file: \"" << fluxvect[0] << std::endl;
throw;
}
fluxhist->SetDirectory(0);
}
} else if (fluxvect.size() == 1) {
MonoEnergy = GeneralUtils::StrToDbl(fluxvect[0]);
RunGENIEPrepareMono(input, target, output);
return;
} else {
LOG(FTL) << "Bad flux specification: \"" << flux << "\"." << std::endl;
throw;
}
// Setup TTree
TChain* tn = new TChain("gtree");
if (input.find_first_of(',') != std::string::npos) {
std::vector<std::string> inputvect = GeneralUtils::ParseToStr(input, ",");
for (size_t iv_it = 0; iv_it < inputvect.size(); ++iv_it) {
tn->AddFile(inputvect[iv_it].c_str());
QLOG(FIT, "Added input file: " << inputvect[iv_it]);
}
} else { // The Add form can accept wildcards.
tn->Add(input.c_str());
}
int nevt = tn->GetEntries();
if (gNEvents != -999) {
LOG(FIT) << "Overriding number of events by user from " << nevt << " to " << gNEvents << std::endl;
nevt = gNEvents;
}
if (!nevt) {
THROW("Couldn't load any events from input specification: \""
<< input.c_str() << "\"");
} else {
QLOG(FIT, "Found " << nevt << " input entries in " << input);
}
- StopTalking();
NtpMCEventRecord* genientpl = NULL;
- StartTalking();
tn->SetBranchAddress("gmcrec", &genientpl);
// Make Event and xsec Hist
TH1D* eventhist = (TH1D*)fluxhist->Clone();
eventhist->Reset();
TH1D* xsechist = (TH1D*)eventhist->Clone();
// Create maps
std::map<std::string, TH1D*> modexsec;
std::map<std::string, TH1D*> modecount;
std::vector<std::string> genieids;
std::vector<std::string> targetids;
std::vector<std::string> interids;
-
// Loop over all events
for (int i = 0; i < nevt; i++) {
tn->GetEntry(i);
// Hussssch GENIE
StopTalking();
// Get the event
EventRecord& event = *(genientpl->event);
// Get the neutrino
GHepParticle* neu = event.Probe();
StartTalking();
// Get XSec From Spline
// Get the GHepRecord
GHepRecord genie_record = static_cast<GHepRecord>(event);
double xsec = (genie_record.XSec() / (1E-38 * genie::units::cm2));
// Parse Interaction String
std::string mode = genie_record.Summary()->AsString();
std::vector<std::string> modevec = GeneralUtils::ParseToStr(mode, ";");
std::string targ = (modevec[0] + ";" + modevec[1]);
std::string inter = mode;
// Get target nucleus
// Alternative ways of getting the summaries
//GHepParticle *target = genie_record.TargetNucleus();
//int pdg = target->Pdg();
// Fill lists of Unique IDS (neutrino and target)
if (std::find(targetids.begin(), targetids.end(), targ) == targetids.end()) {
targetids.push_back(targ);
}
// The full interaction list
if (std::find(interids.begin(), interids.end(), inter) == interids.end()) {
interids.push_back(inter);
}
// Create entries Mode Maps
if (modexsec.find(mode) == modexsec.end()) {
genieids.push_back(mode);
modexsec[mode] = (TH1D*)xsechist->Clone();
modecount[mode] = (TH1D*)xsechist->Clone();
modexsec[mode]->GetYaxis()->SetTitle("d#sigma/dE_{#nu} #times 10^{-38} (events weighted by #sigma)");
modecount[mode]->GetYaxis()->SetTitle("Number of events in file");
}
// Fill XSec Histograms
modexsec[mode]->Fill(neu->E(), xsec);
modecount[mode]->Fill(neu->E());
// Fill total event hist
eventhist->Fill(neu->E());
if (i % (nevt / 20) == 0) {
LOG(FIT) << "Processed " << i << "/" << nevt
<< " GENIE events (E: " << neu->E()
<< " GeV, xsec: " << xsec << " E-38 cm^2/nucleon)" << std::endl;
}
// Clear Event
genientpl->Clear();
}
LOG(FIT) << "Processed all events" << std::endl;
// Once event loop is done we can start saving stuff into the file
TFile* outputfile;
if (!gOutputFile.length()) {
tn->GetEntry(0);
outputfile = tn->GetFile();
outputfile->cd();
} else {
outputfile = new TFile(gOutputFile.c_str(), "RECREATE");
outputfile->cd();
QLOG(FIT, "Cloning input vector to output file: " << gOutputFile);
TTree* cloneTree = tn->CloneTree();
cloneTree->SetDirectory(outputfile);
cloneTree->Write();
+ // ********************************
+ // CLUDGE KLUDGE KLUDGE FOR NOVA
QLOG(FIT, "Cloning input nova_wgts to output file: " << gOutputFile);
// Also check for the nova_wgts tree from Jeremy
TChain *nova_chain = new TChain("nova_wgts");
nova_chain->AddFile(input.c_str());
TTree* nova_tree = nova_chain->CloneTree();
if (!nova_tree) {
QLOG(FIT, "Could not find nova_wgts tree in " << input);
} else {
QLOG(FIT, "Found nova_wgts tree in " << input);
nova_tree->SetDirectory(outputfile);
nova_tree->Write();
}
QLOG(FIT, "Done cloning tree.");
}
LOG(FIT) << "Getting splines..." << std::endl;
// Save each of the reconstructed splines to file
std::map<std::string, TH1D*> modeavg;
TDirectory* inddir = (TDirectory*)outputfile->Get("IndividualGENIESplines");
if (!inddir) inddir = (TDirectory*)outputfile->mkdir("IndividualGENIESplines");
inddir->cd();
// Loop over GENIE ID's and get MEC count
int MECcount = 0;
bool MECcorrect = FitPar::Config().GetParB("CorrectGENIEMECNorm");
for (UInt_t i = 0; i < genieids.size(); i++) {
if (genieids[i].find("MEC") != std::string::npos) {
MECcount++;
}
}
LOG(FIT) << "Found " << MECcount << " repeated MEC instances." << std::endl;
for (UInt_t i = 0; i < genieids.size(); i++) {
std::string mode = genieids[i];
modexsec[mode]->Write((mode + "_summed_xsec").c_str(), TObject::kOverwrite);
modecount[mode]->Write((mode + "_summed_evt").c_str(), TObject::kOverwrite);
// Form extra avg xsec map -> Reconstructed spline
modeavg[mode] = (TH1D*)modexsec[mode]->Clone();
modeavg[mode]->GetYaxis()->SetTitle("#sigma (E_{#nu}) #times 10^{-38} (cm^{2}/target)");
modeavg[mode]->Divide(modecount[mode]);
if (MECcorrect && (mode.find("MEC") != std::string::npos)) {
modeavg[mode]->Scale(1.0 / double(MECcount));
}
modeavg[mode]->Write((mode + "_rec_spline").c_str(), TObject::kOverwrite);
}
TDirectory* targdir = (TDirectory*)outputfile->Get("TargetGENIESplines");
if (!targdir) targdir = (TDirectory*)outputfile->mkdir("TargetGENIESplines");
targdir->cd();
LOG(FIT) << "Getting Target Splines" << std::endl;
-
// For each target save a total spline
std::map<std::string, TH1D*> targetsplines;
for (uint i = 0; i < targetids.size(); i++) {
std::string targ = targetids[i];
LOG(FIT) << "Getting target " << i << ": " << targ << std::endl;
targetsplines[targ] = (TH1D*)xsechist->Clone();
targetsplines[targ]->GetYaxis()->SetTitle("#sigma (E_{#nu}) #times 10^{-38} (cm^{2}/target)");
LOG(FIT) << "Created target spline for " << targ << std::endl;
for (uint j = 0; j < genieids.size(); j++) {
std::string mode = genieids[j];
// Look at all matching modes/targets
if (mode.find(targ) != std::string::npos) {
LOG(FIT) << " Mode " << mode << " contains " << targ << " target" << std::endl;
targetsplines[targ]->Add(modeavg[mode]);
+ LOG(FIT) << "Finished with Mode " << mode << " " << modeavg[mode]->Integral() << std::endl;
}
}
LOG(FIT) << "Saving target spline: " << targ << std::endl;
targetsplines[targ]->Write(("Total_" + targ).c_str(), TObject::kOverwrite);
}
LOG(FIT) << "Getting total splines" << std::endl;
// Now we have each of the targets we need to create a total cross-section.
int totalnucl = 0;
// This has structure target1[fraction1], target2[fraction2]
std::vector<std::string> targprs = GeneralUtils::ParseToStr(target, ",");
std::vector<std::string> targ_list;
std::vector<std::string> frac_list;
// Chop up the target string which has format TARGET1[fraction1],TARGET2[fraction2]
std::cout << "Targets: " << std::endl;
// Loop over the vector of strings "TARGET1[fraction1]" "TARGET2[fraction2]"
for (std::vector<std::string>::iterator it = targprs.begin(); it != targprs.end(); ++it) {
// Cut into "TARGET1" and "fraction1]"
std::vector<std::string> targind = GeneralUtils::ParseToStr(*it, "[");
std::cout << " " << *it << std::endl;
// Cut into "TARGET1" and "fraction1"
for (std::vector<std::string>::iterator jt = targind.begin(); jt != targind.end(); ++jt) {
if ((*jt).find("]") != std::string::npos) {
(*jt) = (*jt).substr(0, (*jt).find("]"));
//*jt = "hello";
frac_list.push_back(*jt);
// Won't find bracket for target
} else {
targ_list.push_back(*jt);
}
- std::cout << " " << *jt << std::endl;
}
}
targprs = targ_list;
- std::cout << "Target list: " << std::endl;
- for (std::vector<std::string>::iterator it = targ_list.begin(); it != targ_list.end(); it++) {
- std::cout << " " << *it << std::endl;
- }
-
- std::cout << "Fraction list: " << std::endl;
std::vector<double> targ_fractions;
double minimum = 1.0;
for (std::vector<std::string>::iterator it = frac_list.begin(); it != frac_list.end(); it++) {
std::cout << " " << *it << std::endl;
double frac = std::atof((*it).c_str());
targ_fractions.push_back(frac);
if (frac < minimum) minimum = frac;
}
- std::cout << "minimum target ratio: " << minimum << std::endl;
- std::cout << "Fraction list rescaled: " << std::endl;
std::vector<double>::iterator it = targ_fractions.begin();
std::vector<std::string>::iterator jt = targ_list.begin();
double scaling = 0;
for (; it != targ_fractions.end(); it++, jt++) {
// First get the mass number from the targ_list
int nucl = atoi((*jt).c_str());
nucl = (nucl%10000)/10;
// Gets the relative portions right
*it = (*it)/minimum;
// Scale relative the atomic mass
//(*it) *= (double(nucl)/(*it));
double tempscaling = double(nucl)/(*it);
if (tempscaling > scaling) scaling=tempscaling;
- std::cout << " " << "scaled by smallest: " << *it << std::endl;
- std::cout << " " << "scaling: " << tempscaling << std::endl;
}
- std::cout << "scaling: " << int(scaling+0.5) << std::endl;
it = targ_fractions.begin();
for (; it != targ_fractions.end(); it++) {
- std::cout << "before scaling and rounding: " << *it << std::endl;
// Round the scaling to nearest integer and multiply
*it *= int(scaling+0.5);
// Round to nearest integer
*it = int(*it+0.5);
- std::cout << "after scaling and rounding: " << *it << std::endl;
totalnucl += *it;
}
- std::cout << "total number of nucleons in one target: " << totalnucl << std::endl;
-
- it = targ_fractions.begin();
- jt = targ_list.begin();
- for (; it != targ_fractions.end(); it++, jt++) {
- int nucl = atoi((*jt).c_str());
- nucl = (nucl%10000)/10;
- std::cout << "final fraction: " << *jt << ": " << *it << "/" << totalnucl << "=" << *it / totalnucl << " or " << *it / nucl << " copies of element " << *jt << std::endl;
- }
-
- // Now count the total number of nucleons
-
TH1D* totalxsec = (TH1D*)xsechist->Clone();
// Loop over the specified targets by the user
for (uint i = 0; i < targprs.size(); i++) {
std::string targpdg = targprs[i];
// Check that we found the user requested target in GENIE
bool FoundTarget = false;
for (std::map<std::string, TH1D*>::iterator iter = targetsplines.begin(); iter != targetsplines.end(); iter++) {
std::string targstr = iter->first;
TH1D* xsec = iter->second;
// Match the user targets to the targets found in GENIE
if (targstr.find(targpdg) != std::string::npos) {
FoundTarget = true;
LOG(FIT) << "Adding target spline " << targstr << " Integral = " << xsec->Integral("width") << std::endl;
totalxsec->Add(xsec);
//int nucl = atoi(targpdg.c_str());
//totalnucl += int((nucl % 10000) / 10);
}
} // Looped over target splines
// Check that targets were all found
if (!FoundTarget) {
ERR(WRN) << "Didn't find target " << targpdg << " in the list of targets recorded by GENIE" << std::endl;
ERR(WRN) << " The list of targets you requested is: " << std::endl;
for (uint i = 0; i < targprs.size(); ++i) ERR(WRN) << " " << targprs[i] << std::endl;
ERR(WRN) << " The list of targets found in GENIE is: " << std::endl;
for (std::map<std::string, TH1D*>::iterator iter = targetsplines.begin(); iter != targetsplines.end(); iter++) ERR(WRN) << " " << iter->first<< std::endl;
}
}
outputfile->cd();
totalxsec->GetYaxis()->SetTitle("#sigma (E_{#nu}) #times 10^{-38} (cm^{2}/nucleon)");
totalxsec->Write("nuisance_xsec", TObject::kOverwrite);
eventhist = (TH1D*)fluxhist->Clone();
eventhist->Multiply(totalxsec);
eventhist->GetYaxis()->SetTitle((std::string("Event rate (N = #sigma #times #Phi) #times 10^{-38} (cm^{2}/nucleon) #times ")+eventhist->GetYaxis()->GetTitle()).c_str());
LOG(FIT) << "Dividing by Total Nucl = " << totalnucl << std::endl;
eventhist->Scale(1.0 / double(totalnucl));
eventhist->Write("nuisance_events", TObject::kOverwrite);
fluxhist->Write("nuisance_flux", TObject::kOverwrite);
LOG(FIT) << "Inclusive XSec Per Nucleon = " << eventhist->Integral("width") * 1E-38 / fluxhist->Integral("width") << std::endl;
LOG(FIT) << "XSec Hist Integral = " << totalxsec->Integral() << std::endl;
outputfile->Close();
return;
};
void PrintOptions() {
-
std::cout << "PrepareGENIEEvents NUISANCE app. " << std::endl
<< "Takes GHep Outputs and prepares events for NUISANCE."
<< std::endl
<< std::endl
<< "PrepareGENIE [-h,-help,--h,--help] [-i "
"inputfile1.root,inputfile2.root,inputfile3.root,...] "
<< "[-f flux_root_file.root,flux_hist_name] [-t "
"target1[frac1],target2[frac2],...]"
<< "[-n number_of_events (experimental)]"
<< std::endl
<< std::endl;
std::cout << "Prepare Mode [Default] : Takes a single GHep file, "
"reconstructs the original GENIE splines, "
<< " and creates a duplicate file that also contains the flux, "
"event rate, and xsec predictions that NUISANCE needs. "
<< std::endl;
std::cout << "Following options are required for Prepare Mode:" << std::endl;
std::cout << " [ -i inputfile.root ] : Reads in a single GHep input file "
"that needs the xsec calculation ran on it. "
<< std::endl;
std::cout << " [ -f flux_file.root,hist_name ] : Path to root file "
"containing the flux histogram the GHep records were generated "
"with."
<< " A simple method is to point this to the flux histogram genie "
"generatrs '-f /path/to/events/input-flux.root,spectrum'. "
<< std::endl;
std::cout << " [ -f elow,ehigh,estep ] : Energy range specification when no "
"flux file was used."
<< std::endl;
std::cout << " [ -t target ] : Target that GHepRecords were generated with. "
"Comma seperated list. E.g. for CH2 "
"target=1000060120,1000010010,1000010010"
<< std::endl;
std::cout << " [ -o outputfile.root ] : File to write prepared input file to."
<< std::endl;
std::cout << " [ -m Mono_E_nu_GeV ] : Run in mono-energetic mode with m GeV neutrino energy."
<< std::endl;
std::cout << " [ -n number_of_evt ] : Run with a reduced number of events for debugging purposes"
<< std::endl;
}
void ParseOptions(int argc, char* argv[]) {
bool flagopt = false;
// If No Arguments print commands
for (int i = 1; i < argc; ++i) {
if (!std::strcmp(argv[i], "-h")) {
flagopt = true;
break;
}
if (i + 1 != argc) {
// Cardfile
if (!std::strcmp(argv[i], "-h")) {
flagopt = true;
break;
} else if (!std::strcmp(argv[i], "-i")) {
gInputFiles = argv[i + 1];
++i;
} else if (!std::strcmp(argv[i], "-o")) {
gOutputFile = argv[i + 1];
++i;
} else if (!std::strcmp(argv[i], "-f")) {
gFluxFile = argv[i + 1];
++i;
} else if (!std::strcmp(argv[i], "-t")) {
gTarget = argv[i + 1];
++i;
} else if (!std::strcmp(argv[i], "-n")) {
gNEvents = GeneralUtils::StrToInt(argv[i + 1]);
++i;
} else if (!std::strcmp(argv[i], "-m")) {
MonoEnergy = GeneralUtils::StrToDbl(argv[i + 1]);
IsMonoE = true;
++i;
} else {
ERR(FTL) << "ERROR: unknown command line option given! - '" << argv[i]
<< " " << argv[i + 1] << "'" << std::endl;
PrintOptions();
break;
}
}
}
if (gInputFiles == "" && !flagopt) {
ERR(FTL) << "No input file(s) specified!" << std::endl;
flagopt = true;
}
if (gFluxFile == "" && !flagopt && !IsMonoE) {
ERR(FTL) << "No flux input specified for Prepare Mode" << std::endl;
flagopt = true;
}
if (gTarget == "" && !flagopt) {
ERR(FTL) << "No target specified for Prepare Mode" << std::endl;
flagopt = true;
}
if (argc < 1 || flagopt) {
PrintOptions();
exit(-1);
}
return;
}
diff --git a/app/PrepareNEUT.cxx b/app/PrepareNEUT.cxx
index 8a0c67e..d177a46 100644
--- a/app/PrepareNEUT.cxx
+++ b/app/PrepareNEUT.cxx
@@ -1,422 +1,424 @@
-#include <stdio.h>
-#include <stdlib.h>
#include "FitLogger.h"
#include "PlotUtils.h"
#include "StatUtils.h"
#include "TFile.h"
#include "TH1D.h"
#include "TTree.h"
+#include <stdio.h>
+#include <stdlib.h>
// If you don't have NEUT enabled, you shouldn't compile this...
#include "neutpart.h"
#include "neutvect.h"
std::string fInputFiles = "";
std::string fOutputFile = "";
std::string fFluxFile = "";
bool fFluxInGeV = false;
bool fIsMonoEFlux = false;
double fMonoEEnergy = 0xdeadbeef;
void PrintOptions();
-void ParseOptions(int argc, char* argv[]);
+void ParseOptions(int argc, char *argv[]);
void AddMonoRateHistogram(std::string inputList, double MonoE,
std::string output);
void CreateRateHistogram(std::string inputList, std::string flux,
std::string output);
//*******************************
-int main(int argc, char* argv[]) {
+int main(int argc, char *argv[]) {
//*******************************
LOG_VERB(FitPar::Config().GetParI("VERBOSITY"));
ERR_VERB(FitPar::Config().GetParI("ERROR"));
ParseOptions(argc, argv);
LOG(FIT) << "Running PrepareNEUT" << std::endl;
if (fIsMonoEFlux) {
AddMonoRateHistogram(fInputFiles, fMonoEEnergy, fOutputFile);
} else {
CreateRateHistogram(fInputFiles, fFluxFile, fOutputFile);
}
};
void AddMonoRateHistogram(std::string inputList, double MonoE,
std::string output) {
// Need to allow for more than one file... will do soon
- TChain* tn = new TChain("neuttree");
+ TChain *tn = new TChain("neuttree");
std::vector<std::string> inputs = GeneralUtils::ParseToStr(inputList, ",");
for (std::vector<std::string>::iterator it = inputs.begin();
it != inputs.end(); ++it) {
LOG(FIT) << "Adding " << *it << " to the output" << std::endl;
tn->AddFile((*it).c_str());
}
if (inputs.size() > 1 && output.empty()) {
ERR(FTL) << "You must provide a new output file name if you want to have "
"more than 1 input file!"
<< std::endl;
throw;
}
int nevts = tn->GetEntries();
if (!nevts) {
ERR(FTL) << "Either the input file is not from NEUT, or it's empty..."
<< std::endl;
throw;
}
- NeutVect* fNeutVect = NULL;
+ NeutVect *fNeutVect = NULL;
tn->SetBranchAddress("vectorbranch", &fNeutVect);
- TH1D* fluxHist = new TH1D("flux", "flux", 1000, 0, fFluxInGeV ? 10 : 10000);
+ TH1D *fluxHist = new TH1D("flux", "flux", 1000, 0, fFluxInGeV ? 10 : 10000);
fluxHist->Fill(MonoE);
fluxHist->Scale(1, "width");
// Make Event Hist
- TH1D* xsecHist = (TH1D*)fluxHist->Clone();
+ TH1D *xsecHist = (TH1D *)fluxHist->Clone();
xsecHist->Reset();
// Make a total cross section hist for shits and giggles
- TH1D* entryHist = (TH1D*)xsecHist->Clone();
+ TH1D *entryHist = (TH1D *)xsecHist->Clone();
double MeanE = 0;
for (int i = 0; i < nevts; ++i) {
tn->GetEntry(i);
- NeutPart* part = fNeutVect->PartInfo(0);
+ NeutPart *part = fNeutVect->PartInfo(0);
double E = part->fP.E();
double xsec = fNeutVect->Totcrs;
// Unit conversion
- if (fFluxInGeV) E *= 1E-3;
+ if (fFluxInGeV)
+ E *= 1E-3;
xsecHist->Fill(E, xsec);
entryHist->Fill(E);
MeanE += E;
if (i % (nevts / 20) == 0) {
LOG(FIT) << "Processed " << i << "/" << nevts << " NEUT events."
<< std::endl;
}
}
MeanE /= double(nevts);
LOG(FIT) << "Processed all events" << std::endl;
xsecHist->Divide(entryHist);
// This will be the evtrt histogram
- TH1D* evtHist = (TH1D*)xsecHist->Clone();
+ TH1D *evtHist = (TH1D *)xsecHist->Clone();
evtHist->Multiply(fluxHist);
// Check whether the overflow is empty. If not, advise that either the wrong
// flux histogram or units were used...
// If the events were generated with a limited range of the flux histogram,
// this may be benign
if (evtHist->Integral(0, -1) != evtHist->Integral() ||
evtHist->Integral(0, -1) == 0) {
- ERR(WRN) << "The input file and flux histogram provided do not match... "
- << std::endl;
+ ERR(WRN) << "The input file(" << evtHist->Integral(0, -1)
+ << ") and flux histogram provided do not match... " << std::endl;
ERR(WRN) << "Are the units correct (MeanE = " << MeanE
<< ", FluxHistoUpperLim: "
<< fluxHist->GetXaxis()->GetBinUpEdge(1000)
<< ")? Did you provide the correct flux file?" << std::endl;
ERR(WRN) << "Use output with caution..." << std::endl;
}
// Pick where the output should go
- TFile* outFile = NULL;
+ TFile *outFile = NULL;
if (!output.empty()) {
LOG(FIT) << "Saving histograms in " << output << std::endl;
outFile = new TFile(output.c_str(), "RECREATE");
} else {
LOG(FIT) << "Saving histograms in " << inputs[0] << std::endl;
outFile = new TFile(inputs[0].c_str(), "UPDATE");
}
outFile->cd();
std::string xsec_name = "xsec_PrepareNeut";
std::string flux_name = "flux_PrepareNeut";
std::string rate_name = "evtrt_PrepareNeut";
if (output.empty()) {
// Check whether we should overwrite existing histograms
std::string input_xsec = PlotUtils::GetObjectWithName(outFile, "xsec");
std::string input_flux = PlotUtils::GetObjectWithName(outFile, "flux");
std::string input_rate = PlotUtils::GetObjectWithName(outFile, "evtrt");
if (!input_xsec.empty()) {
LOG(FIT) << "Updating histogram: " << input_xsec << std::endl;
xsec_name = input_xsec;
}
if (!input_flux.empty()) {
LOG(FIT) << "Updating histogram: " << input_flux << std::endl;
flux_name = input_flux;
}
if (!input_rate.empty()) {
LOG(FIT) << "Updating histogram: " << input_rate << std::endl;
rate_name = input_rate;
}
} else {
LOG(FIT) << "Cloning neuttree into output file." << std::endl;
StopTalking();
- TTree* newtree = (TTree*)tn->CloneTree(-1, "fast");
+ TTree *newtree = (TTree *)tn->CloneTree(-1, "fast");
StartTalking();
newtree->Write();
}
xsecHist->Write(xsec_name.c_str(), TObject::kOverwrite);
fluxHist->Write(flux_name.c_str(), TObject::kOverwrite);
evtHist->Write(rate_name.c_str(), TObject::kOverwrite);
outFile->Close();
}
//*******************************
void CreateRateHistogram(std::string inputList, std::string flux,
std::string output) {
//*******************************
// Need to allow for more than one file... will do soon
- TChain* tn = new TChain("neuttree");
+ TChain *tn = new TChain("neuttree");
std::vector<std::string> inputs = GeneralUtils::ParseToStr(inputList, ",");
for (std::vector<std::string>::iterator it = inputs.begin();
it != inputs.end(); ++it) {
LOG(FIT) << "Adding " << *it << " to the output" << std::endl;
tn->AddFile((*it).c_str());
}
if (inputs.size() > 1 && output.empty()) {
ERR(FTL) << "You must provide a new output file name if you want to have "
"more than 1 input file!"
<< std::endl;
throw;
}
int nevts = tn->GetEntries();
if (!nevts) {
ERR(FTL) << "Either the input file is not from NEUT, or it's empty..."
<< std::endl;
throw;
}
- NeutVect* fNeutVect = NULL;
+ NeutVect *fNeutVect = NULL;
tn->SetBranchAddress("vectorbranch", &fNeutVect);
// Get Flux Hist
std::vector<std::string> fluxvect = GeneralUtils::ParseToStr(flux, ",");
- TH1D* fluxHist = NULL;
+ TH1D *fluxHist = NULL;
if (fluxvect.size() > 1) {
- TFile* fluxfile = new TFile(fluxvect[0].c_str(), "READ");
- fluxHist = (TH1D*)fluxfile->Get(fluxvect[1].c_str());
+ TFile *fluxfile = new TFile(fluxvect[0].c_str(), "READ");
+ fluxHist = (TH1D *)fluxfile->Get(fluxvect[1].c_str());
fluxHist->SetDirectory(0);
} else {
ERR(FTL) << "NO FLUX SPECIFIED" << std::endl;
throw;
}
// Decide what type of flux was given
if (fFluxInGeV)
LOG(FIT) << "Assuming flux histogram is in GeV" << std::endl;
else
LOG(FIT) << "Assuming flux histogram is in MeV" << std::endl;
// Make Event Hist
- TH1D* xsecHist = (TH1D*)fluxHist->Clone();
+ TH1D *xsecHist = (TH1D *)fluxHist->Clone();
xsecHist->Reset();
// Make a total cross section hist for shits and giggles
- TH1D* entryHist = (TH1D*)xsecHist->Clone();
+ TH1D *entryHist = (TH1D *)xsecHist->Clone();
for (int i = 0; i < nevts; ++i) {
tn->GetEntry(i);
- NeutPart* part = fNeutVect->PartInfo(0);
+ NeutPart *part = fNeutVect->PartInfo(0);
double E = part->fP.E();
double xsec = fNeutVect->Totcrs;
// Unit conversion
- if (fFluxInGeV) E *= 1E-3;
+ if (fFluxInGeV)
+ E *= 1E-3;
xsecHist->Fill(E, xsec);
entryHist->Fill(E);
if (i % (nevts / 20) == 0) {
LOG(FIT) << "Processed " << i << "/" << nevts << " NEUT events."
- << std::endl;
+ << "(Enu = " << E << ", xsec = " << xsec << ") " << std::endl;
}
}
LOG(FIT) << "Processed all events" << std::endl;
xsecHist->Divide(entryHist);
// This will be the evtrt histogram
- TH1D* evtHist = NULL;
+ TH1D *evtHist = NULL;
// If the integral of xsecHist is 0 the input file used a really old version
// of NEUT without Totcrs
if (!xsecHist->Integral(0, -1)) {
ERR(WRN) << "Old NEUT input file: events will not be correctly normalized"
<< std::endl;
- evtHist = (TH1D*)entryHist->Clone();
+ evtHist = (TH1D *)entryHist->Clone();
if (evtHist->Integral() != 0)
evtHist->Scale(fluxHist->Integral() / float(evtHist->Integral()));
} else {
- evtHist = (TH1D*)xsecHist->Clone();
+ evtHist = (TH1D *)xsecHist->Clone();
evtHist->Multiply(fluxHist);
}
// Check whether the overflow is empty. If not, advise that either the wrong
// flux histogram or units were used...
// If the events were generated with a limited range of the flux histogram,
// this may be benign
if (evtHist->Integral(0, -1) != evtHist->Integral() ||
evtHist->Integral(0, -1) == 0) {
- ERR(WRN) << "The input file and flux histogram provided do not match... "
- << std::endl;
+ ERR(WRN) << "The input file(" << evtHist->Integral(0, -1)
+ << ") and flux histogram provided do not match... " << std::endl;
ERR(WRN) << "Are the units correct? Did you provide the correct flux file?"
<< std::endl;
ERR(WRN) << "Use output with caution..." << std::endl;
}
// Pick where the output should go
- TFile* outFile = NULL;
+ TFile *outFile = NULL;
if (!output.empty()) {
LOG(FIT) << "Saving histograms in " << output << std::endl;
outFile = new TFile(output.c_str(), "RECREATE");
} else {
LOG(FIT) << "Saving histograms in " << inputs[0] << std::endl;
outFile = new TFile(inputs[0].c_str(), "UPDATE");
}
outFile->cd();
std::string xsec_name = "xsec_PrepareNeut";
std::string flux_name = "flux_PrepareNeut";
std::string rate_name = "evtrt_PrepareNeut";
if (output.empty()) {
// Check whether we should overwrite existing histograms
std::string input_xsec = PlotUtils::GetObjectWithName(outFile, "xsec");
std::string input_flux = PlotUtils::GetObjectWithName(outFile, "flux");
std::string input_rate = PlotUtils::GetObjectWithName(outFile, "evtrt");
if (!input_xsec.empty()) {
LOG(FIT) << "Updating histogram: " << input_xsec << std::endl;
xsec_name = input_xsec;
}
if (!input_flux.empty()) {
LOG(FIT) << "Updating histogram: " << input_flux << std::endl;
flux_name = input_flux;
}
if (!input_rate.empty()) {
LOG(FIT) << "Updating histogram: " << input_rate << std::endl;
rate_name = input_rate;
}
} else {
LOG(FIT) << "Cloning neuttree into output file." << std::endl;
StopTalking();
- TTree* newtree = (TTree*)tn->CloneTree(-1, "fast");
+ TTree *newtree = (TTree *)tn->CloneTree(-1, "fast");
StartTalking();
newtree->Write();
}
xsecHist->Write(xsec_name.c_str(), TObject::kOverwrite);
fluxHist->Write(flux_name.c_str(), TObject::kOverwrite);
evtHist->Write(rate_name.c_str(), TObject::kOverwrite);
outFile->Close();
return;
}
void PrintOptions() {
std::cout << "PrepareNEUT NUISANCE app. " << std::endl
<< "Produces or recalculates evtrt and flux histograms necessary "
"for NUISANCE normalization."
<< std::endl;
std::cout << "PrepareNEUT: " << std::endl;
std::cout << " [-h,-help,--h,--help]" << std::endl;
std::cout << " -i inputfile1.root,inputfile2.root,inputfile3.root,..."
<< std::endl;
std::cout << " Takes any number of files, but assumes all are "
"produced with a single flux"
<< std::endl;
std::cout << " -f flux_root_file.root,flux_hist_name" << std::endl;
std::cout << " Path to root file containing the flux histogram used "
"when generating the NEUT files"
<< std::endl;
std::cout << " [-o outputfile.root] " << std::endl;
std::cout
<< " If an output file is not given, the input file will be used"
<< std::endl;
std::cout << " If more than one input file is given, an output file "
"must be given"
<< std::endl;
std::cout << " [-G]" << std::endl;
std::cout << " Flux is assumed to be in MeV. This switch indicates "
"the input flux is in GeV"
<< std::endl;
std::cout << " [-m E_nu]" << std::endl;
std::cout << " Used to add dummy flux and evt rate histograms to "
"mono-energetic vectors. Adheres to the -G flag."
<< std::endl;
}
-void ParseOptions(int argc, char* argv[]) {
+void ParseOptions(int argc, char *argv[]) {
bool flagopt = false;
// If No Arguments print commands
for (int i = 1; i < argc; ++i) {
if (!std::strcmp(argv[i], "-h")) {
flagopt = true;
break;
} else if (!std::strcmp(argv[i], "-G")) {
fFluxInGeV = true;
continue;
}
if (i + 1 != argc) {
// Cardfile
if (!std::strcmp(argv[i], "-h")) {
flagopt = true;
break;
} else if (!std::strcmp(argv[i], "-i")) {
fInputFiles = argv[i + 1];
++i;
} else if (!std::strcmp(argv[i], "-o")) {
fOutputFile = argv[i + 1];
++i;
} else if (!std::strcmp(argv[i], "-f")) {
fFluxFile = argv[i + 1];
++i;
} else if (!std::strcmp(argv[i], "-m")) {
fIsMonoEFlux = true;
fMonoEEnergy = GeneralUtils::StrToDbl(argv[i + 1]);
++i;
} else {
ERR(FTL) << "ERROR: unknown command line option given! - '" << argv[i]
<< " " << argv[i + 1] << "'" << std::endl;
PrintOptions();
break;
}
}
}
if (fInputFiles == "" && !flagopt) {
ERR(FTL) << "No input file(s) specified!" << std::endl;
flagopt = true;
}
if (fFluxFile == "" && (!flagopt) && (!fIsMonoEFlux)) {
ERR(FTL) << "No flux input specified!" << std::endl;
flagopt = true;
}
if (argc < 1 || flagopt) {
PrintOptions();
exit(-1);
}
return;
}
diff --git a/app/nuisbac.cxx b/app/nuisbac.cxx
new file mode 100644
index 0000000..0b6df2f
--- /dev/null
+++ b/app/nuisbac.cxx
@@ -0,0 +1,9 @@
+#include "Initialiser.h"
+
+int main(){
+
+ for(size_t i = 0; i < 100; ++i){
+ nuisance_init();
+ }
+
+}
diff --git a/cmake/GENIESetup.cmake b/cmake/GENIESetup.cmake
index 7c0b2c5..11c64b3 100644
--- a/cmake/GENIESetup.cmake
+++ b/cmake/GENIESetup.cmake
@@ -1,157 +1,168 @@
# 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/>.
################################################################################
# TODO
# check system for libxml2
# check whether we need the includes
# check if we can use a subset of the GENIE libraries
################################################################################
# Check Dependencies
################################################################################
################################# GENIE ######################################
if(GENIE STREQUAL "")
cmessage(FATAL_ERROR "Variable GENIE is not defined. "
"The location of a pre-built GENIE install must be defined either as"
" $ cmake -DGENIE=/path/to/GENIE or as and environment vairable"
" $ export GENIE=/path/to/GENIE")
endif()
if (BUILD_GEVGEN)
cmessage(STATUS "Building custom gevgen")
LIST(APPEND EXTRA_CXX_FLAGS -D__GEVGEN_ENABLED__)
endif()
# Extract GENIE VERSION
if (GENIE_VERSION STREQUAL "AUTO")
execute_process (COMMAND ${CMAKE_SOURCE_DIR}/cmake/getgenieversion.sh ${GENIE}
OUTPUT_VARIABLE GENIE_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
execute_process (COMMAND genie-config
--libs OUTPUT_VARIABLE GENIE_LD_FLAGS_STR OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process (COMMAND genie-config
--topsrcdir OUTPUT_VARIABLE GENIE_INCLUDES_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REGEX MATCH "-L\([^ ]+\) \(.*\)$" PARSE_GENIE_LIBS_MATCH ${GENIE_LD_FLAGS_STR})
cmessage(DEBUG "genie-config --libs: ${GENIE_LD_FLAGS_STR}")
if(NOT PARSE_GENIE_LIBS_MATCH)
cmessage(FATAL_ERROR "Expected to be able to parse the result of genie-config --libs to a lib directory and a list of libraries to include, but got: \"${GENIE_LD_FLAGS_STR}\"")
endif()
set(GENIE_LIB_DIR ${CMAKE_MATCH_1})
set(GENIE_LIBS_RAW ${CMAKE_MATCH_2})
string(REPLACE "-l" "" GENIE_LIBS_STRIPED "${GENIE_LIBS_RAW}")
cmessage(STATUS "GENIE version : ${GENIE_VERSION}")
cmessage(STATUS "GENIE libdir : ${GENIE_LIB_DIR}")
cmessage(STATUS "GENIE libs : ${GENIE_LIBS_STRIPED}")
string(REGEX MATCH "ReinSeghal" WASMATCHED ${GENIE_LIBS_STRIPED})
if(WASMATCHED AND GENIE_VERSION STREQUAL "210")
set(GENIE_SEHGAL ${GENIE_LIBS_STRIPED})
STRING(REPLACE "ReinSeghal" "ReinSehgal" GENIE_LIBS_STRIPED ${GENIE_SEHGAL})
cmessage(DEBUG "Fixed inconsistency in library naming: ${GENIE_LIBS_STRIPED}")
endif()
string(REGEX MATCH "ReWeight" WASMATCHED ${GENIE_LIBS_STRIPED})
if(NOT WASMATCHED)
set(GENIE_LIBS_STRIPED "GReWeight ${GENIE_LIBS_STRIPED}")
cmessage(DEBUG "Force added ReWeight library: ${GENIE_LIBS_STRIPED}")
endif()
-string(REPLACE " " ";" GENIE_LIBS_LIST "${GENIE_LIBS_STRIPED}")
+string(REPLACE " " ";" GENIE_LIBS_LIST "-Wl,--start-group ${GENIE_LIBS_STRIPED} -Wl,--end-group")
cmessage(DEBUG "genie-config --libs -- MATCH1: ${CMAKE_MATCH_1}")
cmessage(DEBUG "genie-config --libs -- MATCH2: ${CMAKE_MATCH_2}")
cmessage(DEBUG "genie-config --libs -- libs stripped: ${GENIE_LIBS_STRIPED}")
cmessage(DEBUG "genie-config --libs -- libs list: ${GENIE_LIBS_LIST}")
################################ LHAPDF ######################################
if(LHAPDF_LIB STREQUAL "")
cmessage(FATAL_ERROR "Variable LHAPDF_LIB is not defined. The location of a pre-built lhapdf install must be defined either as $ cmake -DLHAPDF_LIB=/path/to/LHAPDF_libraries or as and environment vairable $ export LHAPDF_LIB=/path/to/LHAPDF_libraries")
endif()
if(LHAPDF_INC STREQUAL "")
cmessage(FATAL_ERROR "Variable LHAPDF_INC is not defined. The location of a pre-built lhapdf install must be defined either as $ cmake -DLHAPDF_INC=/path/to/LHAPDF_includes or as and environment vairable $ export LHAPDF_INC=/path/to/LHAPDF_includes")
endif()
if(LHAPATH STREQUAL "")
cmessage(FATAL_ERROR "Variable LHAPATH is not defined. The location of a the LHAPATH directory must be defined either as $ cmake -DLHAPATH=/path/to/LHAPATH or as and environment variable $ export LHAPATH=/path/to/LHAPATH")
endif()
################################ LIBXML ######################################
if(LIBXML2_LIB STREQUAL "")
cmessage(FATAL_ERROR "Variable LIBXML2_LIB is not defined. The location of a pre-built libxml2 install must be defined either as $ cmake -DLIBXML2_LIB=/path/to/LIBXML2_libraries or as and environment vairable $ export LIBXML2_LIB=/path/to/LIBXML2_libraries")
endif()
if(LIBXML2_INC STREQUAL "")
cmessage(FATAL_ERROR "Variable LIBXML2_INC is not defined. The location of a pre-built libxml2 install must be defined either as $ cmake -DLIBXML2_INC=/path/to/LIBXML2_includes or as and environment vairable $ export LIBXML2_INC=/path/to/LIBXML2_includes")
endif()
############################### log4cpp ######################################
if(LOG4CPP_LIB STREQUAL "")
- cmessage(FATAL_ERROR "Variable LOG4CPP_LIB is not defined. The location of a pre-built log4cpp install must be defined either as $ cmake -DLOG4CPP_LIB=/path/to/LOG4CPP_libraries or as and environment vairable $ export LOG4CPP_LIB=/path/to/LOG4CPP_libraries")
+ find_program(LOG4CPPCFG log4cpp-config)
+ if(NOT LOG4CPPCFG STREQUAL "LOG4CPPCFG-NOTFOUND")
+ execute_process (COMMAND ${LOG4CPPCFG}
+ --pkglibdir OUTPUT_VARIABLE LOG4CPP_LIB OUTPUT_STRIP_TRAILING_WHITESPACE)
+ else()
+ message(FATAL_ERROR "Variable LOG4CPP_LIB is not defined. The location of a pre-built log4cpp install must be defined either as $ cmake -DLOG4CPP_LIB=/path/to/LOG4CPP_libraries or as and environment vairable $ export LOG4CPP_LIB=/path/to/LOG4CPP_libraries")
+ endif()
endif()
if(LOG4CPP_INC STREQUAL "")
- cmessage(FATAL_ERROR "Variable LOG4CPP_INC is not defined. The location of a pre-built log4cpp install must be defined either as $ cmake -DGENIE_LOG4CPP_INC=/path/to/LOG4CPP_includes or as and environment vairable $ export LOG4CPP_INC=/path/to/LOG4CPP_includes")
+ find_program(LOG4CPPCFG log4cpp-config)
+ if(NOT LOG4CPPCFG STREQUAL "LOG4CPPCFG-NOTFOUND")
+ execute_process (COMMAND ${LOG4CPPCFG}
+ --pkgincludedir OUTPUT_VARIABLE LOG4CPP_INC OUTPUT_STRIP_TRAILING_WHITESPACE)
+ else()
+ message(FATAL_ERROR "Variable LOG4CPP_INC is not defined. The location of a pre-built log4cpp install must be defined either as $ cmake -DGENIE_LOG4CPP_INC=/path/to/LOG4CPP_includes or as and environment vairable $ export LOG4CPP_INC=/path/to/LOG4CPP_includes")
+ endif()
endif()
################################################################################
LIST(APPEND EXTRA_CXX_FLAGS -D__GENIE_ENABLED__ -D__GENIE_VERSION__=${GENIE_VERSION})
LIST(APPEND RWENGINE_INCLUDE_DIRECTORIES
${GENIE_INCLUDES_DIR}
${GENIE_INCLUDES_DIR}/GHEP
${GENIE_INCLUDES_DIR}/Ntuple
${GENIE_INCLUDES_DIR}/ReWeight
${GENIE_INCLUDES_DIR}/Apps
${GENIE_INCLUDES_DIR}/FluxDrivers
${GENIE_INCLUDES_DIR}/EVGDrivers
${LHAPDF_INC}
${LIBXML2_INC}
${LOG4CPP_INC})
SAYVARS()
LIST(APPEND EXTRA_LINK_DIRS
${GENIE_LIB_DIR}
${LHAPDF_LIB}
${LIBXML2_LIB}
${LOG4CPP_LIB})
-#LIST(REVERSE EXTRA_LIBS)
-#LIST(REVERSE GENIE_LIBS_LIST)
+LIST(APPEND EXTRA_LIBS -Wl,--start-group)
LIST(APPEND EXTRA_LIBS ${GENIE_LIBS_LIST})
-#LIST(REVERSE EXTRA_LIBS)
+LIST(APPEND EXTRA_LIBS -Wl,--end-group)
LIST(APPEND EXTRA_LIBS LHAPDF xml2 log4cpp)
if(USE_PYTHIA8)
set(NEED_PYTHIA8 TRUE)
set(NEED_ROOTPYTHIA8 TRUE)
else()
set(NEED_PYTHIA6 TRUE)
set(NEED_ROOTPYTHIA6 TRUE)
endif()
set(NEED_ROOTEVEGEN TRUE)
SET(USE_GENIE TRUE CACHE BOOL "Whether to enable GENIE (reweight) support. Requires external libraries. <FALSE>" FORCE)
diff --git a/cmake/NEUTSetup.cmake b/cmake/NEUTSetup.cmake
index 85788d5..c4665af 100644
--- a/cmake/NEUTSetup.cmake
+++ b/cmake/NEUTSetup.cmake
@@ -1,83 +1,114 @@
# 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(NEUT_ROOT STREQUAL "")
cmessage(FATAL_ERROR "Variable NEUT_ROOT is not defined. Please export environment variable NEUT_ROOT or configure with -DNEUT_ROOT=/path/to/NEUT. This must be set to point to a prebuilt NEUT instance.")
endif()
if(CERN STREQUAL "")
cmessage(FATAL_ERROR "Variable CERN is not defined. Please export environment variable CERN or configure with -DCERN=/path/to/CERNLIB. This must be set to point to a prebuilt CERNLIB instance.")
endif()
if(CERN_LEVEL STREQUAL "")
cmessage(FATAL_ERROR "Variable CERN_LEVEL is not defined. Please export environment variable CERN_LEVEL or configure with -DCERN_LEVEL=XXXX (likely to be 2005).")
endif()
-set(NEUT_LIB_DIR ${NEUT_ROOT}/lib/Linux_pc)
+if(NOT IS_NEUT_54)
+ set(NEUT_LIB_DIR ${NEUT_ROOT}/lib/Linux_pc)
+else()
+ set(NEUT_LIB_DIR ${NEUT_ROOT}/lib)
+endif()
set(NEUT_CLASS ${NEUT_ROOT}/src/neutclass)
LIST(APPEND EXTRA_CXX_FLAGS -D__NEUT_ENABLED__ )
LIST(APPEND RWENGINE_INCLUDE_DIRECTORIES
${NEUT_ROOT}/include
${NEUT_ROOT}/src/neutclass
${NEUT_ROOT}/src/reweight)
-
LIST(APPEND EXTRA_LINK_DIRS
- ${NEUT_ROOT}/lib/Linux_pc
+ ${NEUT_LIB_DIR}
${CERN}/${CERN_LEVEL}/lib
${NEUT_ROOT}/src/reweight)
-LIST(APPEND EXTRA_LIBS
- NReWeight
- neutcore
- nuccorrspl
- nuceff
- partnuck
- skmcsvc
- tauola
- jetset74
- pdflib804
- mathlib
- packlib
- pawlib)
-
-LIST(APPEND EXTRA_SHAREDOBJS
+if(NOT IS_NEUT_54)
+ LIST(APPEND EXTRA_LIBS
+ NReWeight
+ neutcore
+ nuccorrspl
+ nuceff
+ partnuck
+ skmcsvc
+ tauola
+ jetset74
+ pdflib804
+ mathlib
+ packlib
+ pawlib)
+else()
+ LIST(APPEND EXTRA_LIBS
+ NReWeight
+ neutcore_5.4.0
+ nuccorspl_5.4.0 #typo in NEUT, may hopefully disappear
+ nuceff_5.4.0
+ partnuck_5.4.0
+ skmcsvc_5.4.0
+ tauola_5.4.0
+ HT2p2h_5.4.0
+ N1p1h_5.4.0
+ jetset74
+ pdflib804
+ mathlib
+ packlib
+ pawlib)
+endif()
+
+set(NEUT_ROOT_LIBS)
+
+LIST(APPEND NEUT_ROOT_LIBS
${NEUT_CLASS}/neutctrl.so
${NEUT_CLASS}/neutfsivert.so)
# Check for new versions of NEUT with NUCLEON FSI
if(EXISTS "${NEUT_CLASS}/neutnucfsistep.so")
set(NEUT_NUCFSI 1)
LIST(APPEND EXTRA_CXX_FLAGS -D__NEUT_NUCFSI_ENABLED__ )
- LIST(APPEND EXTRA_SHAREDOBJS
+ LIST(APPEND NEUT_ROOT_LIBS
${NEUT_CLASS}/neutnucfsistep.so
${NEUT_CLASS}/neutnucfsivert.so
)
endif()
-LIST(APPEND EXTRA_SHAREDOBJS
- ${NEUT_CLASS}/neutrootTreeSingleton.so
+if(NOT IS_NEUT_54)
+ LIST(APPEND NEUT_ROOT_LIBS
+ ${NEUT_CLASS}/neutrootTreeSingleton.so)
+endif()
+
+LIST(APPEND NEUT_ROOT_LIBS
${NEUT_CLASS}/neutvtx.so
${NEUT_CLASS}/neutfsipart.so
${NEUT_CLASS}/neutpart.so
${NEUT_CLASS}/neutvect.so
)
+
+foreach(OBJ ${NEUT_ROOT_LIBS})
+ LIST(APPEND EXTRA_SHAREDOBJS ${OBJ})
+endforeach()
diff --git a/cmake/ROOTSetup.cmake b/cmake/ROOTSetup.cmake
index ebf9dee..f6597a3 100644
--- a/cmake/ROOTSetup.cmake
+++ b/cmake/ROOTSetup.cmake
@@ -1,162 +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/>.
################################################################################
if ( NOT DEFINED ENV{ROOTSYS} )
cmessage (FATAL_ERROR "$ROOTSYS is not defined, please set up ROOT first.")
else()
cmessage(STATUS "Using ROOT installed at $ENV{ROOTSYS}")
set(CMAKE_ROOTSYS $ENV{ROOTSYS})
endif()
# Get cflags from ROOT
execute_process (COMMAND root-config
--cflags OUTPUT_VARIABLE ROOT_CXX_FLAGS_RAW OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REPLACE " " ";" ROOT_CXX_FLAGS "${ROOT_CXX_FLAGS_RAW}")
# Get libdir from ROOT
execute_process (COMMAND root-config
--libdir OUTPUT_VARIABLE ROOT_LIBDIR OUTPUT_STRIP_TRAILING_WHITESPACE)
# Get version from ROOT
execute_process (COMMAND root-config
--version OUTPUT_VARIABLE ROOT_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
# Get features from ROOT
execute_process (COMMAND root-config
--features OUTPUT_VARIABLE ROOT_FEATURES OUTPUT_STRIP_TRAILING_WHITESPACE)
LIST(APPEND EXTRA_LINK_DIRS ${ROOT_LIBDIR})
LIST(APPEND ROOT_LIBS
Core
Cint
RIO
XMLIO
Net
Hist
Graf
Graf3d
Gpad
Tree
Rint
Postscript
Matrix
Physics
MathCore
Thread
EG
Geom
GenVector)
if(USE_MINIMIZER)
if("${ROOT_FEATURES}" MATCHES "minuit2")
cmessage(STATUS "ROOT built with MINUIT2 support")
LIST(APPEND EXTRA_CXX_FLAGS -D__MINUIT2_ENABLED__)
else()
cmessage(FATAL_ERROR "ROOT built without MINUIT2 support but minimizer functionality requested. Either configure with -DUSE_MINIMIZER=FALSE or use a version of ROOT with MINUIT2 support.")
endif()
- string(REGEX MATCH "5.34/([0-9]+)" ROOTVERSMATCH ${ROOT_VERSION})
- if(NOT ROOTVERSMATCH OR ${CMAKE_MATCH_1} LESS "19")
- cmessage(FATAL_ERROR "ROOT Version: ${ROOT_VERSION} has out of date minimizer interface, but minimizer functionality requested. Please configure with -DUSE_MINIMIZER=FALSE or update to 5.34/19 or greater to enable minimization features.")
+ string(REGEX MATCH "6.*" ROOTVERSIXMATCH ${ROOT_VERSION})
+ if(ROOTVERSIXMATCH)
+ cmessage(STATUS "Using ROOT6, We are essentially flying blind here.")
+ LIST(REMOVE_ITEM ROOT_LIBS Cint)
+ LIST(APPEND EXTRA_CXX_FLAGS -DROOT6_USE_FIT_FITTER_INTERFACE)
+ set(USE_ROOT6 True)
+ else()
+ string(REGEX MATCH "5.34/([0-9]+)" ROOTVERSMATCH ${ROOT_VERSION})
+ if(NOT ROOTVERSMATCH OR ${CMAKE_MATCH_1} LESS "19")
+ cmessage(FATAL_ERROR "ROOT Version: ${ROOT_VERSION} has out of date minimizer interface, but minimizer functionality requested. Please configure with -DUSE_MINIMIZER=FALSE or update to 5.34/19 or greater to enable minimization features.")
+ endif()
endif()
endif()
if("${ROOT_FEATURES}" MATCHES "opengl")
cmessage(STATUS "ROOT built with OpenGL support")
LIST(APPEND ROOT_LIBS RGL)
endif()
if(DEFINED NEED_ROOTPYTHIA6 AND NEED_ROOTPYTHIA6)
LIST(APPEND ROOT_LIBS EGPythia6 Pythia6)
endif()
cmessage ( STATUS "[ROOT]: root-config --version: ${ROOT_VERSION} ")
cmessage ( STATUS "[ROOT]: root-config --cflags : ${ROOT_CXX_FLAGS} ")
cmessage ( STATUS "[ROOT]: root-config --libs : ${ROOT_LD_FLAGS} ")
LIST(APPEND EXTRA_CXX_FLAGS ${ROOT_CXX_FLAGS})
#Helper functions for building dictionaries
function(GenROOTDictionary OutputDictName Header LinkDef)
get_directory_property(incdirs INCLUDE_DIRECTORIES)
string(REPLACE ";" ";-I" LISTDIRINCLUDES "-I${incdirs}")
string(REPLACE " " ";" LISTCPPFLAGS "${EXTRA_CXX_FLAGS}")
#ROOT5 CINT cannot handle it.
list(REMOVE_ITEM LISTCPPFLAGS "-std=c++11")
message(STATUS "LISTCPPFLAGS: ${LISTCPPFLAGS}")
message(STATUS "LISTINCLUDES: ${LISTDIRINCLUDES}")
#Learn how to generate the Dict.cxx and Dict.hxx
add_custom_command(
OUTPUT "${OutputDictName}.cxx" "${OutputDictName}.h"
COMMAND rootcint
ARGS -f ${OutputDictName}.cxx -c
-p ${LISTDIRINCLUDES} ${LISTCPPFLAGS} ${Header} ${LinkDef}
DEPENDS ${Header};${LinkDef})
endfunction()
function(BuildROOTProject ProjectName InputFile CommaSeparatedClassesToDump LIBLINKMODE)
string(REPLACE "," ";" HeadersToDump ${CommaSeparatedClassesToDump})
set(OUTPUTFILES ${CMAKE_BINARY_DIR}/${ProjectName}/${ProjectName}ProjectSource.cxx
${CMAKE_BINARY_DIR}/${ProjectName}/${ProjectName}LinkDef.h
${CMAKE_BINARY_DIR}/${ProjectName}/${ProjectName}ProjectHeaders.h
${CMAKE_BINARY_DIR}/${ProjectName}/${ProjectName}ProjectInstances.h)
cmessage(STATUS "As part of ROOT project: ${ProjectName}")
foreach (header ${HeadersToDump})
LIST(APPEND OUTPUTFILES "${CMAKE_BINARY_DIR}/${ProjectName}/${header}.h")
cmessage(STATUS "Will generate: ${CMAKE_BINARY_DIR}/${ProjectName}/${header}.h")
endforeach()
add_custom_command(
OUTPUT ${OUTPUTFILES}
COMMAND ${CMAKE_BINARY_DIR}/src/Utils/DumpROOTClassesFromVector
ARGS ${InputFile}
${CMAKE_BINARY_DIR}/${ProjectName}
${CommaSeparatedClassesToDump}
VERBATIM
DEPENDS DumpROOTClassesFromVector)
add_custom_target(${ProjectName}_sources
DEPENDS ${OUTPUTFILES})
GenROOTDictionary(
${CMAKE_BINARY_DIR}/${ProjectName}/${ProjectName}ProjectDict
${CMAKE_BINARY_DIR}/${ProjectName}/${ProjectName}ProjectHeaders.h
${CMAKE_BINARY_DIR}/${ProjectName}/${ProjectName}LinkDef.h
)
add_custom_target(${ProjectName}ProjectDict
DEPENDS
${CMAKE_BINARY_DIR}/${ProjectName}/${ProjectName}ProjectDict.cxx
${CMAKE_BINARY_DIR}/${ProjectName}/${ProjectName}ProjectDict.h )
# add_dependencies(${ProjectName}ProjectDict ${ProjectName}_sources)
#ProjectSource.cxx includes ProjectDict.cxx, so no need to add to compilation.
set(ROAA_SOURCEFILES
${CMAKE_BINARY_DIR}/${ProjectName}/${ProjectName}ProjectSource.cxx)
add_library(${ProjectName} ${LIBLINKMODE} ${ROAA_SOURCEFILES})
add_dependencies(${ProjectName} ${ProjectName}ProjectDict)
endfunction()
diff --git a/cmake/c++CompilerSetup.cmake b/cmake/c++CompilerSetup.cmake
index 266b708..bd9adcb 100644
--- a/cmake/c++CompilerSetup.cmake
+++ b/cmake/c++CompilerSetup.cmake
@@ -1,109 +1,130 @@
# 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(USE_OMP)
LIST(APPEND EXTRA_CXX_FLAGS -fopenmp)
endif()
if(USE_DYNSAMPLES)
LIST(APPEND EXTRA_LIBS dl)
LIST(APPEND EXTRA_CXX_FLAGS -D__USE_DYNSAMPLES__)
endif()
set(CXX_WARNINGS -Wall )
cmessage(DEBUG "EXTRA_CXX_FLAGS: ${EXTRA_CXX_FLAGS}")
string(REPLACE ";" " " STR_EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${STR_EXTRA_CXX_FLAGS} ${CXX_WARNINGS}")
set(CMAKE_Fortran_FLAGS_RELEASE "-fPIC")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0")
if(USE_DYNSAMPLES)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fPIC")
set(CMAKE_Fortran_FLAGS_DEBUG "-fPIC")
endif()
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fPIC -O3")
if(CMAKE_BUILD_TYPE MATCHES DEBUG)
set(CURRENT_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_DEBUG})
elseif(CMAKE_BUILD_TYPE MATCHES RELEASE)
set(CURRENT_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_RELEASE})
else()
cmessage(FATAL_ERROR "[ERROR]: Unknown CMAKE_BUILD_TYPE (\"${CMAKE_BUILD_TYPE}\"): Should be \"DEBUG\" or \"RELEASE\".")
endif()
SET(STR_EXTRA_LINK_DIRS)
if(NOT EXTRA_LINK_DIRS STREQUAL "")
string(REPLACE ";" " -L" STR_EXTRA_LINK_DIRS "-L${EXTRA_LINK_DIRS}")
endif()
+
SET(STR_EXTRA_LIBS)
if(NOT EXTRA_LIBS STREQUAL "")
- string(REPLACE ";" " -l" STR_EXTRA_LIBS "-l${EXTRA_LIBS}")
+ SET(STR_EXTRA_LIBS_NO_SCRUB_LINKOPTS)
+ string(REPLACE ";" " -l" STR_EXTRA_LIBS_NO_SCRUB_LINKOPTS "-l${EXTRA_LIBS}")
+ string(REPLACE "-l-" "-" STR_EXTRA_LIBS ${STR_EXTRA_LIBS_NO_SCRUB_LINKOPTS})
endif()
+
SET(STR_EXTRA_SHAREDOBJS)
if(NOT EXTRA_SHAREDOBJS STREQUAL "")
string(REPLACE ";" " " STR_EXTRA_SHAREDOBJS "${EXTRA_SHAREDOBJS}")
endif()
SET(STR_EXTRA_LINK_FLAGS)
if(NOT EXTRA_LINK_FLAGS STREQUAL "")
string(REPLACE ";" " " STR_EXTRA_LINK_FLAGS "${EXTRA_LINK_FLAGS}")
endif()
cmessage(DEBUG "EXTRA_LINK_DIRS: ${STR_EXTRA_LINK_DIRS}")
cmessage(DEBUG "EXTRA_LIBS: ${STR_EXTRA_LIBS}")
cmessage(DEBUG "EXTRA_SHAREDOBJS: ${STR_EXTRA_SHAREDOBJS}")
cmessage(DEBUG "EXTRA_LINK_FLAGS: ${STR_EXTRA_LINK_FLAGS}")
if(NOT STR_EXTRA_LINK_DIRS STREQUAL "" AND NOT STR_EXTRA_LIBS STREQUAL "")
SET(CMAKE_DEPENDLIB_FLAGS "${STR_EXTRA_LINK_DIRS} ${STR_EXTRA_LIBS}")
endif()
+if(USE_NEUT)
+ foreach(OBJ ${NEUT_ROOT_LIBS})
+ if(NOT CMAKE_DEPENDLIB_FLAGS STREQUAL "")
+ SET(CMAKE_DEPENDLIB_FLAGS "${CMAKE_DEPENDLIB_FLAGS} ${OBJ}")
+ else()
+ SET(CMAKE_DEPENDLIB_FLAGS "${OBJ}")
+ endif()
+ endforeach()
+ foreach(OBJ ${NEUT_ROOT_LIBS})
+ if(NOT CMAKE_DEPENDLIB_FLAGS STREQUAL "")
+ SET(CMAKE_DEPENDLIB_FLAGS "${CMAKE_DEPENDLIB_FLAGS} ${OBJ}")
+ else()
+ SET(CMAKE_DEPENDLIB_FLAGS "${OBJ}")
+ endif()
+ endforeach()
+endif()
+
if(NOT EXTRA_SHAREDOBJS STREQUAL "")
if(NOT STR_EXTRA_LINK_FLAGS STREQUAL "")
SET(STR_EXTRA_LINK_FLAGS "${STR_EXTRA_SHAREDOBJS} ${STR_EXTRA_LINK_FLAGS}")
else()
SET(STR_EXTRA_LINK_FLAGS "${STR_EXTRA_SHAREDOBJS}")
endif()
endif()
if(NOT EXTRA_LINK_FLAGS STREQUAL "")
if(NOT CMAKE_LINK_FLAGS STREQUAL "")
SET(CMAKE_LINK_FLAGS "${CMAKE_LINK_FLAGS} ${STR_EXTRA_LINK_FLAGS}")
else()
SET(CMAKE_LINK_FLAGS "${STR_EXTRA_LINK_FLAGS}")
endif()
endif()
if(USE_OMP)
cmessage(FATAL_ERROR "No OMP features currently enabled so this is a FATAL_ERROR to let you know that you don't gain anything with this declaration.")
endif()
if (VERBOSE)
cmessage (STATUS "C++ Compiler : ${CXX_COMPILER_NAME}")
cmessage (STATUS " flags : ${CMAKE_CXX_FLAGS}")
cmessage (STATUS " Release flags : ${CMAKE_CXX_FLAGS_RELEASE}")
cmessage (STATUS " Debug flags : ${CMAKE_CXX_FLAGS_DEBUG}")
cmessage (STATUS " Link Flags : ${CMAKE_LINK_FLAGS}")
cmessage (STATUS " Lib Flags : ${CMAKE_DEPENDLIB_FLAGS}")
endif()
diff --git a/cmake/cacheVariables.cmake b/cmake/cacheVariables.cmake
index 94d4019..3d52cee 100644
--- a/cmake/cacheVariables.cmake
+++ b/cmake/cacheVariables.cmake
@@ -1,213 +1,216 @@
# 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/>.
################################################################################
function(CheckAndSetDefaultEnv VARNAME DEFAULT CACHETYPE DOCSTRING ENVNAME)
#cmessage(DEBUG "Trying to assign variable ${VARNAME} into the cache.")
if(NOT DEFINED ${VARNAME})
if(DEFINED ENV{${ENVNAME}} AND NOT $ENV{${ENVNAME}} STREQUAL "")
set(${VARNAME} $ENV{${ENVNAME}} CACHE ${CACHETYPE} ${DOCSTRING})
cmessage(DEBUG " Read ${VARNAME} from ENVVAR ${ENVNAME} as $ENV{${ENVNAME}}.")
else()
set(${VARNAME} ${DEFAULT} CACHE ${CACHETYPE} ${DOCSTRING})
endif()
else()
set(${VARNAME} ${${VARNAME}} CACHE ${CACHETYPE} ${DOCSTRING})
unset(${VARNAME})
endif()
cmessage(CACHE "--Set cache variable: \"${VARNAME}\" to \"${${VARNAME}}\", in cache ${CACHETYPE}.")
endfunction()
function(CheckAndSetDefaultCache VARNAME DEFAULT CACHETYPE DOCSTRING)
# cmessage(DEBUG "Trying to assign variable ${VARNAME} into the cache.")
if(NOT DEFINED ${VARNAME})
set(${VARNAME} ${DEFAULT} CACHE ${CACHETYPE} ${DOCSTRING})
else()
set(${VARNAME} ${${VARNAME}} CACHE ${CACHETYPE} ${DOCSTRING})
unset(${VARNAME})
endif()
cmessage(CACHE "--Set cache variable: \"${VARNAME}\" to \"${${VARNAME}}\", in cache ${CACHETYPE}.")
endfunction()
function(CheckAndSetDefault VARNAME DEFAULT)
# cmessage(DEBUG "Trying to assign variable ${VARNAME}.")
if(NOT DEFINED ${VARNAME})
set(${VARNAME} ${DEFAULT} PARENT_SCOPE)
set(${VARNAME} ${DEFAULT})
endif()
cmessage(CACHE "--Set variable: \"${VARNAME}\" to \"${${VARNAME}}\".")
endfunction()
CheckAndSetDefaultCache(VERBOSE TRUE BOOL "Whether to configure loudly.")
set (CMAKE_SKIP_BUILD_RPATH TRUE)
#Changes default install path to be a subdirectory of the build dir.
#Can set build dir at configure time with -DCMAKE_INSTALL_PREFIX=/install/path
if(CMAKE_INSTALL_PREFIX STREQUAL "" OR CMAKE_INSTALL_PREFIX STREQUAL
"/usr/local")
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/${CMAKE_SYSTEM_NAME}")
elseif(NOT DEFINED CMAKE_INSTALL_PREFIX)
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/${CMAKE_SYSTEM_NAME}")
endif()
if(CMAKE_BUILD_TYPE STREQUAL "")
set(CMAKE_BUILD_TYPE DEBUG)
elseif(NOT DEFINED CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE DEBUG)
endif()
CheckAndSetDefaultCache(EXTRA_SETUP_SCRIPT "" PATH "The path to an extra script to inject into the NUISANCE setup script. <>")
CheckAndSetDefaultCache(USE_MINIMIZER TRUE INTERNAL "Whether we are using the ROOT minimization libraries. <TRUE>")
+CheckAndSetDefaultCache(USE_ROOT6 FALSE INTERNAL "Whether we are using the ROOT 6. <FALSE>")
+
CheckAndSetDefaultCache(USE_HEPMC FALSE BOOL "Whether to enable HepMC input support. <FALSE>")
CheckAndSetDefaultEnv(HEPMC "" PATH "Path to HepMC source tree root directory. Overrides environment variable \$HEPMC <>" HEPMC)
CheckAndSetDefaultCache(HEPMC_MOMUNIT "GEV" STRING "HepMC momentum units [MEV|GEV]. <GEV>")
CheckAndSetDefaultCache(HEPMC_LENUNIT "CM" STRING "HepMC momentum units [MM|CM]. <CM>")
CheckAndSetDefaultCache(HEPMC_USED_EP FALSE INTERNAL "Whether we built HepMC or not. <FALSE>")
CheckAndSetDefaultCache(USE_NEUT FALSE BOOL "Whether to enable NEUT (reweight) support. Requires external libraries. <FALSE>")
+CheckAndSetDefaultCache(IS_NEUT_54 FALSE BOOL "Whether to enabled NEUT is version 5.4 or greater. <FALSE>")
CheckAndSetDefaultEnv(NEUT_ROOT "" PATH "Path to NEUT source tree root directory. Overrides environment variable \$NEUT_ROOT <>" NEUT_ROOT)
CheckAndSetDefaultEnv(CERN "" PATH "Path to CERNLIB source tree root directory that NEUT was built against. Overrides environment variable \$CERN <>" CERN)
CheckAndSetDefaultEnv(CERN_LEVEL "" STRING "CERNLIB Library version. Overrides environment variable \$CERN_LEVEL <>" CERN_LEVEL)
CheckAndSetDefaultCache(USE_NuWro FALSE BOOL "Whether to enable NuWro support. <FALSE>")
CheckAndSetDefaultEnv(NUWRO "" PATH "Path to NuWro source tree root directory. Overrides environment variable \$NUWRO <>" NUWRO)
CheckAndSetDefaultEnv(NUWRO_INC "" PATH "Path to NuWro installed includes directory, needs to contain \"params_all.h\". Overrides environment variable \$NUWRO_INC <>" NUWRO_INC)
CheckAndSetDefaultCache(NUWRO_INPUT_FILE "" FILEPATH "Path to an input NuWro event vector, which can be used to build NuWro i/o libraries. <>")
CheckAndSetDefaultCache(NUWRO_BUILT_FROM_FILE FALSE INTERNAL "Whether the NuWro libraries were built by NUISANCE. <FALSE>")
CheckAndSetDefaultCache(USE_NuWro_RW FALSE BOOL "Whether to try and build support for NuWro reweighting. <FALSE>")
CheckAndSetDefaultCache(USE_NuWro_SRW_Event FALSE BOOL "Whether to use cut down NuWro reweight event format. Requires NuWro reweight. <FALSE>")
CheckAndSetDefaultCache(USE_GENIE FALSE BOOL "Whether to enable GENIE (reweight) support. Requires external libraries. <FALSE>")
CheckAndSetDefaultCache(GENIE_VERSION "AUTO" STRING "GENIE Version <AUTO>")
CheckAndSetDefaultEnv(GENIE "" PATH "Path to GENIE source tree root directory. Overrides environment variable \$GENIE <>" GENIE)
CheckAndSetDefaultEnv(LHAPDF_LIB "" PATH "Path to pre-built LHAPDF libraries. Overrides environment variable \$LHAPDF_LIB. <>" LHAPDF_LIB)
CheckAndSetDefaultEnv(LHAPDF_INC "" PATH "Path to installed LHAPDF headers. Overrides environment variable \$LHAPDF_INC. <>" LHAPDF_INC)
CheckAndSetDefaultEnv(LHAPATH "" PATH "Path to LHA PDF inputs. Overrides environment variable \$LHAPATH. <>" LHAPATH)
CheckAndSetDefaultEnv(LIBXML2_LIB "" PATH "Path to pre-built LIBXML2 libraries. Overrides environment variable \$LIBXML2_LIB. <>" LIBXML2_LIB)
CheckAndSetDefaultEnv(LIBXML2_INC "" PATH "Path to installed LIBXML2 headers. Overrides environment variable \$LIBXML2_INC. <>" LIBXML2_INC)
CheckAndSetDefaultEnv(LOG4CPP_LIB "" PATH "Path to pre-built LOG4CPP libraries. Overrides environment variable \$LOG4CPP_LIB. <>" LOG4CPP_LIB)
CheckAndSetDefaultEnv(LOG4CPP_INC "" PATH "Path to installed LOG4CPP headers. Overrides environment variable \$LOG4CPP_INC. <>" LOG4CPP_INC)
CheckAndSetDefaultCache(BUILD_GEVGEN FALSE BOOL "Whether to build nuisance_gevgen app.")
CheckAndSetDefaultCache(USE_T2K FALSE BOOL "Whether to enable T2KReWeight support. Requires external libraries. <FALSE>")
CheckAndSetDefaultEnv(T2KREWEIGHT "" PATH "Path to installed T2KREWEIGHTReWeight. Overrides environment variable \$T2KREWEIGHT. <>" T2KREWEIGHT)
CheckAndSetDefaultCache(USE_NIWG FALSE BOOL "Whether to enable (T2K) NIWG ReWeight support. Requires external libraries. <FALSE>")
CheckAndSetDefaultEnv(NIWG_ROOT "" PATH "Path to installed NIWGReWeight. Overrides environment variable \$NIWG. <>" NIWG)
CheckAndSetDefaultCache(USE_MINERvA_RW FALSE BOOL "Whether to enable MINERvA ReWeight support. <FALSE>")
CheckAndSetDefaultEnv(PYTHIA6 "" PATH "Path to directory containing libPythia6.so. Overrides environment variable \$PYTHIA6 <>" PYTHIA6)
CheckAndSetDefaultEnv(PYTHIA8 "" PATH "Path to directory containing libPythia8.so. Overrides environment variable \$PYTHIA8 <>" PYTHIA8)
CheckAndSetDefaultCache(USE_PYTHIA8 FALSE BOOL "Whether to enable PYTHIA8 event support. <FALSE>")
CheckAndSetDefaultCache(USE_GiBUU TRUE BOOL "Whether to enable GiBUU event support. <TRUE>")
CheckAndSetDefaultCache(BUILD_GiBUU FALSE BOOL "Whether to build supporting GiBUU event tools along with a patched version of GiBUU. <FALSE>")
CheckAndSetDefaultCache(USE_NUANCE TRUE BOOL "Whether to enable NUANCE event support. <TRUE>")
CheckAndSetDefaultCache(USE_PROB3PP FALSE BOOL "Whether to download and compile in Prob3++ support. <FALSE>")
-CheckAndSetDefaultCache(NO_EXTERNAL_UPDATE TRUE BOOL "Whether to perform the update target for external dependencies. <TRUE>")
+CheckAndSetDefaultCache(NO_EXTERNAL_UPDATE FALSE BOOL "Whether to perform the update target for external dependencies. Note this may produce errors for CMake < 3.8 where a bug was fixed for the feature that this option invokes. <FALSE>")
-CheckAndSetDefaultCache(USE_GPERFTOOLS FALSE BOOL "Whether to compile in google performance tools. <TRUE>")
+CheckAndSetDefaultCache(USE_GPERFTOOLS FALSE BOOL "Whether to compile in google performance tools. <FALSE>")
CheckAndSetDefault(NEED_PYTHIA6 FALSE)
CheckAndSetDefault(NEED_PYTHIA8 FALSE)
CheckAndSetDefault(NEED_ROOTEVEGEN FALSE)
CheckAndSetDefault(NEED_ROOTPYTHIA6 FALSE)
CheckAndSetDefaultCache(USE_OMP FALSE BOOL "Whether to enable multicore features (there currently are none...). <FALSE>")
-CheckAndSetDefaultCache(USE_DYNSAMPLES FALSE BOOL "Whether to enable the dynamic sample loader. <FALSE>")
+CheckAndSetDefaultCache(USE_DYNSAMPLES TRUE BOOL "Whether to enable the dynamic sample loader. <TRUE>")
CheckAndSetDefault(NO_EXPERIMENTS FALSE)
cmessage(STATUS "NO_EXPERIMENTS: ${NO_EXPERIMENTS}")
CheckAndSetDefaultCache(NO_ANL ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build ANL samples. <-DNO_EXPERIMENTS=FALSE>")
CheckAndSetDefaultCache(NO_ArgoNeuT ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build ArgoNeuT samples. <-DNO_EXPERIMENTS=FALSE>")
CheckAndSetDefaultCache(NO_BEBC ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build BEBC samples. <-DNO_EXPERIMENTS=FALSE>")
CheckAndSetDefaultCache(NO_BNL ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build BNL samples. <-DNO_EXPERIMENTS=FALSE>")
CheckAndSetDefaultCache(NO_FNAL ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build FNAL samples. <-DNO_EXPERIMENTS=FALSE>")
CheckAndSetDefaultCache(NO_GGM ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build GGM samples. <-DNO_EXPERIMENTS=FALSE>")
CheckAndSetDefaultCache(NO_K2K ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build K2K samples. <-DNO_EXPERIMENTS=FALSE>")
CheckAndSetDefaultCache(NO_MINERvA ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build MINERvA samples. <-DNO_EXPERIMENTS=FALSE>")
CheckAndSetDefaultCache(NO_MiniBooNE ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build MiniBooNE samples. <-DNO_EXPERIMENTS=FALSE>")
CheckAndSetDefaultCache(NO_T2K ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build T2K samples. <-DNO_EXPERIMENTS=FALSE>")
CheckAndSetDefaultCache(NO_SciBooNE ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build SciBooNE samples. <-DNO_EXPERIMENTS=FALSE>")
function(SAYVARS)
LIST(APPEND VARS
USE_HEPMC
HEPMC
HEPMC_MOMUNIT
HEPMC_LENUNIT
HEPMC_USED_EP
USE_NEUT
NEUT_ROOT
CERN
CERN_LEVEL
USE_NuWro
NUWRO
NUWRO_INC
NUWRO_INPUT_FILE
NUWRO_BUILT_FROM_FILE
USE_GENIE
GENIE
LHAPDF_LIB
LHAPDF_INC
LIBXML2_LIB
LIBXML2_INC
LOG4CPP_LIB
GENIE_LOG4CPP_INC
BUILD_GEVGEN
USE_T2K
USE_NIWG
USE_GiBUU
BUILD_GiBUU
USE_NUANCE
NO_EXTERNAL_UPDATE
USE_GPERFTOOLS
NO_ANL
NO_ArgoNeuT
NO_BEBC
NO_BNL
NO_FNAL
NO_GGM
NO_K2K
NO_MINERvA
NO_MiniBooNE
NO_T2K
NO_SciBooNE)
foreach(v ${VARS})
if(DEFINED ${v})
cmessage(DEBUG "VARIABLE: \"${v}\" = \"${${v}}\"")
endif()
endforeach(v)
endfunction()
diff --git a/cmake/setup.sh.in b/cmake/setup.sh.in
index 2fbbe90..123aaef 100644
--- a/cmake/setup.sh.in
+++ b/cmake/setup.sh.in
@@ -1,155 +1,155 @@
# 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
### Adapted from https://unix.stackexchange.com/questions/4965/keep-duplicates-out-of-path-on-source
function add_to_PATH () {
for d; do
d=$(cd -- "$d" && { pwd -P || pwd; }) 2>/dev/null # canonicalize symbolic links
if [ -z "$d" ]; then continue; fi # skip nonexistent directory
if [ "$d" == "/usr/bin" ] || [ "$d" == "/usr/bin64" ] || [ "$d" == "/usr/local/bin" ] || [ "$d" == "/usr/local/bin64" ]; then
case ":$PATH:" in
*":$d:"*) :;;
*) export PATH=$PATH:$d;;
esac
else
case ":$PATH:" in
*":$d:"*) :;;
*) export PATH=$d:$PATH;;
esac
fi
done
}
function add_to_LD_LIBRARY_PATH () {
for d; do
d=$(cd -- "$d" && { pwd -P || pwd; }) 2>/dev/null # canonicalize symbolic links
if [ -z "$d" ]; then continue; fi # skip nonexistent directory
if [ "$d" == "/usr/lib" ] || [ "$d" == "/usr/lib64" ] || [ "$d" == "/usr/local/lib" ] || [ "$d" == "/usr/local/lib64" ]; then
case ":$LD_LIBRARY_PATH:" in
*":$d:"*) :;;
*) export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$d;;
esac
else
case ":$LD_LIBRARY_PATH:" in
*":$d:"*) :;;
*) export LD_LIBRARY_PATH=$d:$LD_LIBRARY_PATH;;
esac
fi
done
}
if [ "@EXTRA_SETUP_SCRIPT@" ]; then
if [ ! -e @EXTRA_SETUP_SCRIPT@ ]; then
echo "[WARN]: Extra setup script \"@EXTRA_SETUP_SCRIPT@\" requested, but could not be found. Skipping..."
else
echo "[INFO]: Sourcing extra setup from \"@EXTRA_SETUP_SCRIPT@\"."
. @EXTRA_SETUP_SCRIPT@
fi
fi
add_to_PATH "@CMAKE_INSTALL_PREFIX@/bin"
add_to_LD_LIBRARY_PATH "@CMAKE_INSTALL_PREFIX@/lib"
if [ ! "${ROOTSYS}" ]; then
echo "[INFO]: Sourcing ROOT from: @CMAKE_ROOTSYS@"
source "@CMAKE_ROOTSYS@/bin/thisroot.sh"
fi
if [ "@USE_T2K@" != "FALSE" ]; then
echo "[INFO]: Adding T2K paths to the environment."
export T2KREWEIGHT=@T2KREWEIGHT@
add_to_LD_LIBRARY_PATH "@T2KREWEIGHT@/lib"
fi
if [ "@USE_NIWG@" != "FALSE" ]; then
echo "[INFO]: Adding NIWG paths to the environment."
export NIWG=@NIWG_ROOT@
export NIWGREWEIGHT_INPUTS=@NIWG_ROOT@/inputs
add_to_LD_LIBRARY_PATH "@NIWG_ROOT@"
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@
- add_to_LD_LIBRARY_PATH "${NEUT_ROOT}/lib/Linux_pc" "${NEUT_ROOT}/src/reweight"
+ add_to_LD_LIBRARY_PATH "${NEUT_LIB_DIR}" "${NEUT_ROOT}/src/reweight"
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@"
add_to_PATH "@NUWRO@/bin"
add_to_LD_LIBRARY_PATH "@NUWRO@/build/@CMAKE_SYSTEM_NAME@/lib"
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@"
add_to_LD_LIBRARY_PATH "@PYTHIA6@"
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
add_to_PATH "@GENIE@/bin"
add_to_LD_LIBRARY_PATH "@GENIE@/lib" "@LHAPDF_LIB@" "@LIBXML2_LIB@" "@LOG4CPP_LIB@"
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/parameters/dial_conversion.card b/parameters/dial_conversion.card
index b34a7d9..0227a07 100644
--- a/parameters/dial_conversion.card
+++ b/parameters/dial_conversion.card
@@ -1,23 +1,38 @@
# par Name Units Nominal FracErr ConvFunc
neut_parameter MaCCQE GeV 1.21*(1.0+x*0.16)
+neut_parameter MaNFFRES GeV 0.95*(1.0+x*0.157894737)
+neut_parameter CA5RES x 1.01*(1.0+x*0.247524752)
+neut_parameter BgSclRES x 1.30*(1.0+x*0.153846154)
+
+neut_parameter FrAbs_pi x 1.1*(1.0+x*0.5)
+neut_parameter FrInelLow_pi x 1*(1.0+x*0.5)
+neut_parameter FrInelHigh_pi x 1.8*(1.0+x*0.3)
+neut_parameter FrPiProd_pi x 1*(1.0+x*0.5)
+neut_parameter FrCExLow_pi x 1*(1.0+x*0.5)
+neut_parameter FrCExHigh_pi x 1.8*(1.0+x*0.3)
+
niwg_parameter NIWGMEC_Norm_C12 % 100.0*(1.0+x)
niwg_parameter VecFFCCQE MDLQE x
niwg_parameter CCQEFermiSurfMom MeV 217*(1.0+x*0.15)
-
t2k_parameter NIWG2014a_pF_C12 MeV 217*(1.0+x*0.073733)
t2k_parameter NIWG2014a_pF_O16 MeV 225*(1.0+x*0.071111)
t2k_parameter NIWGMEC_PDDWeight_C12 x 0.5*(1.0+x*1.0)
t2k_parameter NIWGMEC_PDDWeight_O16 x 0.5*(1.0+x*1.0)
t2k_parameter NXSec_MaCCQE GeV 1.21*(1.0+x*0.165289256)
t2k_parameter NXSec_MaNFFRES GeV 0.95*(1.0+x*0.157894737)
t2k_parameter NXSec_CA5RES x 1.01*(1.0+x*0.247524752)
t2k_parameter NXSec_BgSclCCRES x 1.30*(1.0+x*0.153846154)
t2k_parameter NIWG_Effective_rpaCCQE_A x 1.0*(1.0 + x*0.1)
t2k_parameter NIWG_Effective_rpaCCQE_B x 1.0*(1.0 + x*0.1)
t2k_parameter NIWG_Effective_rpaCCQE_C x 1.0*(1.0 + x*0.1)
t2k_parameter NIWG_Effective_rpaCCQE_D x 1.0*(1.0 + x*0.1)
t2k_parameter NIWG_Effective_rpaCCQE_U x 1.0*(1.0 + x*0.1)
+
+nuwro_parameter kNuwro_Ma_CCQE MeV 1200*(1.0+x*0.160)
+nuwro_parameter kNuwro_MaRES GeV 0.940*(1.0+x*0.1)
+nuwro_parameter kNuwro_CA5 x 1.19*(1.0+x*0.1)
+nuwro_parameter kNuwro_SPPBkgScale x 1.0*(1.0+x*0.26)
diff --git a/scripts/nuissamples b/scripts/nuissamples
index 7721fe5..22d72ce 100755
--- a/scripts/nuissamples
+++ b/scripts/nuissamples
@@ -1,19 +1,27 @@
-#!/bin/sh
+#!/bin/bash
+
+if [[ -z ${NUISANCE} ]]; then
+ echo "NUISANCE environment variable is not set"
+ echo "Getting the sample list depends on this"
+ echo "Please do:"
+ echo "export NUISANCE=YOUR_INSTALL && ./nuissamples"
+ exit
+fi
for line in $(grep compare $NUISANCE/src/FCN/SampleList.cxx); do
- if [[ $line != *"compare"* ]]; then
+ if [[ "${line}" != *"compare"* ]]; then
continue
fi
line=${line//\!name\.compare\(/}
line=${line//\(/}
line=${line//\)/}
line=${line//\"/}
line=${line//\{}
if [[ $line != *"$1"* ]];
then
continue
fi
echo ${2}${line}${3}
done
diff --git a/src/Electron/CLAS6-EG2_Accepter.cxx b/src/Electron/CLAS6-EG2_Accepter.cxx
index d2c4307..5f766c9 100644
--- a/src/Electron/CLAS6-EG2_Accepter.cxx
+++ b/src/Electron/CLAS6-EG2_Accepter.cxx
@@ -1,177 +1,258 @@
#include "ISmearcepter.h"
#include "TH3D.h"
#include "TRandom3.h"
#include <cstdlib>
-#define DEBUG_CLASACCEPT
+// #define DEBUG_CLASACCEPT 1
+
+struct EffMap {
+ TH3D *Generated;
+ TH3D *Accepted;
+
+ void Build(TFile *inpF, std::string const &GenName,
+ std::string const &AccName) {
+ Generated = dynamic_cast<TH3D *>(inpF->Get(GenName.c_str()));
+ Accepted = dynamic_cast<TH3D *>(inpF->Get(AccName.c_str()));
+
+ if (!Generated) {
+ std::cout << "[ERROR]: Could not retrieve \"accepted\" histogram: \""
+ << AccName << "\" from file: \"" << inpF->GetName() << "\"."
+ << std::endl;
+ exit(1);
+ }
+ if (!Accepted) {
+ std::cout << "[ERROR]: Could not retrieve \"generated\" histogram: \""
+ << GenName << "\" from file: \"" << inpF->GetName() << "\"."
+ << std::endl;
+ exit(1);
+ }
+
+ Generated = static_cast<TH3D *>(Generated->Clone());
+ Generated->SetDirectory(NULL);
+ Accepted = static_cast<TH3D *>(Accepted->Clone());
+ Accepted->SetDirectory(NULL);
+ }
+
+ double GetAccRatio(double p_GeV, double costheta, double phi_deg,
+ double defaultAccRatio = 0) const {
+ // For a bin in phase space defined by p, cost, phi:
+ // Find number of generated events
+ Int_t pbin = Generated->GetXaxis()->FindBin(p_GeV);
+
+ Int_t tbin = Generated->GetYaxis()->FindBin(costheta);
+ Int_t phibin = Generated->GetZaxis()->FindBin(phi_deg);
+
+ if (((pbin == 0) || (pbin == (Generated->GetXaxis()->GetNbins() + 1))) ||
+ ((tbin == 0) || (tbin == (Generated->GetYaxis()->GetNbins() + 1))) ||
+ ((phibin == 0) ||
+ (phibin == (Generated->GetZaxis()->GetNbins() + 1)))) {
+ return 0;
+ }
+
+ double num_gen = Generated->GetBinContent(pbin, tbin, phibin);
+ if (num_gen == 0) {
+ return defaultAccRatio;
+ }
+ // Find number of accepted events
+ pbin = Accepted->GetXaxis()->FindBin(p_GeV);
+ tbin = Accepted->GetYaxis()->FindBin(costheta);
+ phibin = Accepted->GetZaxis()->FindBin(phi_deg);
+ double num_acc = Accepted->GetBinContent(pbin, tbin, phibin);
+ double acc_ratio = double(num_acc) / double(num_gen);
+
+ if (((pbin == 0) || (pbin == (Accepted->GetXaxis()->GetNbins() + 1))) ||
+ ((tbin == 0) || (tbin == (Accepted->GetYaxis()->GetNbins() + 1))) ||
+ ((phibin == 0) || (phibin == (Accepted->GetZaxis()->GetNbins() + 1)))) {
+ return 0;
+ }
+
+ if ((acc_ratio != 0 && !std::isnormal(acc_ratio)) || (acc_ratio > 1)) {
+ std::cout << "[BINS]: p " << Generated->GetXaxis()->GetBinLowEdge(1)
+ << " -- "
+ << Generated->GetXaxis()->GetBinUpEdge(
+ Generated->GetXaxis()->GetNbins())
+ << ", cost " << Generated->GetYaxis()->GetBinLowEdge(1)
+ << " -- "
+ << Generated->GetYaxis()->GetBinUpEdge(
+ Generated->GetYaxis()->GetNbins())
+ << ", phi " << Generated->GetZaxis()->GetBinLowEdge(1) << " -- "
+ << Generated->GetZaxis()->GetBinUpEdge(
+ Generated->GetZaxis()->GetNbins())
+ << ". " << std::endl
+ << "[ERROR]: Bad acceptance ratio: " << acc_ratio << " = "
+ << num_acc << " / " << num_gen << ". (" << p_GeV << ", "
+ << costheta << ", " << phi_deg << ")." << std::endl;
+ exit(1);
+ }
+ return acc_ratio;
+ }
+};
class CLASAccepter : public ISmearcepter {
TRandom3 rand;
// Maps a particle PDG to the relevant generated and accepted histograms from
// the input map.
- std::map<int, std::pair<TH3D *, TH3D *> > Acceptance;
+ std::map<int, EffMap> Acceptance;
+ double DefaultAccRatio;
- public:
- CLASAccepter() { ElementName = "CLASAccepter"; }
+public:
+ CLASAccepter() : DefaultAccRatio(0) { ElementName = "CLASAccepter"; }
void SpecifcSetup(nuiskey &nk) {
rand.~TRandom3();
new (&rand) TRandom3();
InstanceName = nk.GetS("name");
+ DefaultAccRatio = nk.GetD("DefaultAccRatio");
std::string const &mapfile = nk.GetS("map");
if (!mapfile.length()) {
std::cout << "[ERROR]: No input file specified by \"map\" attribute."
<< std::endl;
exit(1);
}
TFile *f = new TFile(mapfile.c_str());
if (!f || !f->IsOpen()) {
std::cout << "[ERROR]: Could not open root file specified by \"map\" "
"attribute: \""
<< mapfile << "\"" << std::endl;
exit(1);
}
std::vector<nuiskey> accepts = nk.GetListOfChildNodes("accept");
for (auto &acc : accepts) {
std::string const &genStr = acc.GetS("generated");
std::string const &accStr = acc.GetS("accepted");
if (!genStr.length() || !accStr.length()) {
std::cout << "[ERROR]: expected accept node to contain both "
"\"generated\" and \"accepted\" attributes."
<< std::endl;
exit(1);
}
std::string const &pdgs_s = acc.GetS("PDG");
std::vector<int> pdgs_i = GeneralUtils::ParseToInt(pdgs_s, ",");
if (!pdgs_i.size()) {
std::cout
<< "[ERROR]: Could not find any applicable particle PDG codes."
<< std::endl;
exit(1);
}
- std::pair<TH3D *, TH3D *> genacc;
+ EffMap ef;
- genacc.first = dynamic_cast<TH3D *>(f->Get(accStr.c_str()));
- genacc.second = dynamic_cast<TH3D *>(f->Get(genStr.c_str()));
-
- if (!genacc.first) {
- std::cout << "[ERROR]: Could not retrieve \"accepted\" histogram: \""
- << accStr << "\" from file: \"" << mapfile << "\"."
- << std::endl;
- exit(1);
- }
- if (!genacc.second) {
- std::cout << "[ERROR]: Could not retrieve \"accepted\" histogram: \""
- << genStr << "\" from file: \"" << mapfile << "\"."
- << std::endl;
- exit(1);
- }
-
- genacc.first = static_cast<TH3D *>(genacc.first->Clone());
- genacc.first->SetDirectory(NULL);
- genacc.second = static_cast<TH3D *>(genacc.second->Clone());
- genacc.second->SetDirectory(NULL);
+ ef.Build(f, genStr, accStr);
for (size_t pdg_it = 0; pdg_it < pdgs_i.size(); ++pdg_it) {
if (Acceptance.count(pdgs_i[pdg_it])) {
std::cout
<< "[WARN]: Acceptance map already contains acceptance for PDG: "
<< pdgs_i[pdg_it] << ". Overwriting..." << std::endl;
}
- Acceptance[pdgs_i[pdg_it]] = genacc;
+ Acceptance[pdgs_i[pdg_it]] = ef;
}
}
std::cout << "Loaded " << Acceptance.size()
<< " particle acceptance definitions." << std::endl;
f->Close();
delete f;
}
RecoInfo *Smearcept(FitEvent *fe) {
RecoInfo *ri = new RecoInfo();
for (size_t p_it = 0; p_it < fe->NParticles(); ++p_it) {
FitParticle *fp = fe->GetParticle(p_it);
int PDG = fp->PDG();
- double p = fp->P3().Mag();
+ double p = fp->P3().Mag() * 1E-3;
double cost = fp->P3().CosTheta();
- double phi = fp->P3().Phi();
+ double phi = fp->P3().Phi() * (180.0 / TMath::Pi()) + 150.0;
-#ifdef DEBUG_CLASACCEPT
+#if DEBUG_CLASACCEPT > 1
std::cout << std::endl;
std::cout << "[" << p_it << "]: " << PDG << ", " << fp->Status() << ", "
<< fp->E() << " -- KE:" << fp->KE() << " Mom: " << p
<< std::flush;
#endif
if (fp->Status() != kFinalState) {
-#ifdef DEBUG_CLASACCEPT
+#if DEBUG_CLASACCEPT > 1
std::cout << " -- Not final state." << std::flush;
#endif
continue;
}
if (!Acceptance.count(PDG)) {
-#ifdef DEBUG_CLASACCEPT
+#if DEBUG_CLASACCEPT > 1
std::cout << " -- Unknown acceptance." << std::flush;
#endif
continue;
}
- std::pair<TH3D *, TH3D *> acc = Acceptance[PDG];
-
- // For a bin in phase space defined by p, cost, phi:
- // Find number of generated events
- Int_t pbin = acc.second->GetXaxis()->FindBin(p);
- Int_t tbin = acc.second->GetYaxis()->FindBin(cost);
- Int_t phibin = acc.second->GetZaxis()->FindBin(phi);
- double num_gen = acc.second->GetBinContent(pbin, tbin, phibin);
- // Find number of accepted events
- pbin = acc.first->GetXaxis()->FindBin(p);
- tbin = acc.first->GetYaxis()->FindBin(cost);
- phibin = acc.first->GetZaxis()->FindBin(phi);
- double num_acc = acc.first->GetBinContent(pbin, tbin, phibin);
- double acc_ratio = double(num_acc) / double(num_gen);
+ EffMap const &eff = Acceptance[PDG];
+
+ double acc_ratio = eff.GetAccRatio(p, cost, phi, DefaultAccRatio);
bool accepted = (rand.Uniform() < acc_ratio);
if (accepted) {
#ifdef DEBUG_CLASACCEPT
+ std::cout << "(" << p << ", " << cost << ", " << phi << ")."
+ << std::endl;
std::cout << " -- Reconstructed with probability: " << acc_ratio
<< std::flush;
#endif
ri->RecObjMom.push_back(fp->P3());
ri->RecObjClass.push_back(fp->PDG());
continue;
}
#ifdef DEBUG_CLASACCEPT
+ std::cout << "(" << p << ", " << cost << ", " << phi << ")." << std::endl;
std::cout << " -- Rejected with probability: " << acc_ratio << std::flush;
#endif
-#ifdef DEBUG_CLASACCEPT
- std::cout << std::endl;
-#endif
}
#ifdef DEBUG_CLASACCEPT
- std::cout << "Reconstructed " << ri->RecObjMom.size() << " particles. "
- << std::endl;
+ std::cout << std::endl;
+
+ if (ri->RecObjMom.size()) {
+ std::cout << "Reconstructed " << ri->RecObjMom.size() << " particles. "
+ << std::endl;
+ }
#endif
return ri;
}
+
+ double GetEfficiency(FitEvent *fe) {
+ double effweight = 1;
+ for (size_t p_it = 0; p_it < fe->NParticles(); ++p_it) {
+ FitParticle *fp = fe->GetParticle(p_it);
+
+ int PDG = fp->PDG();
+ double p = fp->P3().Mag() * 1E-3;
+ double cost = fp->P3().CosTheta();
+ double phi = fp->P3().Phi() * (180.0 / TMath::Pi()) + 150.0;
+ if (fp->Status() != kFinalState) {
+ continue;
+ }
+ if (!Acceptance.count(PDG)) {
+ continue;
+ }
+ EffMap eff = Acceptance[PDG];
+
+ effweight *= eff.GetAccRatio(p, cost, phi);
+ }
+ return effweight;
+ }
};
diff --git a/src/Electron/ElectronScattering_DurhamData.cxx b/src/Electron/ElectronScattering_DurhamData.cxx
index c171df5..7e7b616 100644
--- a/src/Electron/ElectronScattering_DurhamData.cxx
+++ b/src/Electron/ElectronScattering_DurhamData.cxx
@@ -1,486 +1,486 @@
// 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 "ElectronScattering_DurhamData.h"
//********************************************************************
ElectronScattering_DurhamData::ElectronScattering_DurhamData(
nuiskey samplekey) {
//********************************************************************
// Sample overview ---------------------------------------------------
std::string descrip =
"Electron Scattering Durham Data sample. \n"
"Target: Multiple \n"
"Flux: Energy should match data being handled \n"
"Signal: Any event with an electron in the final state \n";
fSettings = LoadSampleSettings(samplekey);
fSettings.SetDescription(descrip);
fSettings.DefineAllowedSpecies("electron");
fSettings.SetTitle("Electron");
fSettings.SetAllowedTypes("FIX/DIAG", "FIX,FREE,SHAPE/DIAG/NORM/MASK");
fSettings.SetXTitle("q0");
fSettings.SetYTitle("#sigma");
fIsNoWidth = true;
FinaliseSampleSettings();
// Plot Setup -------------------------------------------------------
SetDataFromName(fSettings.GetS("originalname"));
SetCovarFromDiagonal();
// Scaling Setup ---------------------------------------------------
// ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
// fScaleFactor = ((GetEventHistogram()->Integral("width") * 1E-38 / (fNEvents
// + 0.)) / TotalIntegratedFlux());
EnuMin = fZLowLim;
EnuMax = fZHighLim;
double sigscale = GetEventHistogram()->Integral() * 1E-38 / double(fNEvents) /
TotalIntegratedFlux();
// double dangle = 2 * M_PI * fabs((1. - cos(fYLowLim * M_PI / 180.)) - (1. -
// cos(fYHighLim * M_PI / 180.)));
// fScaleFactor = sigscale / dangle / fZCenter;
fScaleFactor = sigscale;
std::cout << "Event Integral = " << GetEventHistogram()->Integral()
<< std::endl;
std::cout << "Flux Integral = " << TotalIntegratedFlux() << std::endl;
std::cout << "FNEvents = " << fNEvents << std::endl;
std::cout << "Z Limits = " << fZLowLim << " " << fZHighLim << std::endl;
std::cout << "sigscale = " << sigscale << std::endl;
std::cout << "fZCenter = " << fZCenter << std::endl;
std::cout << "ScaleFactor = " << fScaleFactor << std::endl;
// Finish up
FinaliseMeasurement();
};
//********************************************************************
void ElectronScattering_DurhamData::SetDataFromName(std::string name) {
//********************************************************************
// Data Should be given in the format
// Electron_Z_A_Energy_Theta_Source
std::vector<std::string> splitstring = GeneralUtils::ParseToStr(name, "_");
std::string zstring = splitstring[1];
std::string astring = splitstring[2];
std::string estring = splitstring[3];
std::string tstring = splitstring[4];
std::string sstring = splitstring[5];
fYCenter = GeneralUtils::StrToDbl(tstring);
fZCenter = GeneralUtils::StrToDbl(estring);
// Create effective E and Theta bin Edges
std::vector<double> thetabinedges;
std::vector<double> ebinedges;
int nthetabins = FitPar::Config().GetParI("Electron_NThetaBins");
int nebins = FitPar::Config().GetParI("Electron_NEnergyBins");
double thetawidth = FitPar::Config().GetParD("Electron_ThetaWidth");
double ewidth = FitPar::Config().GetParD("Electron_EnergyWidth");
for (int i = -nthetabins; i <= nthetabins; i++) {
thetabinedges.push_back(fYCenter + thetawidth * (double(i)));
}
for (int i = -nebins; i <= nebins; i++) {
double newval = fZCenter + ewidth * (double(i));
if (newval < 0.0) newval = 0.0;
if (newval < GetEventHistogram()->GetXaxis()->GetXmin())
newval = GetEventHistogram()->GetXaxis()->GetXmin();
if (newval > GetEventHistogram()->GetXaxis()->GetXmax())
newval = GetEventHistogram()->GetXaxis()->GetXmax();
if (std::find(ebinedges.begin(), ebinedges.end(), newval) !=
ebinedges.end())
continue;
ebinedges.push_back(newval);
}
// Determine target
std::string target = "";
if (!zstring.compare("6") && !astring.compare("12"))
target = "12C.dat";
else if (!zstring.compare("8") && !astring.compare("16"))
target = "16O.dat";
else {
ERR(FTL) << "Target not supported in electron scattering module!"
<< std::endl;
throw;
}
// Fill Data Points
std::string line;
std::ifstream mask((FitPar::GetDataBase() + "/Electron/" + target).c_str(),
- ifstream::in);
+ std::ifstream::in);
if (!mask.good()) {
ERR(FTL) << "Failed to open e-scattering database file: "
<< (FitPar::GetDataBase() + "/Electron/" + target) << std::endl;
throw;
}
int i = 0;
std::vector<double> pointx;
std::vector<double> errorx;
std::vector<double> pointy;
std::vector<double> errory;
double scalef = 1.E-38 * 1.E5;
while (std::getline(mask >> std::ws, line, '\n')) {
// std::cout << "Line = " << line << std::endl;
if (line.empty()) continue;
std::vector<std::string> lineentries = GeneralUtils::ParseToStr(line, " ");
// std::cout << "Checking : " << line << std::endl;
if (zstring.compare(lineentries[0])) continue;
if (astring.compare(lineentries[1])) continue;
if (estring.compare(lineentries[2])) continue;
if (tstring.compare(lineentries[3])) continue;
if (sstring.compare(lineentries[7])) continue;
// std::cout << "Registering data point : " << line << std::endl;
// std::cout << "Adding Graph Point : " <<
// GeneralUtils::StrToDbl(lineentries[4]) << " " <<
// GeneralUtils::StrToDbl(lineentries[5]) << std::endl;
// Loop through x and y points and find a place to insert
if (pointx.empty()) {
pointx.push_back(GeneralUtils::StrToDbl(lineentries[4]));
errorx.push_back(0.0);
pointy.push_back(GeneralUtils::StrToDbl(lineentries[5]) * scalef);
errory.push_back(GeneralUtils::StrToDbl(lineentries[6]) * scalef);
} else {
for (size_t j = 0; j < pointx.size(); j++) {
if (GeneralUtils::StrToDbl(lineentries[4]) < pointx[j] && j == 0) {
// std::cout << "Inserting at start point iterator " << std::endl;
pointx.insert(pointx.begin() + j,
GeneralUtils::StrToDbl(lineentries[4]));
errorx.insert(errorx.begin() + j, 0.0);
pointy.insert(pointy.begin() + j,
GeneralUtils::StrToDbl(lineentries[5]) * scalef);
errory.insert(errory.begin() + j,
GeneralUtils::StrToDbl(lineentries[6]) * scalef);
break;
} else if (GeneralUtils::StrToDbl(lineentries[4]) > pointx[j] &&
j == pointx.size() - 1) {
// std::cout << "Pushing back data point " << std::endl;
pointx.push_back(GeneralUtils::StrToDbl(lineentries[4]));
errorx.push_back(0.0);
pointy.push_back(GeneralUtils::StrToDbl(lineentries[5]) * scalef);
errory.push_back(GeneralUtils::StrToDbl(lineentries[6]) * scalef);
break;
} else if (GeneralUtils::StrToDbl(lineentries[4]) > pointx[j - 1] &&
GeneralUtils::StrToDbl(lineentries[4]) < pointx[j]) {
// std::cout << "Inserting at point iterator = " << j << std::endl;
pointx.insert(pointx.begin() + j,
GeneralUtils::StrToDbl(lineentries[4]));
errorx.insert(errorx.begin() + j, 0.0);
pointy.insert(pointy.begin() + j,
GeneralUtils::StrToDbl(lineentries[5]) * scalef);
errory.insert(errory.begin() + j,
GeneralUtils::StrToDbl(lineentries[6]) * scalef);
break;
}
}
}
// pointx.push_back(GeneralUtils::StrToDbl(lineentries[4]));
// errorx.push_back(0.0);
// pointy.push_back(GeneralUtils::StrToDbl(lineentries[5]));
// errory.push_back(GeneralUtils::StrToDbl(lineentries[6]));
i++;
}
if (!pointx.size() || (pointx.size() != errorx.size()) || !pointy.size() ||
(pointy.size() != errory.size())) {
ERR(FTL) << "Failed to find dataset: " << name << "{"
<< "Z: " << zstring << ", A: " << astring << ", E: " << estring
<< ", CTheta: " << tstring << ", PubID: " << sstring
<< " } in file: "
<< (FitPar::GetDataBase() + "/Electron/" + target) << std::endl;
throw;
}
// for (uint i = 0; i < pointx.size(); i++) {
// std::cout << "Q0 Point " << i << " = " << pointx[i] << std::endl;
// }
fDataGraph = new TGraphErrors(pointx.size(), &pointx[0], &pointy[0],
&errorx[0], &errory[0]);
fDataGraph->SetNameTitle((fName + "_data_GRAPH").c_str(),
(fName + "_data_GRAPH").c_str());
// Now form an effective data and mc histogram
std::vector<double> q0binedges;
const double* x = fDataGraph->GetX();
// Loop over graph and get mid way point between each data point.
for (int i = 0; i < fDataGraph->GetN(); i++) {
// std::cout << "X Point = " << x[i] << std::endl;
if (i == 0) {
// First point set lower width as half distance to point above
q0binedges.push_back(x[0] - ((x[1] - x[0]) / 2.0));
} else if (i == fDataGraph->GetN() - 1) {
// Last point set upper width as half distance to point above.
q0binedges.push_back(x[i] - ((x[i] - x[i - 1]) / 2.0));
q0binedges.push_back(x[i] + ((x[i] - x[i - 1]) / 2.0));
} else {
// Set half distance to point below
q0binedges.push_back(x[i] - ((x[i] - x[i - 1]) / 2.0));
}
}
// Bubble Sort
// for (uint i = 0; i < q0binedges.size(); i++) {
// std::cout << "Q0 Edge " << i << " = " << q0binedges[i] << std::endl;
// }
// for (uint i = 0; i < ebinedges.size(); i++) {
// std::cout << "e Edge " << i << " = " << ebinedges[i] << std::endl;
// }
// for (uint i = 0; i < thetabinedges.size(); i++) {
// std::cout << "theta Edge " << i << " = " << thetabinedges[i] <<
// std::endl;
// }
// Form the data hist, mchist, etc
fDataHist = new TH1D((fName + "_data").c_str(), (fName + "_data").c_str(),
q0binedges.size() - 1, &q0binedges[0]);
fMCHist = (TH1D*)fDataHist->Clone("MC");
const double* y = fDataGraph->GetY();
const double* ey = fDataGraph->GetEY();
for (int i = 0; i < fDataGraph->GetN(); i++) {
// std::cout << "Setting Data Bin " << i + 1 << " to " << y[i] << " +- " <<
// ey[i] << std::endl;
fDataHist->SetBinContent(i + 1, y[i]);
fDataHist->SetBinError(i + 1, ey[i]);
fMCHist->SetBinContent(i + 1, 0.0);
fMCHist->SetBinError(i + 1, 0.0);
}
fMCScan_Q0vsThetavsE =
new TH3D((fName + "_MC_q0vsthetavse").c_str(), "MC_q0vsthetavse",
q0binedges.size() - 1, &q0binedges[0], thetabinedges.size() - 1,
&thetabinedges[0], ebinedges.size() - 1, &ebinedges[0]);
fMCScan_Q0vsThetavsE->Reset();
fMCScan_Q0vsTheta = new TH2D(
(fName + "_MC_q0vstheta").c_str(), "MC_q0vstheta", q0binedges.size() - 1,
&q0binedges[0], thetabinedges.size() - 1, &thetabinedges[0]);
fMCScan_Q0vsTheta->Reset();
fMCScan_Q0vsE =
new TH2D((fName + "_MC_q0vse").c_str(), "MC_q0vse", q0binedges.size() - 1,
&q0binedges[0], ebinedges.size() - 1, &ebinedges[0]);
fMCScan_Q0vsE->Reset();
fXLowLim = fMCScan_Q0vsThetavsE->GetXaxis()->GetBinLowEdge(1);
fXHighLim = fMCScan_Q0vsThetavsE->GetXaxis()->GetBinLowEdge(
fMCScan_Q0vsThetavsE->GetNbinsX() + 2);
fYLowLim = fMCScan_Q0vsThetavsE->GetYaxis()->GetBinLowEdge(1);
fYHighLim = fMCScan_Q0vsThetavsE->GetYaxis()->GetBinLowEdge(
fMCScan_Q0vsThetavsE->GetNbinsY() + 2);
fZLowLim = fMCScan_Q0vsThetavsE->GetZaxis()->GetBinLowEdge(1);
fZHighLim = fMCScan_Q0vsThetavsE->GetZaxis()->GetBinLowEdge(
fMCScan_Q0vsThetavsE->GetNbinsZ() + 2);
std::cout << "Sample " << name << "initialised: "
<< "{" << fXLowLim << "--" << fXHighLim << ", " << fYLowLim << "--"
<< fYHighLim << ", " << fZLowLim << "--" << fZHighLim << "}"
<< std::endl;
}
//********************************************************************
void ElectronScattering_DurhamData::FillEventVariables(FitEvent* event) {
//********************************************************************
if (event->NumFSParticle(11) == 0) return;
FitParticle* ein = event->PartInfo(0);
FitParticle* eout = event->GetHMFSParticle(11);
double q0 = fabs(ein->fP.E() - eout->fP.E()) / 1000.0;
double E = ein->fP.E() / 1000.0;
double theta = ein->fP.Vect().Angle(eout->fP.Vect()) * 180. / M_PI;
fXVar = q0;
fYVar = theta;
fZVar = E;
return;
};
//********************************************************************
bool ElectronScattering_DurhamData::isSignal(FitEvent* event) {
//********************************************************************
if (event->NumFSParticle(11) == 0) {
std::cout << "Ev Cut due to no FS electron." << std::endl;
return false;
}
// std::cout << "fXVar = " << fXVar << " " << fXLowLim << " " << fXHighLim <<
// std::endl;
// std::cout << "fYVar = " << fYVar << " " << fYLowLim << " " << fYHighLim <<
// std::endl;
// std::cout << "fZVar = " << fZVar << " " << fZLowLim << " " << fZHighLim <<
// std::endl;
// std::cout << "iWeight: " << event->InputWeight << std::endl;
if (fXVar < fXLowLim or fXVar > fXHighLim) {
// std::cout << "Ev Cut due to X lims: " << fXLowLim << " -- " << fXHighLim
// << " !<> " << fXVar << std::endl;
return false;
}
if (fYVar < fYLowLim or fYVar > fYHighLim) {
// std::cout << "Ev Cut due to Y lims: " << fYLowLim << " -- " << fYHighLim
// << " !<> " << fXVar << std::endl;
return false;
}
if (fZVar < fZLowLim or fZVar > fZHighLim) {
// std::cout << "Ev Cut due to Z lims: " << fZLowLim << " -- " << fZHighLim
// << " !<> " << fXVar << std::endl;
return false;
}
return true;
};
//********************************************************************
void ElectronScattering_DurhamData::FillHistograms() {
//********************************************************************
Measurement1D::FillHistograms();
if (Signal) {
fMCScan_Q0vsThetavsE->Fill(fXVar, fYVar, fZVar);
fMCScan_Q0vsTheta->Fill(fXVar, fYVar);
fMCScan_Q0vsE->Fill(fXVar, fZVar);
}
}
// Weight = 1.0;
// if (Signal) {
// fMCHist->Fill(fXVar, Weight);
// fMCFine->Fill(fXVar, Weight);
// fMCStat->Fill(fXVar, 1.0);
// if (fMCHist_Modes) fMCHist_Modes->Fill(Mode, fXVar, Weight);
// }
// }
void ElectronScattering_DurhamData::ResetAll() {
Measurement1D::ResetAll();
fMCScan_Q0vsThetavsE->Reset();
fMCScan_Q0vsTheta->Reset();
fMCScan_Q0vsE->Reset();
}
void ElectronScattering_DurhamData::ApplyNormScale(double norm) {
Measurement1D::ApplyNormScale(norm);
fMCScan_Q0vsThetavsE->Scale(1.0 / norm);
fMCScan_Q0vsTheta->Scale(1.0 / norm);
fMCScan_Q0vsE->Scale(1.0 / norm);
}
//********************************************************************
void ElectronScattering_DurhamData::ScaleEvents() {
//********************************************************************
Measurement1D::ScaleEvents();
/*
fMCScan_Q0vsThetavsE->Scale(fScaleFactor, "width");
// Project into fMCScan_Q0vsTheta
for (int x = 0; x < fMCScan_Q0vsThetavsE->GetNbinsX(); x++) {
for (int y = 0; y < fMCScan_Q0vsThetavsE->GetNbinsY(); y++) {
double total = 0.;
for (int z = 0; z < fMCScan_Q0vsThetavsE->GetNbinsZ(); z++) {
double zwidth = fMCScan_Q0vsThetavsE->GetZaxis()->GetBinWidth(z + 1);
total += fMCScan_Q0vsThetavsE->GetBinContent(x + 1, y + 1, z + 1) *
zwidth;
}
fMCScan_Q0vsTheta->SetBinContent(x + 1, y + 1, total);
}
}
// Project into fMCScan_Q0vsE
for (int x = 0; x < fMCScan_Q0vsThetavsE->GetNbinsX(); x++) {
for (int z = 0; z < fMCScan_Q0vsThetavsE->GetNbinsZ(); z++) {
double total = 0.;
for (int y = 0; y < fMCScan_Q0vsThetavsE->GetNbinsY(); y++) {
double ywidth = fMCScan_Q0vsThetavsE->GetYaxis()->GetBinWidth(y + 1);
total += fMCScan_Q0vsThetavsE->GetBinContent(x + 1, y + 1, z + 1) *
ywidth;
}
fMCScan_Q0vsE->SetBinContent(x + 1, z + 1, total);
}
}
// Project fMCScan_Q0vsTheta into MC Hist
for (int x = 0; x < fMCScan_Q0vsTheta->GetNbinsX(); x++) {
double total = 0.;
for (int y = 0; y < fMCScan_Q0vsTheta->GetNbinsY(); y++) {
double ywidth = fMCScan_Q0vsTheta->GetYaxis()->GetBinWidth(y + 1);
total += fMCScan_Q0vsTheta->GetBinContent(x + 1, y + 1);
}
double xwidth = fMCScan_Q0vsTheta->GetXaxis()->GetBinWidth(x + 1);
fMCHist->SetBinContent(x + 1, total * xwidth);
}
fMCHist->Scale(fDataHist->Integral() / fMCHist->Integral());
*/
}
//********************************************************************
int ElectronScattering_DurhamData::GetNDOF() {
//********************************************************************
return fDataGraph->GetN();
}
void ElectronScattering_DurhamData::Write(std::string drawOpts) {
Measurement1D::Write(drawOpts);
fMCScan_Q0vsThetavsE->Write();
fMCScan_Q0vsTheta->Write();
fMCScan_Q0vsE->Write();
fDataGraph->Write();
}
double ElectronScattering_DurhamData::GetLikelihood() { return 0.0; }
void ElectronScattering_DurhamData::SetFitOptions(std::string opt) { return; }
TH1D* ElectronScattering_DurhamData::GetMCHistogram(void) { return fMCHist; }
TH1D* ElectronScattering_DurhamData::GetDataHistogram(void) {
return fDataHist;
}
diff --git a/src/FCN/JointFCN.cxx b/src/FCN/JointFCN.cxx
index 1c60f88..596d443 100755
--- a/src/FCN/JointFCN.cxx
+++ b/src/FCN/JointFCN.cxx
@@ -1,1139 +1,1122 @@
#include "JointFCN.h"
#include <stdio.h>
#include "FitUtils.h"
-
//***************************************************
JointFCN::JointFCN(TFile* outfile) {
-//***************************************************
+ //***************************************************
fOutputDir = gDirectory;
if (outfile) Config::Get().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) Config::Get().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();
+ 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++) {
-
+ 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();
+ fSampleN = fSamples.size() + fPulls.size();
fSampleLikes = new double[fSampleN];
- fSampleNDOF = new int[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 );
+ fNameValues.push_back(dials[i]);
+ fCurrentValues.push_back(0.0);
}
- fNDials = dials.size();
+ 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());
+ 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() );
+ 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 );
+ 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();
+ 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) {
+ if (countwidth && (i % countwidth == 0)) {
QLOG(REC, curinput->GetName()
- << " : Processed " << i << " events. [M, W] = ["
- << curevent->Mode << ", " << rwweight << "]");
+ << " : 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();
+ 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;
+ ( // 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");
+ 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;
+ 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");
+ 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();
+ fSignalEventBoxes.begin();
std::vector<std::vector<float> >::iterator spline_iter =
- fSignalEventSplines.begin();
+ fSignalEventSplines.begin();
std::vector<std::vector<bool> >::iterator samsig_iter =
- fSampleSignalFlags.begin();
+ 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) {
curevent = 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;
// Custom weights
rwweight *= curevent->CustomWeight;
coreeventweights[splinecount] = rwweight;
if (countwidth && ((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();
+ (*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()));
+ 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();
+ 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;
}
//***************************************************
std::vector<std::string> JointFCN::GetAllNames() {
-//***************************************************
+ //***************************************************
// Vect of all likelihoods and total
std::vector<std::string> namevect;
// Loop over samples first
- for (MeasListConstIter iter = fSamples.begin();
- iter != fSamples.end();
+ for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
iter++) {
MeasurementBase* exp = *iter;
// Get Likelihoods and push to vector
namevect.push_back(exp->GetName());
}
-
// Loop over pulls second
- for (PullListConstIter iter = fPulls.begin();
- iter != fPulls.end();
- iter++) {
+ for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) {
ParamPull* pull = *iter;
// Push back to vector
namevect.push_back(pull->GetName());
}
// Finally add the total
namevect.push_back("total");
return namevect;
}
//***************************************************
std::vector<double> JointFCN::GetAllLikelihoods() {
-//***************************************************
+ //***************************************************
// Vect of all likelihoods and total
std::vector<double> likevect;
double total_likelihood = 0.0;
LOG(MIN) << "Likelihoods : " << std::endl;
// Loop over samples first
- for (MeasListConstIter iter = fSamples.begin();
- iter != fSamples.end();
+ for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
iter++) {
MeasurementBase* exp = *iter;
// Get Likelihoods and push to vector
double singlelike = exp->GetLikelihood();
likevect.push_back(singlelike);
total_likelihood += singlelike;
// Print Out
LOG(MIN) << "-> " << std::left << std::setw(40) << exp->GetName() << " : "
<< singlelike << std::endl;
}
-
// Loop over pulls second
- for (PullListConstIter iter = fPulls.begin();
- iter != fPulls.end();
- iter++) {
+ for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) {
ParamPull* pull = *iter;
// Push back to vector
double singlelike = pull->GetLikelihood();
likevect.push_back(singlelike);
total_likelihood += singlelike;
// Print Out
LOG(MIN) << "-> " << std::left << std::setw(40) << pull->GetName() << " : "
<< singlelike << std::endl;
-
}
// Finally add the total likelihood
likevect.push_back(total_likelihood);
return likevect;
}
//***************************************************
std::vector<int> JointFCN::GetAllNDOF() {
-//***************************************************
+ //***************************************************
// Vect of all ndof and total
std::vector<int> ndofvect;
int total_ndof = 0;
// Loop over samples first
- for (MeasListConstIter iter = fSamples.begin();
- iter != fSamples.end();
+ for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
iter++) {
MeasurementBase* exp = *iter;
// Get Likelihoods and push to vector
int singlendof = exp->GetNDOF();
ndofvect.push_back(singlendof);
total_ndof += singlendof;
}
-
// Loop over pulls second
- for (PullListConstIter iter = fPulls.begin();
- iter != fPulls.end();
- iter++) {
+ for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) {
ParamPull* pull = *iter;
// Push back to vector
int singlendof = pull->GetNDOF();
ndofvect.push_back(singlendof);
total_ndof += singlendof;
}
// Finally add the total ndof
ndofvect.push_back(total_ndof);
return ndofvect;
}
diff --git a/src/FitBase/JointMeas1D.cxx b/src/FitBase/JointMeas1D.cxx
index 6700a10..6c3e699 100644
--- a/src/FitBase/JointMeas1D.cxx
+++ b/src/FitBase/JointMeas1D.cxx
@@ -1,2303 +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);
+ std::ifstream mask(maskfile.c_str(), std::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, 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);
+ std::ifstream smear(smearfile.c_str(), std::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);
+ std::ifstream covarread(covarFile.c_str(), std::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);
+ std::ifstream corr(corrFile.c_str(), std::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/Measurement1D.cxx b/src/FitBase/Measurement1D.cxx
index cb2cdd3..3306167 100644
--- a/src/FitBase/Measurement1D.cxx
+++ b/src/FitBase/Measurement1D.cxx
@@ -1,1903 +1,1905 @@
// 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);
+ std::ifstream mask(maskfile.c_str(), std::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, 1E-38);
// If shape only, set covar and fDecomp using the shape-only matrix (if set)
if (fIsShape && fShapeCovar and FitPar::Config().GetParB("UseShapeCovar")){
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);
+ std::ifstream smear(smearfile.c_str(), std::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) {
+ QLOG(DEB, "Fill MCHist: " << fXVar << ", " << Weight);
+
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();
if((fEvtRateScaleFactor != 0xdeadbeef) && GetMCList().at(0)){
TH1D * PredictedEvtRate = static_cast<TH1D *>(GetMCList().at(0)->Clone());
PredictedEvtRate->Scale(fEvtRateScaleFactor);
PredictedEvtRate->GetYaxis()->SetTitle("Predicted event rate");
PredictedEvtRate->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.Set("name", fName);
samplekey.Set("type",type);
samplekey.Set("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);
+ std::ifstream covarread(covarFile.c_str(), std::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);
+ std::ifstream corr(corrFile.c_str(), std::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);
+// std::ifstream mask(maskFile.c_str(), std::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/Measurement2D.cxx b/src/FitBase/Measurement2D.cxx
index 87f361f..77424bc 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 << " " << dim << 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);
+ std::ifstream mask(maskfile.c_str(), std::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);
}
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;
}
// Config::Get().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);
// 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);
+ std::ifstream data(dataFile.c_str(), std::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);
+ std::ifstream error(errorFile.c_str(), std::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);
+ std::ifstream covar(covarFile.c_str(), std::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);
+ std::ifstream covarread(covarFile.c_str(), std::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/InputHandler/FitEvent.cxx b/src/InputHandler/FitEvent.cxx
index 61751f8..50ef1bc 100644
--- a/src/InputHandler/FitEvent.cxx
+++ b/src/InputHandler/FitEvent.cxx
@@ -1,429 +1,429 @@
// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
/*******************************************************************************
* This file is pddrt 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 "FitEvent.h"
#include <iostream>
#include "TObjArray.h"
FitEvent::FitEvent() {
fGenInfo = NULL;
kRemoveFSIParticles = true;
kRemoveUndefParticles = true;
AllocateParticleStack(400);
};
void FitEvent::AddGeneratorInfo(GeneratorInfoBase* gen) {
fGenInfo = gen;
gen->AllocateParticleStack(kMaxParticles);
}
void FitEvent::AllocateParticleStack(int stacksize) {
LOG(DEB) << "Allocating particle stack of size: " << stacksize << std::endl;
kMaxParticles = stacksize;
fParticleList = new FitParticle*[kMaxParticles];
fParticleMom = new double*[kMaxParticles];
fParticleState = new UInt_t[kMaxParticles];
fParticlePDG = new int[kMaxParticles];
fOrigParticleMom = new double*[kMaxParticles];
fOrigParticleState = new UInt_t[kMaxParticles];
fOrigParticlePDG = new int[kMaxParticles];
for (size_t i = 0; i < kMaxParticles; i++) {
fParticleList[i] = NULL;
fParticleMom[i] = new double[4];
fOrigParticleMom[i] = new double[4];
}
if (fGenInfo) fGenInfo->AllocateParticleStack(kMaxParticles);
}
void FitEvent::ExpandParticleStack(int stacksize) {
DeallocateParticleStack();
AllocateParticleStack(stacksize);
}
void FitEvent::DeallocateParticleStack() {
for (size_t i = 0; i < kMaxParticles; i++) {
if (fParticleList[i]) delete fParticleList[i];
delete fParticleMom[i];
delete fOrigParticleMom[i];
}
delete fParticleMom;
delete fOrigParticleMom;
delete fParticleList;
delete fParticleState;
delete fParticlePDG;
delete fOrigParticleState;
delete fOrigParticlePDG;
if (fGenInfo) fGenInfo->DeallocateParticleStack();
kMaxParticles = 0;
}
void FitEvent::ClearFitParticles() {
for (size_t i = 0; i < kMaxParticles; i++) {
fParticleList[i] = NULL;
}
}
void FitEvent::FreeFitParticles() {
for (size_t i = 0; i < kMaxParticles; i++) {
FitParticle* fp = fParticleList[i];
if (fp) delete fp;
fParticleList[i] = NULL;
}
}
void FitEvent::ResetParticleList() {
for (unsigned int i = 0; i < kMaxParticles; i++) {
FitParticle* fp = fParticleList[i];
if (fp) delete fp;
fParticleList[i] = NULL;
}
}
void FitEvent::HardReset() {
for (unsigned int i = 0; i < kMaxParticles; i++) {
fParticleList[i] = NULL;
}
}
void FitEvent::ResetEvent() {
Mode = 9999;
fEventNo = -1;
fTotCrs = -1.0;
fTargetA = -1;
fTargetZ = -1;
fTargetH = -1;
fBound = false;
fNParticles = 0;
if (fGenInfo) fGenInfo->Reset();
for (unsigned int i = 0; i < kMaxParticles; i++) {
if (fParticleList[i]) delete fParticleList[i];
fParticleList[i] = NULL;
continue;
fParticlePDG[i] = 0;
fParticleState[i] = kUndefinedState;
fParticleMom[i][0] = 0.0;
fParticleMom[i][1] = 0.0;
fParticleMom[i][2] = 0.0;
fParticleMom[i][3] = 0.0;
fOrigParticlePDG[i] = 0;
fOrigParticleState[i] = kUndefinedState;
fOrigParticleMom[i][0] = 0.0;
fOrigParticleMom[i][1] = 0.0;
fOrigParticleMom[i][2] = 0.0;
fOrigParticleMom[i][3] = 0.0;
}
}
void FitEvent::OrderStack() {
// Copy current stack
int npart = fNParticles;
for (int i = 0; i < npart; i++) {
fOrigParticlePDG[i] = fParticlePDG[i];
fOrigParticleState[i] = fParticleState[i];
fOrigParticleMom[i][0] = fParticleMom[i][0];
fOrigParticleMom[i][1] = fParticleMom[i][1];
fOrigParticleMom[i][2] = fParticleMom[i][2];
fOrigParticleMom[i][3] = fParticleMom[i][3];
}
// Now run loops for each particle
fNParticles = 0;
int stateorder[6] = {kInitialState, kFinalState, kFSIState,
kNuclearInitial, kNuclearRemnant, kUndefinedState};
for (int s = 0; s < 6; s++) {
for (int i = 0; i < npart; i++) {
if ((UInt_t)fOrigParticleState[i] != (UInt_t)stateorder[s]) continue;
fParticlePDG[fNParticles] = fOrigParticlePDG[i];
fParticleState[fNParticles] = fOrigParticleState[i];
fParticleMom[fNParticles][0] = fOrigParticleMom[i][0];
fParticleMom[fNParticles][1] = fOrigParticleMom[i][1];
fParticleMom[fNParticles][2] = fOrigParticleMom[i][2];
fParticleMom[fNParticles][3] = fOrigParticleMom[i][3];
fNParticles++;
}
}
if (LOG_LEVEL(DEB)) {
LOG(DEB) << "Ordered stack" << std::endl;
for (int i = 0; i < fNParticles; i++) {
LOG(DEB) << "Particle " << i << ". " << fParticlePDG[i] << " "
<< fParticleMom[i][0] << " " << fParticleMom[i][1] << " "
<< fParticleMom[i][2] << " " << fParticleMom[i][3] << " "
<< fParticleState[i] << std::endl;
}
}
if (fNParticles != npart) {
ERR(FTL) << "Dropped some particles when ordering the stack!" << std::endl;
}
return;
}
void FitEvent::Print() {
if (LOG_LEVEL(FIT)) {
LOG(FIT) << "FITEvent print" << std::endl;
- LOG(FIT) << "Mode: " << Mode << std::endl;
+ LOG(FIT) << "Mode: " << Mode << ", Weight: " << InputWeight << std::endl;
LOG(FIT) << "Particles: " << fNParticles << std::endl;
LOG(FIT) << " -> Particle Stack " << std::endl;
for (int i = 0; i < fNParticles; i++) {
LOG(FIT) << " -> -> " << i << ". " << fParticlePDG[i] << " "
<< fParticleState[i] << " "
<< " Mom(" << fParticleMom[i][0] << ", " << fParticleMom[i][1]
<< ", " << fParticleMom[i][2] << ", " << fParticleMom[i][3]
<< ")." << std::endl;
}
}
return;
}
/* Read/Write own event class */
void FitEvent::SetBranchAddress(TChain* tn) {
tn->SetBranchAddress("Mode", &Mode);
tn->SetBranchAddress("EventNo", &fEventNo);
tn->SetBranchAddress("TotCrs", &fTotCrs);
tn->SetBranchAddress("TargetA", &fTargetA);
tn->SetBranchAddress("TargetH", &fTargetH);
tn->SetBranchAddress("Bound", &fBound);
tn->SetBranchAddress("RWWeight", &SavedRWWeight);
tn->SetBranchAddress("InputWeight", &InputWeight);
}
void FitEvent::AddBranchesToTree(TTree* tn) {
tn->Branch("Mode", &Mode, "Mode/I");
tn->Branch("EventNo", &fEventNo, "EventNo/i");
tn->Branch("TotCrs", &fTotCrs, "TotCrs/D");
tn->Branch("TargetA", &fTargetA, "TargetA/I");
tn->Branch("TargetH", &fTargetH, "TargetH/I");
tn->Branch("Bound", &fBound, "Bound/O");
tn->Branch("RWWeight", &RWWeight, "RWWeight/D");
tn->Branch("InputWeight", &InputWeight, "InputWeight/D");
tn->Branch("NParticles", &fNParticles, "NParticles/I");
tn->Branch("ParticleState", fOrigParticleState,
"ParticleState[NParticles]/i");
tn->Branch("ParticlePDG", fOrigParticlePDG, "ParticlePDG[NParticles]/I");
tn->Branch("ParticleMom", fOrigParticleMom, "ParticleMom[NParticles][4]/D");
}
// ------- EVENT ACCESS FUNCTION --------- //
TLorentzVector FitEvent::GetParticleP4(int index) const {
if (index == -1 or index >= fNParticles) return TLorentzVector();
return TLorentzVector(fParticleMom[index][0], fParticleMom[index][1],
fParticleMom[index][2], fParticleMom[index][3]);
}
TVector3 FitEvent::GetParticleP3(int index) const {
if (index == -1 or index >= fNParticles) return TVector3();
return TVector3(fParticleMom[index][0], fParticleMom[index][1],
fParticleMom[index][2]);
}
double FitEvent::GetParticleMom(int index) const {
if (index == -1 or index >= fNParticles) return 0.0;
return sqrt(fParticleMom[index][0] * fParticleMom[index][0] +
fParticleMom[index][1] * fParticleMom[index][1] +
fParticleMom[index][2] * fParticleMom[index][2]);
}
double FitEvent::GetParticleMom2(int index) const {
if (index == -1 or index >= fNParticles) return 0.0;
return fabs((fParticleMom[index][0] * fParticleMom[index][0] +
fParticleMom[index][1] * fParticleMom[index][1] +
fParticleMom[index][2] * fParticleMom[index][2]));
}
double FitEvent::GetParticleE(int index) const {
if (index == -1 or index >= fNParticles) return 0.0;
return fParticleMom[index][3];
}
int FitEvent::GetParticleState(int index) const {
if (index == -1 or index >= fNParticles) return kUndefinedState;
return (fParticleState[index]);
}
int FitEvent::GetParticlePDG(int index) const {
if (index == -1 or index >= fNParticles) return 0;
return (fParticlePDG[index]);
}
FitParticle* FitEvent::GetParticle(int const i) {
// Check Valid Index
if (i == -1) {
return NULL;
}
// Check Valid
if (i > fNParticles) {
ERR(FTL) << "Requesting particle beyond stack!" << std::endl
<< "i = " << i << " N = " << fNParticles << std::endl
<< "Mode = " << Mode << std::endl;
throw;
}
if (!fParticleList[i]) {
/*
std::cout << "Creating particle with values i " << i << " ";
std::cout << fParticleMom[i][0] << " " << fParticleMom[i][1] << " " <<
fParticleMom[i][2] << " " << fParticleMom[i][3] << " ";
std::cout << fParticlePDG[i] << " " << fParticleState[i] << std::endl;
*/
fParticleList[i] = new FitParticle(fParticleMom[i][0], fParticleMom[i][1],
fParticleMom[i][2], fParticleMom[i][3],
fParticlePDG[i], fParticleState[i]);
} else {
/*
std::cout << "Filling particle with values i " << i << " ";
std::cout << fParticleMom[i][0] << " " << fParticleMom[i][1] << " " <<
fParticleMom[i][2] << " " << fParticleMom[i][3] << " ";
std::cout << fParticlePDG[i] << " "<< fParticleState[i] <<std::endl;
*/
fParticleList[i]->SetValues(fParticleMom[i][0], fParticleMom[i][1],
fParticleMom[i][2], fParticleMom[i][3],
fParticlePDG[i], fParticleState[i]);
}
return fParticleList[i];
}
bool FitEvent::HasParticle(int const pdg, int const state) const {
bool found = false;
for (int i = 0; i < fNParticles; i++) {
if (state != -1 && fParticleState[i] != (uint)state) continue;
if (fParticlePDG[i] == pdg) found = true;
}
return found;
}
int FitEvent::NumParticle(int const pdg, int const state) const {
int nfound = 0;
for (int i = 0; i < fNParticles; i++) {
if (state != -1 and fParticleState[i] != (uint)state) continue;
if (pdg == 0 or fParticlePDG[i] == pdg) nfound += 1;
}
return nfound;
}
std::vector<int> FitEvent::GetAllParticleIndices(int const pdg,
int const state) const {
std::vector<int> indexlist;
for (int i = 0; i < fNParticles; i++) {
if (state != -1 and fParticleState[i] != (uint)state) continue;
if (pdg == 0 or fParticlePDG[i] == pdg) {
indexlist.push_back(i);
}
}
return indexlist;
}
std::vector<FitParticle*> FitEvent::GetAllParticle(int const pdg,
int const state) {
std::vector<int> indexlist = GetAllParticleIndices(pdg, state);
std::vector<FitParticle*> plist;
for (std::vector<int>::iterator iter = indexlist.begin();
iter != indexlist.end(); iter++) {
plist.push_back(GetParticle((*iter)));
}
return plist;
}
int FitEvent::GetHMParticleIndex(int const pdg, int const state) const {
double maxmom2 = -9999999.9;
int maxind = -1;
for (int i = 0; i < fNParticles; i++) {
if (state != -1 and fParticleState[i] != (uint)state) continue;
if (pdg == 0 or fParticlePDG[i] == pdg) {
double newmom2 = GetParticleMom2(i);
if (newmom2 > maxmom2) {
maxind = i;
maxmom2 = newmom2;
}
}
}
return maxind;
}
int FitEvent::GetBeamNeutrinoIndex(void) const {
for (int i = 0; i < fNParticles; i++) {
if (fParticleState[i] != kInitialState) continue;
int pdg = abs(fParticlePDG[i]);
if (pdg == 12 or pdg == 14 or pdg == 16) {
return i;
}
}
return 0;
}
int FitEvent::GetBeamElectronIndex(void) const {
return GetHMISParticleIndex(11);
}
int FitEvent::GetBeamPionIndex(void) const {
return GetHMISParticleIndex(PhysConst::pdg_pions);
}
int FitEvent::NumFSMesons() {
int nMesons = 0;
for (int i = 0; i < fNParticles; i++) {
if (fParticleState[i] != kFinalState) continue;
if (abs(fParticlePDG[i]) >= 111 && abs(fParticlePDG[i]) <= 557)
nMesons += 1;
}
return nMesons;
}
int FitEvent::NumFSLeptons(void) const {
int nLeptons = 0;
for (int i = 0; i < fNParticles; i++) {
if (fParticleState[i] != kFinalState) continue;
if (abs(fParticlePDG[i]) == 11 || abs(fParticlePDG[i]) == 13 ||
abs(fParticlePDG[i]) == 15)
nLeptons += 1;
}
return nLeptons;
}
diff --git a/src/InputHandler/GIBUUInputHandler.cxx b/src/InputHandler/GIBUUInputHandler.cxx
index c0e8724..f61559f 100644
--- a/src/InputHandler/GIBUUInputHandler.cxx
+++ b/src/InputHandler/GIBUUInputHandler.cxx
@@ -1,301 +1,302 @@
#ifdef __GiBUU_ENABLED__
#include "GIBUUInputHandler.h"
#include "InputUtils.h"
GIBUUGeneratorInfo::~GIBUUGeneratorInfo() { DeallocateParticleStack(); }
void GIBUUGeneratorInfo::AddBranchesToTree(TTree* tn) {
// tn->Branch("NEUTParticleN", fNEUTParticleN, "NEUTParticleN/I");
// tn->Branch("NEUTParticleStatusCode", fNEUTParticleStatusCode,
// "NEUTParticleStatusCode[NEUTParticleN]/I");
// tn->Branch("NEUTParticleAliveCode", fNEUTParticleAliveCode,
// "NEUTParticleAliveCode[NEUTParticleN]/I");
}
void GIBUUGeneratorInfo::SetBranchesFromTree(TTree* tn) {
// tn->SetBranchAddress("NEUTParticleN", &fNEUTParticleN );
// tn->SetBranchAddress("NEUTParticleStatusCode", &fNEUTParticleStatusCode );
// tn->SetBranchAddress("NEUTParticleAliveCode", &fNEUTParticleAliveCode );
}
void GIBUUGeneratorInfo::AllocateParticleStack(int stacksize) {
// fNEUTParticleN = 0;
// fNEUTParticleStatusCode = new int[stacksize];
// fNEUTParticleStatusCode = new int[stacksize];
}
void GIBUUGeneratorInfo::DeallocateParticleStack() {
// delete fNEUTParticleStatusCode;
// delete fNEUTParticleAliveCode;
}
void GIBUUGeneratorInfo::FillGeneratorInfo(GiBUUStdHepReader* nevent) {
Reset();
// for (int i = 0; i < nevent->Npart(); i++) {
// fNEUTParticleStatusCode[i] = nevent->PartInfo(i)->fStatus;
// fNEUTParticleAliveCode[i] = nevent->PartInfo(i)->fIsAlive;
// fNEUTParticleN++;
// }
}
void GIBUUGeneratorInfo::Reset() {
// for (int i = 0; i < fNEUTParticleN; i++) {
// fNEUTParticleStatusCode[i] = -1;
// fNEUTParticleAliveCode[i] = 9;
// }
// fNEUTParticleN = 0;
}
GIBUUInputHandler::GIBUUInputHandler(std::string const& handle,
std::string const& rawinputs) {
LOG(SAM) << "Creating GiBUUInputHandler : " << handle << std::endl;
// Run a joint input handling
fName = handle;
fEventType = kGiBUU;
fGIBUUTree = new TChain("giRooTracker");
// Loop over all inputs and grab flux, eventhist, and nevents
std::vector<std::string> inputs = InputUtils::ParseInputFileList(rawinputs);
for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) {
// Open File for histogram access
LOG(SAM) << "Opening event file " << inputs[inp_it] << std::endl;
TFile* inp_file = new TFile(inputs[inp_it].c_str(), "READ");
if ((!inp_file) || (!inp_file->IsOpen())) {
THROW("GiBUU file !IsOpen() at : '"
<< inputs[inp_it] << "'" << std::endl
<< "Check that your file paths are correct and the file exists!");
}
int NFluxes = bool(dynamic_cast<TH1D*>(inp_file->Get("numu_flux"))) +
bool(dynamic_cast<TH1D*>(inp_file->Get("numub_flux"))) +
bool(dynamic_cast<TH1D*>(inp_file->Get("nue_flux"))) +
bool(dynamic_cast<TH1D*>(inp_file->Get("nueb_flux"))) +
bool(dynamic_cast<TH1D*>(inp_file->Get("e_flux")));
if (NFluxes != 1) {
THROW("Found " << NFluxes << " input fluxes in " << inputs[inp_it]
<< ". The NUISANCE GiBUU interface expects to be "
"passed multiple species vectors as separate "
"input files like: "
"\"GiBUU:(MINERVA_FHC_numu_evts.root,MINERVA_FHC_"
"numubar_evts.root,[...])\"");
}
// Get Flux/Event hist
TH1D* fluxhist = dynamic_cast<TH1D*>(inp_file->Get("flux"));
TH1D* eventhist = dynamic_cast<TH1D*>(inp_file->Get("evt"));
if (!fluxhist || !eventhist) {
ERROR(FTL, "Input File Contents: " << inputs[inp_it]);
inp_file->ls();
THROW(
"GiBUU FILE doesn't contain flux/xsec info. You may have to "
"regenerate your MC!");
}
// Get N Events
TTree* giRooTracker = dynamic_cast<TTree*>(inp_file->Get("giRooTracker"));
if (!giRooTracker) {
ERROR(FTL,
"giRooTracker Tree not located in NEUT file: " << inputs[inp_it]);
THROW("Check your inputs, they may need to be completely regenerated!");
throw;
}
int nevents = giRooTracker->GetEntries();
if (nevents <= 0) {
THROW("Trying to a TTree with "
<< nevents << " to TChain from : " << inputs[inp_it]);
}
// Register input to form flux/event rate hists
RegisterJointInput(inputs[inp_it], nevents, fluxhist, eventhist);
// Add To TChain
fGIBUUTree->AddFile(inputs[inp_it].c_str());
}
// Registor all our file inputs
SetupJointInputs();
// Create Fit Event
fNUISANCEEvent = new FitEvent();
fGiReader = new GiBUUStdHepReader();
fGiReader->SetBranchAddresses(fGIBUUTree);
fNUISANCEEvent->HardReset();
};
FitEvent* GIBUUInputHandler::GetNuisanceEvent(const UInt_t entry,
const bool lightweight) {
// Check out of bounds
if (entry >= (UInt_t)fNEvents) return NULL;
// Read Entry from TTree to fill NEUT Vect in BaseFitEvt;
fGIBUUTree->GetEntry(entry);
// Run NUISANCE Vector Filler
if (!lightweight) {
CalcNUISANCEKinematics();
}
#ifdef __PROB3PP_ENABLED__
else {
for (int i = 0; i < fGiReader->StdHepN; i++) {
int state = GetGIBUUParticleStatus(fGiReader->StdHepStatus[i],
fGiReader->StdHepPdg[i]);
if (state != kInitialState) {
continue;
}
if (std::count(PhysConst::pdg_neutrinos, PhysConst::pdg_neutrinos + 4,
fGiReader->StdHepPdg[i])) {
fNUISANCEEvent->probe_E = fGiReader->StdHepP4[i][3] * 1.E3;
fNUISANCEEvent->probe_pdg = fGiReader->StdHepPdg[i];
break;
}
}
}
#endif
fNUISANCEEvent->InputWeight *= GetInputWeight(entry);
+ fNUISANCEEvent->GiRead = fGiReader;
return fNUISANCEEvent;
}
int GetGIBUUParticleStatus(int status, int pdg) {
int state = kUndefinedState;
switch (status) {
case 0: // Incoming
case 11: // Struck nucleon
state = kInitialState;
break;
case 1: // Good Final State
state = kFinalState;
break;
default: // Other
break;
}
// Set Nuclear States Flag
if (pdg > 1000000) {
if (state == kInitialState)
state = kNuclearInitial;
else if (state == kFinalState)
state = kNuclearRemnant;
else
state = kUndefinedState;
}
return state;
}
void GIBUUInputHandler::CalcNUISANCEKinematics() {
// Reset all variables
fNUISANCEEvent->ResetEvent();
FitEvent* evt = fNUISANCEEvent;
evt->Mode = fGiReader->GiBUU2NeutCode;
evt->fEventNo = 0.0;
evt->fTotCrs = 0;
evt->fTargetA = 0.0; // Change to get these from nuclear remnant.
evt->fTargetZ = 0.0;
evt->fTargetH = 0;
evt->fBound = 0.0;
// Extra GiBUU Input Weight
evt->InputWeight = fGiReader->EvtWght;
// Check Stack N
int npart = fGiReader->StdHepN;
int kmax = evt->kMaxParticles;
if ((UInt_t)npart > (UInt_t)kmax) {
ERROR(WRN, "GiBUU has too many particles. Expanding Stack.");
fNUISANCEEvent->ExpandParticleStack(npart);
}
// Create Stack
evt->fNParticles = 0;
for (int i = 0; i < npart; i++) {
// State
int state = GetGIBUUParticleStatus(fGiReader->StdHepStatus[i],
fGiReader->StdHepPdg[i]);
int curpart = evt->fNParticles;
// Set State
evt->fParticleState[evt->fNParticles] = state;
// Mom
evt->fParticleMom[curpart][0] = fGiReader->StdHepP4[i][0] * 1.E3;
evt->fParticleMom[curpart][1] = fGiReader->StdHepP4[i][1] * 1.E3;
evt->fParticleMom[curpart][2] = fGiReader->StdHepP4[i][2] * 1.E3;
evt->fParticleMom[curpart][3] = fGiReader->StdHepP4[i][3] * 1.E3;
// PDG
evt->fParticlePDG[curpart] = fGiReader->StdHepPdg[i];
// Add to total particles
evt->fNParticles++;
}
// Run Initial, FSI, Final, Other ordering.
fNUISANCEEvent->OrderStack();
FitParticle* ISNeutralLepton =
fNUISANCEEvent->GetHMISParticle(PhysConst::pdg_neutrinos);
if (ISNeutralLepton) {
fNUISANCEEvent->probe_E = ISNeutralLepton->E();
fNUISANCEEvent->probe_pdg = ISNeutralLepton->PDG();
}
return;
}
void GIBUUInputHandler::Print() {}
void GIBUUInputHandler::SetupJointInputs() {
if (jointeventinputs.size() <= 1) {
jointinput = false;
} else if (jointeventinputs.size() > 1) {
jointinput = true;
jointindexswitch = 0;
}
fMaxEvents = FitPar::Config().GetParI("MAXEVENTS");
if (fMaxEvents != -1 and jointeventinputs.size() > 1) {
THROW("Can only handle joint inputs when config MAXEVENTS = -1!");
}
for (size_t i = 0; i < jointeventinputs.size(); i++) {
double scale = double(fNEvents) / fEventHist->Integral("width");
scale *= jointfluxinputs.at(i)->Integral("width");
jointindexscale.push_back(scale);
}
fEventHist->SetNameTitle((fName + "_EVT").c_str(), (fName + "_EVT").c_str());
fFluxHist->SetNameTitle((fName + "_FLUX").c_str(), (fName + "_FLUX").c_str());
// Setup Max Events
if (fMaxEvents > 1 && fMaxEvents < fNEvents) {
if (LOG_LEVEL(SAM)) {
std::cout << "\t\t|-> Read Max Entries : " << fMaxEvents << std::endl;
}
fNEvents = fMaxEvents;
}
// Print out Status
if (LOG_LEVEL(SAM)) {
std::cout << "\t\t|-> Total Entries : " << fNEvents << std::endl
<< "\t\t|-> Event Integral : "
<< fEventHist->Integral("width") * 1.E-38 << " events/nucleon"
<< std::endl
<< "\t\t|-> Flux Integral : " << fFluxHist->Integral("width")
<< " /cm2" << std::endl
<< "\t\t|-> Event/Flux : "
<< fEventHist->Integral("width") * 1.E-38 /
fFluxHist->Integral("width")
<< " cm2/nucleon" << std::endl;
}
}
#endif
diff --git a/src/InputHandler/InputHandler.cxx b/src/InputHandler/InputHandler.cxx
index b400590..80e9f65 100644
--- a/src/InputHandler/InputHandler.cxx
+++ b/src/InputHandler/InputHandler.cxx
@@ -1,267 +1,301 @@
// 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 "InputHandler.h"
#include "InputUtils.h"
InputHandlerBase::InputHandlerBase() {
fName = "";
fFluxHist = NULL;
fEventHist = NULL;
fNEvents = 0;
fNUISANCEEvent = NULL;
fBaseEvent = NULL;
kRemoveUndefParticles = FitPar::Config().GetParB("RemoveUndefParticles");
kRemoveFSIParticles = FitPar::Config().GetParB("RemoveFSIParticles");
kRemoveNuclearParticles = FitPar::Config().GetParB("RemoveNuclearParticles");
fMaxEvents = FitPar::Config().GetParI("MAXEVENTS");
fTTreePerformance = NULL;
};
InputHandlerBase::~InputHandlerBase() {
if (fFluxHist) delete fFluxHist;
if (fEventHist) delete fEventHist;
// if (fXSecHist) delete fXSecHist;
// if (fNUISANCEEvent) delete fNUISANCEEvent;
jointfluxinputs.clear();
jointeventinputs.clear();
jointindexlow.clear();
jointindexhigh.clear();
jointindexallowed.clear();
jointindexscale.clear();
// if (fTTreePerformance) {
// fTTreePerformance->SaveAs(("ttreeperfstats_" + fName +
// ".root").c_str());
// }
}
void InputHandlerBase::Print(){};
TH1D* InputHandlerBase::GetXSecHistogram(void) {
fXSecHist = (TH1D*)fFluxHist->Clone();
fXSecHist->Divide(fEventHist);
return fXSecHist;
};
double InputHandlerBase::PredictedEventRate(double low, double high,
std::string intOpt) {
- int minBin = fFluxHist->GetXaxis()->FindBin(low);
- int maxBin = fFluxHist->GetXaxis()->FindBin(high);
+ Int_t minBin = fEventHist->GetXaxis()->FindFixBin(low);
+ Int_t maxBin = fEventHist->GetXaxis()->FindFixBin(high);
- return fEventHist->Integral(minBin, maxBin + 1, intOpt.c_str());
+ if ((fEventHist->IsBinOverflow(minBin) && (low != -9999.9))) {
+ minBin = 1;
+ }
+
+ if ((fEventHist->IsBinOverflow(maxBin) && (high != -9999.9))) {
+ maxBin = fEventHist->GetXaxis()->GetNbins() + 1;
+ }
+
+ // If we are within a single bin
+ if (minBin == maxBin) {
+ // Get the contained fraction of the single bin's width
+ return ((high - low) / fEventHist->GetXaxis()->GetBinWidth(minBin)) *
+ fEventHist->Integral(minBin, minBin, intOpt.c_str());
+ }
+
+ double lowBinUpEdge = fEventHist->GetXaxis()->GetBinUpEdge(minBin);
+ double highBinLowEdge = fEventHist->GetXaxis()->GetBinLowEdge(maxBin);
+
+ double lowBinfracIntegral =
+ ((lowBinUpEdge - low) / fEventHist->GetXaxis()->GetBinWidth(minBin)) *
+ fEventHist->Integral(minBin, minBin, intOpt.c_str());
+ double highBinfracIntegral =
+ ((high - highBinLowEdge) / fEventHist->GetXaxis()->GetBinWidth(maxBin)) *
+ fEventHist->Integral(maxBin, maxBin, intOpt.c_str());
+
+ // If they are neighbouring bins
+ if ((minBin + 1) == maxBin) {
+ std::cout << "Get lowfrac + highfrac" << std::endl;
+ // Get the contained fraction of the two bin's width
+ return lowBinfracIntegral + highBinfracIntegral;
+ }
+
+ double ContainedIntegral =
+ fEventHist->Integral(minBin + 1, maxBin - 1, intOpt.c_str());
+ // If there are filled bins between them
+ return lowBinfracIntegral + highBinfracIntegral + ContainedIntegral;
};
double InputHandlerBase::TotalIntegratedFlux(double low, double high,
std::string intOpt) {
Int_t minBin = fFluxHist->GetXaxis()->FindFixBin(low);
Int_t maxBin = fFluxHist->GetXaxis()->FindFixBin(high);
if ((fFluxHist->IsBinOverflow(minBin) && (low != -9999.9))) {
minBin = 1;
}
if ((fFluxHist->IsBinOverflow(maxBin) && (high != -9999.9))) {
maxBin = fFluxHist->GetXaxis()->GetNbins() + 1;
}
// If we are within a single bin
if (minBin == maxBin) {
// Get the contained fraction of the single bin's width
return ((high - low) / fFluxHist->GetXaxis()->GetBinWidth(minBin)) *
fFluxHist->Integral(minBin, minBin, intOpt.c_str());
}
double lowBinUpEdge = fFluxHist->GetXaxis()->GetBinUpEdge(minBin);
double highBinLowEdge = fFluxHist->GetXaxis()->GetBinLowEdge(maxBin);
double lowBinfracIntegral =
((lowBinUpEdge - low) / fFluxHist->GetXaxis()->GetBinWidth(minBin)) *
fFluxHist->Integral(minBin, minBin, intOpt.c_str());
double highBinfracIntegral =
((high - highBinLowEdge) / fFluxHist->GetXaxis()->GetBinWidth(maxBin)) *
fFluxHist->Integral(maxBin, maxBin, intOpt.c_str());
// If they are neighbouring bins
if ((minBin + 1) == maxBin) {
std::cout << "Get lowfrac + highfrac" << std::endl;
// Get the contained fraction of the two bin's width
return lowBinfracIntegral + highBinfracIntegral;
}
double ContainedIntegral =
fFluxHist->Integral(minBin + 1, maxBin - 1, intOpt.c_str());
// If there are filled bins between them
return lowBinfracIntegral + highBinfracIntegral + ContainedIntegral;
- // return fFluxHist->Integral(minBin + 1, maxBin - 1, intOpt.c_str());
}
std::vector<TH1*> InputHandlerBase::GetFluxList(void) {
return std::vector<TH1*>(1, fFluxHist);
};
std::vector<TH1*> InputHandlerBase::GetEventList(void) {
return std::vector<TH1*>(1, fEventHist);
};
std::vector<TH1*> InputHandlerBase::GetXSecList(void) {
return std::vector<TH1*>(1, GetXSecHistogram());
};
FitEvent* InputHandlerBase::FirstNuisanceEvent() {
fCurrentIndex = 0;
return GetNuisanceEvent(fCurrentIndex);
};
FitEvent* InputHandlerBase::NextNuisanceEvent() {
fCurrentIndex++;
if ((fMaxEvents != -1) && (fCurrentIndex > fMaxEvents)) {
return NULL;
}
return GetNuisanceEvent(fCurrentIndex);
};
BaseFitEvt* InputHandlerBase::FirstBaseEvent() {
fCurrentIndex = 0;
return GetBaseEvent(fCurrentIndex);
};
BaseFitEvt* InputHandlerBase::NextBaseEvent() {
fCurrentIndex++;
if (jointinput and fMaxEvents != -1) {
while (fCurrentIndex < jointindexlow[jointindexswitch] ||
fCurrentIndex >= jointindexhigh[jointindexswitch]) {
jointindexswitch++;
// Loop Around
if (jointindexswitch == jointindexlow.size()) {
jointindexswitch = 0;
}
}
if (fCurrentIndex >
jointindexlow[jointindexswitch] + jointindexallowed[jointindexswitch]) {
fCurrentIndex = jointindexlow[jointindexswitch];
}
}
return GetBaseEvent(fCurrentIndex);
};
void InputHandlerBase::RegisterJointInput(std::string input, int n, TH1D* f,
TH1D* e) {
if (jointfluxinputs.size() == 0) {
jointindexswitch = 0;
fNEvents = 0;
}
// Push into individual input vectors
jointfluxinputs.push_back((TH1D*)f->Clone());
jointeventinputs.push_back((TH1D*)e->Clone());
jointindexlow.push_back(fNEvents);
jointindexhigh.push_back(fNEvents + n);
fNEvents += n;
// Add to the total flux/event hist
if (!fFluxHist)
fFluxHist = (TH1D*)f->Clone();
else
fFluxHist->Add(f);
if (!fEventHist)
fEventHist = (TH1D*)e->Clone();
else
fEventHist->Add(e);
}
void InputHandlerBase::SetupJointInputs() {
if (jointeventinputs.size() <= 1) {
jointinput = false;
} else if (jointeventinputs.size() > 1) {
jointinput = true;
jointindexswitch = 0;
}
fMaxEvents = FitPar::Config().GetParI("MAXEVENTS");
if (fMaxEvents != -1 and jointeventinputs.size() > 1) {
THROW("Can only handle joint inputs when config MAXEVENTS = -1!");
}
if (jointeventinputs.size() > 1) {
ERROR(WRN,
"GiBUU sample contains multiple inputs. This will only work for "
"samples that expect multi-species inputs. If this sample does, you "
"can ignore this warning.");
}
for (size_t i = 0; i < jointeventinputs.size(); i++) {
double scale = double(fNEvents) / fEventHist->Integral("width");
scale *= jointeventinputs.at(i)->Integral("width");
scale /= double(jointindexhigh[i] - jointindexlow[i]);
jointindexscale.push_back(scale);
}
fEventHist->SetNameTitle((fName + "_EVT").c_str(), (fName + "_EVT").c_str());
fFluxHist->SetNameTitle((fName + "_FLUX").c_str(), (fName + "_FLUX").c_str());
// Setup Max Events
if (fMaxEvents > 1 && fMaxEvents < fNEvents) {
if (LOG_LEVEL(SAM)) {
std::cout << "\t\t|-> Read Max Entries : " << fMaxEvents << std::endl;
}
fNEvents = fMaxEvents;
}
// Print out Status
if (LOG_LEVEL(SAM)) {
std::cout << "\t\t|-> Total Entries : " << fNEvents << std::endl
<< "\t\t|-> Event Integral : "
<< fEventHist->Integral("width") * 1.E-38 << " events/nucleon"
<< std::endl
<< "\t\t|-> Flux Integral : " << fFluxHist->Integral("width")
<< " /cm2" << std::endl
<< "\t\t|-> Event/Flux : "
<< fEventHist->Integral("width") * 1.E-38 /
fFluxHist->Integral("width")
<< " cm2/nucleon" << std::endl;
}
}
BaseFitEvt* InputHandlerBase::GetBaseEvent(const UInt_t entry) {
return static_cast<BaseFitEvt*>(GetNuisanceEvent(entry, true));
}
double InputHandlerBase::GetInputWeight(int entry) {
if (!jointinput) return 1.0;
// Find Switch Scale
while (entry < jointindexlow[jointindexswitch] ||
entry >= jointindexhigh[jointindexswitch]) {
jointindexswitch++;
// Loop Around
if (jointindexswitch >= jointindexlow.size()) {
jointindexswitch = 0;
}
}
return jointindexscale[jointindexswitch];
};
diff --git a/src/InputHandler/InputHandler.h b/src/InputHandler/InputHandler.h
index 3377403..1110091 100644
--- a/src/InputHandler/InputHandler.h
+++ b/src/InputHandler/InputHandler.h
@@ -1,145 +1,145 @@
// 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 INPUTHANDLER2_H
#define INPUTHANDLER2_H
/*!
* \addtogroup InputHandler
* @{
*/
#include "TH1D.h"
#include "FitEvent.h"
#include "BaseFitEvt.h"
#include "TTreePerfStats.h"
/// Base InputHandler class defining how events are requested and setup.
class InputHandlerBase {
public:
/// Base constructor resets everything to default
InputHandlerBase();
/// Removes flux/event rate histograms
virtual ~InputHandlerBase();
/// Return NUISANCE FitEvent Class from given event entry.
/// Must be overriden by GeneratorInputHandler. Lightweight allows a faster option
/// to be given where only RW information is needed.
virtual FitEvent* GetNuisanceEvent(const UInt_t entry, const bool lightweight=false) = 0;
/// Calls GetNuisanceEvent(entry, TRUE);
virtual BaseFitEvt* GetBaseEvent(const UInt_t entry);
/// Print current event information
virtual void Print();
/// Return handler ID
inline std::string GetName (void) {return fName; };
/// Return Handler Event Type Index
inline int GetType (void) {return fEventType;};
/// Get Total Number of Events being Handled
inline virtual int GetNEvents (void) {return fNEvents; };
/// Get the Total Flux Histogram these events were generated with
inline virtual TH1D* GetFluxHistogram (void) {return fFluxHist; };
/// Get the Total Event Histogram these events were generated with
inline virtual TH1D* GetEventHistogram (void) {return fEventHist;};
/// Get the Total Cross-section Histogram (EventHist/FluxHist)
virtual TH1D* GetXSecHistogram(void);
/// Return all Flux Histograms for all InputFiles.
virtual std::vector<TH1*> GetFluxList(void);
/// Return all Event Histograms for all InputFiles
virtual std::vector<TH1*> GetEventList(void);
/// Return all Xsec Histograms for all InputFiles
virtual std::vector<TH1*> GetXSecList(void);
/// Placeholder to create a cache to speed up reads in GeneratorInputHandler
inline virtual void CreateCache(){};
/// Placeholder to remove optional cache to free up memory
inline virtual void RemoveCache(){};
/// Return starting NUISANCE event pointer (entry=0)
FitEvent* FirstNuisanceEvent();
/// Iterate to next NUISANCE event. Returns NULL when entry > fNEvents.
FitEvent* NextNuisanceEvent();
/// Returns starting Base Event Pointer (entry=0)
BaseFitEvt* FirstBaseEvent();
/// Iterate to next NUISANCE Base Event. Returns NULL when entry > fNEvents.
BaseFitEvt* NextBaseEvent();
/// Register an input file and update event/flux information
virtual void RegisterJointInput(std::string input, int n, TH1D* f, TH1D* e);
/// Finalise setup of Input event/flux information and calculate
/// joint input weights if joint input is provided.
virtual void SetupJointInputs();
/// Calculate a weight for the event given the joint input information.
/// Used to scale the relative proportion of multiple inputs correctly
/// with respect to one another.
virtual double GetInputWeight(int entry);
/// Returns the total predicted event rate for this input given the
/// low and high energy ranges. intOpt specifies the option the ROOT
/// TH1D integral should use. e.g. "" or "width"
- double PredictedEventRate(double low, double high,
- std::string intOpt);
+ double PredictedEventRate(double low = -9999.9, double high = -9999.9,
+ std::string intOpt = "");
/// Returns the total generated flux for this input given the
/// low and high energy ranges. intOpt specifies the option the ROOT
/// TH1D integral should use. e.g. "" or "width"
double TotalIntegratedFlux(double low = -9999.9, double high = -9999.9,
std::string intOpt = "");
/// Actual data members.
std::vector<TH1D*> jointfluxinputs;
std::vector<TH1D*> jointeventinputs;
std::vector<int> jointindexlow;
std::vector<int> jointindexhigh;
std::vector<int> jointindexallowed;
size_t jointindexswitch;
bool jointinput;
std::vector<double> jointindexscale;
std::string fName;
TH1D* fFluxHist;
TH1D* fEventHist;
TH1D* fXSecHist;
int fNEvents;
int fMaxEvents;
FitEvent* fNUISANCEEvent;
BaseFitEvt* fBaseEvent;
int fEventType;
int fCurrentIndex;
int fCacheSize;
bool kRemoveUndefParticles;
bool kRemoveFSIParticles;
bool kRemoveNuclearParticles;
TTreePerfStats* fTTreePerformance;
};
/*! @} */
#endif
diff --git a/src/InputHandler/InteractionModes.h b/src/InputHandler/InteractionModes.h
index f381f30..22d6adf 100644
--- a/src/InputHandler/InteractionModes.h
+++ b/src/InputHandler/InteractionModes.h
@@ -1,91 +1,121 @@
// 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/>.
-*******************************************************************************/
+ * 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 INTERACTION_MODES_H
#define INTERACTION_MODES_H
+#include <iostream>
+
namespace InputHandler {
enum InteractionModes {
- kCCQE = 1,
- kCC2p2h = 2,
- kCC1piponp = 11,
- kCC1pi0onn = 12,
- kCC1piponn = 13,
- kCCCoherent = 16,
- kCC1gamma = 17,
- kCCmultipi = 21,
- kCC1etaonn = 22,
- kCC1kaonp = 23,
- kCCDIS = 26,
- kNC1pi0onn = 31,
- kNC1pi0onp = 32,
- kNC1pimonn = 33,
- kNC1piponp = 34,
- kNCCoherent = 36,
- kNC1gamman = 38,
- kNC1gammap = 39,
- kNCmultipi = 41,
- kNC1etaonn = 42,
- kNC1etaonp = 43,
- kNC1kaon0 = 44,
- kNC1kaonp = 45,
- kNCDIS = 46,
- kNCELonp = 51,
- kNCELonn = 52,
- kNC2p2h = 53
-}
+ kCCQE = 1,
+ kCC2p2h = 2,
+ kCC1piponp = 11,
+ kCC1pi0onn = 12,
+ kCC1piponn = 13,
+ kCCCoherent = 16,
+ kCC1gamma = 17,
+ kCCmultipi = 21,
+ kCC1etaonn = 22,
+ kCC1kaonp = 23,
+ kCCDIS = 26,
+ kNC1pi0onn = 31,
+ kNC1pi0onp = 32,
+ kNC1pimonn = 33,
+ kNC1piponp = 34,
+ kNCCoherent = 36,
+ kNC1gamman = 38,
+ kNC1gammap = 39,
+ kNCmultipi = 41,
+ kNC1etaonn = 42,
+ kNC1etaonp = 43,
+ kNC1kaon0 = 44,
+ kNC1kaonp = 45,
+ kNCDIS = 46,
+ kNCELonp = 51,
+ kNCELonn = 52,
+ kNC2p2h = 53
+};
}
-inline std::ostream &operator<<(std::ostream &os, InputHandler::InteractionModes it) {
-
- switch(it){
- case InputHandler::kCCQE: return os << "CCQE";
- case InputHandler::kCC2p2h: return os << "CC2p2h";
- case InputHandler::kCC1piponp: return os << "CC1piponp";
- case InputHandler::kCC1pi0onn: return os << "CC1pi0onn";
- case InputHandler::kCC1piponn: return os << "CC1piponn";
- case InputHandler::kCCCoherent: return os << "CCCoherent";
- case InputHandler::kCC1gamma: return os << "CC1gamma";
- case InputHandler::kCCmultipi: return os << "CCmultipi";
- case InputHandler::kCC1etaonn: return os << "CC1etaonn";
- case InputHandler::kCC1kaonp: return os << "CC1kaonp";
- case InputHandler::kCCDIS: return os << "CCDIS";
- case InputHandler::kNC1pi0onn: return os << "NC1pi0onn";
- case InputHandler::kNC1pi0onp: return os << "NC1pi0onp";
- case InputHandler::kNC1pimonn: return os << "NC1pimonn";
- case InputHandler::kNC1piponp: return os << "NC1piponp";
- case InputHandler::kNCCoherent: return os << "NCCoherent";
- case InputHandler::kNC1gamman: return os << "NC1gamman";
- case InputHandler::kNC1gammap: return os << "NC1gammap";
- case InputHandler::kNCmultipi: return os << "NCmultipi";
- case InputHandler::kNC1etaonn: return os << "NC1etaonn";
- case InputHandler::kNC1etaonp: return os << "NC1etaonp";
- case InputHandler::kNC1kaon0: return os << "NC1kaon0";
- case InputHandler::kNC1kaonp: return os << "NC1kaonp";
- case InputHandler::kNCDIS: return os << "NCDIS";
- case InputHandler::kNCELonp: return os << "NCELonp";
- case InputHandler::kNCELonn: return os << "NCELonn";
- case InputHandler::kNC2p2h: return os << "NC2p2h";
- default: return os << "UNKNOWN";
- }
- return os << "UNKNOWN";
+inline std::ostream &operator<<(std::ostream &os,
+ InputHandler::InteractionModes it) {
+ switch (it) {
+ case InputHandler::kCCQE:
+ return os << "CCQE";
+ case InputHandler::kCC2p2h:
+ return os << "CC2p2h";
+ case InputHandler::kCC1piponp:
+ return os << "CC1piponp";
+ case InputHandler::kCC1pi0onn:
+ return os << "CC1pi0onn";
+ case InputHandler::kCC1piponn:
+ return os << "CC1piponn";
+ case InputHandler::kCCCoherent:
+ return os << "CCCoherent";
+ case InputHandler::kCC1gamma:
+ return os << "CC1gamma";
+ case InputHandler::kCCmultipi:
+ return os << "CCmultipi";
+ case InputHandler::kCC1etaonn:
+ return os << "CC1etaonn";
+ case InputHandler::kCC1kaonp:
+ return os << "CC1kaonp";
+ case InputHandler::kCCDIS:
+ return os << "CCDIS";
+ case InputHandler::kNC1pi0onn:
+ return os << "NC1pi0onn";
+ case InputHandler::kNC1pi0onp:
+ return os << "NC1pi0onp";
+ case InputHandler::kNC1pimonn:
+ return os << "NC1pimonn";
+ case InputHandler::kNC1piponp:
+ return os << "NC1piponp";
+ case InputHandler::kNCCoherent:
+ return os << "NCCoherent";
+ case InputHandler::kNC1gamman:
+ return os << "NC1gamman";
+ case InputHandler::kNC1gammap:
+ return os << "NC1gammap";
+ case InputHandler::kNCmultipi:
+ return os << "NCmultipi";
+ case InputHandler::kNC1etaonn:
+ return os << "NC1etaonn";
+ case InputHandler::kNC1etaonp:
+ return os << "NC1etaonp";
+ case InputHandler::kNC1kaon0:
+ return os << "NC1kaon0";
+ case InputHandler::kNC1kaonp:
+ return os << "NC1kaonp";
+ case InputHandler::kNCDIS:
+ return os << "NCDIS";
+ case InputHandler::kNCELonp:
+ return os << "NCELonp";
+ case InputHandler::kNCELonn:
+ return os << "NCELonn";
+ case InputHandler::kNC2p2h:
+ return os << "NC2p2h";
+ default:
+ return os << "UNKNOWN";
+ }
+ return os << "UNKNOWN";
}
#endif
diff --git a/src/InputHandler/NuWroInputHandler.cxx b/src/InputHandler/NuWroInputHandler.cxx
index f4c62ee..384a326 100644
--- a/src/InputHandler/NuWroInputHandler.cxx
+++ b/src/InputHandler/NuWroInputHandler.cxx
@@ -1,473 +1,479 @@
#ifdef __NUWRO_ENABLED__
#include "NuWroInputHandler.h"
#include "InputUtils.h"
NuWroGeneratorInfo::~NuWroGeneratorInfo() { delete fNuWroParticlePDGs; }
void NuWroGeneratorInfo::AddBranchesToTree(TTree* tn) {
tn->Branch("NuWroParticlePDGs", &fNuWroParticlePDGs, "NuWroParticlePDGs/I");
}
void NuWroGeneratorInfo::SetBranchesFromTree(TTree* tn) {
tn->SetBranchAddress("NuWroParticlePDGs", &fNuWroParticlePDGs);
}
void NuWroGeneratorInfo::AllocateParticleStack(int stacksize) {
fNuWroParticlePDGs = new int[stacksize];
}
void NuWroGeneratorInfo::DeallocateParticleStack() {
delete fNuWroParticlePDGs;
}
void NuWroGeneratorInfo::FillGeneratorInfo(event* e) { Reset(); }
void NuWroGeneratorInfo::Reset() {
for (int i = 0; i < kMaxParticles; i++) {
fNuWroParticlePDGs[i] = 0;
}
}
int event1_nof(event* e, int pdg) {
int c = 0;
for (size_t i = 0; i < e->out.size(); i++)
if (e->out[i].pdg == pdg) c++;
return c;
}
NuWroInputHandler::NuWroInputHandler(std::string const& handle,
std::string const& rawinputs) {
LOG(SAM) << "Creating NuWroInputHandler : " << handle << std::endl;
// Run a joint input handling
fName = handle;
fMaxEvents = FitPar::Config().GetParI("MAXEVENTS");
fSaveExtra = false; // FitPar::Config().GetParB("NuWroSaveExtra");
// Setup the TChain
fNuWroTree = new TChain("treeout");
// Loop over all inputs and grab flux, eventhist, and nevents
std::vector<std::string> inputs = InputUtils::ParseInputFileList(rawinputs);
for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) {
// Open File for histogram access
TFile* inp_file = new TFile(inputs[inp_it].c_str(), "READ");
if (!inp_file or inp_file->IsZombie()) {
ERR(FTL) << "nuwro File IsZombie() at " << inputs[inp_it] << std::endl;
throw;
}
// Get Flux/Event hist
TH1D* fluxhist = (TH1D*)inp_file->Get(
(PlotUtils::GetObjectWithName(inp_file, "FluxHist")).c_str());
TH1D* eventhist = (TH1D*)inp_file->Get(
(PlotUtils::GetObjectWithName(inp_file, "EvtHist")).c_str());
if (!fluxhist or !eventhist) {
ERR(FTL) << "nuwro FILE doesn't contain flux/xsec info" << std::endl;
if (FitPar::Config().GetParB("regennuwro")) {
ERR(FTL) << "Regen NuWro has not been added yet. Email the developers!"
<< std::endl;
// ProcessNuWroInputFlux(inputs[inp_it]);
throw;
} else {
ERR(FTL) << "If you would like NUISANCE to generate these for you "
<< "please set parameter regennuwro=1 and re-run."
<< std::endl;
throw;
}
}
// Get N Events
TTree* nuwrotree = (TTree*)inp_file->Get("treeout");
if (!nuwrotree) {
ERR(FTL) << "treeout not located in nuwro file! " << inputs[inp_it]
<< std::endl;
throw;
}
int nevents = nuwrotree->GetEntries();
// Register input to form flux/event rate hists
RegisterJointInput(inputs[inp_it], nevents, fluxhist, eventhist);
// Add to TChain
fNuWroTree->Add(inputs[inp_it].c_str());
}
// Registor all our file inputs
SetupJointInputs();
// Setup Events
fNuWroEvent = NULL;
fNuWroTree->SetBranchAddress("e", &fNuWroEvent);
fNuWroTree->GetEntry(0);
fNUISANCEEvent = new FitEvent();
fNUISANCEEvent->fType = kNUWRO;
fNUISANCEEvent->fNuwroEvent = fNuWroEvent;
fNUISANCEEvent->HardReset();
if (fSaveExtra) {
fNuWroInfo = new NuWroGeneratorInfo();
fNUISANCEEvent->AddGeneratorInfo(fNuWroInfo);
}
};
NuWroInputHandler::~NuWroInputHandler() {
if (fNuWroTree) delete fNuWroTree;
}
void NuWroInputHandler::CreateCache() {
// fNuWroTree->SetCacheEntryRange(0, fNEvents);
// fNuWroTree->AddBranchToCache("*", 1);
// fNuWroTree->SetCacheSize(fCacheSize);
}
void NuWroInputHandler::RemoveCache() {
// fNuWroTree->SetCacheEntryRange(0, fNEvents);
// fNuWroTree->AddBranchToCache("*", 0);
// fNuWroTree->SetCacheSize(0);
}
void NuWroInputHandler::ProcessNuWroInputFlux(const std::string file) {}
FitEvent* NuWroInputHandler::GetNuisanceEvent(const UInt_t entry,
const bool lightweight) {
// Catch too large entries
if (entry >= (UInt_t)fNEvents) return NULL;
// Read Entry from TTree to fill NEUT Vect in BaseFitEvt;
fNuWroTree->GetEntry(entry);
// Run NUISANCE Vector Filler
if (!lightweight) {
CalcNUISANCEKinematics();
}
#ifdef __PROB3PP_ENABLED__
for (size_t i = 0; i < fNUISANCEEvent->fNuwroEvent->in.size(); i++) {
if (std::count(PhysConst::pdg_neutrinos, PhysConst::pdg_neutrinos + 4,
fNUISANCEEvent->fNuwroEvent->in[i].pdg)) {
fNUISANCEEvent->probe_E = fNUISANCEEvent->fNuwroEvent->in[i].t;
fNUISANCEEvent->probe_pdg = fNUISANCEEvent->fNuwroEvent->in[i].pdg;
break;
}
}
#endif
// Setup Input scaling for joint inputs
fNUISANCEEvent->InputWeight = GetInputWeight(entry);
#ifdef __USE_NUWRO_SRW_EVENTS__
if (!rwEvs.size()) {
fNuwroParams = fNuWroEvent->par;
}
-
if (entry >= rwEvs.size()) {
rwEvs.push_back(BaseFitEvt());
+ rwEvs.back().fType = kNUWRO;
+ rwEvs.back().Mode = fNUISANCEEvent->Mode;
rwEvs.back().fNuwroSRWEvent = SRW::SRWEvent(*fNuWroEvent);
rwEvs.back().fNuwroEvent = NULL;
rwEvs.back().fNuwroParams = &fNuwroParams;
rwEvs.back().probe_E = rwEvs.back().fNuwroSRWEvent.NeutrinoEnergy;
rwEvs.back().probe_pdg = rwEvs.back().fNuwroSRWEvent.NeutrinoPDG;
}
+
+ fNUISANCEEvent->fNuwroSRWEvent = SRW::SRWEvent(*fNuWroEvent);
+ fNUISANCEEvent->fNuwroParams = &fNuwroParams;
+ fNUISANCEEvent->probe_E = fNUISANCEEvent->fNuwroSRWEvent.NeutrinoEnergy;
+ fNUISANCEEvent->probe_pdg = fNUISANCEEvent->fNuwroSRWEvent.NeutrinoPDG;
#endif
return fNUISANCEEvent;
}
int NuWroInputHandler::ConvertNuwroMode(event* e) {
Int_t proton_pdg, neutron_pdg, pion_pdg, pion_plus_pdg, pion_minus_pdg,
lambda_pdg, eta_pdg, kaon_pdg, kaon_plus_pdg;
proton_pdg = 2212;
eta_pdg = 221;
neutron_pdg = 2112;
pion_pdg = 111;
pion_plus_pdg = 211;
pion_minus_pdg = -211;
// O_16_pdg = 100069; // oznacznie z Neuta
lambda_pdg = 3122;
kaon_pdg = 311;
kaon_plus_pdg = 321;
if (e->flag.qel) // kwiazielastyczne oddziaływanie
{
if (e->flag.anty) // jeśli jest to oddziaływanie z antyneutrinem
{
if (e->flag.cc)
return -1;
else {
if (event1_nof(e, proton_pdg))
return -51;
else if (event1_nof(e, neutron_pdg))
return -52; // sprawdzam dodatkowo ?
}
} else // oddziaływanie z neutrinem
{
if (e->flag.cc)
return 1;
else {
if (event1_nof(e, proton_pdg))
return 51;
else if (event1_nof(e, neutron_pdg))
return 52;
}
}
}
if (e->flag.mec) {
if (e->flag.anty)
return -2;
else
return 2;
}
if (e->flag.res) // rezonansowa produkcja: pojedynczy pion, pojed.eta, kaon,
// multipiony
{
Int_t liczba_pionow, liczba_kaonow;
liczba_pionow = event1_nof(e, pion_pdg) + event1_nof(e, pion_plus_pdg) +
event1_nof(e, pion_minus_pdg);
liczba_kaonow = event1_nof(e, kaon_pdg) + event1_nof(e, kaon_pdg);
if (liczba_pionow > 1 || liczba_pionow == 0) // multipiony
{
if (e->flag.anty) {
if (e->flag.cc)
return -21;
else
return -41;
} else {
if (e->flag.cc)
return 21;
else
return 41;
}
}
if (liczba_pionow == 1) {
if (e->flag.anty) // jeśli jest to oddziaływanie z antyneutrinem
{
if (e->flag.cc) {
if (event1_nof(e, neutron_pdg) && event1_nof(e, pion_minus_pdg))
return -11;
if (event1_nof(e, neutron_pdg) && event1_nof(e, pion_pdg)) return -12;
if (event1_nof(e, proton_pdg) && event1_nof(e, pion_minus_pdg))
return -13;
} else {
if (event1_nof(e, proton_pdg)) {
if (event1_nof(e, pion_minus_pdg))
return -33;
else if (event1_nof(e, pion_pdg))
return -32;
} else if (event1_nof(e, neutron_pdg)) {
if (event1_nof(e, pion_plus_pdg))
return -34;
else if (event1_nof(e, pion_pdg))
return -31;
}
}
} else // oddziaływanie z neutrinem
{
if (e->flag.cc) {
if (event1_nof(e, proton_pdg) && event1_nof(e, pion_plus_pdg))
return 11;
if (event1_nof(e, proton_pdg) && event1_nof(e, pion_pdg)) return 12;
if (event1_nof(e, neutron_pdg) && event1_nof(e, pion_plus_pdg))
return 13;
} else {
if (event1_nof(e, proton_pdg)) {
if (event1_nof(e, pion_minus_pdg))
return 33;
else if (event1_nof(e, pion_pdg))
return 32;
} else if (event1_nof(e, neutron_pdg)) {
if (event1_nof(e, pion_plus_pdg))
return 34;
else if (event1_nof(e, pion_pdg))
return 31;
}
}
}
}
if (event1_nof(e, eta_pdg)) // produkcja rezonansowa ety
{
if (e->flag.anty) // jeśli jest to oddziaływanie z antyneutrinem
{
if (e->flag.cc)
return -22;
else {
if (event1_nof(e, neutron_pdg))
return -42;
else if (event1_nof(e, proton_pdg))
return -43; // sprawdzam dodatkowo ?
}
} else // oddziaływanie z neutrinem
{
if (e->flag.cc)
return 22;
else {
if (event1_nof(e, neutron_pdg))
return 42;
else if (event1_nof(e, proton_pdg))
return 43;
}
}
}
if (event1_nof(e, lambda_pdg) == 1 &&
liczba_kaonow == 1) // produkcja rezonansowa kaonu
{
if (e->flag.anty) // jeśli jest to oddziaływanie z antyneutrinem
{
if (e->flag.cc && event1_nof(e, kaon_pdg))
return -23;
else {
if (event1_nof(e, kaon_pdg))
return -44;
else if (event1_nof(e, kaon_plus_pdg))
return -45;
}
} else // oddziaływanie z neutrinem
{
if (e->flag.cc && event1_nof(e, kaon_plus_pdg))
return 23;
else {
if (event1_nof(e, kaon_pdg))
return 44;
else if (event1_nof(e, kaon_plus_pdg))
return 45;
}
}
}
}
if (e->flag.coh) // koherentne oddziaływanie tylko na O(16)
{
Int_t _target;
_target = e->par.nucleus_p + e->par.nucleus_n; // liczba masowa O(16)
if (_target == 16) {
if (e->flag.anty) // jeśli jest to oddziaływanie z antyneutrinem
{
if (e->flag.cc && event1_nof(e, pion_minus_pdg))
return -16;
else if (event1_nof(e, pion_pdg))
return -36;
} else // oddziaływanie z neutrinem
{
if (e->flag.cc && event1_nof(e, pion_plus_pdg))
return 16;
else if (event1_nof(e, pion_pdg))
return 36;
}
}
}
// gleboko nieelastyczne rozpraszanie
if (e->flag.dis) {
if (e->flag.anty) {
if (e->flag.cc)
return -26;
else
return -46;
} else {
if (e->flag.cc)
return 26;
else
return 46;
}
}
return 9999;
}
void NuWroInputHandler::CalcNUISANCEKinematics() {
// std::cout << "NuWro Event Address " << fNuWroEvent << std::endl;
// Reset all variables
fNUISANCEEvent->ResetEvent();
FitEvent* evt = fNUISANCEEvent;
// Sort Event Info
evt->Mode = ConvertNuwroMode(fNuWroEvent);
if (abs(evt->Mode) > 60) {
evt->Mode = 0;
}
evt->fEventNo = 0.0;
evt->fTotCrs = 0.0;
evt->fTargetA = fNuWroEvent->par.nucleus_p + fNuWroEvent->par.nucleus_n;
evt->fTargetZ = fNuWroEvent->par.nucleus_p;
evt->fTargetH = 0;
evt->fBound = (evt->fTargetA) == 1;
// Check Particle Stack
UInt_t npart_in = fNuWroEvent->in.size();
UInt_t npart_out = fNuWroEvent->out.size();
UInt_t npart_post = fNuWroEvent->post.size();
UInt_t npart = npart_in + npart_out + npart_post;
UInt_t kmax = evt->kMaxParticles;
if (npart > kmax) {
ERR(WRN) << "NUWRO has too many particles. Expanding stack." << std::endl;
fNUISANCEEvent->ExpandParticleStack(npart);
}
// Sort Particles
evt->fNParticles = 0;
std::vector<particle>::iterator p_iter;
// Initial State
for (p_iter = fNuWroEvent->in.begin(); p_iter != fNuWroEvent->in.end();
p_iter++) {
AddNuWroParticle(fNUISANCEEvent, (*p_iter), kInitialState);
}
// FSI State
// for (size_t i = 0; i < npart_in; i++ ) {
// AddNuWroParticle(fNUISANCEEvent, (*p_iter), kFSIState);
// }
// Final State
for (p_iter = fNuWroEvent->post.begin(); p_iter != fNuWroEvent->post.end();
p_iter++) {
AddNuWroParticle(fNUISANCEEvent, (*p_iter), kFinalState);
}
// Fill Generator Info
if (fSaveExtra) fNuWroInfo->FillGeneratorInfo(fNuWroEvent);
// Run Initial, FSI, Final, Other ordering.
fNUISANCEEvent->OrderStack();
FitParticle* ISNeutralLepton =
fNUISANCEEvent->GetHMISParticle(PhysConst::pdg_neutrinos);
if (ISNeutralLepton) {
fNUISANCEEvent->probe_E = ISNeutralLepton->E();
fNUISANCEEvent->probe_pdg = ISNeutralLepton->PDG();
}
return;
}
void NuWroInputHandler::AddNuWroParticle(FitEvent* evt, particle& p,
int state) {
// Add Mom
evt->fParticleMom[evt->fNParticles][0] = static_cast<vect&>(p).x;
evt->fParticleMom[evt->fNParticles][1] = static_cast<vect&>(p).y;
evt->fParticleMom[evt->fNParticles][2] = static_cast<vect&>(p).z;
evt->fParticleMom[evt->fNParticles][3] = static_cast<vect&>(p).t;
// Status/PDG
evt->fParticleState[evt->fNParticles] = state;
evt->fParticlePDG[evt->fNParticles] = p.pdg;
// Add to particle count
evt->fNParticles++;
}
void NuWroInputHandler::Print() {}
#endif
diff --git a/src/InputHandler/StdHepEvt.cxx b/src/InputHandler/StdHepEvt.cxx
index dfa93f8..02e821a 100644
--- a/src/InputHandler/StdHepEvt.cxx
+++ b/src/InputHandler/StdHepEvt.cxx
@@ -1,135 +1,141 @@
// 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 <iomanip>
#include <iostream>
#include <sstream>
#include "StdHepEvt.h"
// Include logging
#include "FitLogger.h"
StdHepReader::StdHepReader(){};
bool StdHepReader::SetBranchAddresses(TChain *chain) {
bool ok = true;
int SBAStatus = 0;
SBAStatus = chain->SetBranchAddress("StdHepN", &StdHepN);
ok = ok && (SBAStatus || SBAStatus == 5);
if (!(!SBAStatus || SBAStatus == 5)) {
ERR(WRN) << "Failed to set branch address for \"StdHepN\": " << SBAStatus
<< std::endl;
}
SBAStatus = chain->SetBranchAddress("StdHepPdg", StdHepPdg);
ok = ok && (SBAStatus || SBAStatus == 5);
if (!(!SBAStatus || SBAStatus == 5)) {
ERR(WRN) << "Failed to set branch address for \"StdHepPdg\": " << SBAStatus
<< std::endl;
}
SBAStatus = chain->SetBranchAddress("StdHepStatus", StdHepStatus);
ok = ok && (SBAStatus || SBAStatus == 5);
if (!(!SBAStatus || SBAStatus == 5)) {
ERR(WRN) << "Failed to set branch address for \"StdHepStatus\": "
<< SBAStatus << std::endl;
}
SBAStatus = chain->SetBranchAddress("StdHepP4", StdHepP4);
ok = ok && (SBAStatus || SBAStatus == 5);
if (!(!SBAStatus || SBAStatus == 5)) {
ERR(WRN) << "Failed to set branch address for \"StdHepP4\": " << SBAStatus
<< std::endl;
}
return ok;
}
bool GiBUUStdHepReader::SetBranchAddresses(TChain *chain) {
bool ok = true;
int SBAStatus = 0;
ok = ok && StdHepReader::SetBranchAddresses(chain);
SBAStatus = chain->SetBranchAddress("GiBUU2NeutCode", &GiBUU2NeutCode);
ok = ok && (SBAStatus || SBAStatus == 5);
if (!(!SBAStatus || SBAStatus == 5)) {
ERR(WRN) << "Failed to set branch address for \"GiBUU2NeutCode\": "
<< SBAStatus << std::endl;
}
+ SBAStatus = chain->SetBranchAddress("GiBUUReactionCode", &GiBUUReactionCode);
+ ok = ok && (SBAStatus || SBAStatus == 5);
+ if (!(!SBAStatus || SBAStatus == 5)) {
+ ERR(WRN) << "Failed to set branch address for \"GiBUUReactionCode\": "
+ << SBAStatus << std::endl;
+ }
SBAStatus = chain->SetBranchAddress("EvtWght", &EvtWght);
ok = ok && (SBAStatus || SBAStatus == 5);
if (!(!SBAStatus || SBAStatus == 5)) {
ERR(WRN) << "Failed to set branch address for \"EvtWght\": " << SBAStatus
<< std::endl;
}
return ok;
}
std::string NegSpacer(double const &num) { return (num >= 0) ? " " : ""; }
std::ostream &operator<<(std::ostream &os, TLorentzVector const &tlv) {
std::streamsize prec = os.precision();
std::ios_base::fmtflags flags = os.flags();
os.precision(2);
os.flags(std::ios::scientific);
os << "[" << NegSpacer(tlv[0]) << tlv[0] << "," << NegSpacer(tlv[1]) << tlv[1]
<< "," << NegSpacer(tlv[2]) << tlv[2] << "," << NegSpacer(tlv[3]) << tlv[3]
<< ":M(" << tlv.M() << ")]";
os.precision(prec);
os.flags(flags);
return os;
}
std::string WriteGiBUUEvent(GiBUUStdHepReader const &gi) {
std::stringstream ss("");
ss << "[INFO]: contained " << gi.StdHepN
<< ", Event Weight: " << std::setprecision(3) << gi.EvtWght
<< ", NeutConventionReactionCode: " << gi.GiBUU2NeutCode
<< "\n\t[Lep In](" << std::setw(3)
<< gi.StdHepPdg[0] << ") "
<< TLorentzVector(gi.StdHepP4[0][StdHepReader::kStdHepIdxPx],
gi.StdHepP4[0][StdHepReader::kStdHepIdxPy],
gi.StdHepP4[0][StdHepReader::kStdHepIdxPz],
gi.StdHepP4[0][StdHepReader::kStdHepIdxE])
<< std::endl;
ss << "\t[Target] : " << gi.StdHepPdg[1] << std::endl;
ss << "\t[Nuc In] : "
<< TLorentzVector(gi.StdHepP4[3][StdHepReader::kStdHepIdxPx],
gi.StdHepP4[3][StdHepReader::kStdHepIdxPy],
gi.StdHepP4[3][StdHepReader::kStdHepIdxPz],
gi.StdHepP4[3][StdHepReader::kStdHepIdxE])
<< " (" << std::setw(4) << gi.StdHepPdg[3] << ")" << std::endl;
for (Int_t stdHepInd = 4; stdHepInd < gi.StdHepN; ++stdHepInd) {
ss << "\t[" << std::setw(2) << (stdHepInd - (4)) << "](" << std::setw(5)
<< gi.StdHepPdg[stdHepInd] << ") "
<< TLorentzVector(gi.StdHepP4[stdHepInd][StdHepReader::kStdHepIdxPx],
gi.StdHepP4[stdHepInd][StdHepReader::kStdHepIdxPy],
gi.StdHepP4[stdHepInd][StdHepReader::kStdHepIdxPz],
gi.StdHepP4[stdHepInd][StdHepReader::kStdHepIdxE])
<< std::endl;
}
ss << "\t[Lep Out](" << std::setw(3)
<< gi.StdHepPdg[2] << ") "
<< TLorentzVector(gi.StdHepP4[2][StdHepReader::kStdHepIdxPx],
gi.StdHepP4[2][StdHepReader::kStdHepIdxPy],
gi.StdHepP4[2][StdHepReader::kStdHepIdxPz],
gi.StdHepP4[2][StdHepReader::kStdHepIdxE])
<< std::endl;
return ss.str();
}
diff --git a/src/InputHandler/StdHepEvt.h b/src/InputHandler/StdHepEvt.h
index 198279b..96f280c 100644
--- a/src/InputHandler/StdHepEvt.h
+++ b/src/InputHandler/StdHepEvt.h
@@ -1,111 +1,116 @@
#ifndef __STDHEPEVT_SEEN__
#define __STDHEPEVT_SEEN__
// 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 "TChain.h"
#include "TLorentzVector.h"
struct StdHepReader {
public:
const static int kStdHepIdxPx = 0;
const static int kStdHepIdxPy = 1;
const static int kStdHepIdxPz = 2;
const static int kStdHepIdxE = 3;
const static int kStdHepNPmax = 100;
StdHepReader();
///\brief The number of StdHep particles in this event.
Int_t StdHepN;
///\brief The PDG codes of particles in this event.
///
/// This is determined from the GiBUU particle number by
/// GiBUUUtils::GiBUUToPDG.
///\warning This is not a one-to-one mapping, e.g. resonances are not uniquely
/// determined by the GiBUU scheme.
Int_t StdHepPdg[kStdHepNPmax]; //[StdHepN]
///\brief The StdHep Status of particles in this event.
///
/// Status Codes in use:
/// - -1: Initial state real particle.
/// - 1: Final state real particle.
Int_t StdHepStatus[kStdHepNPmax]; //[StdHepN]
///\brief Four momentum for particles in this event.
Double_t StdHepP4[kStdHepNPmax][4];
bool SetBranchAddresses(TChain*);
};
struct GiBUUStdHepReader : public StdHepReader {
GiBUUStdHepReader() : StdHepReader(){};
+ ///\brief GiBUU interaction code
+ ///
+ /// See https://gibuu.hepforge.org/trac/wiki/LesHouches for details
+ Int_t GiBUUReactionCode;
+
///\brief NEUT equivalent reaction code.
/// CC:
/// * 1 : QE
/// * 2 : 2p2h
/// * 10 : Single pion background (non-resonant)
/// * 11 : Delta++ ( -11 : Delta- for nubar)
/// * 12 : Delta+ (-12 : Delta0 for nubar)
/// * 21 : Multi pion production
/// * 26 : DIS
/// * 4 : Higher resonance, charge: -1
/// * 5 : Higher resonance, charge: 0
/// * 6 : Higher resonance, charge: +1
/// * 7 : Higher resonance, charge: +2
///
/// NC:
/// * 30 : Single pion background (non-resonant)
/// * 31 : Delta0
/// * 32 : Delta+
/// * 41 : Multi pion production
/// * 42 : 2p2h
/// * 46 : DIS
/// * 47 : Higher resonance, charge: -1
/// * 48 : Higher resonance, charge: 0
/// * 49 : Higher resonance, charge: +1
/// * 50 : Higher resonance, charge: +2
/// * 51 : NCEL proton-target
/// * 52 : NCEL neutron-target
///
Int_t GiBUU2NeutCode;
///\brief The total XSec weighting that should be applied to this event.
Double_t EvtWght;
///\brief Weighting which takes account of multiple input numu species.
///
/// Defined such that W_numu + W_numubar = 1
Double_t SpeciesWght_numu;
///\brief Weighting which takes account of multiple input nue species.
///
/// Defined such that W_nue + W_nuebar = 1
Double_t SpeciesWght_nue;
///\brief Weighting which takes account of multiple input neutrino species.
///
/// Defined such that \Sum_species W_species = 1
Double_t SpeciesWght;
bool SetBranchAddresses(TChain*);
};
std::string WriteGiBUUEvent(GiBUUStdHepReader const& gi);
#endif
diff --git a/src/Logger/FitLogger.h b/src/Logger/FitLogger.h
index ce46f6c..2fede17 100644
--- a/src/Logger/FitLogger.h
+++ b/src/Logger/FitLogger.h
@@ -1,221 +1,221 @@
// 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 FITLOGGER_HPP
#define FITLOGGER_HPP
/*!
* \addtogroup FitBase
* @{
*/
#include <fstream>
#include <iosfwd>
#include <iostream>
#include <sstream>
#include "TRandom3.h"
#include "Initialiser.h"
#include "NuisConfig.h"
#define RESET "\033[0m"
#define BLACK "\033[30m" /* Black */
#define RED "\033[31m" /* Red */
#define GREEN "\033[32m" /* Green */
#define YELLOW "\033[33m" /* Yellow */
#define BLUE "\033[34m" /* Blue */
#define MAGENTA "\033[35m" /* Magenta */
#define CYAN "\033[36m" /* Cyan */
#define WHITE "\033[37m" /* White */
#define BOLDBLACK "\033[1m\033[30m" /* Bold Black */
#define BOLDRED "\033[1m\033[31m" /* Bold Red */
#define BOLDGREEN "\033[1m\033[32m" /* Bold Green */
#define BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */
#define BOLDBLUE "\033[1m\033[34m" /* Bold Blue */
#define BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */
#define BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */
#define BOLDWHITE "\033[1m\033[37m" /* Bold White */
namespace Logger {
extern int log_verb; //!< Current VERBOSITY
extern int err_verb; //!< Current ERROR VERBOSITY
extern bool external_verb;
extern bool use_colors; //!< Use BASH Terminal Colors Flag
extern bool super_rainbow_mode; //!< For when fitting gets boring.
extern unsigned int super_rainbow_mode_colour;
extern bool showtrace; // Quick Tracing for debugging
extern int nloggercalls;
extern int timelastlog;
extern std::streambuf*
default_cout; //!< Where the STDOUT stream is currently directed
extern std::streambuf*
default_cerr; //!< Where the STDERR stream is currently directed
extern std::ofstream
redirect_stream; //!< Where should unwanted messages be thrown
}
/// Returns full path to file currently in
#define __FILENAME__ \
(strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
// ------ LOGGER FUNCTIONS ------------ //
namespace Logger {
/// NULL Output Stream
extern std::ofstream __LOG_nullstream;
/// Logging Stream
extern std::ostream* __LOG_outstream;
}
/// Fitter VERBOSITY Enumerations
/// These go through the different depths of the fitter.
///
/// 0 QUIET - Little output.
/// 1 FIT - Top Level Minimizer Status
/// 2 MIN - Output from the FCN Minimizer Functions
/// 3 SAM - Output from each of the samples during setup etc
/// 4 REC - Output during each reconfigure. Percentage progress etc.
/// 5 SIG - Output during every signal event that is found.
/// 6 EVT - Output during every event.
/// -1 DEB - Will print only debugging info wherever a LOG(DEB) statement was
/// made
-enum __LOG_levels { DEB = -1, QUIET, FIT, MIN, SAM, REC, SIG, EVT };
+enum __LOG_levels { QUIET = 0, FIT, MIN, SAM, REC, SIG, EVT, DEB };
/// Returns log level for a given file/function
int __GETLOG_LEVEL(int level, const char* filename, const char* funct);
/// Actually runs the logger
std::ostream& __OUTLOG(int level, const char* filename, const char* funct,
int line);
/// Global Logging Definitions
#define QLOG(level, stream) \
{ \
if (Logger::log_verb >= \
__GETLOG_LEVEL(level, __FILENAME__, __FUNCTION__)) { \
__OUTLOG(level, __FILENAME__, __FUNCTION__, __LINE__) << stream \
<< std::endl; \
} \
};
#define BREAK(level) \
{ \
\ if (Logger::log_verb >= \
__GETLOG_LEVEL(level, __FILENAME__, __FUNCTION__)) { \
__OUTLOG(level, __FILENAME__, __FUNCTION__, __LINE__) << std::endl; \
} \
};
/// Return whether logging level is valid
bool LOGGING(int level);
/// Set Global Verbosity
void SETVERBOSITY(int level);
/// Set Global Verbosity from String
void SETVERBOSITY(std::string verb);
/// Set Trace Option
void SETTRACE(bool val);
// ----------- ERROR FUNCTIONS ---------- //
/// Error Stream
extern std::ostream* __ERR_outstream;
/// Fitter ERROR VERBOSITY Enumerations
///
/// 0 QUIET - No Error Output
/// 1 FTL - Show errors only if fatal
/// 2 WRN - Show Warning messages
enum __ERR_levels { ERRQUIET = 0, FTL, WRN };
/// Actually runs the error messager
std::ostream& __OUTERR(int level, const char* filename, const char* funct,
int line);
/// Error Logging Function
#define ERROR(level, stream) \
{ \
__OUTERR(level, __FILENAME__, __FUNCTION__, __LINE__) << stream \
<< std::endl; \
};
// ----------- ERROR HANDLING ------------- //
/// Exit the program with given error message stream
#define THROW(stream) \
{ \
__OUTERR(FTL, __FILENAME__, __FUNCTION__, __LINE__) << stream \
<< std::endl; \
__OUTERR(FTL, __FILENAME__, __FUNCTION__, __LINE__) \
<< "Attempting to save output file." << std::endl; \
- if (Config::Get().out && Config::Get().out->IsOpen()) { \
- Config::Get().out->Write(); \
- Config::Get().out->Close(); \
+ if (Config::Get().out && Config::Get().out->IsOpen()) { \
+ Config::Get().out->Write(); \
+ Config::Get().out->Close(); \
__OUTERR(FTL, __FILENAME__, __FUNCTION__, __LINE__) << "Done." \
<< std::endl; \
} else { \
__OUTERR(FTL, __FILENAME__, __FUNCTION__, __LINE__) \
<< "No output file set." << std::endl; \
} \
__OUTERR(FTL, __FILENAME__, __FUNCTION__, __LINE__) << "Exiting!" \
<< std::endl; \
std::abort(); \
}
// ----------- External Logging ----------- //
void SETEXTERNALVERBOSITY(int level);
void StopTalking();
void StartTalking();
extern "C" {
void shhnuisancepythiaitokay_(void);
void canihaznuisancepythia_(void);
}
// ---------- LEGACY FUNCTIONS -------------- //
bool LOG_LEVEL(int level);
//! Set LOG VERBOSITY from a string
void LOG_VERB(std::string verb);
inline void LOG_VERB(int verb) { Logger::log_verb = verb; };
void SET_TRACE(bool val);
//! Set ERROR VERBOSITY from a string
void ERR_VERB(std::string verb);
inline void ERR_VERB(int verb) { Logger::err_verb = verb; };
/// Logging Function. Use as a string stream. e.g. LOG(SAM) << "This sample is
/// dope." << std::endl;
std::ostream& _LOG(int level, const char* filename, const char* funct,
int line);
#define LOG(level) _LOG(level, __FILENAME__, __FUNCTION__, __LINE__)
//! Error Function. Use as a string stream. e.g. ERR(FTL) << "The fit is
//! completely buggered." << std::endl;
std::ostream& _ERR(int level, const char* filename, const char* funct,
int line);
#define ERR(level) _ERR(level, __FILENAME__, __FUNCTION__, __LINE__)
/*! @} */
#endif
diff --git a/src/Logger/Initialiser.cxx b/src/Logger/Initialiser.cxx
index 923805a..8cb09f2 100644
--- a/src/Logger/Initialiser.cxx
+++ b/src/Logger/Initialiser.cxx
@@ -1,98 +1,101 @@
#include "Initialiser.h"
-void RunNuisance(){
- std::cout << "Starting NUISANCE" << std::endl;
-}
+void RunNuisance() { std::cout << "Starting NUISANCE" << std::endl; }
struct LetterBackronym {
LetterBackronym(size_t n, std::string const &b, float p = 1.0,
std::string const &t = "") {
NUsed = n;
Backkie = b;
ProbAccept = p;
TagLine = t;
};
size_t NUsed;
float ProbAccept;
std::string Backkie;
std::string TagLine;
};
-__attribute__((constructor)) void nuisance_init(void) {
+__attribute__((constructor)) void constructor(void) { nuisance_init(); }
+
+void nuisance_init(void) {
std::vector<std::vector<LetterBackronym> > Letters;
for (size_t i = 0; i < 8; ++i) {
Letters.push_back(std::vector<LetterBackronym>());
}
Letters[0].push_back(LetterBackronym(2, "Neutrino"));
Letters[0].push_back(LetterBackronym(3, "NUIsance", 0.2));
Letters[2].push_back(LetterBackronym(1, "Interaction"));
Letters[3].push_back(LetterBackronym(1, "Systematics"));
Letters[3].push_back(LetterBackronym(
- 1, "Synthesiser", 0.2, "Playing on the comparisons you want to see"));
+ 1, "Synthesiser", 0.2, "Playing on the comparisons you want to see"));
Letters[4].push_back(LetterBackronym(2, "ANalyser"));
Letters[4].push_back(LetterBackronym(1, "Aggregating", 0.5));
Letters[4].push_back(LetterBackronym(3, "from A-Neutrino sCattering", 1,
"You can always find a frame"));
Letters[5].push_back(
- LetterBackronym(1, "New", 1, "The freshest comparisons"));
+ LetterBackronym(1, "New", 1, "The freshest comparisons"));
Letters[6].push_back(LetterBackronym(1, "by Comparing"));
Letters[6].push_back(LetterBackronym(1, "Constraints from"));
Letters[7].push_back(LetterBackronym(1, "Experiments"));
std::vector<std::string> TagLines;
TagLines.push_back("Fit and compare.");
std::stringstream back("");
TRandom3 tr;
tr.SetSeed();
for (size_t i = 0; i < 8;) {
LetterBackronym const &let = Letters[i][tr.Integer(Letters[i].size())];
if (tr.Uniform() > let.ProbAccept) {
continue;
}
back << let.Backkie << " ";
i += let.NUsed;
if (let.TagLine.length()) {
TagLines.push_back(let.TagLine);
}
}
std::string Name = "Nuisance";
std::string TagL = TagLines[tr.Integer(TagLines.size())];
std::vector<std::pair<std::string, std::pair<std::string, std::string> > >
- OneBlob;
+ OneBlob;
OneBlob.push_back(
- std::make_pair("NUISANCE", std::make_pair("", "FiXing your Neutrinos")));
+ std::make_pair("NUISANCE", std::make_pair("", "FiXing your Neutrinos")));
if (tr.Uniform() < 0.01) {
std::pair<std::string, std::pair<std::string, std::string> > const &blob =
- OneBlob[tr.Integer(OneBlob.size())];
+ OneBlob[tr.Integer(OneBlob.size())];
Name = blob.first;
back.str("");
back << blob.second.first;
TagL = blob.second.second;
}
- std::cout << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
- "%%%%%%%%%%%%%%%"
- "%%"
- << std::endl
- << "%% Welcome to " << Name << ": \033[5m" << back.str()
- << "\033[0m-- " << TagL << std::endl
- << "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
- "%%%%%%%%%%%%%%%"
- "%%"
- << std::endl;
-}
\ No newline at end of file
+ // std::cout <<
+ // "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
+ // "%%%%%%%%%%%%%%%"
+ // "%%"
+ // << std::endl
+ // << "%% Welcome to " << Name << ": \033[5m" << back.str()
+ // << "\033[0m-- " << TagL << std::endl
+ // <<
+ // "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"
+ // "%%%%%%%%%%%%%%%"
+ // "%%"
+ // << std::endl;
+ std::cout << Name << ": " << back.str() << " -- " << TagL << std::endl;
+}
diff --git a/src/Logger/Initialiser.h b/src/Logger/Initialiser.h
index 104ead9..4386235 100644
--- a/src/Logger/Initialiser.h
+++ b/src/Logger/Initialiser.h
@@ -1,20 +1,21 @@
#include <iosfwd>
#include <iostream>
#include <fstream>
#include <sstream>
#include <fcntl.h>
#include <unistd.h>
#include <math.h>
#include <stdlib.h>
#include <cstring>
#include <fstream>
#include <iostream>
#include <map>
#include <numeric>
#include <sstream>
#include <sstream>
#include <string>
#include <vector>
#include "TRandom3.h"
void RunNuisance();
+void nuisance_init(void) ;
diff --git a/src/MCStudies/GenericFlux_Tester.cxx b/src/MCStudies/GenericFlux_Tester.cxx
index b32a54f..284b9a8 100644
--- a/src/MCStudies/GenericFlux_Tester.cxx
+++ b/src/MCStudies/GenericFlux_Tester.cxx
@@ -1,576 +1,591 @@
// 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/>.
-*******************************************************************************/
+ * 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 "GenericFlux_Tester.h"
//********************************************************************
/// @brief Class to perform MC Studies on a custom measurement
GenericFlux_Tester::GenericFlux_Tester(std::string name, std::string inputfile,
FitWeight *rw, std::string type,
std::string fakeDataFile) {
//********************************************************************
// Measurement Details
fName = name;
eventVariables = NULL;
// Define our energy range for flux calcs
EnuMin = 0.;
EnuMax = 1E10; // Arbritrarily high energy limit
// Set default fitter flags
fIsDiag = true;
fIsShape = false;
fIsRawEvents = false;
nu_4mom = new TLorentzVector(0, 0, 0, 0);
pmu = new TLorentzVector(0, 0, 0, 0);
ppip = new TLorentzVector(0, 0, 0, 0);
ppim = new TLorentzVector(0, 0, 0, 0);
ppi0 = new TLorentzVector(0, 0, 0, 0);
pprot = new TLorentzVector(0, 0, 0, 0);
pneut = new TLorentzVector(0, 0, 0, 0);
// This function will sort out the input files automatically and parse all the
// inputs,flags,etc.
// There may be complex cases where you have to do this by hand, but usually
// this will do.
Measurement1D::SetupMeasurement(inputfile, type, rw, fakeDataFile);
eventVariables = NULL;
- liteMode = FitPar::Config().GetParB("isLiteMode");
+ liteMode = Config::Get().GetParB("isLiteMode");
+
+ if (Config::HasPar("EnuMin")) {
+ EnuMin = Config::GetParD("EnuMin");
+ }
+
+ if (Config::HasPar("EnuMax")) {
+ EnuMax = Config::GetParD("EnuMax");
+ }
// Setup fDataHist as a placeholder
this->fDataHist = new TH1D(("empty_data"), ("empty-data"), 1, 0, 1);
this->SetupDefaultHist();
fFullCovar = StatUtils::MakeDiagonalCovarMatrix(fDataHist);
covar = StatUtils::GetInvert(fFullCovar);
// 1. The generator is organised in SetupMeasurement so it gives the
// cross-section in "per nucleon" units.
// So some extra scaling for a specific measurement may be required. For
// Example to get a "per neutron" measurement on carbon
// which we do here, we have to multiple by the number of nucleons 12 and
// divide by the number of neutrons 6.
+ // N.B. MeasurementBase::PredictedEventRate includes the 1E-38 factor that is
+ // often included here in other classes that directly integrate the event
+ // histogram. This method is used here as it now respects EnuMin and EnuMax
+ // correctly.
this->fScaleFactor =
- (GetEventHistogram()->Integral("width") * 1E-38 / (fNEvents + 0.)) /
+ (this->PredictedEventRate("width", 0, 1000) / double(fNEvents)) /
this->TotalIntegratedFlux();
if (fScaleFactor <= 0.0) {
ERR(WRN) << "SCALE FACTOR TOO LOW " << std::endl;
throw;
}
- std::cout << EnuMin << " = " << EnuMax << std::endl;
LOG(SAM) << " Generic Flux Scaling Factor = " << fScaleFactor
<< " [= " << (GetEventHistogram()->Integral("width") * 1E-38) << "/("
<< (fNEvents + 0.) << "*" << this->TotalIntegratedFlux() << ")]"
<< std::endl;
// Setup our TTrees
this->AddEventVariablesToTree();
this->AddSignalFlagsToTree();
}
void GenericFlux_Tester::AddEventVariablesToTree() {
// Setup the TTree to save everything
if (!eventVariables) {
Config::Get().out->cd();
eventVariables = new TTree((this->fName + "_VARS").c_str(),
(this->fName + "_VARS").c_str());
}
LOG(SAM) << "Adding Event Variables" << std::endl;
eventVariables->Branch("Mode", &Mode, "Mode/I");
eventVariables->Branch("PDGnu", &PDGnu, "PDGnu/I");
eventVariables->Branch("Enu_true", &Enu_true, "Enu_true/F");
eventVariables->Branch("Nleptons", &Nleptons, "Nleptons/I");
-// all sensible
+ // all sensible
eventVariables->Branch("MLep", &MLep, "MLep/F");
eventVariables->Branch("ELep", &ELep, "ELep/F");
-// negative -999
+ // negative -999
eventVariables->Branch("TLep", &TLep, "TLep/F");
eventVariables->Branch("CosLep", &CosLep, "CosLep/F");
eventVariables->Branch("CosPmuPpip", &CosPmuPpip, "CosPmuPpip/F");
eventVariables->Branch("CosPmuPpim", &CosPmuPpim, "CosPmuPpim/F");
eventVariables->Branch("CosPmuPpi0", &CosPmuPpi0, "CosPmuPpi0/F");
eventVariables->Branch("CosPmuPprot", &CosPmuPprot, "CosPmuPprot/F");
eventVariables->Branch("CosPmuPneut", &CosPmuPneut, "CosPmuPneut/F");
eventVariables->Branch("Nprotons", &Nprotons, "Nprotons/I");
eventVariables->Branch("MPr", &MPr, "MPr/F");
eventVariables->Branch("EPr", &EPr, "EPr/F");
eventVariables->Branch("TPr", &TPr, "TPr/F");
eventVariables->Branch("CosPr", &CosPr, "CosPr/F");
eventVariables->Branch("CosPprotPneut", &CosPprotPneut, "CosPprotPneut/F");
eventVariables->Branch("Nneutrons", &Nneutrons, "Nneutrons/I");
eventVariables->Branch("MNe", &MNe, "MNe/F");
eventVariables->Branch("ENe", &ENe, "ENe/F");
eventVariables->Branch("TNe", &TNe, "TNe/F");
eventVariables->Branch("CosNe", &CosNe, "CosNe/F");
eventVariables->Branch("Npiplus", &Npiplus, "Npiplus/I");
eventVariables->Branch("MPiP", &MPiP, "MPiP/F");
eventVariables->Branch("EPiP", &EPiP, "EPiP/F");
eventVariables->Branch("TPiP", &TPiP, "TPiP/F");
eventVariables->Branch("CosPiP", &CosPiP, "CosPiP/F");
eventVariables->Branch("CosPpipPprot", &CosPpipPprot, "CosPpipProt/F");
eventVariables->Branch("CosPpipPneut", &CosPpipPneut, "CosPpipPneut/F");
eventVariables->Branch("CosPpipPpim", &CosPpipPpim, "CosPpipPpim/F");
eventVariables->Branch("CosPpipPpi0", &CosPpipPpi0, "CosPpipPpi0/F");
eventVariables->Branch("Npineg", &Npineg, "Npineg/I");
eventVariables->Branch("MPiN", &MPiN, "MPiN/F");
eventVariables->Branch("EPiN", &EPiN, "EPiN/F");
eventVariables->Branch("TPiN", &TPiN, "TPiN/F");
eventVariables->Branch("CosPiN", &CosPiN, "CosPiN/F");
eventVariables->Branch("CosPpimPprot", &CosPpimPprot, "CosPpimPprot/F");
eventVariables->Branch("CosPpimPneut", &CosPpimPneut, "CosPpimPneut/F");
eventVariables->Branch("CosPpimPpi0", &CosPpimPpi0, "CosPpimPpi0/F");
eventVariables->Branch("Npi0", &Npi0, "Npi0/I");
eventVariables->Branch("MPi0", &MPi0, "MPi0/F");
eventVariables->Branch("EPi0", &EPi0, "EPi0/F");
eventVariables->Branch("TPi0", &TPi0, "TPi0/F");
eventVariables->Branch("CosPi0", &CosPi0, "CosPi0/F");
eventVariables->Branch("CosPi0Pprot", &CosPi0Pprot, "CosPi0Pprot/F");
eventVariables->Branch("CosPi0Pneut", &CosPi0Pneut, "CosPi0Pneut/F");
eventVariables->Branch("Nother", &Nother, "Nother/I");
eventVariables->Branch("Q2_true", &Q2_true, "Q2_true/F");
eventVariables->Branch("q0_true", &q0_true, "q0_true/F");
eventVariables->Branch("q3_true", &q3_true, "q3_true/F");
eventVariables->Branch("Enu_QE", &Enu_QE, "Enu_QE/F");
eventVariables->Branch("Q2_QE", &Q2_QE, "Q2_QE/F");
eventVariables->Branch("W_nuc_rest", &W_nuc_rest, "W_nuc_rest/F");
eventVariables->Branch("bjorken_x", &bjorken_x, "bjorken_x/F");
eventVariables->Branch("bjorken_y", &bjorken_y, "bjorken_y/F");
eventVariables->Branch("Erecoil_true", &Erecoil_true, "Erecoil_true/F");
eventVariables->Branch("Erecoil_charged", &Erecoil_charged,
"Erecoil_charged/F");
eventVariables->Branch("Erecoil_minerva", &Erecoil_minerva,
"Erecoil_minerva/F");
if (!liteMode) {
eventVariables->Branch("nu_4mom", &nu_4mom);
eventVariables->Branch("pmu_4mom", &pmu);
eventVariables->Branch("hm_ppip_4mom", &ppip);
eventVariables->Branch("hm_ppim_4mom", &ppim);
eventVariables->Branch("hm_ppi0_4mom", &ppi0);
eventVariables->Branch("hm_pprot_4mom", &pprot);
eventVariables->Branch("hm_pneut_4mom", &pneut);
}
// Event Scaling Information
eventVariables->Branch("Weight", &Weight, "Weight/F");
eventVariables->Branch("InputWeight", &InputWeight, "InputWeight/F");
eventVariables->Branch("RWWeight", &RWWeight, "RWWeight/F");
eventVariables->Branch("FluxWeight", &FluxWeight, "FluxWeight/F");
eventVariables->Branch("fScaleFactor", &fScaleFactor, "fScaleFactor/D");
return;
}
void GenericFlux_Tester::AddSignalFlagsToTree() {
if (!eventVariables) {
Config::Get().out->cd();
eventVariables = new TTree((this->fName + "_VARS").c_str(),
(this->fName + "_VARS").c_str());
}
LOG(SAM) << "Adding signal flags" << std::endl;
// Signal Definitions from SignalDef.cxx
eventVariables->Branch("flagCCINC", &flagCCINC, "flagCCINC/O");
eventVariables->Branch("flagNCINC", &flagNCINC, "flagNCINC/O");
eventVariables->Branch("flagCCQE", &flagCCQE, "flagCCQE/O");
eventVariables->Branch("flagCC0pi", &flagCC0pi, "flagCC0pi/O");
eventVariables->Branch("flagCCQELike", &flagCCQELike, "flagCCQELike/O");
eventVariables->Branch("flagNCEL", &flagNCEL, "flagNCEL/O");
eventVariables->Branch("flagNC0pi", &flagNC0pi, "flagNC0pi/O");
eventVariables->Branch("flagCCcoh", &flagCCcoh, "flagCCcoh/O");
eventVariables->Branch("flagNCcoh", &flagNCcoh, "flagNCcoh/O");
eventVariables->Branch("flagCC1pip", &flagCC1pip, "flagCC1pip/O");
eventVariables->Branch("flagNC1pip", &flagNC1pip, "flagNC1pip/O");
eventVariables->Branch("flagCC1pim", &flagCC1pim, "flagCC1pim/O");
eventVariables->Branch("flagNC1pim", &flagNC1pim, "flagNC1pim/O");
eventVariables->Branch("flagCC1pi0", &flagCC1pi0, "flagCC1pi0/O");
eventVariables->Branch("flagNC1pi0", &flagNC1pi0, "flagNC1pi0/O");
};
-
//********************************************************************
void GenericFlux_Tester::ResetVariables() {
-//********************************************************************
+ //********************************************************************
// Reset neutrino PDG
PDGnu = 0;
// Reset energies
Enu_true = Enu_QE = __BAD_FLOAT__;
// Reset auxillaries
- Q2_true = Q2_QE = W_nuc_rest = bjorken_x = bjorken_y = q0_true = q3_true = Erecoil_true = Erecoil_charged = Erecoil_minerva = __BAD_FLOAT__;
+ Q2_true = Q2_QE = W_nuc_rest = bjorken_x = bjorken_y = q0_true = q3_true =
+ Erecoil_true = Erecoil_charged = Erecoil_minerva = __BAD_FLOAT__;
// Reset particle counters
- Nparticles = Nleptons = Nother = Nprotons = Nneutrons = Npiplus = Npineg = Npi0 = 0;
+ Nparticles = Nleptons = Nother = Nprotons = Nneutrons = Npiplus = Npineg =
+ Npi0 = 0;
// Reset Lepton PDG
PDGLep = 0;
// Reset Lepton variables
- TLep = CosLep = ELep = PLep = MLep = __BAD_FLOAT__;
+ TLep = CosLep = ELep = PLep = MLep = __BAD_FLOAT__;
// Rset proton variables
- PPr = CosPr = EPr = TPr = MPr = __BAD_FLOAT__;
+ PPr = CosPr = EPr = TPr = MPr = __BAD_FLOAT__;
// Reset neutron variables
- PNe = CosNe = ENe = TNe = MNe = __BAD_FLOAT__;
+ PNe = CosNe = ENe = TNe = MNe = __BAD_FLOAT__;
// Reset pi+ variables
- PPiP = CosPiP = EPiP = TPiP = MPiP = __BAD_FLOAT__;
+ PPiP = CosPiP = EPiP = TPiP = MPiP = __BAD_FLOAT__;
// Reset pi- variables
- PPiN = CosPiN = EPiN = TPiN = MPiN = __BAD_FLOAT__;
+ PPiN = CosPiN = EPiN = TPiN = MPiN = __BAD_FLOAT__;
// Reset pi0 variables
- PPi0 = CosPi0 = EPi0 = TPi0 = MPi0 = __BAD_FLOAT__;
+ PPi0 = CosPi0 = EPi0 = TPi0 = MPi0 = __BAD_FLOAT__;
// Reset the cos angles
- CosPmuPpip = CosPmuPpim = CosPmuPpi0 = CosPmuPprot = CosPmuPneut = CosPpipPprot = CosPpipPneut = CosPpipPpim = CosPpipPpi0 = CosPpimPprot = CosPpimPneut = CosPpimPpi0 = CosPi0Pprot = CosPi0Pneut = CosPprotPneut = __BAD_FLOAT__;
+ CosPmuPpip = CosPmuPpim = CosPmuPpi0 = CosPmuPprot = CosPmuPneut =
+ CosPpipPprot = CosPpipPneut = CosPpipPpim = CosPpipPpi0 = CosPpimPprot =
+ CosPpimPneut = CosPpimPpi0 = CosPi0Pprot = CosPi0Pneut =
+ CosPprotPneut = __BAD_FLOAT__;
}
//********************************************************************
void GenericFlux_Tester::FillEventVariables(FitEvent *event) {
//********************************************************************
// Fill Signal Variables
FillSignalFlags(event);
LOG(DEB) << "Filling signal" << std::endl;
// Reset the private variables (see header)
ResetVariables();
// Function used to extract any variables of interest to the event
Mode = event->Mode;
// Reset the highest momentum variables
float proton_highmom = __BAD_FLOAT__;
float neutron_highmom = __BAD_FLOAT__;
float piplus_highmom = __BAD_FLOAT__;
float pineg_highmom = __BAD_FLOAT__;
float pi0_highmom = __BAD_FLOAT__;
(*nu_4mom) = event->PartInfo(0)->fP;
if (!liteMode) {
(*pmu) = TLorentzVector(0, 0, 0, 0);
(*ppip) = TLorentzVector(0, 0, 0, 0);
(*ppim) = TLorentzVector(0, 0, 0, 0);
(*ppi0) = TLorentzVector(0, 0, 0, 0);
(*pprot) = TLorentzVector(0, 0, 0, 0);
(*pneut) = TLorentzVector(0, 0, 0, 0);
}
Enu_true = nu_4mom->E();
PDGnu = event->PartInfo(0)->fPID;
bool cc = (abs(event->Mode) < 30);
(void)cc;
// Add all pion distributions for the event.
// Add classifier for CC0pi or CC1pi or CCOther
// Save Modes Properly
// Save low recoil measurements
// Start Particle Loop
UInt_t npart = event->Npart();
for (UInt_t i = 0; i < npart; i++) {
// Skip particles that weren't in the final state
bool part_alive = event->PartInfo(i)->fIsAlive and
event->PartInfo(i)->Status() == kFinalState;
if (!part_alive) continue;
// PDG Particle
int PDGpart = event->PartInfo(i)->fPID;
TLorentzVector part_4mom = event->PartInfo(i)->fP;
Nparticles++;
// Get Charged Lepton
if (abs(PDGpart) == abs(PDGnu) - 1) {
Nleptons++;
PDGLep = PDGpart;
TLep = FitUtils::T(part_4mom) * 1000.0;
PLep = (part_4mom.Vect().Mag());
ELep = (part_4mom.E());
MLep = (part_4mom.Mag());
CosLep = cos(part_4mom.Vect().Angle(nu_4mom->Vect()));
(*pmu) = part_4mom;
Q2_true = -1 * (part_4mom - (*nu_4mom)).Mag2();
float ThetaLep = (event->PartInfo(0))
->fP.Vect()
.Angle((event->PartInfo(i))->fP.Vect());
q0_true = (part_4mom - (*nu_4mom)).E();
q3_true = (part_4mom - (*nu_4mom)).Vect().Mag();
// Get W_true with assumption of initial state nucleon at rest
float m_n = (float)PhysConst::mass_proton * 1000.;
W_nuc_rest = sqrt(-Q2_true + 2 * m_n * (Enu_true - ELep) + m_n * m_n);
// Get the Bjorken x and y variables
// Assume that E_had = Enu - Emu as in MINERvA
bjorken_x = Q2_true / (2 * m_n * (Enu_true - ELep));
bjorken_y = 1 - ELep / Enu_true;
// Quasi-elastic ----------------------
// ------------------------------------
// Q2 QE Assuming Carbon Input. Should change this to be dynamic soon.
Q2_QE =
FitUtils::Q2QErec(part_4mom, cos(ThetaLep), 34., true) * 1000000.0;
Enu_QE = FitUtils::EnuQErec(part_4mom, cos(ThetaLep), 34., true) * 1000.0;
// Pion Production ----------------------
// --------------------------------------
} else if (PDGpart == 2212) {
Nprotons++;
if (part_4mom.Vect().Mag() > proton_highmom) {
proton_highmom = part_4mom.Vect().Mag();
PPr = (part_4mom.Vect().Mag());
EPr = (part_4mom.E());
TPr = FitUtils::T(part_4mom) * 1000.;
MPr = (part_4mom.Mag());
CosPr = cos(part_4mom.Vect().Angle(nu_4mom->Vect()));
(*pprot) = part_4mom;
}
} else if (PDGpart == 2112) {
Nneutrons++;
if (part_4mom.Vect().Mag() > neutron_highmom) {
neutron_highmom = part_4mom.Vect().Mag();
PNe = (part_4mom.Vect().Mag());
ENe = (part_4mom.E());
TNe = FitUtils::T(part_4mom) * 1000.;
MNe = (part_4mom.Mag());
CosNe = cos(part_4mom.Vect().Angle(nu_4mom->Vect()));
(*pneut) = part_4mom;
}
} else if (PDGpart == 211) {
Npiplus++;
if (part_4mom.Vect().Mag() > piplus_highmom) {
piplus_highmom = part_4mom.Vect().Mag();
PPiP = (part_4mom.Vect().Mag());
EPiP = (part_4mom.E());
TPiP = FitUtils::T(part_4mom) * 1000.;
MPiP = (part_4mom.Mag());
CosPiP = cos(part_4mom.Vect().Angle(nu_4mom->Vect()));
(*ppip) = part_4mom;
}
} else if (PDGpart == -211) {
Npineg++;
if (part_4mom.Vect().Mag() > pineg_highmom) {
pineg_highmom = part_4mom.Vect().Mag();
PPiN = (part_4mom.Vect().Mag());
EPiN = (part_4mom.E());
TPiN = FitUtils::T(part_4mom) * 1000.;
MPiN = (part_4mom.Mag());
CosPiN = cos(part_4mom.Vect().Angle(nu_4mom->Vect()));
(*ppim) = part_4mom;
}
} else if (PDGpart == 111) {
Npi0++;
if (part_4mom.Vect().Mag() > pi0_highmom) {
pi0_highmom = part_4mom.Vect().Mag();
PPi0 = (part_4mom.Vect().Mag());
EPi0 = (part_4mom.E());
TPi0 = FitUtils::T(part_4mom) * 1000.;
MPi0 = (part_4mom.Mag());
CosPi0 = cos(part_4mom.Vect().Angle(nu_4mom->Vect()));
(*ppi0) = part_4mom;
}
} else {
Nother++;
}
}
// Get Recoil Definitions ------
// -----------------------------
Erecoil_true = FitUtils::GetErecoil_TRUE(event);
Erecoil_charged = FitUtils::GetErecoil_CHARGED(event);
Erecoil_minerva = FitUtils::GetErecoil_MINERvA_LowRecoil(event);
// Do the angles between final state particles
if (Nleptons > 0 && Npiplus > 0)
CosPmuPpip = cos(pmu->Vect().Angle(ppip->Vect()));
if (Nleptons > 0 && Npineg > 0)
CosPmuPpim = cos(pmu->Vect().Angle(ppim->Vect()));
if (Nleptons > 0 && Npi0 > 0)
CosPmuPpi0 = cos(pmu->Vect().Angle(ppi0->Vect()));
if (Nleptons > 0 && Nprotons > 0)
CosPmuPprot = cos(pmu->Vect().Angle(pprot->Vect()));
if (Nleptons > 0 && Nneutrons > 0)
CosPmuPneut = cos(pmu->Vect().Angle(pneut->Vect()));
if (Npiplus > 0 && Nprotons > 0)
CosPpipPprot = cos(ppip->Vect().Angle(pprot->Vect()));
if (Npiplus > 0 && Nneutrons > 0)
CosPpipPneut = cos(ppip->Vect().Angle(pneut->Vect()));
if (Npiplus > 0 && Npineg > 0)
CosPpipPpim = cos(ppip->Vect().Angle(ppim->Vect()));
if (Npiplus > 0 && Npi0 > 0)
CosPpipPpi0 = cos(ppip->Vect().Angle(ppi0->Vect()));
if (Npineg > 0 && Nprotons > 0)
CosPpimPprot = cos(ppim->Vect().Angle(pprot->Vect()));
if (Npineg > 0 && Nneutrons > 0)
CosPpimPneut = cos(ppim->Vect().Angle(pneut->Vect()));
if (Npineg > 0 && Npi0 > 0)
CosPpimPpi0 = cos(ppim->Vect().Angle(ppi0->Vect()));
if (Npi0 > 0 && Nprotons > 0)
CosPi0Pprot = cos(ppi0->Vect().Angle(pprot->Vect()));
if (Npi0 > 0 && Nneutrons > 0)
CosPi0Pneut = cos(ppi0->Vect().Angle(pneut->Vect()));
if (Nprotons > 0 && Nneutrons > 0)
CosPprotPneut = cos(pprot->Vect().Angle(pneut->Vect()));
// Event Weights ----
// ------------------
Weight = event->RWWeight * event->InputWeight;
RWWeight = event->RWWeight;
InputWeight = event->InputWeight;
FluxWeight =
GetFluxHistogram()->GetBinContent(GetFluxHistogram()->FindBin(Enu)) /
GetFluxHistogram()->Integral();
// Fill the eventVariables Tree
eventVariables->Fill();
return;
};
//********************************************************************
void GenericFlux_Tester::Write(std::string drawOpt) {
//********************************************************************
// First save the TTree
eventVariables->Write();
// Save Flux and Event Histograms too
GetInput()->GetFluxHistogram()->Write();
GetInput()->GetEventHistogram()->Write();
return;
}
//********************************************************************
void GenericFlux_Tester::FillSignalFlags(FitEvent *event) {
//********************************************************************
// Some example flags are given from SignalDef.
// See src/Utils/SignalDef.cxx for more.
int nuPDG = event->PartInfo(0)->fPID;
// Generic signal flags
flagCCINC = SignalDef::isCCINC(event, nuPDG);
flagNCINC = SignalDef::isNCINC(event, nuPDG);
flagCCQE = SignalDef::isCCQE(event, nuPDG);
flagCCQELike = SignalDef::isCCQELike(event, nuPDG);
flagCC0pi = SignalDef::isCC0pi(event, nuPDG);
flagNCEL = SignalDef::isNCEL(event, nuPDG);
flagNC0pi = SignalDef::isNC0pi(event, nuPDG);
flagCCcoh = SignalDef::isCCCOH(event, nuPDG, 211);
flagNCcoh = SignalDef::isNCCOH(event, nuPDG, 111);
flagCC1pip = SignalDef::isCC1pi(event, nuPDG, 211);
flagNC1pip = SignalDef::isNC1pi(event, nuPDG, 211);
flagCC1pim = SignalDef::isCC1pi(event, nuPDG, -211);
flagNC1pim = SignalDef::isNC1pi(event, nuPDG, -211);
flagCC1pi0 = SignalDef::isCC1pi(event, nuPDG, 111);
flagNC1pi0 = SignalDef::isNC1pi(event, nuPDG, 111);
}
// -------------------------------------------------------------------
// Purely MC Plot
// Following functions are just overrides to handle this
// -------------------------------------------------------------------
//********************************************************************
/// Everything is classed as signal...
bool GenericFlux_Tester::isSignal(FitEvent *event) {
//********************************************************************
(void)event;
return true;
};
//********************************************************************
void GenericFlux_Tester::ScaleEvents() {
//********************************************************************
// Saving everything to a TTree so no scaling required
return;
}
//********************************************************************
void GenericFlux_Tester::ApplyNormScale(float norm) {
//********************************************************************
// Saving everything to a TTree so no scaling required
this->fCurrentNorm = norm;
return;
}
//********************************************************************
void GenericFlux_Tester::FillHistograms() {
//********************************************************************
// No Histograms need filling........
return;
}
//********************************************************************
void GenericFlux_Tester::ResetAll() {
//********************************************************************
eventVariables->Reset();
return;
}
//********************************************************************
float GenericFlux_Tester::GetChi2() {
//********************************************************************
// No Likelihood to test, purely MC
return 0.0;
}
diff --git a/src/MCStudies/GenericFlux_Vectors.cxx b/src/MCStudies/GenericFlux_Vectors.cxx
index 0197a73..da0a4ca 100644
--- a/src/MCStudies/GenericFlux_Vectors.cxx
+++ b/src/MCStudies/GenericFlux_Vectors.cxx
@@ -1,327 +1,334 @@
// 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/>.
-*******************************************************************************/
+ * 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 "GenericFlux_Vectors.h"
-GenericFlux_Vectors::GenericFlux_Vectors(std::string name, std::string inputfile,
- FitWeight *rw, std::string type,
- std::string fakeDataFile) {
+GenericFlux_Vectors::GenericFlux_Vectors(std::string name,
+ std::string inputfile, FitWeight *rw,
+ std::string type,
+ std::string fakeDataFile) {
// Measurement Details
fName = name;
eventVariables = NULL;
// Define our energy range for flux calcs
EnuMin = 0.;
EnuMax = 1E10; // Arbritrarily high energy limit
+ if (Config::HasPar("EnuMin")) {
+ EnuMin = Config::GetParD("EnuMin");
+ }
+
+ if (Config::HasPar("EnuMax")) {
+ EnuMax = Config::GetParD("EnuMax");
+ }
+
// Set default fitter flags
fIsDiag = true;
fIsShape = false;
fIsRawEvents = false;
// This function will sort out the input files automatically and parse all the
// inputs,flags,etc.
// There may be complex cases where you have to do this by hand, but usually
// this will do.
Measurement1D::SetupMeasurement(inputfile, type, rw, fakeDataFile);
eventVariables = NULL;
// Setup fDataHist as a placeholder
this->fDataHist = new TH1D(("empty_data"), ("empty-data"), 1, 0, 1);
this->SetupDefaultHist();
fFullCovar = StatUtils::MakeDiagonalCovarMatrix(fDataHist);
covar = StatUtils::GetInvert(fFullCovar);
// 1. The generator is organised in SetupMeasurement so it gives the
// cross-section in "per nucleon" units.
// So some extra scaling for a specific measurement may be required. For
// Example to get a "per neutron" measurement on carbon
// which we do here, we have to multiple by the number of nucleons 12 and
// divide by the number of neutrons 6.
- fScaleFactor =
- (GetEventHistogram()->Integral("width") * 1E-38 / (fNEvents + 0.)) /
+ // N.B. MeasurementBase::PredictedEventRate includes the 1E-38 factor that is
+ // often included here in other classes that directly integrate the event
+ // histogram. This method is used here as it now respects EnuMin and EnuMax
+ // correctly.
+ this->fScaleFactor =
+ (this->PredictedEventRate("width", 0, EnuMax) / double(fNEvents)) /
this->TotalIntegratedFlux();
LOG(SAM) << " Generic Flux Scaling Factor = " << fScaleFactor
<< " [= " << (GetEventHistogram()->Integral("width") * 1E-38) << "/("
<< (fNEvents + 0.) << "*" << this->TotalIntegratedFlux() << ")]"
<< std::endl;
if (fScaleFactor <= 0.0) {
ERR(WRN) << "SCALE FACTOR TOO LOW " << std::endl;
throw;
}
// Setup our TTrees
this->AddEventVariablesToTree();
this->AddSignalFlagsToTree();
}
void GenericFlux_Vectors::AddEventVariablesToTree() {
// Setup the TTree to save everything
if (!eventVariables) {
Config::Get().out->cd();
eventVariables = new TTree((this->fName + "_VARS").c_str(),
(this->fName + "_VARS").c_str());
}
LOG(SAM) << "Adding Event Variables" << std::endl;
- eventVariables->Branch("Mode", &Mode, "Mode/I" );
- eventVariables->Branch("cc", &cc, "cc/B" );
- eventVariables->Branch("PDGnu", &PDGnu, "PDGnu/I" );
- eventVariables->Branch("Enu_true", &Enu_true, "Enu_true/F" );
- eventVariables->Branch("tgt", &tgt, "tgt/I" );
+ eventVariables->Branch("Mode", &Mode, "Mode/I");
+ eventVariables->Branch("cc", &cc, "cc/B");
+ eventVariables->Branch("PDGnu", &PDGnu, "PDGnu/I");
+ eventVariables->Branch("Enu_true", &Enu_true, "Enu_true/F");
+ eventVariables->Branch("tgt", &tgt, "tgt/I");
eventVariables->Branch("PDGLep", &PDGLep, "PDGLep/I");
- eventVariables->Branch("ELep", &ELep, "ELep/F" );
+ eventVariables->Branch("ELep", &ELep, "ELep/F");
eventVariables->Branch("CosLep", &CosLep, "CosLep/F");
// Basic interaction kinematics
- eventVariables->Branch("Q2", &Q2, "Q2/F");
- eventVariables->Branch("q0", &q0, "q0/F");
- eventVariables->Branch("q3", &q3, "q3/F");
+ eventVariables->Branch("Q2", &Q2, "Q2/F");
+ eventVariables->Branch("q0", &q0, "q0/F");
+ eventVariables->Branch("q3", &q3, "q3/F");
eventVariables->Branch("Enu_QE", &Enu_QE, "Enu_QE/F");
- eventVariables->Branch("Q2_QE", &Q2_QE, "Q2_QE/F");
+ eventVariables->Branch("Q2_QE", &Q2_QE, "Q2_QE/F");
eventVariables->Branch("W_nuc_rest", &W_nuc_rest, "W_nuc_rest/F");
- eventVariables->Branch("W", &W, "W/F");
- eventVariables->Branch("x", &x, "x/F");
- eventVariables->Branch("y", &y, "y/F");
+ eventVariables->Branch("W", &W, "W/F");
+ eventVariables->Branch("x", &x, "x/F");
+ eventVariables->Branch("y", &y, "y/F");
// Save outgoing particle vectors
eventVariables->Branch("nfsp", &nfsp, "nfsp/I");
- eventVariables->Branch("px", px, "px[nfsp]/F");
- eventVariables->Branch("py", py, "py[nfsp]/F");
- eventVariables->Branch("pz", pz, "pz[nfsp]/F");
- eventVariables->Branch("E", E, "E[nfsp]/F");
- eventVariables->Branch("pdg", pdg, "pdg[nfsp]/I");
+ eventVariables->Branch("px", px, "px[nfsp]/F");
+ eventVariables->Branch("py", py, "py[nfsp]/F");
+ eventVariables->Branch("pz", pz, "pz[nfsp]/F");
+ eventVariables->Branch("E", E, "E[nfsp]/F");
+ eventVariables->Branch("pdg", pdg, "pdg[nfsp]/I");
// Event Scaling Information
eventVariables->Branch("Weight", &Weight, "Weight/F");
eventVariables->Branch("InputWeight", &InputWeight, "InputWeight/F");
eventVariables->Branch("RWWeight", &RWWeight, "RWWeight/F");
+ // Should be a double because may be 1E-39 and less
eventVariables->Branch("fScaleFactor", &fScaleFactor, "fScaleFactor/D");
// The customs
eventVariables->Branch("CustomWeight", &CustomWeight, "CustomWeight/F");
eventVariables->Branch("CustomWeightArray", CustomWeightArray, "CustomWeightArray[6]/F");
return;
}
-
void GenericFlux_Vectors::FillEventVariables(FitEvent *event) {
ResetVariables();
// Fill Signal Variables
FillSignalFlags(event);
LOG(DEB) << "Filling signal" << std::endl;
// Now fill the information
Mode = event->Mode;
cc = (abs(event->Mode) < 30);
// Get the incoming neutrino and outgoing lepton
- FitParticle *nu = event->GetNeutrinoIn();
+ FitParticle *nu = event->GetNeutrinoIn();
FitParticle *lep = event->GetHMFSAnyLepton();
PDGnu = nu->fPID;
- Enu_true = nu->fP.E()/1E3;
+ Enu_true = nu->fP.E() / 1E3;
tgt = event->fTargetPDG;
if (lep != NULL) {
PDGLep = lep->fPID;
- ELep = lep->fP.E()/1E3;
+ ELep = lep->fP.E() / 1E3;
CosLep = cos(nu->fP.Vect().Angle(lep->fP.Vect()));
// Basic interaction kinematics
- Q2 = -1*(nu->fP - lep->fP).Mag2()/1E6;
- q0 = (nu->fP - lep->fP).E()/1E3;
- q3 = (nu->fP - lep->fP).Vect().Mag()/1E3;
+ Q2 = -1 * (nu->fP - lep->fP).Mag2() / 1E6;
+ q0 = (nu->fP - lep->fP).E() / 1E3;
+ q3 = (nu->fP - lep->fP).Vect().Mag() / 1E3;
// These assume C12 binding from MINERvA... not ideal
Enu_QE = FitUtils::EnuQErec(lep->fP, CosLep, 34., true);
- Q2_QE = FitUtils::Q2QErec(lep->fP, CosLep, 34., true);
+ Q2_QE = FitUtils::Q2QErec(lep->fP, CosLep, 34., true);
// Get W_true with assumption of initial state nucleon at rest
float m_n = (float)PhysConst::mass_proton;
// Q2 assuming nucleon at rest
W_nuc_rest = sqrt(-Q2 + 2 * m_n * q0 + m_n * m_n);
// True Q2
W = sqrt(-Q2 + 2 * m_n * q0 + m_n * m_n);
- x = Q2/(2 * m_n * q0);
- y = 1 - ELep/Enu_true;
+ x = Q2 / (2 * m_n * q0);
+ y = 1 - ELep / Enu_true;
}
// Loop over the particles and store all the final state particles in a vector
for (UInt_t i = 0; i < event->Npart(); ++i) {
- bool part_alive = event->PartInfo(i)->fIsAlive and event->PartInfo(i)->Status() == kFinalState;
+ bool part_alive = event->PartInfo(i)->fIsAlive &&
+ event->PartInfo(i)->Status() == kFinalState;
if (!part_alive) continue;
- partList .push_back(event->PartInfo(i));
+ partList.push_back(event->PartInfo(i));
}
// Save outgoing particle vectors
nfsp = (int)partList.size();
- for (int i = 0; i < nfsp; ++i){
- px[i] = partList[i]->fP.X()/1E3;
- py[i] = partList[i]->fP.Y()/1E3;
- pz[i] = partList[i]->fP.Z()/1E3;
- E[i] = partList[i]->fP.E()/1E3;
+ for (int i = 0; i < nfsp; ++i) {
+ px[i] = partList[i]->fP.X() / 1E3;
+ py[i] = partList[i]->fP.Y() / 1E3;
+ pz[i] = partList[i]->fP.Z() / 1E3;
+ E[i] = partList[i]->fP.E() / 1E3;
pdg[i] = partList[i]->fPID;
}
// Fill event weights
Weight = event->RWWeight * event->InputWeight;
RWWeight = event->RWWeight;
InputWeight = event->InputWeight;
// And the Customs
CustomWeight = event->CustomWeight;
for (int i = 0; i < 6; ++i) {
CustomWeightArray[i] = event->CustomWeightArray[i];
}
// Fill the eventVariables Tree
eventVariables->Fill();
return;
};
//********************************************************************
void GenericFlux_Vectors::ResetVariables() {
//********************************************************************
cc = false;
// Reset all Function used to extract any variables of interest to the event
Mode = PDGnu = tgt = PDGLep = 0;
Enu_true = ELep = CosLep = Q2 = q0 = q3 = Enu_QE = Q2_QE = W_nuc_rest = W = x = y = -999.9;
nfsp = 0;
for (int i = 0; i < kMAX; ++i){
px[i] = py[i] = pz[i] = E[i] = -999;
pdg[i] = 0;
}
Weight = InputWeight = RWWeight = 0.0;
CustomWeight = 0.0;
for (int i = 0; i < 6; ++i) CustomWeightArray[i] = 0.0;
partList.clear();
flagCCINC = flagNCINC = flagCCQE = flagCC0pi = flagCCQELike = flagNCEL = flagNC0pi = flagCCcoh = flagNCcoh = flagCC1pip = flagNC1pip = flagCC1pim = flagNC1pim = flagCC1pi0 = flagNC1pi0 = false;
}
//********************************************************************
void GenericFlux_Vectors::FillSignalFlags(FitEvent *event) {
//********************************************************************
// Some example flags are given from SignalDef.
// See src/Utils/SignalDef.cxx for more.
int nuPDG = event->PartInfo(0)->fPID;
// Generic signal flags
flagCCINC = SignalDef::isCCINC(event, nuPDG);
flagNCINC = SignalDef::isNCINC(event, nuPDG);
flagCCQE = SignalDef::isCCQE(event, nuPDG);
flagCCQELike = SignalDef::isCCQELike(event, nuPDG);
flagCC0pi = SignalDef::isCC0pi(event, nuPDG);
flagNCEL = SignalDef::isNCEL(event, nuPDG);
flagNC0pi = SignalDef::isNC0pi(event, nuPDG);
flagCCcoh = SignalDef::isCCCOH(event, nuPDG, 211);
flagNCcoh = SignalDef::isNCCOH(event, nuPDG, 111);
flagCC1pip = SignalDef::isCC1pi(event, nuPDG, 211);
flagNC1pip = SignalDef::isNC1pi(event, nuPDG, 211);
flagCC1pim = SignalDef::isCC1pi(event, nuPDG, -211);
flagNC1pim = SignalDef::isNC1pi(event, nuPDG, -211);
flagCC1pi0 = SignalDef::isCC1pi(event, nuPDG, 111);
flagNC1pi0 = SignalDef::isNC1pi(event, nuPDG, 111);
}
void GenericFlux_Vectors::AddSignalFlagsToTree() {
if (!eventVariables) {
Config::Get().out->cd();
eventVariables = new TTree((this->fName + "_VARS").c_str(),
(this->fName + "_VARS").c_str());
}
LOG(SAM) << "Adding signal flags" << std::endl;
// Signal Definitions from SignalDef.cxx
eventVariables->Branch("flagCCINC", &flagCCINC, "flagCCINC/O");
eventVariables->Branch("flagNCINC", &flagNCINC, "flagNCINC/O");
eventVariables->Branch("flagCCQE", &flagCCQE, "flagCCQE/O");
eventVariables->Branch("flagCC0pi", &flagCC0pi, "flagCC0pi/O");
eventVariables->Branch("flagCCQELike", &flagCCQELike, "flagCCQELike/O");
eventVariables->Branch("flagNCEL", &flagNCEL, "flagNCEL/O");
eventVariables->Branch("flagNC0pi", &flagNC0pi, "flagNC0pi/O");
eventVariables->Branch("flagCCcoh", &flagCCcoh, "flagCCcoh/O");
eventVariables->Branch("flagNCcoh", &flagNCcoh, "flagNCcoh/O");
eventVariables->Branch("flagCC1pip", &flagCC1pip, "flagCC1pip/O");
eventVariables->Branch("flagNC1pip", &flagNC1pip, "flagNC1pip/O");
eventVariables->Branch("flagCC1pim", &flagCC1pim, "flagCC1pim/O");
eventVariables->Branch("flagNC1pim", &flagNC1pim, "flagNC1pim/O");
eventVariables->Branch("flagCC1pi0", &flagCC1pi0, "flagCC1pi0/O");
eventVariables->Branch("flagNC1pi0", &flagNC1pi0, "flagNC1pi0/O");
};
void GenericFlux_Vectors::Write(std::string drawOpt) {
// First save the TTree
eventVariables->Write();
// Save Flux and Event Histograms too
GetInput()->GetFluxHistogram()->Write();
GetInput()->GetEventHistogram()->Write();
return;
}
-
// Override functions which aren't really necessary
bool GenericFlux_Vectors::isSignal(FitEvent *event) {
(void)event;
return true;
};
-void GenericFlux_Vectors::ScaleEvents() {
- return;
-}
+void GenericFlux_Vectors::ScaleEvents() { return; }
void GenericFlux_Vectors::ApplyNormScale(float norm) {
this->fCurrentNorm = norm;
return;
}
-void GenericFlux_Vectors::FillHistograms() {
- return;
-}
+void GenericFlux_Vectors::FillHistograms() { return; }
void GenericFlux_Vectors::ResetAll() {
eventVariables->Reset();
return;
}
-float GenericFlux_Vectors::GetChi2() {
- return 0.0;
-}
+float GenericFlux_Vectors::GetChi2() { return 0.0; }
diff --git a/src/MCStudies/GenericFlux_Vectors.h b/src/MCStudies/GenericFlux_Vectors.h
index 9fc92c5..92a965c 100644
--- a/src/MCStudies/GenericFlux_Vectors.h
+++ b/src/MCStudies/GenericFlux_Vectors.h
@@ -1,125 +1,125 @@
// 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 GenericFlux_Vectors_H_SEEN
#define GenericFlux_Vectors_H_SEEN
#include "Measurement1D.h"
class GenericFlux_Vectors : public Measurement1D {
public:
GenericFlux_Vectors(std::string name, std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile);
virtual ~GenericFlux_Vectors() {};
//! Grab info from event
void FillEventVariables(FitEvent *event);
//! Fill signal flags
void FillSignalFlags(FitEvent *event);
void ResetVariables();
//! Fill Custom Histograms
void FillHistograms();
//! ResetAll
void ResetAll();
//! Scale
void ScaleEvents();
//! Norm
void ApplyNormScale(float norm);
//! Define this samples signal
bool isSignal(FitEvent *nvect);
//! Write Files
void Write(std::string drawOpt);
//! Get Chi2
float GetChi2();
void AddEventVariablesToTree();
void AddSignalFlagsToTree();
private:
TTree* eventVariables;
std::vector<FitParticle*> partList;
int Mode;
bool cc;
int PDGnu;
int tgt;
int PDGLep;
float ELep;
float CosLep;
// Basic interaction kinematics
float Q2;
float q0;
float q3;
float Enu_QE;
float Enu_true;
float Q2_QE;
float W_nuc_rest;
float W;
float x;
float y;
-
+
// Save outgoing particle vectors
int nfsp;
static const int kMAX = 200;
float px[kMAX];
float py[kMAX];
float pz[kMAX];
float E[kMAX];
int pdg[kMAX];
-
+
// Basic event info
float Weight;
float InputWeight;
float RWWeight;
double fScaleFactor;
// Custom weights
float CustomWeight;
float CustomWeightArray[6];
// Generic signal flags
bool flagCCINC;
bool flagNCINC;
bool flagCCQE;
bool flagCC0pi;
bool flagCCQELike;
bool flagNCEL;
bool flagNC0pi;
bool flagCCcoh;
bool flagNCcoh;
bool flagCC1pip;
bool flagNC1pip;
bool flagCC1pim;
bool flagNC1pim;
bool flagCC1pi0;
bool flagNC1pi0;
};
#endif
diff --git a/src/MINERvA/MINERvA_CC1pi0_XSec_1D_nu.cxx b/src/MINERvA/MINERvA_CC1pi0_XSec_1D_nu.cxx
index 39fa194..d3a797b 100644
--- a/src/MINERvA/MINERvA_CC1pi0_XSec_1D_nu.cxx
+++ b/src/MINERvA/MINERvA_CC1pi0_XSec_1D_nu.cxx
@@ -1,320 +1,320 @@
// 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_1D_nu.h"
// Implementation of 2017 MINERvA numu CC1pi0
// arxiv:1708.03723v1 hep-ex
// c.wret14@imperial.ac.uk
//********************************************************************
void MINERvA_CC1pi0_XSec_1D_nu::SetupDataSettings(){
//********************************************************************
// Set Distribution
// See header file for enum and some descriptions
std::string name = fSettings.GetS("name");
if (!name.compare("MINERvA_CC1pi0_XSec_1DTpi_nu")) fDist = kTpi;
else if (!name.compare("MINERvA_CC1pi0_XSec_1Dth_nu")) fDist= kth;
else if (!name.compare("MINERvA_CC1pi0_XSec_1Dpmu_nu")) fDist= kpmu;
else if (!name.compare("MINERvA_CC1pi0_XSec_1Dthmu_nu")) fDist= kthmu;
else if (!name.compare("MINERvA_CC1pi0_XSec_1DQ2_nu")) fDist= kQ2;
else if (!name.compare("MINERvA_CC1pi0_XSec_1DEnu_nu")) fDist= kEnu;
else if (!name.compare("MINERvA_CC1pi0_XSec_1DWexp_nu")) fDist= kWexp;
else if (!name.compare("MINERvA_CC1pi0_XSec_1DPPi0Mass_nu")) fDist= kPPi0Mass;
else if (!name.compare("MINERvA_CC1pi0_XSec_1DPPi0MassDelta_nu")) fDist= kPPi0MassDelta;
else if (!name.compare("MINERvA_CC1pi0_XSec_1DCosAdler_nu")) fDist= kCosAdler;
else if (!name.compare("MINERvA_CC1pi0_XSec_1DPhiAdler_nu")) fDist= kPhiAdler;
// Define what files to use from the dist
std::string datafile = "";
std::string corrfile = "";
std::string titles = "";
std::string distdescript = "";
// Set the default to essentially not be a cut on proton kinetic energy
// The Adler angles and reconstructed p,pi0 invariant mass have cuts on these
ProtonCut = 100;
// W exp is 1.8 GeV or lower (dealt with below)
WexpCut = 1.8;
// Load up the data
switch (fDist) {
case (kTpi):
datafile = "data/XSec_Table_pi0_KE_xsec.csv";
corrfile = "corr/Correlation_Table_pi0_KE_xsec.csv";
titles = "CC1#pi^{0};T_{#pi} (GeV);d#sigma/dT_{#pi} (cm^{2}/nucleon/GeV)";
break;
case (kth):
datafile = "data/XSec_Table_pi0_theta_xsec.csv";
corrfile = "corr/Correlation_Table_pi0_theta_xsec.csv";
titles = "CC1#pi^{0};#theta_{#pi} (degrees); d#sigma/d#theta_{#pi} (cm^{2}/nucleon/degree)";
break;
case (kpmu):
datafile = "data/XSec_Table_muon_P_xsec.csv";
corrfile = "corr/Correlation_Table_muon_P_xsec.csv";
titles = "CC1#pi^{0};p_{#mu} (GeV);d#sigma/dp_{#mu} (cm^{2}/nucleon/GeV)";
break;
case (kthmu):
datafile = "data/XSec_Table_muon_theta_xsec.csv";
corrfile = "corr/Correlation_Table_muon_theta_xsec.csv";
titles = "CC1#pi^{0};#theta_{#mu} (degrees);d#sigma/d#theta_{#mu} (cm^{2}/nucleon/degree)";
break;
case (kQ2):
datafile = "data/XSec_Table_QSq_xsec.csv";
corrfile = "corr/Correlation_Table_QSq_xsec.csv";
titles = "CC1#pi^{0};Q^{2} (GeV^{2});d#sigma/dQ^{2} (cm^{2}/nucleon/GeV^{2})";
break;
case (kEnu):
datafile = "data/XSec_Table_Enu_xsec.csv";
corrfile = "corr/Correlation_Table_Enu_xsec.csv";
titles = "CC1#pi^{0};E_{#nu} (GeV);#sigma(E_#nu) (cm^{2}/nucleon)";
break;
case (kWexp):
datafile = "data/XSec_Table_W_xsec.csv";
corrfile = "corr/Correlation_Table_W_xsec.csv";
titles = "CC1#pi^{0};W_{exp} (GeV);d#sigma/dW_{exp} (cm^{2}/nucleon/GeV)";
break;
case (kPPi0Mass):
datafile = "data/XSec_Table_deltaInvMass_xsec.csv";
corrfile = "corr/Correlation_Table_deltaInvMass_xsec.csv";
titles = "CC1#pi^{0}; M_{p#pi^{0}} (GeV); d#sigma/dM_{p#pi^{0}} (cm^{2}/nucleon/GeV)";
break;
case (kPPi0MassDelta):
datafile = "data/XSec_Table_deltaInvMass_xsec_DeltaRich.csv";
corrfile = "corr/Correlation_Table_deltaInvMass_xsec_DeltaRich.csv";
titles = "CC1#pi^{0}; M_{p#pi^{0}} W_{exp} < 1.4 (GeV); d#sigma/dM_{p#pi^{0}} (cm^{2}/nucleon/GeV)";
break;
case (kCosAdler):
datafile = "data/XSec_Table_Delta_pi_theta_xsec.csv";
corrfile = "corr/Correlation_Table_Delta_pi_theta_xsec.csv";
titles = "CC1#pi^{0}; cos#theta_{Adler}; d#sigma/dcos#theta_{Adler} (cm^{2}/nucleon/0.1)";
break;
case (kPhiAdler):
datafile = "data/XSec_Table_Delta_pi_phi_xsec.csv";
corrfile = "corr/Correlation_Table_Delta_pi_phi_xsec.csv";
titles = "CC1#pi^{0}; #phi_{Adler} (degrees); d#sigma/d#phi_{Adler} (cm^{2}/nucleon/degree)";
break;
default:
THROW("Unknown Analysis Distribution : " << fDist);
}
// Set the Wexp and proton kinetic energy cuts depending on sample
// for Ppi0Mass distributions and Adler angles we require a proton of at least 100 MeV kinetic energy
if (fDist >= kPPi0Mass) {
ProtonCut = 0.1;
// 0.1 GeV proton kinetic energy cut
// Some distributions have a Wexp cut at 1.4 GeV which attempts to isolate delta production
if (fDist >= kPPi0MassDelta) {
WexpCut = 1.4;
}
}
// Only have xsec covariance (not shape only)
// 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 1pi0 in FS, no mesons, any nucleon(s). W < 1.8" \
"Alt Signal: Add in requirement of 1 proton with 100 MeV and sometimes W < 1.4";
fSettings.SetDescription(descrip);
// Specify the data
fSettings.SetDataInput( GeneralUtils::GetTopLevelDir()+"/data/MINERvA/CC1pi0/2017_nu/" + datafile);
// And the correlations
fSettings.SetCovarInput(GeneralUtils::GetTopLevelDir()+"/data/MINERvA/CC1pi0/2017_nu/" + corrfile);
fSettings.SetTitle( GeneralUtils::ParseToStr(titles,";")[0] );
fSettings.SetXTitle( GeneralUtils::ParseToStr(titles,";")[1] );
fSettings.SetYTitle( GeneralUtils::ParseToStr(titles,";")[2] );
return;
}
//********************************************************************
MINERvA_CC1pi0_XSec_1D_nu::MINERvA_CC1pi0_XSec_1D_nu(nuiskey samplekey) {
//********************************************************************
// Define Sample Settings common to all data distributions
fSettings = LoadSampleSettings(samplekey);
fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/FULL");
// From 1.5 to 20 GeV Enu
fSettings.SetEnuRange(1.5, 20.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() );
// The errors come as a percent of the cross-section for this measurement so need rescaling
// Have set the fDataHist above so just loop over and set new errors
for (int i = 0; i < fDataHist->GetNbinsX(); ++i) {
fDataHist->SetBinError(i+1, (fDataHist->GetBinError(i+1)/100.0)*fDataHist->GetBinContent(i+1));
}
// And finally all the numbers are in units of 1E-40 so scale the histograms as such
fDataHist->Scale(1.0E-40);
// This measurement gives us a correlation matrix, so should set it up as such
SetCorrelationFromTextFile( fSettings.GetCovarInput() );
// Final setup ---------------------------------------------------
FinaliseMeasurement();
};
//********************************************************************
void MINERvA_CC1pi0_XSec_1D_nu::FillEventVariables(FitEvent *event) {
//********************************************************************
fXVar = -999.9;
// Need a neutral pion and a muon
if (event->NumFSParticle(111) == 0 || event->NumFSParticle(13) == 0) {
return;
}
// Get the TLorentzVectors from the event
TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP;
TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
// Pion kinetic energy
double Tpi = (Ppi0.E() - Ppi0.Mag())/1.E3;
// Pion-neutrino angle
double th = (180./M_PI)*FitUtils::th(Pnu, Ppi0);
// Muon momentum
double pmu = Pmu.Vect().Mag()/1.E3;
// Muon-neutrino angle
double thmu = (180.0/M_PI)*FitUtils::th(Pnu, Pmu);
// True Q2
double Q2 = fabs((Pmu - Pnu).Mag2()) / 1.E6;
// True Enu
double Enu = Pnu.E() / 1.E3;
// Wexp (derived from "kinematic quantities" but uses EnuTrue)
double Wexp = FitUtils::Wrec(Pnu, Pmu)/1.E3;
// Wexp cut of 1.8 GeV in signal definition
// N.B. the Adler angles and PPi0 mass requires this to be 1400
if (Wexp > WexpCut) return;
// Some distributions require the final state proton: check that it exists
if (fDist >= kPPi0Mass && event->NumFSParticle(2212) == 0) return;
-
+
// Fill the variables depending on the enums
switch (fDist) {
case kTpi:
fXVar = Tpi;
break;
case kth:
fXVar = th;
break;
case kpmu:
// Pmu has a theta_mu < 25degree cut
if (thmu > 25) return;
else fXVar = pmu;
break;
case kthmu:
// thmu has a theta_mu < 25degree cut
if (thmu > 25) return;
else fXVar = pmu;
fXVar = thmu;
break;
case kQ2:
fXVar = Q2;
break;
case kEnu:
fXVar = Enu;
break;
case kWexp:
fXVar = Wexp;
break;
// p, pi0 invariant mass with Wexp < 1.8 or Wexp < 1.4: already checked these above
case kPPi0Mass:
case kPPi0MassDelta:
{
// Get the proton
TLorentzVector Pprot = event->GetHMFSParticle(2212)->fP;
double Ppi0Mass = (Ppi0+Pprot).Mag()/1.E3;
fXVar = Ppi0Mass;
break;
}
// Cos theta Adler angle
case kCosAdler:
{
TLorentzVector Pprot = event->GetHMFSParticle(2212)->fP;
double CosThAdler = FitUtils::CosThAdler(Pnu, Pmu, Ppi0, Pprot);
fXVar = CosThAdler;
break;
}
// Phi Adler angle
case kPhiAdler:
{
TLorentzVector Pprot = event->GetHMFSParticle(2212)->fP;
double PhiAdler = FitUtils::PhiAdler(Pnu, Pmu, Ppi0, Pprot);
fXVar = PhiAdler;
break;
}
default:
THROW("DIST NOT FOUND : " << fDist);
break;
}
};
//********************************************************************
bool MINERvA_CC1pi0_XSec_1D_nu::isSignal(FitEvent *event) {
//********************************************************************
// Some of the distributions require a proton with at least 100 MeV KE
if (fDist >= kPPi0Mass) {
// First of needs a proton in the final state
if (event->NumFSParticle(2212) == 0) return false;
// Needs to pass CC1pi0 signal definition
bool pass_cc1pi0 = SignalDef::isCC1pi0_MINERvA_nu(event, EnuMin, EnuMax);
if (!pass_cc1pi0) return false;
// And the proton needs at least 100 MeV kinetic energy
TLorentzVector Pprot = event->GetHMFSParticle(2212)->fP;
double ke = (Pprot.E() - Pprot.Mag())/1.E3;
if (pass_cc1pi0 && ke > ProtonCut) {
return true;
} else {
return false;
}
// The other distributions ahve a more generic "1mu, 1pi0, no mesons, any nucleon(s)"
// The W cut is instead made in FillEventVariables
} else {
return SignalDef::isCC1pi0_MINERvA_nu(event, EnuMin, EnuMax);
}
}
diff --git a/src/Reweight/NUISANCEWeightCalcs.cxx b/src/Reweight/NUISANCEWeightCalcs.cxx
index 5f9020a..4e14b90 100644
--- a/src/Reweight/NUISANCEWeightCalcs.cxx
+++ b/src/Reweight/NUISANCEWeightCalcs.cxx
@@ -1,447 +1,443 @@
#include "NUISANCEWeightCalcs.h"
#include "FitEvent.h"
#include "GeneralUtils.h"
#include "NUISANCESyst.h"
#include "WeightUtils.h"
using namespace Reweight;
-ModeNormCalc::ModeNormCalc(){
- fNormRES = 1.0;
-}
+ModeNormCalc::ModeNormCalc() { fNormRES = 1.0; }
double ModeNormCalc::CalcWeight(BaseFitEvt* evt) {
int mode = abs(evt->Mode);
double w = 1.0;
if (mode == 11 or mode == 12 or mode == 13) {
w *= fNormRES;
}
return w;
}
void ModeNormCalc::SetDialValue(std::string name, double val) {
SetDialValue(Reweight::ConvDial(name, kCUSTOM), val);
}
void ModeNormCalc::SetDialValue(int rwenum, double val) {
int curenum = rwenum % 1000;
// Check Handled
if (!IsHandled(curenum)) return;
if (curenum == kModeNorm_NormRES) fNormRES = val;
}
bool ModeNormCalc::IsHandled(int rwenum) {
-
int curenum = rwenum % 1000;
switch (curenum) {
case kModeNorm_NormRES:
return true;
default:
return false;
}
}
SBLOscWeightCalc::SBLOscWeightCalc() {
fDistance = 0.0;
fMassSplitting = 0.0;
fSin2Theta = 0.0;
}
double SBLOscWeightCalc::CalcWeight(BaseFitEvt* evt) {
FitEvent* fevt = static_cast<FitEvent*>(evt);
FitParticle* pnu = fevt->PartInfo(0);
double E = pnu->fP.E() / 1.E3;
// Extract energy
return GetSBLOscWeight(E);
}
void SBLOscWeightCalc::SetDialValue(std::string name, double val) {
SetDialValue(Reweight::ConvDial(name, kCUSTOM), val);
}
void SBLOscWeightCalc::SetDialValue(int rwenum, double val) {
int curenum = rwenum % 1000;
if (!IsHandled(curenum)) return;
- if (curenum == kSBLOsc_Distance) fDistance = val;
+ if (curenum == kSBLOsc_Distance) fDistance = val;
if (curenum == kSBLOsc_MassSplitting) fMassSplitting = val;
- if (curenum == kSBLOsc_Sin2Theta) fSin2Theta = val;
+ if (curenum == kSBLOsc_Sin2Theta) fSin2Theta = val;
}
bool SBLOscWeightCalc::IsHandled(int rwenum) {
-
int curenum = rwenum % 1000;
switch (curenum) {
- case kSBLOsc_Distance: return true;
- case kSBLOsc_MassSplitting: return true;
- case kSBLOsc_Sin2Theta: return true;
- default: return false;
+ case kSBLOsc_Distance:
+ return true;
+ case kSBLOsc_MassSplitting:
+ return true;
+ case kSBLOsc_Sin2Theta:
+ return true;
+ default:
+ return false;
}
}
-double SBLOscWeightCalc::GetSBLOscWeight(double E){
+double SBLOscWeightCalc::GetSBLOscWeight(double E) {
if (E <= 0.0) return 1.0 - 0.5 * fSin2Theta;
- return 1.0 - fSin2Theta * pow( sin(1.267 * fMassSplitting * fDistance / E ), 2);
+ return 1.0 - fSin2Theta * pow(sin(1.267 * fMassSplitting * fDistance / E), 2);
}
-
GaussianModeCorr::GaussianModeCorr() {
// Apply the tilt-shift Gauss by Patrick
// Alternatively set in config
fMethod = true;
// Init
fApply_CCQE = false;
fGausVal_CCQE[kPosNorm] = 0.0;
fGausVal_CCQE[kPosTilt] = 0.0;
fGausVal_CCQE[kPosPq0] = 1.0;
fGausVal_CCQE[kPosWq0] = 1.0;
fGausVal_CCQE[kPosPq3] = 1.0;
fGausVal_CCQE[kPosWq3] = 1.0;
fApply_2p2h = false;
fGausVal_2p2h[kPosNorm] = 0.0;
fGausVal_2p2h[kPosTilt] = 0.0;
fGausVal_2p2h[kPosPq0] = 1.0;
fGausVal_2p2h[kPosWq0] = 1.0;
fGausVal_2p2h[kPosPq3] = 1.0;
fGausVal_2p2h[kPosWq3] = 1.0;
fApply_2p2h_PPandNN = false;
fGausVal_2p2h_PPandNN[kPosNorm] = 0.0;
fGausVal_2p2h_PPandNN[kPosTilt] = 0.0;
fGausVal_2p2h_PPandNN[kPosPq0] = 1.0;
fGausVal_2p2h_PPandNN[kPosWq0] = 1.0;
fGausVal_2p2h_PPandNN[kPosPq3] = 1.0;
fGausVal_2p2h_PPandNN[kPosWq3] = 1.0;
fApply_2p2h_NP = false;
fGausVal_2p2h_NP[kPosNorm] = 0.0;
fGausVal_2p2h_NP[kPosTilt] = 0.0;
fGausVal_2p2h_NP[kPosPq0] = 1.0;
fGausVal_2p2h_NP[kPosWq0] = 1.0;
fGausVal_2p2h_NP[kPosPq3] = 1.0;
fGausVal_2p2h_NP[kPosWq3] = 1.0;
fApply_CC1pi = false;
fGausVal_CC1pi[kPosNorm] = 0.0;
fGausVal_CC1pi[kPosTilt] = 0.0;
fGausVal_CC1pi[kPosPq0] = 1.0;
fGausVal_CC1pi[kPosWq0] = 1.0;
fGausVal_CC1pi[kPosPq3] = 1.0;
fGausVal_CC1pi[kPosWq3] = 1.0;
fAllowSuppression = false;
fDebugStatements = FitPar::Config().GetParB("GaussianModeCorr_DEBUG");
}
double GaussianModeCorr::CalcWeight(BaseFitEvt* evt) {
FitEvent* fevt = static_cast<FitEvent*>(evt);
double rw_weight = 1.0;
// Get Neutrino
if (!fevt->Npart()) {
THROW("NO particles found in stack!");
}
FitParticle* pnu = fevt->GetHMISAnyLeptons();
if (!pnu) {
THROW("NO Starting particle found in stack!");
}
int pdgnu = pnu->fPID;
int expect_fsleppdg = 0;
if (pdgnu & 1) {
expect_fsleppdg = pdgnu;
} else {
expect_fsleppdg = abs(pdgnu) - 1;
}
FitParticle* plep = fevt->GetHMFSParticle(expect_fsleppdg);
if (!plep) return 1.0;
TLorentzVector q = pnu->fP - plep->fP;
// Extra q0,q3
double q0 = fabs(q.E()) / 1.E3;
double q3 = fabs(q.Vect().Mag()) / 1.E3;
int initialstate = -1; // Undef
if (abs(fevt->Mode) == 2) {
-
int npr = 0;
int nne = 0;
for (UInt_t j = 0; j < fevt->Npart(); j++) {
if ((fevt->PartInfo(j))->fIsAlive) continue;
- if (fevt->PartInfo(j)->fPID == 2212) npr++;
- else if (fevt->PartInfo(j)->fPID == 2112) nne++;
+ if (fevt->PartInfo(j)->fPID == 2212)
+ npr++;
+ else if (fevt->PartInfo(j)->fPID == 2112)
+ nne++;
}
- // std::cout << "PN State = " << npr << " " << nne << std::endl;
- if (fevt->Mode == 2 and npr == 1 and nne == 1) {
+ if (fevt->Mode == 2 && npr == 1 && nne == 1) {
initialstate = 2;
- } else if (fevt->Mode == 2 and ((npr == 0 and nne == 2) or (npr == 2 and nne == 0))) {
+ } else if (fevt->Mode == 2 && ((npr == 0 && nne == 2) || (npr == 2 && nne == 0))) {
initialstate = 1;
}
}
- // std::cout << "Got q0 q3 = " << q0 << " " << q3 << std::endl;
+ if (fDebugStatements) std::cout << "Got q0 q3 = " << q0 << " " << q3 << std::endl;
// Apply weighting
- if (fApply_CCQE and abs(fevt->Mode) == 1) {
+ if (fApply_CCQE && abs(fevt->Mode) == 1) {
if (fDebugStatements) std::cout << "Getting CCQE Weight" << std::endl;
double g = GetGausWeight(q0, q3, fGausVal_CCQE);
if (g < 1.0) g = 1.0;
rw_weight *= g;
}
- if (fApply_2p2h and abs(fevt->Mode) == 2) {
+ if (fApply_2p2h && abs(fevt->Mode) == 2) {
if (fDebugStatements) std::cout << "Getting 2p2h Weight" << std::endl;
rw_weight *= GetGausWeight(q0, q3, fGausVal_2p2h);
}
- if (fApply_2p2h_PPandNN and abs(fevt->Mode) == 2 and initialstate == 1) {
+ if (fApply_2p2h_PPandNN && abs(fevt->Mode) == 2 && initialstate == 1) {
if (fDebugStatements) std::cout << "Getting 2p2h PPandNN Weight" << std::endl;
rw_weight *= GetGausWeight(q0, q3, fGausVal_2p2h_PPandNN);
}
- if (fApply_2p2h_NP and abs(fevt->Mode) == 2 and initialstate == 2) {
+ if (fApply_2p2h_NP && abs(fevt->Mode) == 2 && initialstate == 2) {
if (fDebugStatements) std::cout << "Getting 2p2h NP Weight" << std::endl;
rw_weight *= GetGausWeight(q0, q3, fGausVal_2p2h_NP);
}
- if (fApply_CC1pi and abs(fevt->Mode) >= 11 and abs(fevt->Mode) <= 13) {
+ if (fApply_CC1pi && abs(fevt->Mode) >= 11 && abs(fevt->Mode) <= 13) {
if (fDebugStatements) std::cout << "Getting CC1pi Weight" << std::endl;
rw_weight *= GetGausWeight(q0, q3, fGausVal_CC1pi);
}
-
-
-
- // if (fDebugStatements) std::cout << "Returning Weight " << rw_weight << std::endl;
+ if (fDebugStatements) std::cout << "Returning Weight " << rw_weight << std::endl;
return rw_weight;
}
void GaussianModeCorr::SetMethod(bool method) {
fMethod = method;
if (fMethod == true) {
LOG(FIT) << " Using tilt-shift Gaussian parameters for Gaussian enhancement..." << std::endl;
} else {
LOG(FIT) << " Using Normal Gaussian parameters for Gaussian enhancement..." << std::endl;
}
};
double GaussianModeCorr::GetGausWeight(double q0, double q3, double vals[]) {
// The weight
double w = 1.0;
// Use tilt-shift method by Patrick
if (fMethod) {
if (fDebugStatements) {
std::cout << "Using Patrick gaussian" << std::endl;
}
// // CCQE Without Suppression
// double Norm = 4.82788679036;
// double Tilt = 2.3501416116;
// double Pq0 = 0.363964889702;
// double Wq0 = 0.133976806938;
// double Pq3 = 0.431769740224;
// double Wq3 = 0.207666663434;
// // Also add for CCQE at the end
// return (w > 1.0) ? w : 1.0;
// // 2p2h with suppression
// double Norm = 15.967;
// double Tilt = -0.455655;
// double Pq0 = 0.214598;
// double Wq0 = 0.0291061;
// double Pq3 = 0.480194;
// double Wq3 = 0.134588;
double Norm = vals[kPosNorm];
double Tilt = vals[kPosTilt];
double Pq0 = vals[kPosPq0];
double Wq0 = vals[kPosWq0];
double Pq3 = vals[kPosPq3];
double Wq3 = vals[kPosWq3];
double a = cos(Tilt) * cos(Tilt) / (2 * Wq0 * Wq0);
a += sin(Tilt) * sin(Tilt) / (2 * Wq3 * Wq3);
double b = -sin(2 * Tilt) / (4 * Wq0 * Wq0);
b += sin(2 * Tilt) / (4 * Wq3 * Wq3);
double c = sin(Tilt) * sin(Tilt) / (2 * Wq0 * Wq0);
c += cos(Tilt) * cos(Tilt) / (2 * Wq3 * Wq3);
w = Norm;
w *= exp(-a * (q0 - Pq0) * (q0 - Pq0));
w *= exp(+2.0 * b * (q0 - Pq0) * (q3 - Pq3));
w *= exp(-c * (q3 - Pq3) * (q3 - Pq3));
if (fDebugStatements) {
std::cout << "Applied Tilt " << Tilt << " " << cos(Tilt) << " " << sin(Tilt) << std::endl;
std::cout << "abc = " << a << " " << b << " " << c << std::endl;
std::cout << "Returning " << Norm << " " << Pq0 << " " << Wq0 << " " << Pq3 << " " << Wq3 << " " << w << std::endl;
}
if (w != w || std::isnan(w) || w < 0.0) {
w = 0.0;
}
if (w < 1.0 and !fAllowSuppression) {
w = 1.0;
}
// Use the MINERvA Gaussian method
} else {
/*
* From MINERvA and Daniel Ruterbories:
* Old notes here: * http://cdcvs.fnal.gov/cgi-bin/public-cvs/cvsweb-public.cgi/AnalysisFramework/Ana/CCQENu/ana_common/data/?cvsroot=mnvsoft
* These parameters are slightly altered
*
* FRESH:
* 10.5798
* 0.254032
* 0.50834
* 0.0571035
* 0.129051
* 0.875287
*/
if (fDebugStatements) {
std::cout << "Using MINERvA Gaussian" << std::endl;
}
double norm = vals[kPosNorm];
double meanq0 = vals[kPosTilt];
double meanq3 = vals[kPosPq0];
double sigmaq0 = vals[kPosWq0];
double sigmaq3 = vals[kPosPq3];
double corr = vals[kPosWq3];
double z = (q0 - meanq0)*(q0 - meanq0) /sigmaq0/sigmaq0
+ (q3 - meanq3)*(q3 - meanq3) / sigmaq3/sigmaq3
- 2*corr*(q0-meanq0)*(q3-meanq3)/ (sigmaq0 * sigmaq3);
double ret = norm*exp( -0.5 * z / (1 - corr*corr) );
//Need to add 1 to the results
w = 1.0 + ret;
}
return w;
}
void GaussianModeCorr::SetDialValue(std::string name, double val) {
SetDialValue(Reweight::ConvDial(name, kCUSTOM), val);
}
void GaussianModeCorr::SetDialValue(int rwenum, double val) {
int curenum = rwenum % 1000;
// Check Handled
if (!IsHandled(curenum)) return;
// CCQE Setting
for (int i = kGaussianCorr_CCQE_norm; i <= kGaussianCorr_CCQE_Wq3; i++) {
if (i == curenum) {
int index = i - kGaussianCorr_CCQE_norm;
fGausVal_CCQE[index] = val;
fApply_CCQE = true;
}
}
// 2p2h Setting
for (int i = kGaussianCorr_2p2h_norm; i <= kGaussianCorr_2p2h_Wq3; i++) {
if (i == curenum) {
int index = i - kGaussianCorr_2p2h_norm;
fGausVal_2p2h[index] = val;
fApply_2p2h = true;
}
}
// 2p2h_PPandNN Setting
for (int i = kGaussianCorr_2p2h_PPandNN_norm; i <= kGaussianCorr_2p2h_PPandNN_Wq3; i++) {
if (i == curenum) {
int index = i - kGaussianCorr_2p2h_PPandNN_norm;
fGausVal_2p2h_PPandNN[index] = val;
fApply_2p2h_PPandNN = true;
}
}
// 2p2h_NP Setting
for (int i = kGaussianCorr_2p2h_NP_norm; i <= kGaussianCorr_2p2h_NP_Wq3; i++) {
if (i == curenum) {
int index = i - kGaussianCorr_2p2h_NP_norm;
fGausVal_2p2h_NP[index] = val;
fApply_2p2h_NP = true;
}
}
// CC1pi Setting
for (int i = kGaussianCorr_CC1pi_norm; i <= kGaussianCorr_CC1pi_Wq3; i++) {
if (i == curenum) {
int index = i - kGaussianCorr_CC1pi_norm;
fGausVal_CC1pi[index] = val;
fApply_CC1pi = true;
}
}
if (curenum == kGaussianCorr_AllowSuppression) {
fAllowSuppression = (val > 0.5);
}
}
bool GaussianModeCorr::IsHandled(int rwenum) {
int curenum = rwenum % 1000;
switch (curenum) {
case kGaussianCorr_CCQE_norm:
case kGaussianCorr_CCQE_tilt:
case kGaussianCorr_CCQE_Pq0:
case kGaussianCorr_CCQE_Wq0:
case kGaussianCorr_CCQE_Pq3:
case kGaussianCorr_CCQE_Wq3:
case kGaussianCorr_2p2h_norm:
case kGaussianCorr_2p2h_tilt:
case kGaussianCorr_2p2h_Pq0:
case kGaussianCorr_2p2h_Wq0:
case kGaussianCorr_2p2h_Pq3:
case kGaussianCorr_2p2h_Wq3:
case kGaussianCorr_2p2h_PPandNN_norm:
case kGaussianCorr_2p2h_PPandNN_tilt:
case kGaussianCorr_2p2h_PPandNN_Pq0:
case kGaussianCorr_2p2h_PPandNN_Wq0:
case kGaussianCorr_2p2h_PPandNN_Pq3:
case kGaussianCorr_2p2h_PPandNN_Wq3:
case kGaussianCorr_2p2h_NP_norm:
case kGaussianCorr_2p2h_NP_tilt:
case kGaussianCorr_2p2h_NP_Pq0:
case kGaussianCorr_2p2h_NP_Wq0:
case kGaussianCorr_2p2h_NP_Pq3:
case kGaussianCorr_2p2h_NP_Wq3:
case kGaussianCorr_CC1pi_norm:
case kGaussianCorr_CC1pi_tilt:
case kGaussianCorr_CC1pi_Pq0:
case kGaussianCorr_CC1pi_Wq0:
case kGaussianCorr_CC1pi_Pq3:
case kGaussianCorr_CC1pi_Wq3:
case kGaussianCorr_AllowSuppression:
return true;
default:
return false;
}
}
diff --git a/src/Reweight/OscWeightEngine.cxx b/src/Reweight/OscWeightEngine.cxx
index bcb9292..1577175 100644
--- a/src/Reweight/OscWeightEngine.cxx
+++ b/src/Reweight/OscWeightEngine.cxx
@@ -1,329 +1,331 @@
// 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/>.
*******************************************************************************/
//#define DEBUG_OSC_WE
#include "OscWeightEngine.h"
#include <limits>
enum nuTypes {
kNuebarType = -1,
kNumubarType = -2,
kNutaubarType = -3,
kNueType = 1,
kNumuType = 2,
kNutauType = 3,
};
nuTypes GetNuType(int pdg) {
switch (pdg) {
case 16:
return kNutauType;
case 14:
return kNumuType;
case 12:
return kNueType;
case -16:
return kNutaubarType;
case -14:
return kNumubarType;
case -12:
return kNuebarType;
default: { THROW("Attempting to convert \"neutrino pdg\": " << pdg); }
}
}
OscWeightEngine::OscWeightEngine()
:
#ifdef __PROB3PP_ENABLED__
bp(),
#endif
theta12(0.825),
theta13(0.10),
theta23(1.0),
dm12(7.9e-5),
dm23(2.5e-3),
dcp(0.0),
LengthParam(0xdeadbeef),
TargetNuType(0),
ForceFromNuPDG(0) {
Config();
}
void OscWeightEngine::Config() {
std::vector<nuiskey> OscParam = Config::QueryKeys("OscParam");
if (OscParam.size() < 1) {
ERROR(WRN,
"Oscillation parameters specified but no OscParam element "
"configuring the experimental characteristics found.\nExpect at "
"least <OscParam baseline_km=\"XXX\" />. Pausing for "
"10...");
sleep(10);
return;
}
if (OscParam[0].Has("baseline_km")) {
LengthParamIsZenith = false;
LengthParam = OscParam[0].GetD("baseline_km");
constant_density = OscParam[0].Has("matter_density")
? OscParam[0].GetD("matter_density")
: 0xdeadbeef;
} else if (OscParam[0].Has("detection_zenith_deg")) {
LengthParamIsZenith = true;
static const double deg2rad = asin(1) / 90.0;
LengthParam = cos(OscParam[0].GetD("detection_zenith_deg") * deg2rad);
} else {
ERROR(WRN,
"It appeared that you wanted to set up an oscillation weight "
"branch, but it was not correctly configured. You need to specify "
"either: detection_zenith_deg or baseline_km attributes on the "
"OscParam element, and if baseline_km is specified, you can "
"optionally also set matter_density for oscillations through a "
"constant matter density. Pausing for 10...");
sleep(10);
return;
}
dm23 = OscParam[0].Has("dm23") ? OscParam[0].GetD("dm23") : dm23;
theta23 = OscParam[0].Has("sinsq_theta23") ? OscParam[0].GetD("sinsq_theta23")
: theta23;
theta13 = OscParam[0].Has("sinsq_theta13") ? OscParam[0].GetD("sinsq_theta13")
: theta13;
dm12 = OscParam[0].Has("dm12") ? OscParam[0].GetD("dm12") : dm12;
theta12 = OscParam[0].Has("sinsq_theta12") ? OscParam[0].GetD("sinsq_theta12")
: theta12;
dcp = OscParam[0].Has("dcp") ? OscParam[0].GetD("dcp") : dcp;
TargetNuType = OscParam[0].Has("TargetNuPDG")
? GetNuType(OscParam[0].GetI("TargetNuPDG"))
: 0;
ForceFromNuPDG = OscParam[0].Has("ForceFromNuPDG")
? GetNuType(OscParam[0].GetI("ForceFromNuPDG"))
: 0;
QLOG(FIT, "Configured oscillation weighter:");
if (LengthParamIsZenith) {
QLOG(FIT,
"Earth density profile with detection cos(zenith) = " << LengthParam);
} else {
if (constant_density != 0xdeadbeef) {
QLOG(FIT,
"Constant density with experimental baseline = " << LengthParam);
} else {
QLOG(FIT,
"Vacuum oscillations with experimental baseline = " << LengthParam);
}
}
params[0] = dm23;
params[1] = theta23;
params[2] = theta13;
params[3] = dm12;
params[4] = theta12;
params[5] = dcp;
QLOG(FIT, "\tdm23 : " << params[0]);
QLOG(FIT, "\tsinsq_theta23: " << params[1]);
QLOG(FIT, "\tsinsq_theta13: " << params[2]);
QLOG(FIT, "\tdm12 : " << params[3]);
QLOG(FIT, "\tsinsq_theta12: " << params[4]);
QLOG(FIT, "\tdcp : " << params[5]);
if (TargetNuType) {
QLOG(FIT, "\tTargetNuType: " << TargetNuType);
}
if (ForceFromNuPDG) {
QLOG(FIT, "\tForceFromNuPDG: " << ForceFromNuPDG);
}
#ifdef __PROB3PP_ENABLED__
bp.SetMNS(params[theta12_idx], params[theta13_idx], params[theta23_idx],
params[dm12_idx], params[dm23_idx], params[dcp_idx], 1, true, 2);
bp.DefinePath(LengthParam, 0);
- QLOG(FIT, "\tBaseline : " << (bp.GetBaseline() / 100.0) << " km.");
+ if (LengthParamIsZenith) {
+ QLOG(FIT, "\tBaseline : " << (bp.GetBaseline() / 100.0) << " km.");
+ }
#endif
}
void OscWeightEngine::IncludeDial(std::string name, double startval) {
#ifdef DEBUG_OSC_WE
std::cout << "IncludeDial: " << name << " at " << startval << std::endl;
#endif
int dial = SystEnumFromString(name);
if (!dial) {
THROW("OscWeightEngine passed dial: " << name
<< " that it does not understand.");
}
params[dial - 1] = startval;
}
void OscWeightEngine::SetDialValue(int nuisenum, double val) {
#ifdef DEBUG_OSC_WE
std::cout << "SetDial: " << (nuisenum % 1000) << " at " << val << std::endl;
#endif
fHasChanged = (params[(nuisenum % 1000) - 1] - val) >
std::numeric_limits<double>::epsilon();
params[(nuisenum % 1000) - 1] = val;
}
void OscWeightEngine::SetDialValue(std::string name, double val) {
#ifdef DEBUG_OSC_WE
std::cout << "SetDial: " << name << " at " << val << std::endl;
#endif
int dial = SystEnumFromString(name);
if (!dial) {
THROW("OscWeightEngine passed dial: " << name
<< " that it does not understand.");
}
fHasChanged =
(params[dial - 1] - val) > std::numeric_limits<double>::epsilon();
params[dial - 1] = val;
}
bool OscWeightEngine::IsDialIncluded(std::string name) {
return SystEnumFromString(name);
}
bool OscWeightEngine::IsDialIncluded(int nuisenum) {
return ((nuisenum % 1000) > 0) && ((nuisenum % 1000) < 6);
}
double OscWeightEngine::GetDialValue(std::string name) {
int dial = SystEnumFromString(name);
if (!dial) {
THROW("OscWeightEngine passed dial: " << name
<< " that it does not understand.");
}
return params[dial - 1];
}
double OscWeightEngine::GetDialValue(int nuisenum) {
if (!(nuisenum % 1000) || (nuisenum % 1000) > 6) {
THROW("OscWeightEngine passed dial enum: "
<< (nuisenum % 1000)
<< " that it does not understand, expected [1,6].");
}
return params[(nuisenum % 1000) - 1];
}
void OscWeightEngine::Reconfigure(bool silent) { fHasChanged = false; };
bool OscWeightEngine::NeedsEventReWeight() {
if (fHasChanged) {
return true;
}
return false;
}
double OscWeightEngine::CalcWeight(BaseFitEvt* evt) {
static bool Warned = false;
if (evt->probe_E == 0xdeadbeef) {
if (!Warned) {
ERROR(WRN,
"Oscillation weights asked for but using 'litemode' or "
"unsupported generator input. Pasuing for 10...");
sleep(10);
Warned = true;
}
return 1;
}
return CalcWeight(evt->probe_E * 1E-3, evt->probe_pdg);
}
double OscWeightEngine::CalcWeight(double ENu, int PDGNu, int TargetPDGNu) {
if (LengthParam == 0xdeadbeef) { // not configured.
return 1;
}
#ifdef __PROB3PP_ENABLED__
int NuType = (ForceFromNuPDG != 0) ? ForceFromNuPDG : GetNuType(PDGNu);
bp.SetMNS(params[theta12_idx], params[theta13_idx], params[theta23_idx],
params[dm12_idx], params[dm23_idx], params[dcp_idx], ENu, true,
NuType);
int pmt = 0;
double prob_weight = 1;
TargetPDGNu = (TargetPDGNu == -1) ? (TargetNuType ? TargetNuType : NuType)
: GetNuType(TargetPDGNu);
if (LengthParamIsZenith) { // Use earth density
bp.DefinePath(LengthParam, 0);
bp.propagate(NuType);
pmt = 0;
prob_weight = bp.GetProb(NuType, TargetPDGNu);
} else {
if (constant_density != 0xdeadbeef) {
bp.propagateLinear(NuType, LengthParam, constant_density);
pmt = 1;
prob_weight = bp.GetProb(NuType, TargetPDGNu);
} else {
pmt = 2;
prob_weight =
bp.GetVacuumProb(NuType, TargetPDGNu, ENu * 1E-3, LengthParam);
}
}
#ifdef DEBUG_OSC_WE
if (prob_weight != prob_weight) {
THROW("Calculated bad prob weight: " << prob_weight << "(Osc Type: " << pmt
<< " -- " << NuType << " -> "
<< TargetPDGNu << ")");
}
if (prob_weight > 1) {
THROW("Calculated bad prob weight: " << prob_weight << "(Osc Type: " << pmt
<< " -- " << NuType << " -> "
<< TargetPDGNu << ")");
}
std::cout << NuType << " -> " << TargetPDGNu << ": " << ENu << " = "
<< prob_weight << "%%." << std::endl;
#endif
return prob_weight;
#else
return 1;
#endif
}
int OscWeightEngine::SystEnumFromString(std::string const& name) {
if (name == "dm23") {
return 1;
} else if (name == "sinsq_theta23") {
return 2;
} else if (name == "sinsq_theta13") {
return 3;
} else if (name == "dm12") {
return 4;
} else if (name == "sinsq_theta12") {
return 5;
} else if (name == "dcp") {
return 6;
} else {
return 0;
}
}
void OscWeightEngine::Print() {
std::cout << "OscWeightEngine: " << std::endl;
std::cout << "\t theta12: " << params[theta12_idx] << std::endl;
std::cout << "\t theta13: " << params[theta13_idx] << std::endl;
std::cout << "\t theta23: " << params[theta23_idx] << std::endl;
std::cout << "\t dm12: " << params[dm12_idx] << std::endl;
std::cout << "\t dm23: " << params[dm23_idx] << std::endl;
std::cout << "\t dcp: " << params[dcp_idx] << std::endl;
}
diff --git a/src/Reweight/OscWeightEngine.h b/src/Reweight/OscWeightEngine.h
index 8cacff7..774fb99 100644
--- a/src/Reweight/OscWeightEngine.h
+++ b/src/Reweight/OscWeightEngine.h
@@ -1,143 +1,144 @@
// 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 "FitLogger.h"
#include "FitEvent.h"
#include "PhysConst.h"
#include "WeightEngineBase.h"
#ifdef __PROB3PP_ENABLED__
#include "BargerPropagator.h"
#endif
#include <cmath>
#ifdef __PROB3PP_ENABLED__
class BG : public BargerPropagator {
public:
BG() : BargerPropagator(){};
double GetBaseline() { return Earth->get_Pathlength(); }
};
#endif
class OscWeightEngine : public WeightEngineBase {
enum params {
dm23_idx = 0,
theta23_idx,
theta13_idx,
dm12_idx,
theta12_idx,
dcp_idx,
};
#ifdef __PROB3PP_ENABLED__
BG bp;
#endif
//******************************* Osc params ******************************
double theta12;
double theta13;
double theta23;
/// The 1-2 mass squared splitting (small) [eV]
double dm12;
/// The 2-3 mass squared splitting (large) [eV]
double dm23;
/// The PMNS CP-violating phase
double dcp;
///\brief The constant matter density used for simple given baseline
/// oscillation [g/cm^3]
double constant_density;
/// Whether LengthParam corresponds to a Zenith or a baseline.
///
/// If we just want to calculate the osc. prob. with a constant matter density
/// then this should be false and constant_density should be set
/// (or 0 for vacuum prob).
bool LengthParamIsZenith;
/// Either a path length or a post oscillation zenith angle
///
/// N.B. For a beamline that has a dip angle of X degrees, the post
/// oscillation zenith angle will be 90+X degrees.
double LengthParam;
/// Holds current value of oscillation parameters.
double params[6];
/// The oscillation target type
///
/// If unspecified in the <OscParam /> element, it will default to
/// disappearance probability.
int TargetNuType;
/// The initial neutrino species
///
/// If unspecified in the <OscParam /> element, it will be determined by
/// the incoming events.
int ForceFromNuPDG;
public:
OscWeightEngine();
/// Configures oscillation parameters from input xml file.
///
/// Osc parameters configured from OscParam XML element as:
/// <nuisance>
/// <OscParam dm23="XX" dm12="XX" theta23="XX" theta12="XX" theta13="XX"
/// dcp="XX" matter_density="XX" baseline="XX" detection_zenith_deg="XX"
/// TargetNuPDG="[12,14,16,-12,-14,-16]"/>
/// </nuisance>
/// If matter_density and baseline are present, then oscillation probability
/// is calculated for a constant matter density.
/// If detection_zenith_deg is present, then the baseline and density are
/// calculated from the density profile and radius of the earth.
/// If none are present, a vacuum oscillation is calculated.
/// If TargetNuPDG is unspecified, oscillation will default to
/// disappearance probability.
void Config();
// Functions requiring Override
void IncludeDial(std::string name, double startval);
void SetDialValue(int nuisenum, double val);
void SetDialValue(std::string name, double val);
bool IsDialIncluded(std::string name);
bool IsDialIncluded(int nuisenum);
double GetDialValue(std::string name);
double GetDialValue(int nuisenum);
void Reconfigure(bool silent);
bool NeedsEventReWeight();
double CalcWeight(BaseFitEvt* evt);
+ /// ENu [GeV]
double CalcWeight(double ENu, int PDGNu, int TargetPDGNu = -1);
static int SystEnumFromString(std::string const& name);
void Print();
};
diff --git a/src/Routines/MinimizerRoutines.cxx b/src/Routines/MinimizerRoutines.cxx
index 24cd30d..19acb7f 100755
--- a/src/Routines/MinimizerRoutines.cxx
+++ b/src/Routines/MinimizerRoutines.cxx
@@ -1,1506 +1,1517 @@
// 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 "MinimizerRoutines.h"
#include "Simple_MH_Sampler.h"
/*
Constructor/Destructor
*/
//************************
void MinimizerRoutines::Init() {
//************************
fInputFile = "";
fInputRootFile = NULL;
fOutputFile = "";
fOutputRootFile = NULL;
fCovar = NULL;
fCovFree = NULL;
fCorrel = NULL;
fCorFree = NULL;
fDecomp = NULL;
fDecFree = NULL;
fStrategy = "Migrad,FixAtLimBreak,Migrad";
fRoutines.clear();
fCardFile = "";
fFakeDataInput = "";
fSampleFCN = NULL;
fMinimizer = NULL;
fMinimizerFCN = NULL;
fCallFunctor = NULL;
fAllowedRoutines =
("Migrad,Simplex,Combined,"
"Brute,Fumili,ConjugateFR,"
"ConjugatePR,BFGS,BFGS2,"
"SteepDesc,GSLSimAn,FixAtLim,FixAtLimBreak,"
"Chi2Scan1D,Chi2Scan2D,Contours,ErrorBands,"
"DataToys,MCMC");
};
//*************************************
MinimizerRoutines::~MinimizerRoutines(){
//*************************************
};
/*
Input Functions
*/
//*************************************
+MinimizerRoutines::MinimizerRoutines() {
+//*************************************
+ Init();
+}
+
+//*************************************
MinimizerRoutines::MinimizerRoutines(int argc, char* argv[]) {
//*************************************
// Initialise Defaults
Init();
nuisconfig configuration = Config::Get();
// Default containers
std::string cardfile = "";
std::string maxevents = "-1";
int errorcount = 0;
int verbocount = 0;
std::vector<std::string> xmlcmds;
std::vector<std::string> configargs;
// Make easier to handle arguments.
std::vector<std::string> args = GeneralUtils::LoadCharToVectStr(argc, argv);
ParserUtils::ParseArgument(args, "-c", fCardFile, true);
ParserUtils::ParseArgument(args, "-o", fOutputFile, false, false);
ParserUtils::ParseArgument(args, "-n", maxevents, false, false);
ParserUtils::ParseArgument(args, "-f", fStrategy, false, false);
ParserUtils::ParseArgument(args, "-d", fFakeDataInput, false, false);
ParserUtils::ParseArgument(args, "-i", xmlcmds);
ParserUtils::ParseArgument(args, "-q", configargs);
ParserUtils::ParseCounter(args, "e", errorcount);
ParserUtils::ParseCounter(args, "v", verbocount);
ParserUtils::CheckBadArguments(args);
// Add extra defaults if none given
if (fCardFile.empty() and xmlcmds.empty()) {
ERR(FTL) << "No input supplied!" << std::endl;
throw;
}
if (fOutputFile.empty() and !fCardFile.empty()) {
fOutputFile = fCardFile + ".root";
ERR(WRN) << "No output supplied so saving it to: " << fOutputFile
<< std::endl;
} else if (fOutputFile.empty()) {
ERR(FTL) << "No output file or cardfile supplied!" << std::endl;
throw;
}
// Configuration Setup =============================
// Check no comp key is available
nuiskey fCompKey;
if (Config::Get().GetNodes("nuiscomp").empty()) {
fCompKey = Config::Get().CreateNode("nuiscomp");
} else {
fCompKey = Config::Get().GetNodes("nuiscomp")[0];
}
- if (!fCardFile.empty()) fCompKey.Set("cardfile", fCardFile);
+ if (!fCardFile.empty()) fCompKey.Set("cardfile", fCardFile);
if (!fOutputFile.empty()) fCompKey.Set("outputfile", fOutputFile);
- if (!fStrategy.empty()) fCompKey.Set("strategy", fStrategy);
+ if (!fStrategy.empty()) fCompKey.Set("strategy", fStrategy);
// Load XML Cardfile
- configuration.LoadSettings( fCompKey.GetS("cardfile"), "");
+ configuration.LoadSettings(fCompKey.GetS("cardfile"), "");
// Add Config Args
for (size_t i = 0; i < configargs.size(); i++) {
configuration.OverrideConfig(configargs[i]);
}
if (maxevents.compare("-1")) {
configuration.OverrideConfig("MAXEVENTS=" + maxevents);
}
// Finish configuration XML
configuration.FinaliseSettings(fCompKey.GetS("outputfile") + ".xml");
// Add Error Verbo Lines
verbocount += Config::GetParI("VERBOSITY");
errorcount += Config::GetParI("ERROR");
std::cout << "[ NUISANCE ]: Setting VERBOSITY=" << verbocount << std::endl;
std::cout << "[ NUISANCE ]: Setting ERROR=" << errorcount << std::endl;
// FitPar::log_verb = verbocount;
SETVERBOSITY(verbocount);
// ERR_VERB(errorcount);
// Minimizer Setup ========================================
fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE");
SetupMinimizerFromXML();
SetupCovariance();
SetupRWEngine();
SetupFCN();
return;
};
//*************************************
void MinimizerRoutines::SetupMinimizerFromXML() {
//*************************************
LOG(FIT) << "Setting up nuismin" << std::endl;
// Setup Parameters ------------------------------------------
std::vector<nuiskey> parkeys = Config::QueryKeys("parameter");
if (!parkeys.empty()) {
LOG(FIT) << "Number of parameters : " << parkeys.size() << std::endl;
}
for (size_t i = 0; i < parkeys.size(); i++) {
nuiskey key = parkeys.at(i);
// Check for type,name,nom
if (!key.Has("type")) {
ERR(FTL) << "No type given for parameter " << i << std::endl;
throw;
} else if (!key.Has("name")) {
ERR(FTL) << "No name given for parameter " << i << std::endl;
throw;
} else if (!key.Has("nominal")) {
ERR(FTL) << "No nominal given for parameter " << i << std::endl;
throw;
}
// Get Inputs
std::string partype = key.GetS("type");
std::string parname = key.GetS("name");
double parnom = key.GetD("nominal");
double parlow = parnom - 1;
double parhigh = parnom + 1;
double parstep = 1;
// Override state if none given
if (!key.Has("state")) {
key.SetS("state", "FIX");
}
std::string parstate = key.GetS("state");
// Extra limits
if (key.Has("low")) {
parlow = key.GetD("low");
parhigh = key.GetD("high");
parstep = key.GetD("step");
LOG(FIT) << "Read " << partype << " : " << parname << " = " << parnom
<< " : " << parlow << " < p < " << parhigh << " : " << parstate
<< std::endl;
} else {
LOG(FIT) << "Read " << partype << " : " << parname << " = " << parnom
<< " : " << parstate << std::endl;
}
// Run Parameter Conversion if needed
if (parstate.find("ABS") != std::string::npos) {
+ double opnom = parnom;
+ double oparstep = parstep;
parnom = FitBase::RWAbsToSigma(partype, parname, parnom);
parlow = FitBase::RWAbsToSigma(partype, parname, parlow);
parhigh = FitBase::RWAbsToSigma(partype, parname, parhigh);
- parstep = FitBase::RWAbsToSigma(partype, parname, parstep);
+ parstep =
+ FitBase::RWAbsToSigma(partype, parname, opnom + parstep) - parnom;
+ std::cout << "ParStep: " << parstep << " (" << oparstep << ")."
+ << std::endl;
} else if (parstate.find("FRAC") != std::string::npos) {
parnom = FitBase::RWFracToSigma(partype, parname, parnom);
parlow = FitBase::RWFracToSigma(partype, parname, parlow);
parhigh = FitBase::RWFracToSigma(partype, parname, parhigh);
parstep = FitBase::RWFracToSigma(partype, parname, parstep);
}
// Push into vectors
fParams.push_back(parname);
fTypeVals[parname] = FitBase::ConvDialType(partype);
- ;
+
fStartVals[parname] = parnom;
fCurVals[parname] = parnom;
fErrorVals[parname] = 0.0;
fStateVals[parname] = parstate;
bool fixstate = parstate.find("FIX") != std::string::npos;
fFixVals[parname] = fixstate;
fStartFixVals[parname] = fFixVals[parname];
fMinVals[parname] = parlow;
fMaxVals[parname] = parhigh;
fStepVals[parname] = parstep;
}
// Setup Samples ----------------------------------------------
std::vector<nuiskey> samplekeys = Config::QueryKeys("sample");
if (!samplekeys.empty()) {
LOG(FIT) << "Number of samples : " << samplekeys.size() << std::endl;
}
for (size_t i = 0; i < samplekeys.size(); i++) {
nuiskey key = samplekeys.at(i);
// Get Sample Options
std::string samplename = key.GetS("name");
std::string samplefile = key.GetS("input");
std::string sampletype = key.Has("type") ? key.GetS("type") : "DEFAULT";
double samplenorm = key.Has("norm") ? key.GetD("norm") : 1.0;
// Print out
LOG(FIT) << "Read sample info " << i << " : " << samplename << std::endl
<< "\t\t input -> " << samplefile << std::endl
<< "\t\t state -> " << sampletype << std::endl
<< "\t\t norm -> " << samplenorm << std::endl;
// If FREE add to parameters otherwise continue
if (sampletype.find("FREE") == std::string::npos) {
continue;
}
// Form norm dial from samplename + sampletype + "_norm";
std::string normname = samplename + "_norm";
// Check normname not already present
if (fTypeVals.find(normname) != fTypeVals.end()) {
continue;
}
// Add new norm dial to list if its passed above checks
fParams.push_back(normname);
fTypeVals[normname] = kNORM;
fStateVals[normname] = sampletype;
fStartVals[normname] = samplenorm;
fCurVals[normname] = samplenorm;
fErrorVals[normname] = 0.0;
fMinVals[normname] = 0.1;
fMaxVals[normname] = 10.0;
fStepVals[normname] = 0.5;
bool state = sampletype.find("FREE") == std::string::npos;
fFixVals[normname] = state;
fStartFixVals[normname] = state;
}
// Setup Fake Parameters -----------------------------
std::vector<nuiskey> fakekeys = Config::QueryKeys("fakeparameter");
if (!fakekeys.empty()) {
LOG(FIT) << "Number of fake parameters : " << fakekeys.size() << std::endl;
}
for (size_t i = 0; i < fakekeys.size(); i++) {
nuiskey key = fakekeys.at(i);
// Check for type,name,nom
if (!key.Has("name")) {
ERR(FTL) << "No name given for fakeparameter " << i << std::endl;
throw;
} else if (!key.Has("nom")) {
ERR(FTL) << "No nominal given for fakeparameter " << i << std::endl;
throw;
}
// Get Inputs
std::string parname = key.GetS("name");
double parnom = key.GetD("nom");
// Push into vectors
fFakeVals[parname] = parnom;
}
}
/*
Setup Functions
*/
//*************************************
void MinimizerRoutines::SetupRWEngine() {
//*************************************
for (UInt_t i = 0; i < fParams.size(); i++) {
std::string name = fParams[i];
FitBase::GetRW()->IncludeDial(name, fTypeVals.at(name));
}
UpdateRWEngine(fStartVals);
return;
}
//*************************************
void MinimizerRoutines::SetupFCN() {
//*************************************
LOG(FIT) << "Making the jointFCN" << std::endl;
if (fSampleFCN) delete fSampleFCN;
// fSampleFCN = new JointFCN(fCardFile, fOutputRootFile);
fSampleFCN = new JointFCN(fOutputRootFile);
SetFakeData();
fMinimizerFCN = new MinimizerFCN(fSampleFCN);
fCallFunctor = new ROOT::Math::Functor(*fMinimizerFCN, fParams.size());
fSampleFCN->CreateIterationTree("fit_iterations", FitBase::GetRW());
return;
}
//******************************************
void MinimizerRoutines::SetupFitter(std::string routine) {
//******************************************
// Make the fitter
std::string fitclass = "";
std::string fittype = "";
bool UseMCMC = false;
// Get correct types
if (!routine.compare("Migrad")) {
fitclass = "Minuit2";
fittype = "Migrad";
} else if (!routine.compare("Simplex")) {
fitclass = "Minuit2";
fittype = "Simplex";
} else if (!routine.compare("Combined")) {
fitclass = "Minuit2";
fittype = "Combined";
} else if (!routine.compare("Brute")) {
fitclass = "Minuit2";
fittype = "Scan";
} else if (!routine.compare("Fumili")) {
fitclass = "Minuit2";
fittype = "Fumili";
} else if (!routine.compare("ConjugateFR")) {
fitclass = "GSLMultiMin";
fittype = "ConjugateFR";
} else if (!routine.compare("ConjugatePR")) {
fitclass = "GSLMultiMin";
fittype = "ConjugatePR";
} else if (!routine.compare("BFGS")) {
fitclass = "GSLMultiMin";
fittype = "BFGS";
} else if (!routine.compare("BFGS2")) {
fitclass = "GSLMultiMin";
fittype = "BFGS2";
} else if (!routine.compare("SteepDesc")) {
fitclass = "GSLMultiMin";
fittype = "SteepestDescent";
// } else if (!routine.compare("GSLMulti")) { fitclass = "GSLMultiFit";
// fittype = ""; // Doesn't work out of the box
} else if (!routine.compare("GSLSimAn")) {
fitclass = "GSLSimAn";
fittype = "";
} else if (!routine.compare("MCMC")) {
UseMCMC = true;
}
// make minimizer
if (fMinimizer) delete fMinimizer;
if (UseMCMC) {
fMinimizer = new Simple_MH_Sampler();
} else {
fMinimizer = ROOT::Math::Factory::CreateMinimizer(fitclass, fittype);
}
fMinimizer->SetMaxFunctionCalls(
FitPar::Config().GetParI("MAXCALLS"));
if (!routine.compare("Brute")) {
fMinimizer->SetMaxFunctionCalls(fParams.size() * fParams.size() * 4);
fMinimizer->SetMaxIterations(fParams.size() * fParams.size() * 4);
}
fMinimizer->SetMaxIterations(
FitPar::Config().GetParI("MAXITERATIONS"));
fMinimizer->SetTolerance(FitPar::Config().GetParD("TOLERANCE"));
fMinimizer->SetStrategy(FitPar::Config().GetParI("STRATEGY"));
fMinimizer->SetFunction(*fCallFunctor);
int ipar = 0;
// Add Fit Parameters
for (UInt_t i = 0; i < fParams.size(); i++) {
std::string syst = fParams.at(i);
bool fixed = true;
double vstart, vstep, vlow, vhigh;
vstart = vstep = vlow = vhigh = 0.0;
if (fCurVals.find(syst) != fCurVals.end()) vstart = fCurVals.at(syst);
if (fMinVals.find(syst) != fMinVals.end()) vlow = fMinVals.at(syst);
if (fMaxVals.find(syst) != fMaxVals.end()) vhigh = fMaxVals.at(syst);
if (fStepVals.find(syst) != fStepVals.end()) vstep = fStepVals.at(syst);
if (fFixVals.find(syst) != fFixVals.end()) fixed = fFixVals.at(syst);
// fix for errors
if (vhigh == vlow) vhigh += 1.0;
fMinimizer->SetVariable(ipar, syst, vstart, vstep);
fMinimizer->SetVariableLimits(ipar, vlow, vhigh);
if (fixed) {
fMinimizer->FixVariable(ipar);
LOG(FIT) << "Fixed Param: " << syst << std::endl;
} else {
LOG(FIT) << "Free Param: " << syst << " Start:" << vstart
<< " Range:" << vlow << " to " << vhigh << " Step:" << vstep
<< std::endl;
}
ipar++;
}
LOG(FIT) << "Setup Minimizer: " << fMinimizer->NDim() << "(NDim) "
<< fMinimizer->NFree() << "(NFree)" << std::endl;
return;
}
//*************************************
// Set fake data from user input
void MinimizerRoutines::SetFakeData() {
//*************************************
// If the fake data input field (-d) isn't provided, return to caller
if (fFakeDataInput.empty()) return;
// If user specifies -d MC we set the data to the MC
// User can also specify fake data parameters to reweight by doing
// "fake_parameter" in input card file
// "fake_parameter" gets read in ReadCard function (reads to fFakeVals)
if (fFakeDataInput.compare("MC") == 0) {
LOG(FIT) << "Setting fake data from MC starting prediction." << std::endl;
// fFakeVals get read in in ReadCard
UpdateRWEngine(fFakeVals);
// Reconfigure the reweight engine
FitBase::GetRW()->Reconfigure();
// Reconfigure all the samples to the new reweight
fSampleFCN->ReconfigureAllEvents();
// Feed on and set the fake-data in each measurement class
fSampleFCN->SetFakeData("MC");
// Changed the reweight engine values back to the current values
// So we start the fit at a different value than what we set the fake-data
// to
UpdateRWEngine(fCurVals);
LOG(FIT) << "Set all data to fake MC predictions." << std::endl;
} else {
fSampleFCN->SetFakeData(fFakeDataInput);
}
return;
}
/*
Fitting Functions
*/
//*************************************
void MinimizerRoutines::UpdateRWEngine(
std::map<std::string, double>& updateVals) {
//*************************************
for (UInt_t i = 0; i < fParams.size(); i++) {
std::string name = fParams[i];
if (updateVals.find(name) == updateVals.end()) continue;
FitBase::GetRW()->SetDialValue(name, updateVals.at(name));
}
FitBase::GetRW()->Reconfigure();
return;
}
//*************************************
void MinimizerRoutines::Run() {
//*************************************
LOG(FIT) << "Running MinimizerRoutines : " << fStrategy << std::endl;
if (FitPar::Config().GetParB("save_nominal")) {
SaveNominal();
}
// Parse given routines
fRoutines = GeneralUtils::ParseToStr(fStrategy, ",");
if (fRoutines.empty()) {
ERR(FTL) << "Trying to run MinimizerRoutines with no routines given!"
<< std::endl;
throw;
}
for (UInt_t i = 0; i < fRoutines.size(); i++) {
std::string routine = fRoutines.at(i);
int fitstate = kFitUnfinished;
LOG(FIT) << "Running Routine: " << routine << std::endl;
// Try Routines
if (routine.find("LowStat") != std::string::npos)
LowStatRoutine(routine);
else if (routine == "FixAtLim")
FixAtLimit();
else if (routine == "FixAtLimBreak")
fitstate = FixAtLimit();
else if (routine.find("ErrorBands") != std::string::npos)
GenerateErrorBands();
else if (routine.find("DataToys") != std::string::npos)
ThrowDataToys();
else if (!routine.compare("Chi2Scan1D"))
Create1DScans();
else if (!routine.compare("Chi2Scan2D"))
Chi2Scan2D();
else
fitstate = RunFitRoutine(routine);
// If ending early break here
if (fitstate == kFitFinished || fitstate == kNoChange) {
LOG(FIT) << "Ending fit routines loop." << std::endl;
break;
}
}
return;
}
//*************************************
int MinimizerRoutines::RunFitRoutine(std::string routine) {
//*************************************
int endfits = kFitUnfinished;
// set fitter at the current start values
fOutputRootFile->cd();
SetupFitter(routine);
// choose what to do with the minimizer depending on routine.
if (!routine.compare("Migrad") or !routine.compare("Simplex") or
!routine.compare("Combined") or !routine.compare("Brute") or
!routine.compare("Fumili") or !routine.compare("ConjugateFR") or
!routine.compare("ConjugatePR") or !routine.compare("BFGS") or
!routine.compare("BFGS2") or !routine.compare("SteepDesc") or
// !routine.compare("GSLMulti") or
!routine.compare("GSLSimAn") or !routine.compare("MCMC")) {
if (fMinimizer->NFree() > 0) {
LOG(FIT) << fMinimizer->Minimize() << std::endl;
GetMinimizerState();
}
}
// other otptions
else if (!routine.compare("Contour")) {
CreateContours();
}
return endfits;
}
//*************************************
void MinimizerRoutines::PrintState() {
//*************************************
LOG(FIT) << "------------" << std::endl;
// Count max size
int maxcount = 0;
for (UInt_t i = 0; i < fParams.size(); i++) {
maxcount = max(int(fParams[i].size()), maxcount);
}
// Header
LOG(FIT) << " # " << left << setw(maxcount) << "Parameter "
<< " = " << setw(10) << "Value"
<< " +- " << setw(10) << "Error"
<< " " << setw(8) << "(Units)"
<< " " << setw(10) << "Conv. Val"
<< " +- " << setw(10) << "Conv. Err"
<< " " << setw(8) << "(Units)" << std::endl;
// Parameters
for (UInt_t i = 0; i < fParams.size(); i++) {
std::string syst = fParams.at(i);
std::string typestr = FitBase::ConvDialType(fTypeVals[syst]);
std::string curunits = "(sig.)";
double curval = fCurVals[syst];
double curerr = fErrorVals[syst];
if (fStateVals[syst].find("ABS") != std::string::npos) {
curval = FitBase::RWSigmaToAbs(typestr, syst, curval);
curerr = (FitBase::RWSigmaToAbs(typestr, syst, curerr) -
FitBase::RWSigmaToAbs(typestr, syst, 0.0));
curunits = "(Abs.)";
} else if (fStateVals[syst].find("FRAC") != std::string::npos) {
curval = FitBase::RWSigmaToFrac(typestr, syst, curval);
curerr = (FitBase::RWSigmaToFrac(typestr, syst, curerr) -
FitBase::RWSigmaToFrac(typestr, syst, 0.0));
curunits = "(Frac)";
}
std::string convunits = "(" + FitBase::GetRWUnits(typestr, syst) + ")";
double convval = FitBase::RWSigmaToAbs(typestr, syst, curval);
double converr = (FitBase::RWSigmaToAbs(typestr, syst, curerr) -
FitBase::RWSigmaToAbs(typestr, syst, 0.0));
std::ostringstream curparstring;
curparstring << " " << setw(3) << left << i << ". " << setw(maxcount)
<< syst << " = " << setw(10) << curval << " +- " << setw(10)
<< curerr << " " << setw(8) << curunits << " " << setw(10)
<< convval << " +- " << setw(10) << converr << " " << setw(8)
<< convunits;
LOG(FIT) << curparstring.str() << std::endl;
}
LOG(FIT) << "------------" << std::endl;
double like = fSampleFCN->GetLikelihood();
LOG(FIT) << std::left << std::setw(46) << "Likelihood for JointFCN: " << like
<< std::endl;
LOG(FIT) << "------------" << std::endl;
}
//*************************************
void MinimizerRoutines::GetMinimizerState() {
//*************************************
LOG(FIT) << "Minimizer State: " << std::endl;
// Get X and Err
const double* values = fMinimizer->X();
const double* errors = fMinimizer->Errors();
// int ipar = 0;
for (UInt_t i = 0; i < fParams.size(); i++) {
std::string syst = fParams.at(i);
fCurVals[syst] = values[i];
fErrorVals[syst] = errors[i];
}
PrintState();
// Covar
SetupCovariance();
if (fMinimizer->CovMatrixStatus() > 0) {
// Fill Full Covar
std::cout << "Filling covariance" << std::endl;
for (int i = 0; i < fCovar->GetNbinsX(); i++) {
for (int j = 0; j < fCovar->GetNbinsY(); j++) {
fCovar->SetBinContent(i + 1, j + 1, fMinimizer->CovMatrix(i, j));
}
}
int freex = 0;
int freey = 0;
for (int i = 0; i < fCovar->GetNbinsX(); i++) {
if (fMinimizer->IsFixedVariable(i)) continue;
freey = 0;
for (int j = 0; j < fCovar->GetNbinsY(); j++) {
if (fMinimizer->IsFixedVariable(j)) continue;
fCovFree->SetBinContent(freex + 1, freey + 1,
fMinimizer->CovMatrix(i, j));
freey++;
}
freex++;
}
fCorrel = PlotUtils::GetCorrelationPlot(fCovar, "correlation");
fDecomp = PlotUtils::GetDecompPlot(fCovar, "decomposition");
if (fMinimizer->NFree() > 0) {
fCorFree = PlotUtils::GetCorrelationPlot(fCovFree, "correlation_free");
fDecFree = PlotUtils::GetDecompPlot(fCovFree, "decomposition_free");
}
}
std::cout << "Got STATE" << std::endl;
return;
};
//*************************************
void MinimizerRoutines::LowStatRoutine(std::string routine) {
//*************************************
LOG(FIT) << "Running Low Statistics Routine: " << routine << std::endl;
int lowstatsevents = FitPar::Config().GetParI("LOWSTATEVENTS");
int maxevents = FitPar::Config().GetParI("MAXEVENTS");
int verbosity = FitPar::Config().GetParI("VERBOSITY");
std::string trueroutine = routine;
std::string substring = "LowStat";
trueroutine.erase(trueroutine.find(substring), substring.length());
// Set MAX EVENTS=1000
Config::SetPar("MAXEVENTS", lowstatsevents);
Config::SetPar("VERBOSITY", 3);
SetupFCN();
RunFitRoutine(trueroutine);
Config::SetPar("MAXEVENTS", maxevents);
SetupFCN();
Config::SetPar("VERBOSITY", verbosity);
return;
}
//*************************************
void MinimizerRoutines::Create1DScans() {
//*************************************
// 1D Scan Routine
// Steps through all free parameters about nominal using the step size
// Creates a graph for each free parameter
// At the current point create a 1D Scan for all parametes (Uncorrelated)
for (UInt_t i = 0; i < fParams.size(); i++) {
if (fFixVals[fParams[i]]) continue;
LOG(FIT) << "Running 1D Scan for " << fParams[i] << std::endl;
fSampleFCN->CreateIterationTree(fParams[i] + "_scan1D_iterations",
FitBase::GetRW());
double scanmiddlepoint = fCurVals[fParams[i]];
// Determine N points needed
double limlow = fMinVals[fParams[i]];
double limhigh = fMaxVals[fParams[i]];
double step = fStepVals[fParams[i]];
int npoints = int(fabs(limhigh - limlow) / (step + 0.));
TH1D* contour =
new TH1D(("Chi2Scan1D_" + fParams[i]).c_str(),
("Chi2Scan1D_" + fParams[i] + ";" + fParams[i]).c_str(),
npoints, limlow, limhigh);
// Fill bins
for (int x = 0; x < contour->GetNbinsX(); x++) {
// Set X Val
fCurVals[fParams[i]] = contour->GetXaxis()->GetBinCenter(x + 1);
// Run Eval
double* vals = FitUtils::GetArrayFromMap(fParams, fCurVals);
double chi2 = fSampleFCN->DoEval(vals);
delete vals;
// Fill Contour
contour->SetBinContent(x + 1, chi2);
}
// Save contour
contour->Write();
// Reset Parameter
fCurVals[fParams[i]] = scanmiddlepoint;
// Save TTree
fSampleFCN->WriteIterationTree();
}
return;
}
//*************************************
void MinimizerRoutines::Chi2Scan2D() {
//*************************************
// Chi2 Scan 2D
// Creates a 2D chi2 scan by stepping through all free parameters
// Works for all pairwise combos of free parameters
// Scan I
for (UInt_t i = 0; i < fParams.size(); i++) {
if (fFixVals[fParams[i]]) continue;
// Scan J
for (UInt_t j = 0; j < i; j++) {
if (fFixVals[fParams[j]]) continue;
fSampleFCN->CreateIterationTree(
fParams[i] + "_" + fParams[j] + "_" + "scan2D_iterations",
FitBase::GetRW());
double scanmid_i = fCurVals[fParams[i]];
double scanmid_j = fCurVals[fParams[j]];
double limlow_i = fMinVals[fParams[i]];
double limhigh_i = fMaxVals[fParams[i]];
double step_i = fStepVals[fParams[i]];
double limlow_j = fMinVals[fParams[j]];
double limhigh_j = fMaxVals[fParams[j]];
double step_j = fStepVals[fParams[j]];
int npoints_i = int(fabs(limhigh_i - limlow_i) / (step_i + 0.)) + 1;
int npoints_j = int(fabs(limhigh_j - limlow_j) / (step_j + 0.)) + 1;
TH2D* contour = new TH2D(
("Chi2Scan2D_" + fParams[i] + "_" + fParams[j]).c_str(),
("Chi2Scan2D_" + fParams[i] + "_" + fParams[j] + ";" + fParams[i] +
";" + fParams[j])
.c_str(),
npoints_i, limlow_i, limhigh_i, npoints_j, limlow_j, limhigh_j);
// Begin Scan
LOG(FIT) << "Running scan for " << fParams[i] << " " << fParams[j]
<< std::endl;
// Fill bins
for (int x = 0; x < contour->GetNbinsX(); x++) {
// Set X Val
fCurVals[fParams[i]] = contour->GetXaxis()->GetBinCenter(x + 1);
// Loop Y
for (int y = 0; y < contour->GetNbinsY(); y++) {
// Set Y Val
fCurVals[fParams[j]] = contour->GetYaxis()->GetBinCenter(y + 1);
// Run Eval
double* vals = FitUtils::GetArrayFromMap(fParams, fCurVals);
double chi2 = fSampleFCN->DoEval(vals);
delete vals;
// Fill Contour
contour->SetBinContent(x + 1, y + 1, chi2);
fCurVals[fParams[j]] = scanmid_j;
}
fCurVals[fParams[i]] = scanmid_i;
fCurVals[fParams[j]] = scanmid_j;
}
// Save contour
contour->Write();
// Save Iterations
fSampleFCN->WriteIterationTree();
}
}
return;
}
//*************************************
void MinimizerRoutines::CreateContours() {
//*************************************
// Use MINUIT for this if possible
ERR(FTL) << " Contours not yet implemented as it is really slow!"
<< std::endl;
throw;
return;
}
//*************************************
int MinimizerRoutines::FixAtLimit() {
//*************************************
bool fixedparam = false;
for (UInt_t i = 0; i < fParams.size(); i++) {
std::string syst = fParams.at(i);
if (fFixVals[syst]) continue;
double curVal = fCurVals.at(syst);
double minVal = fMinVals.at(syst);
double maxVal = fMinVals.at(syst);
if (fabs(curVal - minVal) < 0.0001) {
fCurVals[syst] = minVal;
fFixVals[syst] = true;
fixedparam = true;
}
if (fabs(maxVal - curVal) < 0.0001) {
fCurVals[syst] = maxVal;
fFixVals[syst] = true;
fixedparam = true;
}
}
if (!fixedparam) {
LOG(FIT) << "No dials needed fixing!" << std::endl;
return kNoChange;
} else
return kStateChange;
}
/*
Write Functions
*/
//*************************************
void MinimizerRoutines::SaveResults() {
//*************************************
fOutputRootFile->cd();
if (fMinimizer) {
SetupCovariance();
SaveMinimizerState();
}
SaveCurrentState();
}
//*************************************
void MinimizerRoutines::SaveMinimizerState() {
//*************************************
std::cout << "Saving Minimizer State" << std::endl;
if (!fMinimizer) {
ERR(FTL) << "Can't save minimizer state without min object" << std::endl;
throw;
}
// Save main fit tree
fSampleFCN->WriteIterationTree();
// Get Vals and Errors
GetMinimizerState();
// Save tree with fit status
std::vector<std::string> nameVect;
std::vector<double> valVect;
std::vector<double> errVect;
std::vector<double> minVect;
std::vector<double> maxVect;
std::vector<double> startVect;
std::vector<int> endfixVect;
std::vector<int> startfixVect;
// int NFREEPARS = fMinimizer->NFree();
int NPARS = fMinimizer->NDim();
int ipar = 0;
// Dial Vals
for (UInt_t i = 0; i < fParams.size(); i++) {
std::string name = fParams.at(i);
nameVect.push_back(name);
valVect.push_back(fCurVals.at(name));
errVect.push_back(fErrorVals.at(name));
minVect.push_back(fMinVals.at(name));
maxVect.push_back(fMaxVals.at(name));
startVect.push_back(fStartVals.at(name));
endfixVect.push_back(fFixVals.at(name));
startfixVect.push_back(fStartFixVals.at(name));
ipar++;
}
int NFREE = fMinimizer->NFree();
int NDIM = fMinimizer->NDim();
double CHI2 = fSampleFCN->GetLikelihood();
int NBINS = fSampleFCN->GetNDOF();
int NDOF = NBINS - NFREE;
// Write fit results
TTree* fit_tree = new TTree("fit_result", "fit_result");
fit_tree->Branch("parameter_names", &nameVect);
fit_tree->Branch("parameter_values", &valVect);
fit_tree->Branch("parameter_errors", &errVect);
fit_tree->Branch("parameter_min", &minVect);
fit_tree->Branch("parameter_max", &maxVect);
fit_tree->Branch("parameter_start", &startVect);
fit_tree->Branch("parameter_fix", &endfixVect);
fit_tree->Branch("parameter_startfix", &startfixVect);
fit_tree->Branch("CHI2", &CHI2, "CHI2/D");
fit_tree->Branch("NDOF", &NDOF, "NDOF/I");
fit_tree->Branch("NBINS", &NBINS, "NBINS/I");
fit_tree->Branch("NDIM", &NDIM, "NDIM/I");
fit_tree->Branch("NFREE", &NFREE, "NFREE/I");
fit_tree->Fill();
fit_tree->Write();
// Make dial variables
TH1D dialvar = TH1D("fit_dials", "fit_dials", NPARS, 0, NPARS);
TH1D startvar = TH1D("start_dials", "start_dials", NPARS, 0, NPARS);
TH1D minvar = TH1D("min_dials", "min_dials", NPARS, 0, NPARS);
TH1D maxvar = TH1D("max_dials", "max_dials", NPARS, 0, NPARS);
TH1D dialvarfree = TH1D("fit_dials_free", "fit_dials_free", NFREE, 0, NFREE);
TH1D startvarfree =
TH1D("start_dials_free", "start_dials_free", NFREE, 0, NFREE);
TH1D minvarfree = TH1D("min_dials_free", "min_dials_free", NFREE, 0, NFREE);
TH1D maxvarfree = TH1D("max_dials_free", "max_dials_free", NFREE, 0, NFREE);
int freecount = 0;
for (UInt_t i = 0; i < nameVect.size(); i++) {
std::string name = nameVect.at(i);
dialvar.SetBinContent(i + 1, valVect.at(i));
dialvar.SetBinError(i + 1, errVect.at(i));
dialvar.GetXaxis()->SetBinLabel(i + 1, name.c_str());
startvar.SetBinContent(i + 1, startVect.at(i));
startvar.GetXaxis()->SetBinLabel(i + 1, name.c_str());
minvar.SetBinContent(i + 1, minVect.at(i));
minvar.GetXaxis()->SetBinLabel(i + 1, name.c_str());
maxvar.SetBinContent(i + 1, maxVect.at(i));
maxvar.GetXaxis()->SetBinLabel(i + 1, name.c_str());
if (NFREE > 0) {
if (!startfixVect.at(i)) {
freecount++;
dialvarfree.SetBinContent(freecount, valVect.at(i));
dialvarfree.SetBinError(freecount, errVect.at(i));
dialvarfree.GetXaxis()->SetBinLabel(freecount, name.c_str());
startvarfree.SetBinContent(freecount, startVect.at(i));
startvarfree.GetXaxis()->SetBinLabel(freecount, name.c_str());
minvarfree.SetBinContent(freecount, minVect.at(i));
minvarfree.GetXaxis()->SetBinLabel(freecount, name.c_str());
maxvarfree.SetBinContent(freecount, maxVect.at(i));
maxvarfree.GetXaxis()->SetBinLabel(freecount, name.c_str());
}
}
}
// Save Dial Plots
dialvar.Write();
startvar.Write();
minvar.Write();
maxvar.Write();
if (NFREE > 0) {
dialvarfree.Write();
startvarfree.Write();
minvarfree.Write();
maxvarfree.Write();
}
// Save fit_status plot
TH1D statusplot = TH1D("fit_status", "fit_status", 8, 0, 8);
std::string fit_labels[8] = {"status", "cov_status", "maxiter",
"maxfunc", "iter", "func",
"precision", "tolerance"};
double fit_vals[8];
fit_vals[0] = fMinimizer->Status() + 0.;
fit_vals[1] = fMinimizer->CovMatrixStatus() + 0.;
fit_vals[2] = fMinimizer->MaxIterations() + 0.;
fit_vals[3] = fMinimizer->MaxFunctionCalls() + 0.;
fit_vals[4] = fMinimizer->NIterations() + 0.;
fit_vals[5] = fMinimizer->NCalls() + 0.;
fit_vals[6] = fMinimizer->Precision() + 0.;
fit_vals[7] = fMinimizer->Tolerance() + 0.;
for (int i = 0; i < 8; i++) {
statusplot.SetBinContent(i + 1, fit_vals[i]);
statusplot.GetXaxis()->SetBinLabel(i + 1, fit_labels[i].c_str());
}
statusplot.Write();
// Save Covars
if (fCovar) fCovar->Write();
if (fCovFree) fCovFree->Write();
if (fCorrel) fCorrel->Write();
if (fCorFree) fCorFree->Write();
if (fDecomp) fDecomp->Write();
if (fDecFree) fDecFree->Write();
return;
}
//*************************************
void MinimizerRoutines::SaveCurrentState(std::string subdir) {
//*************************************
LOG(FIT) << "Saving current full FCN predictions" << std::endl;
// Setup DIRS
TDirectory* curdir = gDirectory;
if (!subdir.empty()) {
TDirectory* newdir = (TDirectory*)gDirectory->mkdir(subdir.c_str());
newdir->cd();
}
FitBase::GetRW()->Reconfigure();
fSampleFCN->ReconfigureAllEvents();
fSampleFCN->Write();
// Change back to current DIR
curdir->cd();
return;
}
//*************************************
void MinimizerRoutines::SaveNominal() {
//*************************************
fOutputRootFile->cd();
LOG(FIT) << "Saving Nominal Predictions (be cautious with this)" << std::endl;
FitBase::GetRW()->Reconfigure();
SaveCurrentState("nominal");
};
//*************************************
void MinimizerRoutines::SavePrefit() {
//*************************************
fOutputRootFile->cd();
LOG(FIT) << "Saving Prefit Predictions" << std::endl;
UpdateRWEngine(fStartVals);
SaveCurrentState("prefit");
UpdateRWEngine(fCurVals);
};
/*
MISC Functions
*/
//*************************************
int MinimizerRoutines::GetStatus() {
//*************************************
return 0;
}
//*************************************
void MinimizerRoutines::SetupCovariance() {
//*************************************
// Remove covares if they exist
if (fCovar) delete fCovar;
if (fCovFree) delete fCovFree;
if (fCorrel) delete fCorrel;
if (fCorFree) delete fCorFree;
if (fDecomp) delete fDecomp;
if (fDecFree) delete fDecFree;
LOG(FIT) << "Building covariance matrix.." << std::endl;
int NFREE = 0;
int NDIM = 0;
// Get NFREE from min or from vals (for cases when doing throws)
if (fMinimizer) {
std::cout << "NFREE FROM MINIMIZER" << std::endl;
NFREE = fMinimizer->NFree();
NDIM = fMinimizer->NDim();
} else {
NDIM = fParams.size();
for (UInt_t i = 0; i < fParams.size(); i++) {
std::cout << "Getting Param " << fParams[i] << std::endl;
if (!fFixVals[fParams[i]]) NFREE++;
}
}
if (NDIM == 0) return;
LOG(FIT) << "NFREE == " << NFREE << std::endl;
fCovar = new TH2D("covariance", "covariance", NDIM, 0, NDIM, NDIM, 0, NDIM);
if (NFREE > 0) {
fCovFree = new TH2D("covariance_free", "covariance_free", NFREE, 0, NFREE,
NFREE, 0, NFREE);
} else {
fCovFree = NULL;
}
// Set Bin Labels
int countall = 0;
int countfree = 0;
for (UInt_t i = 0; i < fParams.size(); i++) {
std::cout << "Getting Param " << i << std::endl;
std::cout << "ParamI = " << fParams[i] << std::endl;
fCovar->GetXaxis()->SetBinLabel(countall + 1, fParams[i].c_str());
fCovar->GetYaxis()->SetBinLabel(countall + 1, fParams[i].c_str());
countall++;
if (!fFixVals[fParams[i]] and NFREE > 0) {
fCovFree->GetXaxis()->SetBinLabel(countfree + 1, fParams[i].c_str());
fCovFree->GetYaxis()->SetBinLabel(countfree + 1, fParams[i].c_str());
countfree++;
}
}
std::cout << "Filling Matrices" << std::endl;
fCorrel = PlotUtils::GetCorrelationPlot(fCovar, "correlation");
fDecomp = PlotUtils::GetDecompPlot(fCovar, "decomposition");
if (NFREE > 0) {
fCorFree = PlotUtils::GetCorrelationPlot(fCovFree, "correlation_free");
fDecFree = PlotUtils::GetDecompPlot(fCovFree, "decomposition_free");
} else {
fCorFree = NULL;
fDecFree = NULL;
}
std::cout << " Set the covariance" << std::endl;
return;
};
//*************************************
void MinimizerRoutines::ThrowCovariance(bool uniformly) {
//*************************************
std::vector<double> rands;
if (!fDecFree) {
ERR(WRN) << "Trying to throw 0 free parameters" << std::endl;
return;
}
// Generate Random Gaussians
for (Int_t i = 0; i < fDecFree->GetNbinsX(); i++) {
rands.push_back(gRandom->Gaus(0.0, 1.0));
}
// Reset Thrown Values
for (UInt_t i = 0; i < fParams.size(); i++) {
fThrownVals[fParams[i]] = fCurVals[fParams[i]];
}
// Loop and get decomp
for (Int_t i = 0; i < fDecFree->GetNbinsX(); i++) {
std::string parname = std::string(fDecFree->GetXaxis()->GetBinLabel(i + 1));
double mod = 0.0;
if (!uniformly) {
for (Int_t j = 0; j < fDecFree->GetNbinsY(); j++) {
mod += rands[j] * fDecFree->GetBinContent(j + 1, i + 1);
}
}
if (fCurVals.find(parname) != fCurVals.end()) {
if (uniformly)
fThrownVals[parname] =
gRandom->Uniform(fMinVals[parname], fMaxVals[parname]);
else {
fThrownVals[parname] = fCurVals[parname] + mod;
}
}
}
// Check Limits
for (UInt_t i = 0; i < fParams.size(); i++) {
std::string syst = fParams[i];
if (fFixVals[syst]) continue;
if (fThrownVals[syst] < fMinVals[syst]) fThrownVals[syst] = fMinVals[syst];
if (fThrownVals[syst] > fMaxVals[syst]) fThrownVals[syst] = fMaxVals[syst];
}
return;
};
//*************************************
void MinimizerRoutines::GenerateErrorBands() {
//*************************************
TDirectory* errorDIR = (TDirectory*)fOutputRootFile->mkdir("error_bands");
errorDIR->cd();
// Make a second file to store throws
std::string tempFileName = fOutputFile;
if (tempFileName.find(".root") != std::string::npos)
tempFileName.erase(tempFileName.find(".root"), 5);
tempFileName += ".throws.root";
TFile* tempfile = new TFile(tempFileName.c_str(), "RECREATE");
tempfile->cd();
int nthrows = FitPar::Config().GetParI("error_throws");
UpdateRWEngine(fCurVals);
fSampleFCN->ReconfigureAllEvents();
TDirectory* nominal = (TDirectory*)tempfile->mkdir("nominal");
nominal->cd();
fSampleFCN->Write();
TDirectory* outnominal = (TDirectory*)fOutputRootFile->mkdir("nominal_throw");
outnominal->cd();
fSampleFCN->Write();
errorDIR->cd();
TTree* parameterTree = new TTree("throws", "throws");
double chi2;
for (UInt_t i = 0; i < fParams.size(); i++)
parameterTree->Branch(fParams[i].c_str(), &fThrownVals[fParams[i]],
(fParams[i] + "/D").c_str());
parameterTree->Branch("chi2", &chi2, "chi2/D");
bool uniformly = FitPar::Config().GetParB("error_uniform");
// Run Throws and save
for (Int_t i = 0; i < nthrows; i++) {
TDirectory* throwfolder = (TDirectory*)tempfile->mkdir(Form("throw_%i", i));
throwfolder->cd();
// Generate Random Parameter Throw
ThrowCovariance(uniformly);
// Run Eval
double* vals = FitUtils::GetArrayFromMap(fParams, fThrownVals);
chi2 = fSampleFCN->DoEval(vals);
delete vals;
// Save the FCN
fSampleFCN->Write();
parameterTree->Fill();
}
errorDIR->cd();
fDecFree->Write();
fCovFree->Write();
parameterTree->Write();
delete parameterTree;
// Now go through the keys in the temporary file and look for TH1D, and TH2D
// plots
TIter next(nominal->GetListOfKeys());
TKey* key;
while ((key = (TKey*)next())) {
TClass* cl = gROOT->GetClass(key->GetClassName());
if (!cl->InheritsFrom("TH1D") and !cl->InheritsFrom("TH2D")) continue;
TH1D* baseplot = (TH1D*)key->ReadObj();
std::string plotname = std::string(baseplot->GetName());
int nbins = baseplot->GetNbinsX() * baseplot->GetNbinsY();
// Setup TProfile with RMS option
TProfile* tprof =
new TProfile((plotname + "_prof").c_str(), (plotname + "_prof").c_str(),
nbins, 0, nbins, "S");
// Setup The TTREE
double* bincontents;
bincontents = new double[nbins];
double* binlowest;
binlowest = new double[nbins];
double* binhighest;
binhighest = new double[nbins];
errorDIR->cd();
TTree* bintree =
new TTree((plotname + "_tree").c_str(), (plotname + "_tree").c_str());
for (Int_t i = 0; i < nbins; i++) {
bincontents[i] = 0.0;
binhighest[i] = 0.0;
binlowest[i] = 0.0;
bintree->Branch(Form("content_%i", i), &bincontents[i],
Form("content_%i/D", i));
}
for (Int_t i = 0; i < nthrows; i++) {
TH1* newplot =
(TH1*)tempfile->Get(Form(("throw_%i/" + plotname).c_str(), i));
for (Int_t j = 0; j < nbins; j++) {
tprof->Fill(j + 0.5, newplot->GetBinContent(j + 1));
bincontents[j] = newplot->GetBinContent(j + 1);
if (bincontents[j] < binlowest[j] or i == 0)
binlowest[j] = bincontents[j];
if (bincontents[j] > binhighest[j] or i == 0)
binhighest[j] = bincontents[j];
}
errorDIR->cd();
bintree->Fill();
delete newplot;
}
errorDIR->cd();
for (Int_t j = 0; j < nbins; j++) {
if (!uniformly) {
baseplot->SetBinError(j + 1, tprof->GetBinError(j + 1));
} else {
baseplot->SetBinContent(j + 1, (binlowest[j] + binhighest[j]) / 2.0);
baseplot->SetBinError(j + 1, (binhighest[j] - binlowest[j]) / 2.0);
}
}
errorDIR->cd();
baseplot->Write();
tprof->Write();
bintree->Write();
delete baseplot;
delete tprof;
delete bintree;
delete[] bincontents;
}
return;
};
void MinimizerRoutines::ThrowDataToys() {
LOG(FIT) << "Generating Toy Data Throws" << std::endl;
int verb = Config::GetParI("VERBOSITY");
SETVERBOSITY(FIT);
int nthrows = FitPar::Config().GetParI("NToyThrows");
double maxlike = -1.0;
double minlike = -1.0;
std::vector<double> values;
for (int i = 0; i < 1.E4; i++) {
fSampleFCN->ThrowDataToy();
double like = fSampleFCN->GetLikelihood();
values.push_back(like);
if (maxlike == -1.0 or like > maxlike) maxlike = like;
if (minlike == -1.0 or like < minlike) minlike = like;
}
SETVERBOSITY(verb);
// Fill Histogram
TH1D* likes = new TH1D("toydatalikelihood", "toydatalikelihood",
int(sqrt(nthrows)), minlike, maxlike);
for (size_t i = 0; i < values.size(); i++) {
likes->Fill(values[i]);
}
// Save to file
LOG(FIT) << "Writing toy data throws" << std::endl;
fOutputRootFile->cd();
likes->Write();
}
diff --git a/src/Routines/MinimizerRoutines.h b/src/Routines/MinimizerRoutines.h
index 0733601..3918e7a 100755
--- a/src/Routines/MinimizerRoutines.h
+++ b/src/Routines/MinimizerRoutines.h
@@ -1,270 +1,278 @@
// 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 MINIMIZER_ROUTINES_H
#define MINIMIZER_ROUTINES_H
/*!
* \addtogroup Minimizer
* @{
*/
#include "TH1.h"
#include "TF1.h"
#include "TMatrixD.h"
#include "TVectorD.h"
+
+#ifdef ROOT6_USE_FIT_FITTER_INTERFACE
+#include "Fit/Fitter.h"
+#else
#include "Minuit2/FCNBase.h"
#include "TFitterMinuit.h"
+#endif
+
#include "TSystem.h"
#include "TFile.h"
#include "TProfile.h"
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <cstring>
#include "FitEvent.h"
#include "JointFCN.h"
#include "MinimizerFCN.h"
#include "Math/Minimizer.h"
#include "Math/Factory.h"
#include "Math/Functor.h"
#include "FitLogger.h"
#include "ParserUtils.h"
enum minstate {
kErrorStatus = -1,
kGoodStatus,
kFitError,
kNoChange,
kFitFinished,
kFitUnfinished,
kStateChange,
};
//*************************************
//! Collects all possible fit routines into a single class to avoid repeated code
class MinimizerRoutines{
//*************************************
public:
/*
Constructor/Destructor
*/
+ MinimizerRoutines();
+
//! Constructor reads in arguments given at the command line for the fit here.
MinimizerRoutines(int argc, char* argv[]);
-
+
//! Default destructor
~MinimizerRoutines();
//! Reset everything to default/NULL
void Init();
-
+
/*
Input Functions
*/
//! Splits the arguments ready for initial setup
void ParseArgs(int argc, char* argv[]);
//! Sorts out configuration and verbosity right at the very start.
//! Calls readCard to set everything else up.
void InitialSetup();
//! Loops through each line of the card file and passes it to other read functions
void ReadCard(std::string cardfile);
//! Check for parameter string in the line and assign the correct type.
//! Fills maps for each of the parameters
int ReadParameters(std::string parstring);
//! Reads in fake parameters and assigns them (Requires the parameter to be included as a normal parameter as well)
int ReadFakeDataPars(std::string parstring);
//! Read in the samples so we can set up the free normalisation dials if required
int ReadSamples(std::string sampleString);
void SetupMinimizerFromXML();
/*
Setup Functions
*/
//! Setup the configuration given the arguments passed at the commandline and card file
void SetupConfig();
//! Setups up our custom RW engine with all the parameters passed in the card file
void SetupRWEngine();
//! Setups up the jointFCN.
void SetupFCN();
//! Sets up the minimizerObj for ROOT. there are cases where this is called repeatedly, e.g. If you are using a brute force scan before using Migrad.
void SetupFitter(std::string routine);
//! Set the current data histograms in each sample to the fake data.
void SetFakeData();
//! Setup the covariances with the correct dimensions. At the start this is either uncorrelated or merged given all the input covariances.
//! At the end of the fit this produces the blank covariances which can then be filled by the minimizerObj with best fit covariances.
void SetupCovariance();
/*
Fitting Functions
*/
//! Main function to actually start iterating over the different required fit routines
void Run();
//! Given a new map change the values that the RW engine is currently set to
void UpdateRWEngine(std::map<std::string,double>& updateVals);
//! Given a single routine (see tutorial for options) run that fit routine now.
int RunFitRoutine(std::string routine);
//! Get the current state of minimizerObj and fill it into currentVals and currentNorms
void GetMinimizerState();
//! Print current value
void PrintState();
-
+
//! Performs a fit routine where the input.maxevents is set to a much lower value to try and move closer to the best fit minimum.
void LowStatRoutine(std::string routine);
//! Perform a chi2 scan in 1D around the current point
void Create1DScans();
//! Perform a chi2 scan in 2D around the current point
void Chi2Scan2D();
//! Currently a placeholder NEEDS UPDATING
void CreateContours();
//! If any currentVals are close to the limits set them to the limit and fix them
int FixAtLimit();
//! Throw the current covariance of dial values we have, and fill the thrownVals and thrownNorms maps.
//! If uniformly is true parameters will be thrown uniformly between their upper and lower limits.
void ThrowCovariance(bool uniformly);
//! Given the covariance we currently have generate error bands by throwing the covariance.
//! The FitPar config "error_uniform" defines whether to throw using the covariance or uniformly.
//! The FitPar config "error_throws" defines how many throws are needed.
//! Currently only supports TH1D plots.
void GenerateErrorBands();
/*
Write Functions
*/
//! Write plots and TTrees listing the minimizerObj result of the fit to file
void SaveMinimizerState();
//! Save the sample plots for current MC
//! dir if not empty forces plots to be saved in a subdirectory of outputfile
void SaveCurrentState(std::string subdir="");
//! Save starting predictions into a seperate folder
void SaveNominal();
//! Save predictions before the fit is ran into a seperate folder
void SavePrefit();
void SaveResults();
/*
MISC Functions
*/
//! Get previous fit status from a file
Int_t GetStatus();
/// Makes a histogram of likelihoods when throwing the data according to its statistics
void ThrowDataToys();
protected:
//! Our Custom ReWeight Object
FitWeight* rw;
std::string fOutputFile;
std::string fInputFile;
TFile* fInputRootFile;
TFile* fOutputRootFile;
//! Flag for whether the fit should be continued if an output file is already found.
bool fitContinue;
//! Minimizer Object for handling roots different minimizer methods
ROOT::Math::Minimizer* fMinimizer;
JointFCN* fSampleFCN;
MinimizerFCN* fMinimizerFCN;
ROOT::Math::Functor* fCallFunctor;
int nfreepars;
std::string fCardFile;
std::string fStrategy;
std::vector<std::string> fRoutines;
std::string fAllowedRoutines;
-
+
std::string fFakeDataInput;
// Input Dial Vals
//! Vector of dial names
std::vector<std::string> fParams;
std::map<std::string, std::string> fStateVals;
std::map<std::string, double> fStartVals;
std::map<std::string, double> fCurVals;
std::map<std::string, double> fErrorVals;
std::map<std::string, double> fMinVals;
std::map<std::string, double> fMaxVals;
std::map<std::string, double> fStepVals;
std::map<std::string, int> fTypeVals;
std::map<std::string, bool> fFixVals;
std::map<std::string, bool> fStartFixVals;
//! Vector of fake parameter names
std::map<std::string,double> fFakeVals;
//! Map of thrown parameter names and values (After ThrowCovariance)
std::map<std::string,double> fThrownVals;
TH2D* fCorrel;
TH2D* fDecomp;
TH2D* fCovar;
-
+
TH2D* fCorFree;
TH2D* fDecFree;
TH2D* fCovFree;
nuiskey fCompKey;
};
/*! @} */
#endif
diff --git a/src/Splines/SplineWriter.h b/src/Splines/SplineWriter.h
index ffc0655..87d7cc6 100644
--- a/src/Splines/SplineWriter.h
+++ b/src/Splines/SplineWriter.h
@@ -1,92 +1,98 @@
#ifndef SPLINEWRITER_H
#define SPLINEWRITER_H
#include "FitWeight.h"
#include "Spline.h"
#include "SplineUtils.h"
#ifdef __MINUIT2_ENABLED__
+
+#ifdef ROOT6_USE_FIT_FITTER_INTERFACE
+#include "Fit/Fitter.h"
+#else
#include "TFitterMinuit.h"
#endif
+#endif
+
class SplineFCN {
public:
SplineFCN(Spline* spl, std::vector<std::vector<double> > v, std::vector<double> w) { fSpl = spl; fVal = v; fWeight = w; };
~SplineFCN() {};
double operator()(const double* x) const;
double DoEval(const double *x) const;
void SaveAs(std::string name, const float* fx);
void UpdateWeights(std::vector<double>& w);
void SetCorrelated(bool state = true);
bool uncorrelated;
std::vector< std::vector<double> > fVal;
std::vector< double > fWeight;
Spline* fSpl;
};
class SplineWriter : public SplineReader {
public:
SplineWriter(FitWeight* fw) {
fRW = fw;
fDrawSplines = FitPar::Config().GetParB("drawsplines");
};
~SplineWriter() {};
void SetupSplineSet();
void Write(std::string name);
void AddCoefficientsToTree(TTree* tree);
void FitSplinesForEvent(TCanvas* fitcanvas = NULL, bool saveplot = false);
void AddWeightsToTree(TTree* tr);
void ReadWeightsFromTree(TTree* tr);
void FitSplinesForEvent(double* weightvals, float* coeff);
void GetWeightsForEvent(FitEvent* event, double* weights);
void GetWeightsForEvent(FitEvent* event);
void ReconfigureSet(int iset);
double GetWeightForThisSet(FitEvent* event, int iset=-1);
void SetWeights(double* weights);
inline int GetNWeights(){return fParVect.size();};
inline int GetNPars(){ return fNCoEff;};
int fNCoEff;
// double* fCoEffStorer;
float* fCoEffStorer;
std::vector< std::vector<double> > fParVect;
std::vector< int > fSetIndex;
double* fWeightList;
std::vector< std::vector<double> > fValList;
int fCurrentSet;
FitWeight* fRW;
bool fDrawSplines;
std::vector<TH1D*> fAllDrawnHists;
std::vector<TGraph*> fAllDrawnGraphs;
#ifdef __MINUIT2_ENABLED__
std::map<Spline*, SplineFCN*> fSplineFCNs;
std::map<Spline*, ROOT::Math::Functor*> fSplineFunctors;
std::map<Spline*, ROOT::Math::Minimizer*> fSplineMinimizers;
#endif
// Spline* gSpline;
// Available Fitting Functions
void FitCoeff(Spline* spl, std::vector< std::vector<double> >& v, std::vector<double>& w, float* coeff, bool draw);
void FitCoeff1DGraph(Spline* spl, int n, double* x, double* y, float* coeff, bool draw);
void GetCoeff1DTSpline3(Spline* spl, int n, double* x, double* y, float* coeff, bool draw);
// void FitCoeff2DGraph(Spline* spl, std::vector< std::vector<double> >& v, std::vector<double>& w, float* coeff, bool draw);
void FitCoeffNDGraph(Spline* spl, std::vector< std::vector<double> >& v, std::vector<double>& w, float* coeff, bool draw);
void FitCoeff2DGraph(Spline* spl, int n, double* x, double* y, double* w, float* coeff, bool draw);
//double Func2DWrapper(double* x, double* p);
};
#endif
diff --git a/src/Statistical/StatUtils.cxx b/src/Statistical/StatUtils.cxx
index 1af6e2e..e052685 100644
--- a/src/Statistical/StatUtils.cxx
+++ b/src/Statistical/StatUtils.cxx
@@ -1,1303 +1,1304 @@
// 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"
-#include "NuisConfig.h"
#include "GeneralUtils.h"
+#include "NuisConfig.h"
+#include "TH1D.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();
+ TH1D* calc_mc = (TH1D*)mc->Clone();
// Add MC Error to data if required
if (FitPar::Config().GetParB("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);
+ 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;
+ 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 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) {
-//*******************************************************************
+Double_t StatUtils::GetChi2FromDiag(TH2D* data, TH2D* mc, TH2I* map,
+ TH2I* mask) {
+ //*******************************************************************
// Generate a simple map
- if (!map) map = GenerateMap(data);
+ if (!map) map = GenerateMap(data);
// Convert to 1D Histograms
TH1D* data_1D = MapToTH1D(data, map);
- TH1D* mc_1D = MapToTH1D(mc, 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);
+ 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 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();
+ TMatrixDSym* calc_cov = (TMatrixDSym*)invcov->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 = ApplyInvertedMatrixMasking(invcov, mask);
+ calc_cov = ApplyInvertedMatrixMasking(invcov, mask);
calc_data = ApplyHistogramMasking(data, mask);
- calc_mc = ApplyHistogramMasking(mc, mask);
+ calc_mc = ApplyHistogramMasking(mc, mask);
}
// Add MC Error to data if required
- if (FitPar::Config().GetParB("addmcerror")) {
-
+ 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);
- std::cout << "Adding cov stat " << mcerr*mcerr << " to " << (*newcov)(i,i) << std::endl;
+ std::cout << "Adding cov stat " << mcerr * mcerr << " to "
+ << (*newcov)(i, i) << std::endl;
(*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;
}
calc_data->Scale(data_scale);
- calc_mc ->Scale(data_scale);
+ calc_mc->Scale(data_scale);
(*calc_cov) *= covar_scale;
// iterate over bins in X (i,j)
+ QLOG(DEB, "START Chi2 Calculation=================");
for (int i = 0; i < calc_data->GetNbinsX(); i++) {
-
+ QLOG(DEB,
+ "[CHI2] i = " << i << " ["
+ << calc_data->GetXaxis()->GetBinLowEdge(i + 1) << " -- "
+ << calc_data->GetXaxis()->GetBinUpEdge(i + 1) << "].");
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) ) );
+ QLOG(DEB, "[CHI2]\t j = "
+ << i << " [" << calc_data->GetXaxis()->GetBinLowEdge(j + 1)
+ << " -- " << calc_data->GetXaxis()->GetBinUpEdge(j + 1)
+ << "].");
+ if ((calc_data->GetBinContent(i + 1) != 0 ||
+ calc_mc->GetBinContent(i + 1) != 0) &&
+ ((*calc_cov)(i, j) != 0)) {
+ QLOG(DEB, "[CHI2]\t\t Chi2 contribution (i,j) = (" << i << "," << j
+ << ")");
+ QLOG(DEB, "[CHI2]\t\t Data - MC(i) = "
+ << calc_data->GetBinContent(i + 1) << " - "
+ << calc_mc->GetBinContent(i + 1) << " = "
+ << (calc_data->GetBinContent(i + 1) -
+ calc_mc->GetBinContent(i + 1)));
+
+ QLOG(DEB, "[CHI2]\t\t Data - MC(j) = "
+ << calc_data->GetBinContent(j + 1) << " - "
+ << calc_mc->GetBinContent(j + 1) << " = "
+ << (calc_data->GetBinContent(j + 1) -
+ calc_mc->GetBinContent(j + 1)));
+
+ QLOG(DEB, "[CHI2]\t\t Covar = " << (*calc_cov)(i, j));
+
+ QLOG(DEB, "[CHI2]\t\t 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);
+
+ 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;
-
+ QLOG(DEB, "Skipping chi2 contribution (i,j) = ("
+ << i << "," << j
+ << "), Data = " << calc_data->GetBinContent(i + 1)
+ << ", MC = " << calc_mc->GetBinContent(i + 1)
+ << ", Cov = " << (*calc_cov)(i, j));
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) {
//*******************************************************************
+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);
+ 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);
+ 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 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();
+ 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_cov = StatUtils::ApplyMatrixMasking(cov, mask);
calc_data = StatUtils::ApplyHistogramMasking(data, mask);
- calc_mc = StatUtils::ApplyHistogramMasking(mc, 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() );
+ 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) ;
+ 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) {
//*******************************************************************
+Double_t StatUtils::GetChi2FromSVD(TH2D* data, TH2D* mc, TMatrixDSym* cov,
+ TH2I* map, TH2I* mask) {
+ //*******************************************************************
// Generate a simple map
- if (!map)
- map = StatUtils::GenerateMap(data);
+ if (!map) map = StatUtils::GenerateMap(data);
// Convert to 1D Histograms
TH1D* data_1D = MapToTH1D(data, map);
- TH1D* mc_1D = MapToTH1D(mc, 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
+ // 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();
+ TH1D* calc_mc = (TH1D*)mc->Clone();
// Apply masking if required
if (mask) {
calc_data = ApplyHistogramMasking(data, mask);
- calc_mc = ApplyHistogramMasking(mc, 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)));
+ 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) {
-//*******************************************************************
+Double_t StatUtils::GetChi2FromEventRate(TH2D* data, TH2D* mc, TH2I* map,
+ TH2I* mask) {
+ //*******************************************************************
// Generate a simple map
- if (!map)
- map = StatUtils::GenerateMap(data);
+ if (!map) map = StatUtils::GenerateMap(data);
// Convert to 1D Histograms
TH1D* data_1D = MapToTH1D(data, map);
- TH1D* mc_1D = MapToTH1D(mc, 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;
+ (void)data;
+ (void)mc;
+ (void)mask;
return 0.0;
};
//*******************************************************************
-Double_t StatUtils::GetLikelihoodFromDiag(TH2D* data, TH2D* mc, TH2I* map, TH2I* mask) {
-//*******************************************************************
+Double_t StatUtils::GetLikelihoodFromDiag(TH2D* data, TH2D* mc, TH2I* map,
+ TH2I* mask) {
+ //*******************************************************************
// Generate a simple map
- if (!map)
- map = StatUtils::GenerateMap(data);
+ if (!map) map = StatUtils::GenerateMap(data);
// Convert to 1D Histograms
TH1D* data_1D = MapToTH1D(data, map);
- TH1D* mc_1D = MapToTH1D(mc, 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) {
//*******************************************************************
+Double_t StatUtils::GetLikelihoodFromCov(TH1D* data, TH1D* mc,
+ TMatrixDSym* invcov, TH1I* mask) {
+ //*******************************************************************
// Currently just a placeholder !
- (void) data;
- (void) mc;
- (void) invcov;
- (void) mask;
+ (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) {
-//*******************************************************************
+Double_t StatUtils::GetLikelihoodFromCov(TH2D* data, TH2D* mc,
+ TMatrixDSym* invcov, TH2I* map,
+ TH2I* mask) {
+ //*******************************************************************
// Generate a simple map
- if (!map)
- map = StatUtils::GenerateMap(data);
+ if (!map) map = StatUtils::GenerateMap(data);
// Convert to 1D Histograms
TH1D* data_1D = MapToTH1D(data, map);
- TH1D* mc_1D = MapToTH1D(mc, 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);
+ 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) {
-//*******************************************************************
+Double_t StatUtils::GetLikelihoodFromSVD(TH1D* data, TH1D* mc, TMatrixDSym* cov,
+ TH1I* mask) {
+ //*******************************************************************
// Currently just a placeholder!
- (void) data;
- (void) mc;
- (void) cov;
- (void) mask;
+ (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) {
-//*******************************************************************
+Double_t StatUtils::GetLikelihoodFromSVD(TH2D* data, TH2D* mc, TMatrixDSym* cov,
+ TH2I* map, TH2I* mask) {
+ //*******************************************************************
// Generate a simple map
- if (!map)
- map = StatUtils::GenerateMap(data);
+ if (!map) map = StatUtils::GenerateMap(data);
// Convert to 1D Histograms
TH1D* data_1D = MapToTH1D(data, map);
- TH1D* mc_1D = MapToTH1D(mc, 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) {
-//*******************************************************************
+Double_t StatUtils::GetLikelihoodFromEventRate(TH1D* data, TH1D* mc,
+ TH1I* mask) {
+ //*******************************************************************
// Currently just a placeholder!
- (void) data;
- (void) mc;
- (void) mask;
+ (void)data;
+ (void)mc;
+ (void)mask;
return 0.0;
};
-
-//*******************************************************************
-Double_t StatUtils::GetLikelihoodFromEventRate(TH2D* data, TH2D* mc, TH2I* map, TH2I* mask) {
//*******************************************************************
+Double_t StatUtils::GetLikelihoodFromEventRate(TH2D* data, TH2D* mc, TH2I* map,
+ TH2I* mask) {
+ //*******************************************************************
// Generate a simple map
- if (!map)
- map = StatUtils::GenerateMap(data);
+ if (!map) map = StatUtils::GenerateMap(data);
// Convert to 1D Histograms
TH1D* data_1D = MapToTH1D(data, map);
- TH1D* mc_1D = MapToTH1D(mc, 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* 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();
+ 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_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
+ // 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) ;
+ correl_val += rand_val[j] * (*decomp_cov)(j, i);
}
- calc_hist->SetBinContent(i + 1, (calc_hist->GetBinContent(i + 1) + correl_val * 1E-38));
+ 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) {
-//*******************************************************************
+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;
+ (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() );
+ if (!mask) return ((TH1D*)hist->Clone());
- // This masking is only sufficient for chi2 calculations, and will have dodgy bin edges.
+ // 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);
+ 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;
+ 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();
+ 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) {
-//*******************************************************************
+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);
+ TMatrixDSym* newmat = StatUtils::ApplyMatrixMasking(mat, mask_1D);
delete mask_1D;
return newmat;
}
-
-
-//*******************************************************************
-TMatrixDSym* StatUtils::ApplyInvertedMatrixMasking(TMatrixDSym* mat, TH1I* mask) {
//*******************************************************************
+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) {
//*******************************************************************
+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(), "");
+ 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 ) {
-//*******************************************************************
+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;
+ (*newmat)(i, i) =
+ data->GetBinError(i + 1) * data->GetBinError(i + 1) * scaleF * scaleF;
}
return newmat;
}
-
-
-//*******************************************************************
-TMatrixDSym* StatUtils::MakeDiagonalCovarMatrix(TH2D* data, TH2I* map, double scaleF) {
//*******************************************************************
+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) {
//*******************************************************************
+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;
+ 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 );
+ data->SetBinError(i + 1, sqrt((*cov)(i, i)) * scale);
}
return;
}
//*******************************************************************
-void StatUtils::SetDataErrorFromCov(TH2D* data, TMatrixDSym* cov, TH2I* map, double scale) {
-//*******************************************************************
+void StatUtils::SetDataErrorFromCov(TH2D* data, TMatrixDSym* cov, TH2I* map,
+ double scale) {
+ //*******************************************************************
// Create map if required
if (!map) map = StatUtils::GenerateMap(data);
// 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 );
-
+ data->SetBinError(i + 1, j + 1, sqrt((*cov)(count, count)) * scale);
}
}
return;
}
-
-TMatrixDSym* StatUtils::ExtractShapeOnlyCovar(TMatrixDSym* full_covar, TH1* data_hist, double data_scale){
-
+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;
+ 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;
+ 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_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;
+ total_data += data_hist->GetBinContent(i + 1) * data_scale;
for (int j = 0; j < nbins; ++j) {
- total_covar += (*full_covar)(i,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;
+
+ 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;
-
+ 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;
+ 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 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);
+
+ 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;
+ 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());
+ 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) {
-
+ 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));
+ 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));
+ 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);
+ (*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) {
//*******************************************************************
+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;
+ 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;
+ "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.");
+ // 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) {
-//*******************************************************************
+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){
-//*******************************************************************
+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);
+ 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){
-//*******************************************************************
+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);
+ 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/Tests/CMakeLists.txt b/src/Tests/CMakeLists.txt
index 6fe0313..f02aea6 100644
--- a/src/Tests/CMakeLists.txt
+++ b/src/Tests/CMakeLists.txt
@@ -1,40 +1,58 @@
# 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_directories(${MINIMUM_INCLUDE_DIRECTORIES})
include_directories(${CMAKE_SOURCE_DIR}/src/Routines)
include_directories(${CMAKE_SOURCE_DIR}/src/FCN)
include_directories(${CMAKE_SOURCE_DIR}/src/MCStudies)
include_directories(${CMAKE_SOURCE_DIR}/src/Smearceptance)
include_directories(${EXP_INCLUDE_DIRECTORIES})
SET(TESTAPPS SignalDefTests ParserTests SmearceptanceTests)
+if(USE_MINIMIZER)
+ # LIST(APPEND TESTAPPS FitMechanicsTests)
+endif()
+
foreach(appimpl ${TESTAPPS})
add_executable(${appimpl} ${appimpl}.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};${appimpl})
target_link_libraries(${appimpl} ${MODULETargets})
target_link_libraries(${appimpl} ${CMAKE_DEPENDLIB_FLAGS})
target_link_libraries(${appimpl} ${ROOT_LIBS})
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(${appimpl} PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
install(TARGETS ${appimpl} DESTINATION tests)
add_test(${appimpl} ${appimpl} 1)
endforeach()
+
+list (FIND TESTAPPS FitMechanicsTests _index)
+if (${_index} GREATER -1)
+ add_library(DummySample SHARED DummySample.cxx)
+ target_link_libraries(DummySample ${MODULETargets})
+ target_link_libraries(DummySample ${CMAKE_DEPENDLIB_FLAGS})
+ target_link_libraries(DummySample ${ROOT_LIBS})
+
+ if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
+ set_target_properties(DummySample PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
+ endif()
+
+ install(TARGETS DummySample DESTINATION tests)
+endif()
diff --git a/src/Tests/ConstructibleFitEvent.h b/src/Tests/ConstructibleFitEvent.h
new file mode 100644
index 0000000..a8b8759
--- /dev/null
+++ b/src/Tests/ConstructibleFitEvent.h
@@ -0,0 +1,59 @@
+#include "TLorentzVector.h"
+#include "TRandom3.h"
+#include "FitEvent.h"
+
+struct ConstructibleFitEvent : public FitEvent {
+ ConstructibleFitEvent() : FitEvent() { fNParticles = 0; }
+ void AddPart(double Mom[4], size_t State, int PDG) {
+ fParticleMom[fNParticles][0] = Mom[0];
+ fParticleMom[fNParticles][1] = Mom[1];
+ fParticleMom[fNParticles][2] = Mom[2];
+ fParticleMom[fNParticles][3] = Mom[3];
+ fParticleState[fNParticles] = State;
+ fParticlePDG[fNParticles] = PDG;
+ fNParticles++;
+ }
+ void SetMode(int mode) { Mode = mode; }
+ std::string ToString() {
+ std::stringstream ss("");
+ ss << "Mode: " << Mode << std::endl;
+ ss << "Particles: " << fNParticles << std::endl;
+ ss << " -> Particle Stack " << std::endl;
+ for (int i = 0; i < fNParticles; i++) {
+ ss << " -> -> " << i << ". " << fParticlePDG[i] << " "
+ << fParticleState[i] << " "
+ << " Mom(" << fParticleMom[i][0] << ", " << fParticleMom[i][1] << ", "
+ << fParticleMom[i][2] << ", " << fParticleMom[i][3] << ")."
+ << std::endl;
+ }
+ return ss.str();
+ }
+};
+
+template <size_t N, size_t M>
+ConstructibleFitEvent MakePDGStackEvent(int (&ISpdgs)[N], int (&FSpdgs)[M],
+ int Mode = 1) {
+ ConstructibleFitEvent fe;
+ double MomHolder[4] = {0, 0, 1E3, 1E3};
+ for (size_t p_it = 0; p_it < N; ++p_it) {
+ fe.AddPart(MomHolder, kInitialState, ISpdgs[p_it]);
+ }
+
+ TRandom3 rnd;
+ TLorentzVector rnd4M;
+ TVector3 rn3M;
+ for (size_t p_it = 0; p_it < M; ++p_it) {
+ /// Could do better and actually get the correct masses...
+ rn3M.SetMagThetaPhi(fabs(rnd.Gaus(200, 50)), rnd.Uniform(M_PI),
+ 2 * rnd.Uniform(M_PI));
+ rnd4M.SetVectM(rn3M, 105);
+ MomHolder[0] = rnd4M[0];
+ MomHolder[1] = rnd4M[1];
+ MomHolder[2] = rnd4M[2];
+ MomHolder[3] = rnd4M[3];
+ fe.AddPart(MomHolder, kFinalState, FSpdgs[p_it]);
+ }
+ fe.SetMode(Mode);
+ fe.OrderStack();
+ return fe;
+}
diff --git a/src/Tests/ConstructibleInputHandler.h b/src/Tests/ConstructibleInputHandler.h
new file mode 100644
index 0000000..3c8ee1f
--- /dev/null
+++ b/src/Tests/ConstructibleInputHandler.h
@@ -0,0 +1,25 @@
+#include "InputHandler.h"
+
+struct ConstructibleInputHandler : public InputHandlerBase {
+ std::vector<FitEvent *> FitEvents;
+
+ ConstructibleInputHandler(
+ std::string const& name) {
+ fName = name;
+ }
+
+ void AddFitEvent(FitEvent *fe) {
+ FitEvents.push_back(fe);
+
+ fNEvents = FitEvents.size();
+
+ std::cout << "[INFO]: Added event " << std::endl;
+ fe->Print();
+ }
+
+ FitEvent* GetNuisanceEvent(
+ const UInt_t entry, const bool lightweight) {
+ if (entry >= (UInt_t)fNEvents) return NULL;
+ return FitEvents[entry];
+ }
+};
diff --git a/src/Tests/DummyMinimizer.h b/src/Tests/DummyMinimizer.h
new file mode 100644
index 0000000..5ef73b3
--- /dev/null
+++ b/src/Tests/DummyMinimizer.h
@@ -0,0 +1,61 @@
+#include "MinimizerRoutines.h"
+
+struct DummyMinimizer : public MinimizerRoutines {
+ DummyMinimizer() : MinimizerRoutines() {
+ nuiskey p_m1 = Config::CreateKey("parameter");
+
+ p_m1.SetS("type", "modenorm_parameter");
+ p_m1.SetS("name", "mode_1");
+ p_m1.SetD("nominal", 1);
+ p_m1.SetS("state", "FREE");
+ p_m1.SetD("low", 0);
+ p_m1.SetD("high", 3);
+ p_m1.SetD("step", 0.1);
+
+ nuiskey p_m2 = Config::CreateKey("parameter");
+
+ p_m2.SetS("type", "modenorm_parameter");
+ p_m2.SetS("name", "mode_2");
+ p_m2.SetD("nominal", 1);
+ p_m2.SetS("state", "FREE");
+ p_m2.SetD("low", 0);
+ p_m2.SetD("high", 3);
+ p_m2.SetD("step", 0.1);
+
+ nuiskey p_m3 = Config::CreateKey("parameter");
+
+ p_m3.SetS("type", "modenorm_parameter");
+ p_m3.SetS("name", "mode_3");
+ p_m3.SetD("nominal", 1);
+ p_m3.SetS("state", "FREE");
+ p_m3.SetD("low", 0);
+ p_m3.SetD("high", 3);
+ p_m3.SetD("step", 0.1);
+
+ nuiskey dummysample = Config::CreateKey("sample");
+ dummysample.SetS("name", "DummySample");
+
+ Config::SetPar("dynamic_sample.path",
+ std::string(getenv("NUISANCE")) + "/build/Linux/tests");
+
+ Config::SetPar("EventManager", false);
+ // SETVERBOSITY(DEB);
+
+
+
+ std::cout << "[INFO]: Parameter config:" << std::endl;
+ nuisconfig::GetConfig().PrintXML(NULL);
+ std::cout << "================" << std::endl;
+
+ fOutputRootFile = new TFile("TestOutput.root", "RECREATE");
+
+ SetupMinimizerFromXML();
+ SetupRWEngine();
+ SetupFCN();
+ }
+
+ std::string GetParamName (int i) { return fParams[i]; }
+ double GetParamVal (int i) { return fCurVals[GetParamName(i)]; }
+ double GetParamError (int i) { return fErrorVals[GetParamName(i)]; }
+
+};
diff --git a/src/Tests/DummySample.cxx b/src/Tests/DummySample.cxx
new file mode 100644
index 0000000..0734dc9
--- /dev/null
+++ b/src/Tests/DummySample.cxx
@@ -0,0 +1,89 @@
+#include "ConstructibleFitEvent.h"
+#include "ConstructibleInputHandler.h"
+#include "Measurement1D.h"
+
+struct DummySample : public Measurement1D {
+
+ std::vector<ConstructibleFitEvent *> FitEvents;
+ DummySample(nuiskey samplekey) {
+ ConstructibleInputHandler *cih = new ConstructibleInputHandler("DummyIHandler");
+ fInput = cih;
+
+ fSettings = SampleSettings(samplekey);
+ fSettings.SetTitle("DummySample");
+ FinaliseSampleSettings();
+
+ fDataHist = new TH1D("data", "", 3, 1, 4);
+ fMCHist = new TH1D("data", "", 3, 1, 4);
+
+ double FakeDataError = Config::GetParD("FakeDataError");
+
+ fScaleFactor = 1;
+
+ int IS[] = {14};
+ int FS_CC0pi_1[] = {13, 2212};
+ int FS_CC1pi_1[] = {13, 2212, 211};
+ int FS_CC2pi_1[] = {13, 2212, 211, -211};
+ FitEvents.push_back(new ConstructibleFitEvent(MakePDGStackEvent(IS, FS_CC0pi_1)));
+ FitEvents.back()->SetMode(1);
+ FitEvents.push_back(new ConstructibleFitEvent(MakePDGStackEvent(IS, FS_CC1pi_1)));
+ FitEvents.back()->SetMode(2);
+ FitEvents.push_back(new ConstructibleFitEvent(MakePDGStackEvent(IS, FS_CC2pi_1)));
+ FitEvents.back()->SetMode(3);
+
+ for(size_t fe_it = 0; fe_it < FitEvents.size(); ++fe_it){
+ cih->AddFitEvent(FitEvents[fe_it]);
+ fDataHist->SetBinContent(FitEvents[fe_it]->Mode, 1.0 + float(fe_it)*0.5);
+ fDataHist->SetBinError(FitEvents[fe_it]->Mode, FakeDataError);
+ }
+
+ SetupDefaultHist();
+ SetCovarFromDiagonal();
+ FinaliseMeasurement();
+ }
+ void FillEventVariables(FitEvent* nvect) { fXVar = nvect->Mode; }
+
+ bool isSignal(FitEvent* nvect) { return true; }
+
+ virtual ~DummySample(){
+ for(size_t fe_it = 0; fe_it < FitEvents.size(); ++fe_it){
+ delete FitEvents[fe_it];
+ }
+ }
+};
+
+static char const* SampleNames[] = {"DummySample"};
+static int const NSamples = 1;
+
+extern "C" {
+int DSF_NSamples() { return NSamples; }
+char const* DSF_GetSampleName(int i) {
+ if (i < NSamples) {
+ return SampleNames[i];
+ }
+ return 0;
+}
+MeasurementBase* DSF_GetSample(int i, void* samplekey) {
+ nuiskey* sk = reinterpret_cast<nuiskey*>(samplekey);
+ if (!sk) {
+ return 0;
+ }
+
+ if (sk->GetS("name") != DSF_GetSampleName(i)) {
+ std::cout
+ << "[ERROR]: When instantiating dynamic sample. Samplekey named: "
+ << sk->GetS("name")
+ << ", but requested sample named: " << DSF_GetSampleName(i)
+ << ". It is possible that the nuiskey object is lost in translation. "
+ "Was NUISANCE and this dynamic sample manifest built with the same "
+ "environment and compiler?"
+ << std::endl;
+ }
+
+ if (i == 0) {
+ return new DummySample(*sk);
+ }
+ return 0;
+}
+void DSF_DestroySample(MeasurementBase* mb) { delete mb; }
+}
diff --git a/src/Tests/FitMechanicsTest.cxx b/src/Tests/FitMechanicsTest.cxx
new file mode 100644
index 0000000..9bb9531
--- /dev/null
+++ b/src/Tests/FitMechanicsTest.cxx
@@ -0,0 +1,41 @@
+#include "DummyMinimizer.h"
+
+int main() {
+
+ double FakeDataError = 1E-4;
+ double FakeDataErrorTol = 1.01 * FakeDataError;
+ Config::SetPar("FakeDataError", FakeDataError);
+
+ DummyMinimizer min;
+
+ std::cout << "======Running simple minimizer test======" << std::endl;
+
+ min.Run();
+
+ std::cout << "======Done minimizing, checking output======" << std::endl;
+
+ std::vector<string> pnames;
+ pnames.push_back("mode_1");
+ pnames.push_back("mode_2");
+ pnames.push_back("mode_3");
+
+ std::vector<double> postfitvals;
+ postfitvals.push_back(1);
+ postfitvals.push_back(1.5);
+ postfitvals.push_back(2);
+
+ for (size_t i = 0; i < 3; ++i) {
+ std::cout << "\tTest param name: " << pnames[i]
+ << " == " << min.GetParamName(i) << std::endl;
+ assert(pnames[i] == min.GetParamName(i));
+ std::cout << "\tTest param post-fit value : fabs(" << postfitvals[i]
+ << " - " << min.GetParamVal(i) << ") < " << min.GetParamError(i)
+ << std::endl;
+ assert(fabs(postfitvals[i] - min.GetParamVal(i)) < min.GetParamError(i));
+ std::cout << "\tTest post-fit error " << min.GetParamError(i) << " < "
+ << FakeDataErrorTol << std::endl;
+ assert(min.GetParamError(i) < FakeDataErrorTol);
+ }
+
+ return 0;
+}
diff --git a/src/Tests/SignalDefTests.cxx b/src/Tests/SignalDefTests.cxx
index 551f66b..031526f 100644
--- a/src/Tests/SignalDefTests.cxx
+++ b/src/Tests/SignalDefTests.cxx
@@ -1,447 +1,389 @@
#include <cassert>
#include <sstream>
-#include "TLorentzVector.h"
-#include "TRandom3.h"
-
-#include "FitEvent.h"
#include "SignalDef.h"
+#include "ConstructibleFitEvent.h"
-struct ConstructibleFitEvent : public FitEvent {
- ConstructibleFitEvent() : FitEvent() { fNParticles = 0; }
- void AddPart(double Mom[4], size_t State, int PDG) {
- fParticleMom[fNParticles][0] = Mom[0];
- fParticleMom[fNParticles][1] = Mom[1];
- fParticleMom[fNParticles][2] = Mom[2];
- fParticleMom[fNParticles][3] = Mom[3];
- fParticleState[fNParticles] = State;
- fParticlePDG[fNParticles] = PDG;
- fNParticles++;
- }
- void SetMode(int mode) { Mode = mode; }
- std::string ToString() {
- std::stringstream ss("");
- ss << "Mode: " << Mode << std::endl;
- ss << "Particles: " << fNParticles << std::endl;
- ss << " -> Particle Stack " << std::endl;
- for (int i = 0; i < fNParticles; i++) {
- ss << " -> -> " << i << ". " << fParticlePDG[i] << " "
- << fParticleState[i] << " "
- << " Mom(" << fParticleMom[i][0] << ", " << fParticleMom[i][1] << ", "
- << fParticleMom[i][2] << ", " << fParticleMom[i][3] << ")."
- << std::endl;
- }
- return ss.str();
- }
-};
-
-template <size_t N, size_t M>
-ConstructibleFitEvent MakePDGStackEvent(int (&ISpdgs)[N], int (&FSpdgs)[M],
- int Mode = 1) {
- ConstructibleFitEvent fe;
- double MomHolder[4] = {0, 0, 1E3, 1E3};
- for (size_t p_it = 0; p_it < N; ++p_it) {
- fe.AddPart(MomHolder, kInitialState, ISpdgs[p_it]);
- }
-
- TRandom3 rnd;
- TLorentzVector rnd4M;
- TVector3 rn3M;
- for (size_t p_it = 0; p_it < M; ++p_it) {
- /// Could do better and actually get the correct masses...
- rn3M.SetMagThetaPhi(fabs(rnd.Gaus(200, 50)), rnd.Uniform(M_PI),
- 2 * rnd.Uniform(M_PI));
- rnd4M.SetVectM(rn3M, 105);
- MomHolder[0] = rnd4M[0];
- MomHolder[1] = rnd4M[1];
- MomHolder[2] = rnd4M[2];
- MomHolder[3] = rnd4M[3];
- fe.AddPart(MomHolder, kFinalState, FSpdgs[p_it]);
- }
- fe.SetMode(Mode);
- fe.OrderStack();
- return fe;
-}
int main(int argc, char const *argv[]) {
bool FailOnFail = (argc > 1);
LOG_VERB(SAM);
LOG(FIT) << "* Running SignalDef Tests" << std::endl;
LOG(FIT) << "***************************************************"
<< std::endl;
int IS[] = {14};
int FS_CC0pi_1[] = {13, 2112, 2212, 2112, 2212};
ConstructibleFitEvent fe_CC0pi_1 = MakePDGStackEvent(IS, FS_CC0pi_1);
int FS_CC0pi_2[] = {13, 2112, 2212, 2112, 2212};
ConstructibleFitEvent fe_CC0pi_2 = MakePDGStackEvent(IS, FS_CC0pi_2, 2);
int FS_CC0pi_3[] = {-13, 2112, 2212, 2112, 2212};
ConstructibleFitEvent fe_CC0pi_3 = MakePDGStackEvent(IS, FS_CC0pi_3);
int FS_CC0pi_4[] = {13, 2112, 2212};
ConstructibleFitEvent fe_CC0pi_4 = MakePDGStackEvent(IS, FS_CC0pi_4, 12);
int FS_CC1pip_1[] = {13, 2212, 2112, 211};
ConstructibleFitEvent fe_CC1pip_1 = MakePDGStackEvent(IS, FS_CC1pip_1, 2);
int FS_CC1pim_1[] = {13, -211, 2212, 2112};
ConstructibleFitEvent fe_CC1pim_1 = MakePDGStackEvent(IS, FS_CC1pim_1, 11);
int FS_CC1pi0_1[] = {13, 2212, 111, 2112};
ConstructibleFitEvent fe_CC1pi0_1 = MakePDGStackEvent(IS, FS_CC1pi0_1, 12);
int FS_CC1pi0_2[] = {11, 2212, 111, 2112};
ConstructibleFitEvent fe_CC1pi0_2 = MakePDGStackEvent(IS, FS_CC1pi0_2, 12);
int FS_CCNpi_1[] = {13, 2212, 111, 2112, 211};
ConstructibleFitEvent fe_CCNpi_1 = MakePDGStackEvent(IS, FS_CCNpi_1, 21);
int FS_CCNpi_2[] = {13, -211, 211, 2112, 211};
ConstructibleFitEvent fe_CCNpi_2 = MakePDGStackEvent(IS, FS_CCNpi_2, 21);
int FS_CCNpi_3[] = {13, 2212, 111, 211, -211};
ConstructibleFitEvent fe_CCNpi_3 = MakePDGStackEvent(IS, FS_CCNpi_3, 26);
int FS_CCNpi_4[] = {13, 2212, 111, 111, 111};
ConstructibleFitEvent fe_CCNpi_4 = MakePDGStackEvent(IS, FS_CCNpi_4, 26);
int FS_CCCOH_1[] = {13, 211};
ConstructibleFitEvent fe_CCCOH_1 = MakePDGStackEvent(IS, FS_CCCOH_1, 16);
int FS_NCel_1[] = {14, 2112};
ConstructibleFitEvent fe_NCel_1 = MakePDGStackEvent(IS, FS_NCel_1, 52);
int FS_NCel_2[] = {12, 2212};
ConstructibleFitEvent fe_NCel_2 = MakePDGStackEvent(IS, FS_NCel_2, 51);
int FS_NC1pi_1[] = {14, 2112, -211};
ConstructibleFitEvent fe_NC1pi_1 = MakePDGStackEvent(IS, FS_NC1pi_1, 31);
int FS_NCNpi_1[] = {14, 2212, 211};
ConstructibleFitEvent fe_NCNpi_1 = MakePDGStackEvent(IS, FS_NCNpi_1, 32);
LOG(FIT) << "* Testing: SignalDef::isCCINC" << std::endl;
std::map<ConstructibleFitEvent *, bool> isCCINC_PassExpectations;
isCCINC_PassExpectations[&fe_CC0pi_1] = true; // numu CC0pi
isCCINC_PassExpectations[&fe_CC0pi_2] = true; // numu CC0pi (2p2h)
isCCINC_PassExpectations[&fe_CC0pi_3] = false; // numub CC0pi
isCCINC_PassExpectations[&fe_CC0pi_4] = true; // numu CC0pi (RES)
isCCINC_PassExpectations[&fe_CC1pip_1] = true; // numu CC1pip (2p2h)
isCCINC_PassExpectations[&fe_CC1pim_1] = true; // numu CC1pim
isCCINC_PassExpectations[&fe_CC1pi0_1] = true; // numu CC1pi0
isCCINC_PassExpectations[&fe_CC1pi0_2] = false; // nue CC1pi0
isCCINC_PassExpectations[&fe_CCNpi_1] = true; // numu CC multi pi
isCCINC_PassExpectations[&fe_CCNpi_2] = true; // numu CC multi pi
isCCINC_PassExpectations[&fe_CCNpi_3] = true; // numu CC multi pi
isCCINC_PassExpectations[&fe_CCNpi_4] = true; // numu CC multi pi
isCCINC_PassExpectations[&fe_CCCOH_1] = true; // numu CC COH pi
isCCINC_PassExpectations[&fe_NCel_1] = false; // numu NCEl
isCCINC_PassExpectations[&fe_NCel_2] = false; // nue NCEl
isCCINC_PassExpectations[&fe_NC1pi_1] = false; // numu NC1pi
isCCINC_PassExpectations[&fe_NCNpi_1] = false; // numu NC multi pi
size_t ctr = 0;
for (std::map<ConstructibleFitEvent *, bool>::iterator
fe_it = isCCINC_PassExpectations.begin();
fe_it != isCCINC_PassExpectations.end(); ++fe_it, ++ctr) {
bool res = SignalDef::isCCINC(fe_it->first, 14);
if (res != fe_it->second) {
ERR(FTL) << "Event: (" << ctr << ")\n"
<< fe_it->first->ToString() << std::endl;
ERR(FTL) << (res ? "passed" : "failed")
<< " SignalDef::isCCINC unexpectedly." << std::endl;
} else {
LOG(SAM) << "Event: (" << ctr << ") " << (res ? "passed" : "failed")
<< " as expected." << std::endl;
}
if (FailOnFail) {
assert(res == fe_it->second);
}
}
LOG(FIT) << "* Testing: SignalDef::isNCINC" << std::endl;
std::map<ConstructibleFitEvent *, bool> isNCINC_PassExpectations;
isNCINC_PassExpectations[&fe_CC0pi_1] = false; // numu CC0pi
isNCINC_PassExpectations[&fe_CC0pi_2] = false; // numu CC0pi (2p2h)
isNCINC_PassExpectations[&fe_CC0pi_3] = false; // numub CC0pi
isNCINC_PassExpectations[&fe_CC0pi_4] = false; // numu CC0pi (RES)
isNCINC_PassExpectations[&fe_CC1pip_1] = false; // numu CC1pip (2p2h)
isNCINC_PassExpectations[&fe_CC1pim_1] = false; // numu CC1pim
isNCINC_PassExpectations[&fe_CC1pi0_1] = false; // numu CC1pi0
isNCINC_PassExpectations[&fe_CC1pi0_2] = false; // nue CC1pi0
isNCINC_PassExpectations[&fe_CCNpi_1] = false; // numu CC multi pi
isNCINC_PassExpectations[&fe_CCNpi_2] = false; // numu CC multi pi
isNCINC_PassExpectations[&fe_CCNpi_3] = false; // numu CC multi pi
isNCINC_PassExpectations[&fe_CCNpi_4] = false; // numu CC multi pi
isNCINC_PassExpectations[&fe_CCCOH_1] = false; // numu CC COH pi
isNCINC_PassExpectations[&fe_NCel_1] = true; // numu NCEl
isNCINC_PassExpectations[&fe_NCel_2] = false; // nue NCEl
isNCINC_PassExpectations[&fe_NC1pi_1] = true; // numu NC1pi
isNCINC_PassExpectations[&fe_NCNpi_1] = true; // numu NC multi pi
ctr = 0;
for (std::map<ConstructibleFitEvent *, bool>::iterator
fe_it = isNCINC_PassExpectations.begin();
fe_it != isNCINC_PassExpectations.end(); ++fe_it, ++ctr) {
bool res = SignalDef::isNCINC(fe_it->first, 14);
if (res != fe_it->second) {
ERR(FTL) << "Event: (" << ctr << ")\n"
<< fe_it->first->ToString() << std::endl;
ERR(FTL) << (res ? "passed" : "failed")
<< " SignalDef::isNCINC unexpectedly." << std::endl;
} else {
LOG(SAM) << "Event: (" << ctr << ") " << (res ? "passed" : "failed")
<< " as expected." << std::endl;
}
if (FailOnFail) {
assert(res == fe_it->second);
}
}
LOG(FIT) << "* Testing: SignalDef::isCC0pi" << std::endl;
std::map<ConstructibleFitEvent *, bool> isCC0pi_PassExpectations;
isCC0pi_PassExpectations[&fe_CC0pi_1] = true; // numu CC0pi
isCC0pi_PassExpectations[&fe_CC0pi_2] = true; // numu CC0pi (2p2h)
isCC0pi_PassExpectations[&fe_CC0pi_3] = false; // numub CC0pi
isCC0pi_PassExpectations[&fe_CC0pi_4] = true; // numu CC0pi (RES)
isCC0pi_PassExpectations[&fe_CC1pip_1] = false; // numu CC1pip (2p2h)
isCC0pi_PassExpectations[&fe_CC1pim_1] = false; // numu CC1pim
isCC0pi_PassExpectations[&fe_CC1pi0_1] = false; // numu CC1pi0
isCC0pi_PassExpectations[&fe_CC1pi0_2] = false; // nue CC1pi0
isCC0pi_PassExpectations[&fe_CCNpi_1] = false; // numu CC multi pi
isCC0pi_PassExpectations[&fe_CCNpi_2] = false; // numu CC multi pi
isCC0pi_PassExpectations[&fe_CCNpi_3] = false; // numu CC multi pi
isCC0pi_PassExpectations[&fe_CCNpi_4] = false; // numu CC multi pi
isCC0pi_PassExpectations[&fe_CCCOH_1] = false; // numu CC COH pi
isCC0pi_PassExpectations[&fe_NCel_1] = false; // numu NCEl
isCC0pi_PassExpectations[&fe_NCel_2] = false; // nue NCEl
isCC0pi_PassExpectations[&fe_NC1pi_1] = false; // numu NC1pi
isCC0pi_PassExpectations[&fe_NCNpi_1] = false; // numu NC multi pi
ctr = 0;
for (std::map<ConstructibleFitEvent *, bool>::iterator
fe_it = isCC0pi_PassExpectations.begin();
fe_it != isCC0pi_PassExpectations.end(); ++fe_it, ++ctr) {
bool res = SignalDef::isCC0pi(fe_it->first, 14);
if (res != fe_it->second) {
ERR(FTL) << "Event: (" << ctr << ")\n"
<< fe_it->first->ToString() << " " << std::endl;
ERR(FTL) << (res ? "passed" : "failed")
<< " SignalDef::isCC0pi unexpectedly." << std::endl;
} else {
LOG(SAM) << "Event: (" << ctr << ") " << (res ? "passed" : "failed")
<< " as expected." << std::endl;
}
if (FailOnFail) {
assert(res == fe_it->second);
}
}
LOG(FIT) << "* Testing: SignalDef::isCCQELike" << std::endl;
std::map<ConstructibleFitEvent *, bool> isCCQELike_PassExpectations;
isCCQELike_PassExpectations[&fe_CC0pi_1] = true; // numu CC0pi
isCCQELike_PassExpectations[&fe_CC0pi_2] = true; // numu CC0pi (2p2h)
isCCQELike_PassExpectations[&fe_CC0pi_3] = false; // numub CC0pi
isCCQELike_PassExpectations[&fe_CC0pi_4] = false; // numu CC0pi (RES)
isCCQELike_PassExpectations[&fe_CC1pip_1] = true; // numu CC1pip (2p2h)
isCCQELike_PassExpectations[&fe_CC1pim_1] = false; // numu CC1pim
isCCQELike_PassExpectations[&fe_CC1pi0_1] = false; // numu CC1pi0
isCCQELike_PassExpectations[&fe_CC1pi0_2] = false; // nue CC1pi0
isCCQELike_PassExpectations[&fe_CCNpi_1] = false; // numu CC multi pi
isCCQELike_PassExpectations[&fe_CCNpi_2] = false; // numu CC multi pi
isCCQELike_PassExpectations[&fe_CCNpi_3] = false; // numu CC multi pi
isCCQELike_PassExpectations[&fe_CCNpi_4] = false; // numu CC multi pi
isCCQELike_PassExpectations[&fe_CCCOH_1] = false; // numu CC COH pi
isCCQELike_PassExpectations[&fe_NCel_1] = false; // numu NCEl
isCCQELike_PassExpectations[&fe_NCel_2] = false; // nue NCEl
isCCQELike_PassExpectations[&fe_NC1pi_1] = false; // numu NC1pi
isCCQELike_PassExpectations[&fe_NCNpi_1] = false; // numu NC multi pi
ctr = 0;
for (std::map<ConstructibleFitEvent *, bool>::iterator
fe_it = isCCQELike_PassExpectations.begin();
fe_it != isCCQELike_PassExpectations.end(); ++fe_it, ++ctr) {
bool res = SignalDef::isCCQELike(fe_it->first, 14);
if (res != fe_it->second) {
ERR(FTL) << "Event: (" << ctr << ")\n"
<< fe_it->first->ToString() << std::endl;
ERR(FTL) << (res ? "passed" : "failed")
<< " SignalDef::isCCQELike unexpectedly." << std::endl;
} else {
LOG(SAM) << "Event: (" << ctr << ") " << (res ? "passed" : "failed")
<< " as expected." << std::endl;
}
if (FailOnFail) {
assert(res == fe_it->second);
}
}
LOG(FIT) << "* Testing: SignalDef::isCCQE" << std::endl;
std::map<ConstructibleFitEvent *, bool> isCCQE_PassExpectations;
isCCQE_PassExpectations[&fe_CC0pi_1] = true; // numu CC0pi
isCCQE_PassExpectations[&fe_CC0pi_2] = false; // numu CC0pi (2p2h)
isCCQE_PassExpectations[&fe_CC0pi_3] = false; // numub CC0pi
isCCQE_PassExpectations[&fe_CC0pi_4] = false; // numu CC0pi (RES)
isCCQE_PassExpectations[&fe_CC1pip_1] = false; // numu CC1pip (2p2h)
isCCQE_PassExpectations[&fe_CC1pim_1] = false; // numu CC1pim
isCCQE_PassExpectations[&fe_CC1pi0_1] = false; // numu CC1pi0
isCCQE_PassExpectations[&fe_CC1pi0_2] = false; // nue CC1pi0
isCCQE_PassExpectations[&fe_CCNpi_1] = false; // numu CC multi pi
isCCQE_PassExpectations[&fe_CCNpi_2] = false; // numu CC multi pi
isCCQE_PassExpectations[&fe_CCNpi_3] = false; // numu CC multi pi
isCCQE_PassExpectations[&fe_CCNpi_4] = false; // numu CC multi pi
isCCQE_PassExpectations[&fe_CCCOH_1] = false; // numu CC COH pi
isCCQE_PassExpectations[&fe_NCel_1] = false; // numu NCEl
isCCQE_PassExpectations[&fe_NCel_2] = false; // nue NCEl
isCCQE_PassExpectations[&fe_NC1pi_1] = false; // numu NC1pi
isCCQE_PassExpectations[&fe_NCNpi_1] = false; // numu NC multi pi
ctr = 0;
for (std::map<ConstructibleFitEvent *, bool>::iterator
fe_it = isCCQE_PassExpectations.begin();
fe_it != isCCQE_PassExpectations.end(); ++fe_it, ++ctr) {
bool res = SignalDef::isCCQE(fe_it->first, 14);
if (res != fe_it->second) {
ERR(FTL) << "Event: (" << ctr << ")\n"
<< fe_it->first->ToString() << std::endl;
ERR(FTL) << (res ? "passed" : "failed")
<< " SignalDef::isCCQE unexpectedly." << std::endl;
} else {
LOG(SAM) << "Event: (" << ctr << ") " << (res ? "passed" : "failed")
<< " as expected." << std::endl;
}
if (FailOnFail) {
assert(res == fe_it->second);
}
}
LOG(FIT) << "* Testing: SignalDef::isCCCOH" << std::endl;
std::map<ConstructibleFitEvent *, bool> isCCCOH_PassExpectations;
isCCCOH_PassExpectations[&fe_CC0pi_1] = false; // numu CC0pi
isCCCOH_PassExpectations[&fe_CC0pi_2] = false; // numu CC0pi (2p2h)
isCCCOH_PassExpectations[&fe_CC0pi_3] = false; // numub CC0pi
isCCCOH_PassExpectations[&fe_CC0pi_4] = false; // numu CC0pi (RES)
isCCCOH_PassExpectations[&fe_CC1pip_1] = false; // numu CC1pip (2p2h)
isCCCOH_PassExpectations[&fe_CC1pim_1] = false; // numu CC1pim
isCCCOH_PassExpectations[&fe_CC1pi0_1] = false; // numu CC1pi0
isCCCOH_PassExpectations[&fe_CC1pi0_2] = false; // nue CC1pi0
isCCCOH_PassExpectations[&fe_CCNpi_1] = false; // numu CC multi pi
isCCCOH_PassExpectations[&fe_CCNpi_2] = false; // numu CC multi pi
isCCCOH_PassExpectations[&fe_CCNpi_3] = false; // numu CC multi pi
isCCCOH_PassExpectations[&fe_CCNpi_4] = false; // numu CC multi pi
isCCCOH_PassExpectations[&fe_CCCOH_1] = true; // numu CC COH pi
isCCCOH_PassExpectations[&fe_NCel_1] = false; // numu NCEl
isCCCOH_PassExpectations[&fe_NCel_2] = false; // nue NCEl
isCCCOH_PassExpectations[&fe_NC1pi_1] = false; // numu NC1pi
isCCCOH_PassExpectations[&fe_NCNpi_1] = false; // numu NC multi pi
ctr = 0;
for (std::map<ConstructibleFitEvent *, bool>::iterator
fe_it = isCCCOH_PassExpectations.begin();
fe_it != isCCCOH_PassExpectations.end(); ++fe_it, ++ctr) {
bool res = SignalDef::isCCCOH(fe_it->first, 14, 211);
if (res != fe_it->second) {
ERR(FTL) << "Event: (" << ctr << ")\n"
<< fe_it->first->ToString() << std::endl;
ERR(FTL) << (res ? "passed" : "failed")
<< " SignalDef::isCCCOH unexpectedly." << std::endl;
} else {
LOG(SAM) << "Event: (" << ctr << ") " << (res ? "passed" : "failed")
<< " as expected." << std::endl;
}
if (FailOnFail) {
assert(res == fe_it->second);
}
}
LOG(FIT) << "* Testing: SignalDef::isCC1pi" << std::endl;
std::map<ConstructibleFitEvent *, bool> isCC1pi_PassExpectations;
isCC1pi_PassExpectations[&fe_CC0pi_1] = false; // numu CC0pi
isCC1pi_PassExpectations[&fe_CC0pi_2] = false; // numu CC0pi (2p2h)
isCC1pi_PassExpectations[&fe_CC0pi_3] = false; // numub CC0pi
isCC1pi_PassExpectations[&fe_CC0pi_4] = false; // numu CC0pi (RES)
isCC1pi_PassExpectations[&fe_CC1pip_1] = true; // numu CC1pip (2p2h)
isCC1pi_PassExpectations[&fe_CC1pim_1] = false; // numu CC1pim
isCC1pi_PassExpectations[&fe_CC1pi0_1] = false; // numu CC1pi0
isCC1pi_PassExpectations[&fe_CC1pi0_2] = false; // nue CC1pi0
isCC1pi_PassExpectations[&fe_CCNpi_1] = false; // numu CC multi pi
isCC1pi_PassExpectations[&fe_CCNpi_2] = false; // numu CC multi pi
isCC1pi_PassExpectations[&fe_CCNpi_3] = false; // numu CC multi pi
isCC1pi_PassExpectations[&fe_CCNpi_4] = false; // numu CC multi pi
isCC1pi_PassExpectations[&fe_CCCOH_1] = true; // numu CC COH pi
isCC1pi_PassExpectations[&fe_NCel_1] = false; // numu NCEl
isCC1pi_PassExpectations[&fe_NCel_2] = false; // nue NCEl
isCC1pi_PassExpectations[&fe_NC1pi_1] = false; // numu NC1pi
isCC1pi_PassExpectations[&fe_NCNpi_1] = false; // numu NC multi pi
ctr = 0;
for (std::map<ConstructibleFitEvent *, bool>::iterator
fe_it = isCC1pi_PassExpectations.begin();
fe_it != isCC1pi_PassExpectations.end(); ++fe_it, ++ctr) {
bool res = SignalDef::isCC1pi(fe_it->first, 14, 211);
if (res != fe_it->second) {
ERR(FTL) << "Event: (" << ctr << ")\n"
<< fe_it->first->ToString() << std::endl;
ERR(FTL) << (res ? "passed" : "failed")
<< " SignalDef::isCC1pi unexpectedly." << std::endl;
} else {
LOG(SAM) << "Event: (" << ctr << ") " << (res ? "passed" : "failed")
<< " as expected." << std::endl;
}
if (FailOnFail) {
assert(res == fe_it->second);
}
}
LOG(FIT) << "* Testing: SignalDef::isNC1pi" << std::endl;
std::map<ConstructibleFitEvent *, bool> isNC1pi_PassExpectations;
isNC1pi_PassExpectations[&fe_CC0pi_1] = false; // numu CC0pi
isNC1pi_PassExpectations[&fe_CC0pi_2] = false; // numu CC0pi (2p2h)
isNC1pi_PassExpectations[&fe_CC0pi_3] = false; // numub CC0pi
isCCINC_PassExpectations[&fe_CC0pi_4] = false; // numu CC0pi (RES)
isNC1pi_PassExpectations[&fe_CC1pip_1] = false; // numu CC1pip (2p2h)
isNC1pi_PassExpectations[&fe_CC1pim_1] = false; // numu CC1pim
isNC1pi_PassExpectations[&fe_CC1pi0_1] = false; // numu CC1pi0
isNC1pi_PassExpectations[&fe_CC1pi0_2] = false; // nue CC1pi0
isNC1pi_PassExpectations[&fe_CCNpi_1] = false; // numu CC multi pi
isNC1pi_PassExpectations[&fe_CCNpi_2] = false; // numu CC multi pi
isNC1pi_PassExpectations[&fe_CCNpi_3] = false; // numu CC multi pi
isNC1pi_PassExpectations[&fe_CCNpi_4] = false; // numu CC multi pi
isCCINC_PassExpectations[&fe_CCCOH_1] = false; // numu CC COH pi
isNC1pi_PassExpectations[&fe_NCel_1] = false; // numu NCEl
isNC1pi_PassExpectations[&fe_NCel_2] = false; // nue NCEl
isCCINC_PassExpectations[&fe_NC1pi_1] = true; // numu NC1pi
isCCINC_PassExpectations[&fe_NCNpi_1] = false; // numu NC multi pi
ctr = 0;
for (std::map<ConstructibleFitEvent *, bool>::iterator
fe_it = isNC1pi_PassExpectations.begin();
fe_it != isNC1pi_PassExpectations.end(); ++fe_it, ++ctr) {
bool res = SignalDef::isNC1pi(fe_it->first, 14, -211);
if (res != fe_it->second) {
ERR(FTL) << "Event: (" << ctr << ")\n"
<< fe_it->first->ToString() << std::endl;
ERR(FTL) << (res ? "passed" : "failed")
<< " SignalDef::isNC1pi unexpectedly." << std::endl;
} else {
LOG(SAM) << "Event: (" << ctr << ") " << (res ? "passed" : "failed")
<< " as expected." << std::endl;
}
if (FailOnFail) {
assert(res == fe_it->second);
}
}
// SignalDef::isCCWithFS(&fe,14);
}
diff --git a/src/Utils/PlotUtils.cxx b/src/Utils/PlotUtils.cxx
index 1c84777..40d2f13 100644
--- a/src/Utils/PlotUtils.cxx
+++ b/src/Utils/PlotUtils.cxx
@@ -1,1027 +1,1029 @@
// 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 "PlotUtils.h"
#include "FitEvent.h"
#include "StatUtils.h"
// MOVE TO MB UTILS!
// This function is intended to be modified to enforce a consistent masking for
// all models.
TH2D* PlotUtils::SetMaskHist(std::string type, TH2D* data) {
TH2D* fMaskHist = (TH2D*)data->Clone("fMaskHist");
for (int xBin = 0; xBin < fMaskHist->GetNbinsX(); ++xBin) {
for (int yBin = 0; yBin < fMaskHist->GetNbinsY(); ++yBin) {
if (data->GetBinContent(xBin + 1, yBin + 1) == 0)
fMaskHist->SetBinContent(xBin + 1, yBin + 1, 0);
else
fMaskHist->SetBinContent(xBin + 1, yBin + 1, 0.5);
if (!type.compare("MB_numu_2D")) {
if (yBin == 19 && xBin < 8)
fMaskHist->SetBinContent(xBin + 1, yBin + 1, 1.0);
} else {
if (yBin == 19 && xBin < 11)
fMaskHist->SetBinContent(xBin + 1, yBin + 1, 1.0);
}
if (yBin == 18 && xBin < 3)
fMaskHist->SetBinContent(xBin + 1, yBin + 1, 1.0);
if (yBin == 17 && xBin < 2)
fMaskHist->SetBinContent(xBin + 1, yBin + 1, 1.0);
if (yBin == 16 && xBin < 1)
fMaskHist->SetBinContent(xBin + 1, yBin + 1, 1.0);
}
}
return fMaskHist;
};
// MOVE TO GENERAL UTILS?
bool PlotUtils::CheckObjectWithName(TFile* inFile, std::string substring) {
TIter nextkey(inFile->GetListOfKeys());
TKey* key;
while ((key = (TKey*)nextkey())) {
std::string test(key->GetName());
if (test.find(substring) != std::string::npos) return true;
}
return false;
};
// MOVE TO GENERAL UTILS?
std::string PlotUtils::GetObjectWithName(TFile* inFile, std::string substring) {
TIter nextkey(inFile->GetListOfKeys());
TKey* key;
std::string output = "";
while ((key = (TKey*)nextkey())) {
std::string test(key->GetName());
if (test.find(substring) != std::string::npos) output = test;
}
return output;
};
void PlotUtils::CreateNeutModeArray(TH1* hist, TH1* neutarray[]) {
for (int i = 0; i < 60; i++) {
neutarray[i] = (TH1*)hist->Clone(Form("%s_NMODE_%i", hist->GetName(), i));
}
return;
};
void PlotUtils::DeleteNeutModeArray(TH1* neutarray[]) {
for (int i = 0; i < 60; i++) {
delete neutarray[i];
}
return;
};
void PlotUtils::FillNeutModeArray(TH1D* hist[], int mode, double xval,
double weight) {
if (abs(mode) > 60) return;
hist[abs(mode)]->Fill(xval, weight);
return;
};
void PlotUtils::FillNeutModeArray(TH2D* hist[], int mode, double xval,
double yval, double weight) {
if (abs(mode) > 60) return;
hist[abs(mode)]->Fill(xval, yval, weight);
return;
};
THStack PlotUtils::GetNeutModeStack(std::string title, TH1* ModeStack[],
int option) {
(void)option;
THStack allmodes = THStack(title.c_str(), title.c_str());
for (int i = 0; i < 60; i++) {
allmodes.Add(ModeStack[i]);
}
// Credit to Clarence for copying all this out.
// CC
ModeStack[1]->SetTitle("CCQE");
ModeStack[1]->SetFillColor(kBlue);
// ModeStack[1]->SetFillStyle(3444);
ModeStack[1]->SetLineColor(kBlue);
ModeStack[2]->SetTitle("2p/2h Nieves");
ModeStack[2]->SetFillColor(kRed);
// ModeStack[2]->SetFillStyle(3344);
ModeStack[2]->SetLineColor(kRed);
// ModeStack[11]->SetTitle("#it{#nu + p #rightarrow l^{-} + p + #pi^{+}}");
ModeStack[11]->SetTitle("CC1#pi^{+} on p");
ModeStack[11]->SetFillColor(kGreen);
// ModeStack[11]->SetFillStyle(3004);
ModeStack[11]->SetLineColor(kGreen);
// ModeStack[12]->SetTitle("#it{#nu + n #rightarrow l^{-} + p + #pi^{0}}");
ModeStack[12]->SetTitle("CC1#pi^{0} on n");
ModeStack[12]->SetFillColor(kGreen + 3);
// ModeStack[12]->SetFillStyle(3005);
ModeStack[12]->SetLineColor(kGreen);
// ModeStack[13]->SetTitle("#it{#nu + n #rightarrow l^{-} + n + #pi^{+}}");
ModeStack[13]->SetTitle("CC1#pi^{+} on n");
ModeStack[13]->SetFillColor(kGreen - 2);
// ModeStack[13]->SetFillStyle(3004);
ModeStack[13]->SetLineColor(kGreen);
ModeStack[16]->SetTitle("CC coherent");
ModeStack[16]->SetFillColor(kBlue);
// ModeStack[16]->SetFillStyle(3644);
ModeStack[16]->SetLineColor(kBlue);
// ModeStack[17]->SetTitle("#it{#nu + n #rightarrow l^{-} + p + #gamma}");
ModeStack[17]->SetTitle("CC1#gamma");
ModeStack[17]->SetFillColor(kMagenta);
// ModeStack[17]->SetFillStyle(3001);
ModeStack[17]->SetLineColor(kMagenta);
ModeStack[21]->SetTitle("Multi #pi (1.3 < W < 2.0)");
ModeStack[21]->SetFillColor(kYellow);
// ModeStack[21]->SetFillStyle(3005);
ModeStack[21]->SetLineColor(kYellow);
// ModeStack[22]->SetTitle("#it{#nu + n #rightarrow l^{-} + p + #eta^{0}}");
ModeStack[22]->SetTitle("CC1#eta^{0} on n");
ModeStack[22]->SetFillColor(kYellow - 2);
// ModeStack[22]->SetFillStyle(3013);
ModeStack[22]->SetLineColor(kYellow - 2);
// ModeStack[23]->SetTitle("#it{#nu + n #rightarrow l^{-} + #Lambda +
// K^{+}}");
ModeStack[23]->SetTitle("CC1#Labda1K^{+}");
ModeStack[23]->SetFillColor(kYellow - 6);
// ModeStack[23]->SetFillStyle(3013);
ModeStack[23]->SetLineColor(kYellow - 6);
ModeStack[26]->SetTitle("DIS (W > 2.0)");
ModeStack[26]->SetFillColor(kRed);
// ModeStack[26]->SetFillStyle(3006);
ModeStack[26]->SetLineColor(kRed);
// NC
// ModeStack[31]->SetTitle("#it{#nu + n #rightarrow #nu + n + #pi^{0}}");
ModeStack[31]->SetTitle("NC1#pi^{0} on n");
ModeStack[31]->SetFillColor(kBlue);
// ModeStack[31]->SetFillStyle(3004);
ModeStack[31]->SetLineColor(kBlue);
// ModeStack[32]->SetTitle("#it{#nu + p #rightarrow #nu + p + #pi^{0}}");
ModeStack[32]->SetTitle("NC1#pi^{0} on p");
ModeStack[32]->SetFillColor(kBlue + 3);
// ModeStack[32]->SetFillStyle(3004);
ModeStack[32]->SetLineColor(kBlue + 3);
// ModeStack[33]->SetTitle("#it{#nu + n #rightarrow #nu + p + #pi^{-}}");
ModeStack[33]->SetTitle("NC1#pi^{-} on n");
ModeStack[33]->SetFillColor(kBlue - 2);
// ModeStack[33]->SetFillStyle(3005);
ModeStack[33]->SetLineColor(kBlue - 2);
// ModeStack[34]->SetTitle("#it{#nu + p #rightarrow #nu + n + #pi^{+}}");
ModeStack[34]->SetTitle("NC1#pi^{+} on p");
ModeStack[34]->SetFillColor(kBlue - 8);
// ModeStack[34]->SetFillStyle(3005);
ModeStack[34]->SetLineColor(kBlue - 8);
ModeStack[36]->SetTitle("NC Coherent");
ModeStack[36]->SetFillColor(kBlue + 8);
// ModeStack[36]->SetFillStyle(3644);
ModeStack[36]->SetLineColor(kBlue + 8);
// ModeStack[38]->SetTitle("#it{#nu + n #rightarrow #nu + n + #gamma}");
ModeStack[38]->SetTitle("NC1#gamma on n");
ModeStack[38]->SetFillColor(kMagenta);
// ModeStack[38]->SetFillStyle(3001);
ModeStack[38]->SetLineColor(kMagenta);
// ModeStack[39]->SetTitle("#it{#nu + p #rightarrow #nu + p + #gamma}");
ModeStack[39]->SetTitle("NC1#gamma on p");
ModeStack[39]->SetFillColor(kMagenta - 10);
// ModeStack[39]->SetFillStyle(3001);
ModeStack[39]->SetLineColor(kMagenta - 10);
ModeStack[41]->SetTitle("Multi #pi (1.3 < W < 2.0)");
ModeStack[41]->SetFillColor(kBlue - 10);
// ModeStack[41]->SetFillStyle(3005);
ModeStack[41]->SetLineColor(kBlue - 10);
// ModeStack[42]->SetTitle("#it{#nu + n #rightarrow #nu + n + #eta^{0}}");
ModeStack[42]->SetTitle("NC1#eta^{0} on n");
ModeStack[42]->SetFillColor(kYellow - 2);
// ModeStack[42]->SetFillStyle(3013);
ModeStack[42]->SetLineColor(kYellow - 2);
// ModeStack[43]->SetTitle("#it{#nu + p #rightarrow #nu + p + #eta^{0}}");
ModeStack[43]->SetTitle("NC1#eta^{0} on p");
ModeStack[43]->SetFillColor(kYellow - 4);
// ModeStack[43]->SetFillStyle(3013);
ModeStack[43]->SetLineColor(kYellow - 4);
// ModeStack[44]->SetTitle("#it{#nu + n #rightarrow #nu + #Lambda + K^{0}}");
ModeStack[44]->SetTitle("NC1#Lambda1K^{0} on n");
ModeStack[44]->SetFillColor(kYellow - 6);
// ModeStack[44]->SetFillStyle(3014);
ModeStack[44]->SetLineColor(kYellow - 6);
// ModeStack[45]->SetTitle("#it{#nu + p #rightarrow #nu + #Lambda + K^{+}}");
ModeStack[45]->SetTitle("NC1#Lambda1K^{+}");
ModeStack[45]->SetFillColor(kYellow - 10);
// ModeStack[45]->SetFillStyle(3014);
ModeStack[45]->SetLineColor(kYellow - 10);
ModeStack[46]->SetTitle("DIS (W > 2.0)");
ModeStack[46]->SetFillColor(kRed);
// ModeStack[46]->SetFillStyle(3006);
ModeStack[46]->SetLineColor(kRed);
// ModeStack[51]->SetTitle("#it{#nu + p #rightarrow #nu + p}");
ModeStack[51]->SetTitle("NC on p");
ModeStack[51]->SetFillColor(kBlack);
// ModeStack[51]->SetFillStyle(3444);
ModeStack[51]->SetLineColor(kBlack);
// ModeStack[52]->SetTitle("#it{#nu + n #rightarrow #nu + n}");
ModeStack[52]->SetTitle("NC on n");
ModeStack[52]->SetFillColor(kGray);
// ModeStack[52]->SetFillStyle(3444);
ModeStack[52]->SetLineColor(kGray);
return allmodes;
};
TLegend PlotUtils::GenerateStackLegend(THStack stack, int xlow, int ylow,
int xhigh, int yhigh) {
TLegend leg = TLegend(xlow, ylow, xhigh, yhigh);
TObjArray* histarray = stack.GetStack();
int nhist = histarray->GetEntries();
for (int i = 0; i < nhist; i++) {
TH1* hist = (TH1*)(histarray->At(i));
leg.AddEntry((hist), ((TH1*)histarray->At(i))->GetTitle(), "fl");
}
leg.SetName(Form("%s_LEG", stack.GetName()));
return leg;
};
void PlotUtils::ScaleNeutModeArray(TH1* hist[], double factor,
std::string option) {
for (int i = 0; i < 60; i++) {
if (hist[i]) hist[i]->Scale(factor, option.c_str());
}
return;
};
void PlotUtils::ResetNeutModeArray(TH1* hist[]) {
for (int i = 0; i < 60; i++) {
if (hist[i]) hist[i]->Reset();
}
return;
};
//********************************************************************
// This assumes the Enu axis is the x axis, as is the case for MiniBooNE 2D
// distributions
void PlotUtils::FluxUnfoldedScaling(TH2D* fMCHist, TH1D* fhist, TH1D* ehist,
double scalefactor) {
//********************************************************************
// Make clones to avoid changing stuff
TH1D* eventhist = (TH1D*)ehist->Clone();
TH1D* fFluxHist = (TH1D*)fhist->Clone();
// Undo width integral in SF
fMCHist->Scale(scalefactor /
eventhist->Integral(1, eventhist->GetNbinsX() + 1, "width"));
// Standardise The Flux
eventhist->Scale(1.0 / fFluxHist->Integral());
fFluxHist->Scale(1.0 / fFluxHist->Integral());
// Do interpolation for 2D plots?
// fFluxHist = PlotUtils::InterpolateFineHistogram(fFluxHist,100,"width");
// eventhist = PlotUtils::InterpolateFineHistogram(eventhist,100,"width");
// eventhist->Scale(1.0/fFluxHist->Integral());
// fFluxHist->Scale(1.0/fFluxHist->Integral());
// Scale fMCHist by eventhist integral
fMCHist->Scale(eventhist->Integral(1, eventhist->GetNbinsX() + 1));
// Now Get a flux PDF assuming X axis is Enu
TH1D* pdfflux = (TH1D*)fMCHist->ProjectionX()->Clone();
// pdfflux->Write( (std::string(fMCHist->GetName()) + "_PROJX").c_str());
pdfflux->Reset();
// Awful MiniBooNE Check for the time being
bool ismb =
std::string(fMCHist->GetName()).find("MiniBooNE") != std::string::npos;
for (int i = 0; i < pdfflux->GetNbinsX(); i++) {
double Ml = pdfflux->GetXaxis()->GetBinLowEdge(i + 1);
double Mh = pdfflux->GetXaxis()->GetBinLowEdge(i + 2);
// double Mc = pdfflux->GetXaxis()->GetBinCenter(i+1);
// double Mw = pdfflux->GetBinWidth(i+1);
double fluxint = 0.0;
// Scaling to match flux for MB
if (ismb) {
Ml /= 1.E3;
Mh /= 1.E3;
// Mc /= 1.E3;
// Mw /= 1.E3;
}
for (int j = 0; j < fFluxHist->GetNbinsX(); j++) {
// double Fc = fFluxHist->GetXaxis()->GetBinCenter(j+1);
double Fl = fFluxHist->GetXaxis()->GetBinLowEdge(j + 1);
double Fh = fFluxHist->GetXaxis()->GetBinLowEdge(j + 2);
double Fe = fFluxHist->GetBinContent(j + 1);
double Fw = fFluxHist->GetXaxis()->GetBinWidth(j + 1);
if (Fl >= Ml and Fh <= Mh) {
fluxint += Fe;
} else if (Fl < Ml and Fl < Mh and Fh > Ml and Fh < Mh) {
fluxint += Fe * (Fh - Ml) / Fw;
} else if (Fh > Mh and Fl < Mh and Fh > Ml and Fl > Ml) {
fluxint += Fe * (Mh - Fl) / Fw;
} else if (Ml >= Fl and Mh <= Fh) {
fluxint += Fe * (Mh - Ml) / Fw;
} else {
continue;
}
}
pdfflux->SetBinContent(i + 1, fluxint);
}
for (int i = 0; i < fMCHist->GetNbinsX(); i++) {
for (int j = 0; j < fMCHist->GetNbinsY(); j++) {
if (pdfflux->GetBinContent(i + 1) == 0.0) continue;
double binWidth = fMCHist->GetYaxis()->GetBinLowEdge(j + 2) -
fMCHist->GetYaxis()->GetBinLowEdge(j + 1);
fMCHist->SetBinContent(i + 1, j + 1,
fMCHist->GetBinContent(i + 1, j + 1) /
pdfflux->GetBinContent(i + 1) / binWidth);
fMCHist->SetBinError(i + 1, j + 1, fMCHist->GetBinError(i + 1, j + 1) /
pdfflux->GetBinContent(i + 1) /
binWidth);
}
}
delete eventhist;
delete fFluxHist;
return;
};
TH1D* PlotUtils::InterpolateFineHistogram(TH1D* hist, int res,
std::string opt) {
int nbins = hist->GetNbinsX();
double elow = hist->GetXaxis()->GetBinLowEdge(1);
double ehigh = hist->GetXaxis()->GetBinLowEdge(nbins + 1);
bool width = true; // opt.find("width") != std::string::npos;
TH1D* fine = new TH1D("fine", "fine", nbins * res, elow, ehigh);
TGraph* temp = new TGraph();
for (int i = 0; i < nbins; i++) {
double E = hist->GetXaxis()->GetBinCenter(i + 1);
double C = hist->GetBinContent(i + 1);
double W = hist->GetXaxis()->GetBinWidth(i + 1);
if (!width) W = 1.0;
if (W != 0.0) temp->SetPoint(temp->GetN(), E, C / W);
}
for (int i = 0; i < fine->GetNbinsX(); i++) {
double E = fine->GetXaxis()->GetBinCenter(i + 1);
double W = fine->GetBinWidth(i + 1);
if (!width) W = 1.0;
fine->SetBinContent(i + 1, temp->Eval(E, 0, "S") * W);
}
fine->Scale(hist->Integral(1, hist->GetNbinsX() + 1) /
fine->Integral(1, fine->GetNbinsX() + 1));
std::cout << "Interpolation Difference = "
<< fine->Integral(1, fine->GetNbinsX() + 1) << "/"
<< hist->Integral(1, hist->GetNbinsX() + 1) << std::endl;
return fine;
}
//********************************************************************
// This interpolates the flux by a TGraph instead of requiring the flux and MC
// flux to have the same binning
void PlotUtils::FluxUnfoldedScaling(TH1D* mcHist, TH1D* fhist, TH1D* ehist,
double scalefactor, int nevents) {
//********************************************************************
TH1D* eventhist = (TH1D*)ehist->Clone();
TH1D* fFluxHist = (TH1D*)fhist->Clone();
if (FitPar::Config().GetParB("save_flux_debug")) {
std::string name = std::string(mcHist->GetName());
mcHist->Write((name + "_UNF_MC").c_str());
fFluxHist->Write((name + "_UNF_FLUX").c_str());
eventhist->Write((name + "_UNF_EVT").c_str());
TH1D* scalehist = new TH1D("scalehist", "scalehist", 1, 0.0, 1.0);
scalehist->SetBinContent(1, scalefactor);
scalehist->SetBinContent(2, nevents);
scalehist->Write((name + "_UNF_SCALE").c_str());
}
// Undo width integral in SF
mcHist->Scale(scalefactor /
eventhist->Integral(1, eventhist->GetNbinsX() + 1, "width"));
// Standardise The Flux
eventhist->Scale(1.0 / fFluxHist->Integral());
fFluxHist->Scale(1.0 / fFluxHist->Integral());
// Scale mcHist by eventhist integral
mcHist->Scale(eventhist->Integral(1, eventhist->GetNbinsX() + 1));
// Now Get a flux PDF
TH1D* pdfflux = (TH1D*)mcHist->Clone();
pdfflux->Reset();
for (int i = 0; i < mcHist->GetNbinsX(); i++) {
double Ml = mcHist->GetXaxis()->GetBinLowEdge(i + 1);
double Mh = mcHist->GetXaxis()->GetBinLowEdge(i + 2);
// double Mc = mcHist->GetXaxis()->GetBinCenter(i+1);
// double Me = mcHist->GetBinContent(i+1);
// double Mw = mcHist->GetBinWidth(i+1);
double fluxint = 0.0;
for (int j = 0; j < fFluxHist->GetNbinsX(); j++) {
// double Fc = fFluxHist->GetXaxis()->GetBinCenter(j+1);
double Fl = fFluxHist->GetXaxis()->GetBinLowEdge(j + 1);
double Fh = fFluxHist->GetXaxis()->GetBinLowEdge(j + 2);
double Fe = fFluxHist->GetBinContent(j + 1);
double Fw = fFluxHist->GetXaxis()->GetBinWidth(j + 1);
if (Fl >= Ml and Fh <= Mh) {
fluxint += Fe;
} else if (Fl < Ml and Fl < Mh and Fh > Ml and Fh < Mh) {
fluxint += Fe * (Fh - Ml) / Fw;
} else if (Fh > Mh and Fl < Mh and Fh > Ml and Fl > Ml) {
fluxint += Fe * (Mh - Fl) / Fw;
} else if (Ml >= Fl and Mh <= Fh) {
fluxint += Fe * (Mh - Ml) / Fw;
} else {
continue;
}
}
pdfflux->SetBinContent(i + 1, fluxint);
}
// Scale MC hist by pdfflux
for (int i = 0; i < mcHist->GetNbinsX(); i++) {
if (pdfflux->GetBinContent(i + 1) == 0.0) continue;
mcHist->SetBinContent(
i + 1, mcHist->GetBinContent(i + 1) / pdfflux->GetBinContent(i + 1));
mcHist->SetBinError(
i + 1, mcHist->GetBinError(i + 1) / pdfflux->GetBinContent(i + 1));
}
delete eventhist;
delete fFluxHist;
return;
};
// MOVE TO GENERAL UTILS
//********************************************************************
void PlotUtils::Set2DHistFromText(std::string dataFile, TH2* hist, double norm,
bool skipbins) {
//********************************************************************
std::string line;
- std::ifstream data(dataFile.c_str(), ifstream::in);
+ std::ifstream data(dataFile.c_str(), std::ifstream::in);
int yBin = 0;
while (std::getline(data >> std::ws, line, '\n')) {
std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
// Loop over entries and insert them into the histogram
for (uint xBin = 0; xBin < entries.size(); xBin++) {
if (!skipbins or entries[xBin] != -1.0)
hist->SetBinContent(xBin + 1, yBin + 1, entries[xBin] * norm);
}
yBin++;
}
return;
}
// MOVE TO GENERAL UTILS
TH1D* PlotUtils::GetTH1DFromFile(std::string dataFile, std::string title,
std::string fPlotTitles,
std::string alt_name) {
TH1D* tempPlot;
// If format is a root file
if (dataFile.find(".root") != std::string::npos) {
TFile* temp_infile = new TFile(dataFile.c_str(), "READ");
tempPlot = (TH1D*)temp_infile->Get(title.c_str());
tempPlot->SetDirectory(0);
temp_infile->Close();
delete temp_infile;
// Else its a space seperated txt file
} else {
// Make a TGraph Errors
TGraphErrors* gr = new TGraphErrors(dataFile.c_str(), "%lg %lg %lg");
if (gr->IsZombie()) {
exit(-1);
}
double* bins = gr->GetX();
double* values = gr->GetY();
double* errors = gr->GetEY();
int npoints = gr->GetN();
// Fill the histogram from it
tempPlot = new TH1D(title.c_str(), title.c_str(), npoints - 1, bins);
for (int i = 0; i < npoints; ++i) {
tempPlot->SetBinContent(i + 1, values[i]);
// If only two columns are present in the input file, use the sqrt(values)
// as the error
// equivalent to assuming that the error is statistical
if (!errors[i])
tempPlot->SetBinError(i + 1, sqrt(values[i]));
else
tempPlot->SetBinError(i + 1, errors[i]);
}
delete gr;
}
// Allow alternate naming for root files
if (!alt_name.empty()) {
tempPlot->SetNameTitle(alt_name.c_str(), alt_name.c_str());
}
// Allow alternate axis titles
if (!fPlotTitles.empty()) {
tempPlot->SetNameTitle(
tempPlot->GetName(),
(std::string(tempPlot->GetTitle()) + fPlotTitles).c_str());
}
return tempPlot;
};
TH1D* PlotUtils::GetRatioPlot(TH1D* hist1, TH1D* hist2) {
// make copy of first hist
TH1D* new_hist = (TH1D*)hist1->Clone();
// Do bins and errors ourselves as scales can go awkward
for (int i = 0; i < new_hist->GetNbinsX(); i++) {
if (hist2->GetBinContent(i + 1) == 0.0) {
new_hist->SetBinContent(i + 1, 0.0);
}
new_hist->SetBinContent(
i + 1, hist1->GetBinContent(i + 1) / hist2->GetBinContent(i + 1));
new_hist->SetBinError(
i + 1, hist1->GetBinError(i + 1) / hist2->GetBinContent(i + 1));
}
return new_hist;
};
TH1D* PlotUtils::GetRenormalisedPlot(TH1D* hist1, TH1D* hist2) {
// make copy of first hist
TH1D* new_hist = (TH1D*)hist1->Clone();
if (hist1->Integral("width") == 0 or hist2->Integral("width") == 0) {
new_hist->Reset();
return new_hist;
}
Double_t scaleF = hist2->Integral("width") / hist1->Integral("width");
new_hist->Scale(scaleF);
return new_hist;
};
TH1D* PlotUtils::GetShapePlot(TH1D* hist1) {
// make copy of first hist
TH1D* new_hist = (TH1D*)hist1->Clone();
if (hist1->Integral("width") == 0) {
new_hist->Reset();
return new_hist;
}
Double_t scaleF1 = 1.0 / hist1->Integral("width");
new_hist->Scale(scaleF1);
return new_hist;
};
TH1D* PlotUtils::GetShapeRatio(TH1D* hist1, TH1D* hist2) {
TH1D* new_hist1 = GetShapePlot(hist1);
TH1D* new_hist2 = GetShapePlot(hist2);
// Do bins and errors ourselves as scales can go awkward
for (int i = 0; i < new_hist1->GetNbinsX(); i++) {
if (hist2->GetBinContent(i + 1) == 0) {
new_hist1->SetBinContent(i + 1, 0.0);
}
new_hist1->SetBinContent(i + 1, new_hist1->GetBinContent(i + 1) /
new_hist2->GetBinContent(i + 1));
new_hist1->SetBinError(
i + 1, new_hist1->GetBinError(i + 1) / new_hist2->GetBinContent(i + 1));
}
delete new_hist2;
return new_hist1;
};
TH2D* PlotUtils::GetCovarPlot(TMatrixDSym* cov, std::string name,
std::string title) {
TH2D* CovarPlot;
if (cov)
CovarPlot = new TH2D((*cov));
else
CovarPlot = new TH2D(name.c_str(), title.c_str(), 1, 0, 1, 1, 0, 1);
CovarPlot->SetName(name.c_str());
CovarPlot->SetTitle(title.c_str());
return CovarPlot;
}
TH2D* PlotUtils::GetFullCovarPlot(TMatrixDSym* cov, std::string name) {
return PlotUtils::GetCovarPlot(
cov, name + "_COV", name + "_COV;Bins;Bins;Covariance (#times10^{-76})");
}
TH2D* PlotUtils::GetInvCovarPlot(TMatrixDSym* cov, std::string name) {
return PlotUtils::GetCovarPlot(
cov, name + "_INVCOV",
name + "_INVCOV;Bins;Bins;Inv. Covariance (#times10^{-76})");
}
TH2D* PlotUtils::GetDecompCovarPlot(TMatrixDSym* cov, std::string name) {
return PlotUtils::GetCovarPlot(
cov, name + "_DECCOV",
name + "_DECCOV;Bins;Bins;Decomp Covariance (#times10^{-76})");
}
TH1D* PlotUtils::GetTH1DFromRootFile(std::string file, std::string name) {
if (name.empty()) {
std::vector<std::string> tempfile = GeneralUtils::ParseToStr(file, ";");
file = tempfile[0];
name = tempfile[1];
}
TFile* rootHistFile = new TFile(file.c_str(), "READ");
TH1D* tempHist = (TH1D*)rootHistFile->Get(name.c_str())->Clone();
tempHist->SetDirectory(0);
rootHistFile->Close();
return tempHist;
}
TH2D* PlotUtils::GetTH2DFromRootFile(std::string file, std::string name) {
if (name.empty()) {
std::vector<std::string> tempfile = GeneralUtils::ParseToStr(file, ";");
file = tempfile[0];
name = tempfile[1];
}
TFile* rootHistFile = new TFile(file.c_str(), "READ");
TH2D* tempHist = (TH2D*)rootHistFile->Get(name.c_str())->Clone();
tempHist->SetDirectory(0);
rootHistFile->Close();
+ delete rootHistFile;
return tempHist;
}
TH1* PlotUtils::GetTH1FromRootFile(std::string file, std::string name) {
if (name.empty()) {
std::vector<std::string> tempfile = GeneralUtils::ParseToStr(file, ";");
file = tempfile[0];
name = tempfile[1];
}
TFile* rootHistFile = new TFile(file.c_str(), "READ");
if (!rootHistFile || rootHistFile->IsZombie()) {
THROW("Couldn't open root file: \"" << file << "\".");
}
TH1* tempHist = dynamic_cast<TH1*>(rootHistFile->Get(name.c_str())->Clone());
if (!tempHist) {
THROW("Couldn't retrieve: \"" << name << "\" from root file: \"" << file
<< "\".");
}
tempHist->SetDirectory(0);
rootHistFile->Close();
+ delete rootHistFile;
return tempHist;
}
TGraph* PlotUtils::GetTGraphFromRootFile(std::string file, std::string name) {
if (name.empty()) {
std::vector<std::string> tempfile = GeneralUtils::ParseToStr(file, ";");
file = tempfile[0];
name = tempfile[1];
}
TDirectory* olddir = gDirectory;
TFile* rootHistFile = new TFile(file.c_str(), "READ");
if (!rootHistFile || rootHistFile->IsZombie()) {
THROW("Couldn't open root file: \"" << file << "\".");
}
TDirectory* newdir = gDirectory;
TGraph* temp = dynamic_cast<TGraph*>(rootHistFile->Get(name.c_str())->Clone());
if (!temp) {
THROW("Couldn't retrieve: \"" << name << "\" from root file: \"" << file
<< "\".");
}
newdir->Remove(temp);
olddir->Append(temp);
rootHistFile->Close();
olddir->cd();
return temp;
}
/// Returns a vector of named TH1*s found in a single input file.
///
/// Expects a descriptor like: file.root[hist1|hist2|...]
std::vector<TH1*> PlotUtils::GetTH1sFromRootFile(
std::string const& descriptor) {
std::vector<std::string> descriptors =
GeneralUtils::ParseToStr(descriptor, ",");
std::vector<TH1*> hists;
for (size_t d_it = 0; d_it < descriptors.size(); ++d_it) {
std::string& d = descriptors[d_it];
std::vector<std::string> fname = GeneralUtils::ParseToStr(d, "[");
if (!fname.size() || !fname[0].length()) {
THROW("Couldn't find input file when attempting to parse : \""
<< d << "\". Expected input.root[hist1|hist2|...].");
}
if (fname[1][fname[1].length() - 1] == ']') {
fname[1] = fname[1].substr(0, fname[1].length() - 1);
}
std::vector<std::string> histnames =
GeneralUtils::ParseToStr(fname[1], "|");
if (!histnames.size()) {
THROW(
"Couldn't find any histogram name specifiers when attempting to "
"parse "
": \""
<< fname[1] << "\". Expected hist1|hist2|...");
}
TFile* rootHistFile = new TFile(fname[0].c_str(), "READ");
if (!rootHistFile || rootHistFile->IsZombie()) {
THROW("Couldn't open root file: \"" << fname[0] << "\".");
}
for (size_t i = 0; i < histnames.size(); ++i) {
TH1* tempHist =
dynamic_cast<TH1*>(rootHistFile->Get(histnames[i].c_str())->Clone());
if (!tempHist) {
THROW("Couldn't retrieve: \"" << histnames[i] << "\" from root file: \""
<< fname[0] << "\".");
}
tempHist->SetDirectory(0);
hists.push_back(tempHist);
}
rootHistFile->Close();
}
return hists;
}
TH2D* PlotUtils::GetTH2DFromTextFile(std::string file) {
/// Contents should be
/// Low Edfe
return NULL;
}
void PlotUtils::AddNeutModeArray(TH1D* hist1[], TH1D* hist2[], double scaling) {
for (int i = 0; i < 60; i++) {
if (!hist2[i]) continue;
if (!hist1[i]) continue;
hist1[i]->Add(hist2[i], scaling);
}
return;
}
void PlotUtils::ScaleToData(TH1D* data, TH1D* mc, TH1I* mask) {
double scaleF = GetDataMCRatio(data, mc, mask);
mc->Scale(scaleF);
return;
}
void PlotUtils::MaskBins(TH1D* hist, TH1I* mask) {
for (int i = 0; i < hist->GetNbinsX(); i++) {
if (mask->GetBinContent(i + 1) <= 0.5) continue;
hist->SetBinContent(i + 1, 0.0);
hist->SetBinError(i + 1, 0.0);
LOG(REC) << "MaskBins: Set " << hist->GetName() << " Bin " << i + 1
<< " to 0.0 +- 0.0" << std::endl;
}
return;
}
void PlotUtils::MaskBins(TH2D* hist, TH2I* mask) {
for (int i = 0; i < hist->GetNbinsX(); i++) {
for (int j = 0; j < hist->GetNbinsY(); j++) {
if (mask->GetBinContent(i + 1, j + 1) <= 0.5) continue;
hist->SetBinContent(i + 1, j + 1, 0.0);
hist->SetBinError(i + 1, j + 1, 0.0);
LOG(REC) << "MaskBins: Set " << hist->GetName() << " Bin " << i + 1 << " "
<< j + 1 << " to 0.0 +- 0.0" << std::endl;
}
}
return;
}
double PlotUtils::GetDataMCRatio(TH1D* data, TH1D* mc, TH1I* mask) {
double rat = 1.0;
TH1D* newmc = (TH1D*)mc->Clone();
TH1D* newdt = (TH1D*)data->Clone();
if (mask) {
MaskBins(newmc, mask);
MaskBins(newdt, mask);
}
rat = newdt->Integral() / newmc->Integral();
return rat;
}
TH2D* PlotUtils::GetCorrelationPlot(TH2D* cov, std::string name) {
TH2D* cor = (TH2D*)cov->Clone();
cor->Reset();
for (int i = 0; i < cov->GetNbinsX(); i++) {
for (int j = 0; j < cov->GetNbinsY(); j++) {
if (cov->GetBinContent(i + 1, i + 1) != 0.0 and
cov->GetBinContent(j + 1, j + 1) != 0.0)
cor->SetBinContent(i + 1, j + 1,
cov->GetBinContent(i + 1, j + 1) /
(sqrt(cov->GetBinContent(i + 1, i + 1) *
cov->GetBinContent(j + 1, j + 1))));
}
}
if (!name.empty()) {
cor->SetNameTitle(name.c_str(), (name + ";;correlation").c_str());
}
cor->SetMinimum(-1);
cor->SetMaximum(1);
return cor;
}
TH2D* PlotUtils::GetDecompPlot(TH2D* cov, std::string name) {
TMatrixDSym* covarmat = new TMatrixDSym(cov->GetNbinsX());
for (int i = 0; i < cov->GetNbinsX(); i++)
for (int j = 0; j < cov->GetNbinsY(); j++)
(*covarmat)(i, j) = cov->GetBinContent(i + 1, j + 1);
TMatrixDSym* decompmat = StatUtils::GetDecomp(covarmat);
TH2D* dec = (TH2D*)cov->Clone();
for (int i = 0; i < cov->GetNbinsX(); i++)
for (int j = 0; j < cov->GetNbinsY(); j++)
dec->SetBinContent(i + 1, j + 1, (*decompmat)(i, j));
delete covarmat;
delete decompmat;
dec->SetNameTitle(name.c_str(), (name + ";;;decomposition").c_str());
return dec;
}
TH2D* PlotUtils::MergeIntoTH2D(TH1D* xhist, TH1D* yhist, std::string zname) {
std::vector<double> xedges, yedges;
for (int i = 0; i < xhist->GetNbinsX() + 2; i++) {
xedges.push_back(xhist->GetXaxis()->GetBinLowEdge(i + 1));
}
for (int i = 0; i < yhist->GetNbinsX() + 2; i++) {
yedges.push_back(yhist->GetXaxis()->GetBinLowEdge(i + 1));
}
int nbinsx = xhist->GetNbinsX();
int nbinsy = yhist->GetNbinsX();
std::string name =
std::string(xhist->GetName()) + "_vs_" + std::string(yhist->GetName());
std::string titles = ";" + std::string(xhist->GetXaxis()->GetTitle()) + ";" +
std::string(yhist->GetXaxis()->GetTitle()) + ";" + zname;
TH2D* newplot = new TH2D(name.c_str(), (name + titles).c_str(), nbinsx,
&xedges[0], nbinsy, &yedges[0]);
return newplot;
}
//***************************************************
void PlotUtils::MatchEmptyBins(TH1D* data, TH1D* mc) {
//**************************************************
for (int i = 0; i < data->GetNbinsX(); i++) {
if (data->GetBinContent(i + 1) == 0.0 or data->GetBinError(i + 1) == 0.0)
mc->SetBinContent(i + 1, 0.0);
}
return;
}
//***************************************************
void PlotUtils::MatchEmptyBins(TH2D* data, TH2D* mc) {
//**************************************************
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 or
data->GetBinError(i + 1, j + 1) == 0.0)
mc->SetBinContent(i + 1, j + 1, 0.0);
}
}
return;
}
//***************************************************
TH1D* PlotUtils::GetProjectionX(TH2D* hist, TH2I* mask) {
//***************************************************
TH2D* maskedhist = StatUtils::ApplyHistogramMasking(hist, mask);
TH1D* hist_X = maskedhist->ProjectionX();
delete maskedhist;
return hist_X;
}
//***************************************************
TH1D* PlotUtils::GetProjectionY(TH2D* hist, TH2I* mask) {
//***************************************************
TH2D* maskedhist = StatUtils::ApplyHistogramMasking(hist, mask);
TH1D* hist_Y = maskedhist->ProjectionY();
delete maskedhist;
return hist_Y;
}

File Metadata

Mime Type
text/x-diff
Expires
Sat, Dec 21, 2:17 PM (12 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4023086
Default Alt Text
(707 KB)

Event Timeline