diff --git a/CMakeLists.txt b/CMakeLists.txt index ceba75d..590b423 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,217 +1,228 @@ # 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 . ################################################################################ cmake_minimum_required (VERSION 2.6 FATAL_ERROR) 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/nuisflat.cxx b/app/nuisflat.cxx index c5c0f1b..cb128e6 100644 --- a/app/nuisflat.cxx +++ b/app/nuisflat.cxx @@ -1,177 +1,187 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "ComparisonRoutines.h" #include "InputUtils.h" #include "MeasurementBase.h" #include "GenericFlux_Tester.h" +#include "GenericFlux_Vectors.h" #include "Smearceptance_Tester.h" // Global Arguments std::string gOptInputFile = ""; std::string gOptFormat = ""; std::string gOptOutputFile = ""; std::string gOptType = "DEFAULT"; std::string gOptNumberEvents = "NULL"; std::string gOptCardInput = ""; std::string gOptOptions = ""; //******************************* void PrintSyntax() { //******************************* - std::cout << "nuisflat -i input -f format [-o outfile] [-n nevents] [-t " + std::cout << "nuisflat -i input [-f format] [-o outfile] [-n nevents] [-t " "options] [-q con=val] \n"; std::cout << "\n Arguments : " << "\n\t -i input : Path to input vector of events to flatten" << "\n\t" << "\n\t This should be given in the same format a normal " "input file" << "\n\t is given to NUISANCE. {e.g. NUWRO:eventsout.root}." << "\n\t" - << "\n\t -f format : FlatTree format to output:" - << "\n\t\t GenericFlux : Standard event summary format." + << "\n\t -f format : FlatTree format to output. If none given GenericVectors used." + << "\n\t\t GenericFlux : Flat event summary format." + << "\n\t\t GenericVectors : Standard event summary format with particle vectors." << "\n\t " << "\n\t[-c crd.xml]: Input card file to override configs or set dial values." << "\n\t " << "\n\t[-o outfile]: Optional output file path. " << "\n\t " << "\n\t If none given, input.format.root is chosen." << "\n\t" << "\n\t[-n nevents]: Optional choice of Nevents to run over. Default is " "all." << "\n\t" << "\n\t[-t options]: Pass OPTION to the FlatTree sample. " << "\n\t Similar to type field in comparison xml configs." << "\n\t" << "\n\t[-q con=val]: Configuration overrides." << std::endl; exit(-1); }; //____________________________________________________________________________ void GetCommandLineArgs(int argc, char** argv) { // Check for -h flag. for (int i = 0; i < argc; i++) { if ((!std::string(argv[i]).compare("-h")) || (!std::string(argv[i]).compare("-?")) || (!std::string(argv[i]).compare("--help"))) PrintSyntax(); } // Format is nuwro -r run_number -n n events std::vector args = GeneralUtils::LoadCharToVectStr(argc, argv); // Parse input file ParserUtils::ParseArgument(args, "-i", gOptInputFile, false); if (gOptInputFile == "") { THROW("Need to provide a valid input file to nuisflat using -i flag!"); } else { LOG(FIT) << "Reading Input File = " << gOptInputFile << std::endl; } // Get Output Format ParserUtils::ParseArgument(args, "-f", gOptFormat, false); if (gOptFormat == "") { - THROW("Need to provide a valid output format to nuisflat!"); + gOptFormat = "GenericVectors"; + LOG(FIT) << "Saving flattree in default format = " << gOptFormat << std::endl; } else { LOG(FIT) << "Saving flattree in format = " << gOptFormat << std::endl; } // Get Output File ParserUtils::ParseArgument(args, "-o", gOptOutputFile, false); if (gOptOutputFile == "") { gOptOutputFile = gOptInputFile + "." + gOptFormat + ".root"; LOG(FIT) << "No output file given so saving nuisflat output to:" << gOptOutputFile << std::endl; } else { LOG(FIT) << "Saving nuisflat output to " << gOptOutputFile << std::endl; } // Get N Events and Configs nuisconfig configuration = Config::Get(); ParserUtils::ParseArgument(args, "-n", gOptNumberEvents, false); if (gOptNumberEvents.compare("NULL")) { configuration.OverrideConfig("MAXEVENTS=" + gOptNumberEvents); } std::vector configargs; ParserUtils::ParseArgument(args, "-q", configargs); for (size_t i = 0; i < configargs.size(); i++) { configuration.OverrideConfig(configargs[i]); } ParserUtils::ParseArgument(args, "-c", gOptCardInput, false); if (gOptCardInput != "") { QLOG(FIT, "Reading cardfile: " << gOptCardInput); configuration.LoadSettings(gOptCardInput, ""); } ParserUtils::ParseArgument(args, "-t", gOptOptions, false); if (gOptOptions != "") { QLOG(FIT, "Read options: \"" << gOptOptions << "\'"); } return; } //******************************* int main(int argc, char* argv[]) { //******************************* // Parse GetCommandLineArgs(argc, argv); // Make output file TFile* f = new TFile(gOptOutputFile.c_str(), "RECREATE"); if (f->IsZombie()) { THROW("Cannot create output file!"); } f->cd(); FitPar::Config().out = f; // Create a new measurementbase class depending on the Format MeasurementBase* flattreecreator = NULL; // Make a new sample key for the format of interest. nuiskey samplekey = Config::CreateKey("sample"); if (!gOptFormat.compare("GenericFlux")) { samplekey.Set("name", "FlatTree"); samplekey.Set("input", gOptInputFile); samplekey.Set("type", gOptType); flattreecreator = new GenericFlux_Tester("FlatTree", gOptInputFile, FitBase::GetRW(), gOptType, ""); + } else if (!gOptFormat.compare("GenericVectors")) { + samplekey.Set("name", "FlatTree"); + samplekey.Set("input", gOptInputFile); + samplekey.Set("type", gOptType); + flattreecreator = new GenericFlux_Vectors("FlatTree", gOptInputFile, + FitBase::GetRW(), gOptType, ""); + } else { ERR(FTL) << "Unknown FlatTree format!" << std::endl; } // Make the FlatTree reconfigure flattreecreator->Reconfigure(); f->cd(); flattreecreator->Write(); f->Close(); // Show Final Status LOG(FIT) << "-------------------------------------" << std::endl; LOG(FIT) << "Flattree Generation Complete." << std::endl; LOG(FIT) << "-------------------------------------" << std::endl; return 0; } diff --git a/cmake/BinBlobSetup.header b/cmake/BinBlobSetup.header new file mode 100644 index 0000000..d83827c --- /dev/null +++ b/cmake/BinBlobSetup.header @@ -0,0 +1,47 @@ +### 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 ! echo "${BASH_SOURCE}" | grep "/" --silent; then + SETUP_DIR=$(readlink -f $PWD) +else + SETUP_DIR=$(readlink -f ${BASH_SOURCE%/*}) +fi +export NUISANCE=${SETUP_DIR} diff --git a/cmake/MakeBinaryBlob.in b/cmake/MakeBinaryBlob.in new file mode 100644 index 0000000..b6554b9 --- /dev/null +++ b/cmake/MakeBinaryBlob.in @@ -0,0 +1,173 @@ +# 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 . +################################################################################ + +#!/bin/sh + +if [ ! ${NUISANCE} ]; then + echo "[ERROR]; NUISANCE envrionment variable is not defined, please source NUSIANCE before trying to make a binary blob." + exit 1 +fi + +mkdir BinBlob +cd BinBlob + +echo "#!/bin/sh" > setup.sh + +cat @PROJECT_SOURCE_DIR@/cmake/BinBlobSetup.header >> setup.sh + +mkdir deps exes + +mkdir root + +mkdir -p root/lib/root +echo "[INFO]: Copying ROOT libraries from @CMAKE_ROOTSYS@/lib/root" +cp @CMAKE_ROOTSYS@/lib/root/*.so* root/lib/root/ + +mkdir root/bin +echo "[INFO]: Copying ROOT binary from @CMAKE_ROOTSYS@/bin" +cp @CMAKE_ROOTSYS@/bin/* root/bin + +mkdir -p root/share/man/man1 +echo "[INFO]: Copying ROOT man pages from @CMAKE_ROOTSYS@/share/man/man1" +cp -r @CMAKE_ROOTSYS@/share/man/man1 root/share/man/man1 + +cat root/bin/thisroot.sh | sed 's:@CMAKE_ROOTSYS@:__INST_ROOT__:g' > root/bin/thisroot.sh_tmp +rm root/bin/thisroot.sh + +echo "cat \$NUISANCE/root/bin/thisroot.sh_tmp | sed \"s:__INST_ROOT__:\$NUISANCE/root:g\" > \$NUISANCE/root/bin/thisroot.sh" >> setup.sh + +cat root/bin/thisroot.csh | sed 's:@CMAKE_ROOTSYS@:__INST_ROOT__:g' > root/bin/thisroot.csh_tmp +rm root/bin/thisroot.csh + +echo "cat \$NUISANCE/root/bin/thisroot.csh_tmp | sed \"s:__INST_ROOT__:\$NUISANCE/root:g\" > \$NUISANCE/root/bin/thisroot.csh" >> setup.sh + +echo "source \$NUISANCE/root/bin/thisroot.sh" >> setup.sh + +if [ "@USE_T2K@" != "FALSE" ]; then + mkdir deps/t2k + + echo "[INFO]: Copying T2K libraries from @T2KREWEIGHT@" + cp @T2KREWEIGHT@/lib/*.so deps/t2k/ + + echo "add_to_LD_LIBRARY_PATH \$NUISANCE/deps/t2k" >> setup.sh +fi + + +if [ "@USE_NIWG@" != "FALSE" ]; then + mkdir deps/niwg + echo "[INFO]: Copying NIWG libraries from @NIWG@" + cp @NIWG@/lib/*.so deps/niwg/ + + echo "add_to_LD_LIBRARY_PATH \$NUISANCE/deps/niwg" >> setup.sh +fi + +if [ "@USE_NEUT@" != "FALSE" ]; then + mkdir deps/neut + mkdir exes/neut + + echo "[INFO]: Copying NEUT libraries from @NEUT_ROOT@" + cp @NEUT_ROOT@/src/reweight/*.so* deps/neut + cp @NEUT_ROOT@/src/neutclass/*.so* deps/neut + + cp @NEUT_ROOT@/src/neutsmpl/neutroot2 exes/neut + + echo "add_to_LD_LIBRARY_PATH \$NUISANCE/deps/neut" >> setup.sh +fi + +if [ "@USE_NuWro@" != "FALSE" ]; then + if [ "@NUWRO_BUILT_FROM_FILE@" == "FALSE" ]; then + mkdir deps/nuwro + mkdir exes/nuwro + mkdir data + mkdir data/nuwro + + echo "[INFO]: Copying NuWro libraries from @NUWRO@" + + cp @NUWRO@/lib/*.so deps/nuwro + + cp @NUWRO@/bin/nuwro exes/nuwro/ + cp -r @NUWRO@/data data/nuwro + + echo "add_to_LD_LIBRARY_PATH \$NUISANCE/deps/nuwro" >> setup.sh + echo "export NUWRO=\$NUISANCE/data/nuwro" >> setup.sh + + else + echo "[INFO]: NuWro support included from input event file." + fi +fi + +if [ "@NEED_PYTHIA6@" != "FALSE" ]; then + mkdir deps/pythia + echo "[INFO]: Copying PYTHIA libraries from @PYTHIA6@" + cp @PYTHIA6@/*.so deps/pythia/ + + echo "add_to_LD_LIBRARY_PATH \$NUISANCE/deps/pythia" >> setup.sh +fi + +if [ "@USE_GENIE@" != "FALSE" ]; then + mkdir -p deps/genie/{,libxml2,lhapdf,log4cpp} + mkdir exes/genie + + echo "[INFO]: Copying LHAPDF libraries from @LHAPDF_LIB@" + cp @LHAPDF_LIB@/libLHAPDF.so* deps/genie/lhapdf + echo "add_to_LD_LIBRARY_PATH \$NUISANCE/deps/genie/lhapdf" >> setup.sh + + echo "[INFO]: Copying LIBXML2 libraries from @LIBXML2_LIB@" + cp @LIBXML2_LIB@/libxml2.so* deps/genie/libxml2 + echo "add_to_LD_LIBRARY_PATH \$NUISANCE/deps/genie/libxml2" >> setup.sh + + echo "[INFO]: Copying LOG4CPP libraries from @LOG4CPP_LIB@" + cp @LOG4CPP_LIB@/liblog4cpp.so* deps/genie/log4cpp + echo "add_to_LD_LIBRARY_PATH \$NUISANCE/deps/genie/log4cpp" >> setup.sh + + + if [ "@LHAPATH@" ]; then + mkdir -p data/genie/lhapdf + cp @LHAPATH@/*.LHgrid data/genie/lhapdf/ + echo "export LHAPATH=\"\$NUISANCE/data/genie/lhapdf\"" >> setup.sh + fi + + echo "[INFO]: Copying GENIE libraries from @GENIE@/lib" + cp @GENIE@/lib/*.so* deps/genie/ + echo "add_to_LD_LIBRARY_PATH \$NUISANCE/deps/genie" >> setup.sh + + echo "[INFO]: Copying GENIE binaries from @GENIE@/bin" + cp @GENIE@/bin/* exes/genie/ + echo "add_to_PATH \$NUISANCE/exes/genie" >> setup.sh + +fi + +mkdir exes/nuisance +cp @CMAKE_INSTALL_PREFIX@/bin/* exes/nuisance/ +echo "add_to_PATH \$NUISANCE/exes/nuisance" >> setup.sh + +rm exes/nuisance/BuildDynamic* + +if [ @CMAKE_BUILD_TYPE@ == "RELEASE" ]; then + mkdir deps/nuisance + echo "add_to_LD_LIBRARY_PATH \$NUISANCE/deps/nuisance" >> setup.sh + cp @CMAKE_INSTALL_PREFIX@/lib/*.so deps/nuisance/ +fi + +if [ -e data ]; then + tar -zcvf nuisblob.tar.gz setup.sh exes/* deps/* root/* data/* +else + tar -zcvf nuisblob.tar.gz setup.sh exes/* deps/* root/* +fi +cd ../ diff --git a/parameters/config.xml b/parameters/config.xml index e1b0a45..3feb65d 100644 --- a/parameters/config.xml +++ b/parameters/config.xml @@ -1,213 +1,202 @@ - - - + - - - - - - - - - - - - + + + + - + - - - + + + - + - - - + + + - diff --git a/src/Config/NuisConfig.cxx b/src/Config/NuisConfig.cxx index f1f1033..7e78d66 100644 --- a/src/Config/NuisConfig.cxx +++ b/src/Config/NuisConfig.cxx @@ -1,802 +1,817 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "NuisConfig.h" #include "FitLogger.h" #include "GeneralUtils.h" #include "TXMLEngine.h" namespace Config { nuisconfig &Get() { return nuisconfig::GetConfig(); }; std::string GetPar(std::string const &name) { return Get().GetConfig(name); } bool HasPar(std::string const &name) { return Get().HasConfig(name); } std::string GetParS(std::string const &name) { return Get().GetConfigS(name); } int GetParI(std::string const &name) { return Get().GetConfigI(name); } bool GetParB(std::string const &name) { return Get().GetConfigB(name); } float GetParF(std::string const &name) { return Get().GetConfigF(name); } double GetParD(std::string const &name) { return Get().GetConfigD(name); } void SetPar(std::string const &name, std::string const &val) { Get().SetConfig(name, val); } void SetPar(std::string const &name, char const *val) { Get().SetConfig(name, val); } void SetPar(std::string const &name, bool val) { Get().SetConfig(name, val); } void SetPar(std::string const &name, int val) { Get().SetConfig(name, val); } void SetPar(std::string const &name, float val) { Get().SetConfig(name, val); } void SetPar(std::string const &name, double val) { Get().SetConfig(name, val); } } namespace FitPar { std::string GetDataBase() { return GeneralUtils::GetTopLevelDir() + "/data/"; }; nuisconfig &Config() { return Config::Get(); }; } nuisconfig *nuisconfig::m_nuisconfigInstance = NULL; nuisconfig &nuisconfig::GetConfig(void) { if (!m_nuisconfigInstance) m_nuisconfigInstance = new nuisconfig; return *m_nuisconfigInstance; }; // Main Class Definition nuisconfig::nuisconfig() { // Load default Parameters std::string filename = (GeneralUtils::GetTopLevelDir() + "/parameters/config.xml"); std::cout << "[ NUISANCE ]: Loading DEFAULT settings from : " << filename; // Create XML Engine fXML = new TXMLEngine; fXML->SetSkipComments(true); // Load in documents fXMLDocs.push_back(fXML->ParseFile(filename.c_str(), 1000000)); if (!fXMLDocs[0]) { THROW("Cannot Read Parameters File!"); } // Setup Main XML Node to be the first file read fMainNode = fXML->DocGetRootElement(fXMLDocs[0]); // Print result std::cout << " -> DONE." << std::endl; } nuisconfig::~nuisconfig() { // Should really delete XML objects here but we don't } void nuisconfig::LoadSettings(std::string const &filename, std::string const &state) { // Open file and see if its XML std::cout << "[ NUISANCE ]: Trying to parse file : " << filename; StopTalking(); XMLDocPointer_t readdoc = fXML->ParseFile(filename.c_str(), 1000000); StartTalking(); // If it is parse it as a nice XML config file if (readdoc) { std::cout << " -> Found XML file." << std::endl; LoadXMLSettings(filename, state); // Otherwise its an old simple card file } else { std::cout << " -> Assuming its a simple card file." << std::endl; LoadCardSettings(filename, state); } } void nuisconfig::LoadXMLSettings(std::string const &filename, std::string const &state) { std::cout << "[ NUISANCE ]: Loading XML settings from : " << filename << std::endl; // Add new file to xml docs list fXMLDocs.push_back(fXML->ParseFile(filename.c_str(), 1000000)); if (!fXMLDocs.back()) { THROW("Failed to read: " << filename); } // Loop over children and add XMLNodePointer_t child = fXML->GetChild(fXML->DocGetRootElement(fXMLDocs.back())); // // Here we manually load all the children from the card file into our root // node if (!child) { THROW("CANNOT Find child inside settings file!"); } while (child) { // SPECIAL CONFIG CASE // If its a config node, then remove previous attributes, overriding old // value if (!std::string(fXML->GetNodeName(child)).compare("config")) { // Loop over attribues XMLAttrPointer_t attr1 = fXML->GetFirstAttr(child); while (attr1) { // If a valid attribute name is given then compare if (!GetConfigS(fXML->GetAttrName(attr1)).empty()) { // Get full list of present configs std::vector confignodes = GetNodes("config"); // Loop over present configs and compare for (size_t i = 0; i < confignodes.size(); i++) { // If we already have this config, free the old attribute if (fXML->HasAttr(confignodes[i], fXML->GetAttrName(attr1))) { fXML->FreeAttr(confignodes[i], fXML->GetAttrName(attr1)); break; } } } // Move onto next config attribute attr1 = fXML->GetNextAttr(attr1); } } TString nodeStr; fXML->SaveSingleNode(child, &nodeStr); XMLNodePointer_t copyNode = fXML->ReadSingleNode(nodeStr.Data()); + // std::cout << "copying node..." << std::endl; + // PrintXML(copyNode); + // Add this child to the main config list fXML->AddChild(fMainNode, copyNode); + // std::cout << "Done, was it added?" << std::endl; + // PrintXML(fMainNode); + // Get Next Child child = fXML->GetNext(child); } std::cout << " -> DONE." << std::endl; } void nuisconfig::LoadCardSettings(std::string const &filename, std::string const &state) { std::cout << "[ NUISANCE ]: Loading simple config from : " << filename; // Build XML Config from the card file by parsing each line std::vector cardlines = GeneralUtils::ParseFileToStr(filename, "\n"); int linecount = 0; // Loop over all input lines for (std::vector::iterator iter = cardlines.begin(); iter != cardlines.end(); iter++) { std::string line = (*iter); linecount++; // Skip Comments if (line.empty()) continue; if (line.c_str()[0] == '#') continue; // Parse whitespace std::vector strvct = GeneralUtils::ParseToStr(line, " "); if (strvct.empty()) continue; // Get Identifier std::string id = strvct[0]; // Build backwards compatible xml configs // Sample structure if (!id.compare("sample")) { CreateSampleNodeFromLine(line); } // Any parameter structure if (id.find("_parameter") != std::string::npos) { CreateParameterNodeFromLine(line); } // Any covar structure if (!id.compare("covar") || !id.compare("pull") || !id.compare("throw")) { CreatePullNodeFromLine(line); } // Any config structure if (!id.compare("config")) { CreateOldConfigNodeFromLine(line); } } std::cout << " -> DONE." << std::endl; } XMLNodePointer_t nuisconfig::CreateSampleNodeFromLine(std::string const &line) { // Create new node entry XMLNodePointer_t samplenode = CreateNode("sample"); // Parse line std::vector strvct = GeneralUtils::ParseToStr(line, " "); // Add line elements to the node // name input type norm if (strvct.size() > 1) Set(samplenode, "name", strvct[1]); if (strvct.size() > 2) Set(samplenode, "input", strvct[2]); if (strvct.size() > 3) Set(samplenode, "type", strvct[3]); if (strvct.size() > 4) Set(samplenode, "norm", strvct[4]); return samplenode; } XMLNodePointer_t nuisconfig::CreateParameterNodeFromLine( std::string const &line) { // Create new node entry XMLNodePointer_t parnode = CreateNode("parameter"); // Parse line std::vector strvct = GeneralUtils::ParseToStr(line, " "); // Add line elements to the node // type name nominal [low] [high] [step] state if (strvct.size() > 0) Set(parnode, "type", strvct[0]); if (strvct.size() > 1) Set(parnode, "name", strvct[1]); if (strvct.size() > 2) Set(parnode, "nominal", strvct[2]); // If free structure if (strvct.size() == 7) { Set(parnode, "low", strvct[3]); Set(parnode, "high", strvct[4]); Set(parnode, "step", strvct[5]); Set(parnode, "state", strvct[6]); // Fixed param structure } else if (strvct.size() == 3) { Set(parnode, "state", "FIX"); } else if (strvct.size() == 4) { Set(parnode, "state", strvct[3]); } return parnode; } XMLNodePointer_t nuisconfig::CreatePullNodeFromLine(std::string const &line) { // Create new node entry XMLNodePointer_t parnode = CreateNode("covar"); // Parse line std::vector strvct = GeneralUtils::ParseToStr(line, " "); // Add line elements to the node // name input type if (strvct.size() > 1) Set(parnode, "name", strvct[1]); if (strvct.size() > 2) Set(parnode, "input", strvct[2]); if (strvct.size() > 3) Set(parnode, "type", strvct[3]); return parnode; } XMLNodePointer_t nuisconfig::CreateOldConfigNodeFromLine( std::string const &line) { // Create new node entry XMLNodePointer_t confignode = CreateNode("config"); // Parse line std::vector strvct = GeneralUtils::ParseToStr(line, " "); // Add line elements to the node // name value if (strvct.size() > 2) Set(confignode, strvct[1], strvct[2]); return confignode; } void nuisconfig::FinaliseSettings(std::string const &name) { std::cout << "[ NUISANCE ]: Finalising run settings"; WriteSettings(name); // Save full config to file RemoveEmptyNodes(); RemoveIdenticalNodes(); std::cout << " -> DONE." << std::endl; } void nuisconfig::WriteSettings(std::string const &outputname) { // Create a New XML Doc XMLDocPointer_t newxmldoc = fXML->NewDoc(); fXML->DocSetRootElement(newxmldoc, fMainNode); // Save document to file if (GetConfigB("SaveParsedXMLFile")) { fXML->SaveDoc(newxmldoc, outputname.c_str()); } } void nuisconfig::PrintXML(XMLNodePointer_t node, int indent) { + if (!node) { + node = fMainNode; + } + std::stringstream ss(""); for (int i = 0; i < indent; ++i) { ss << " "; } std::cout << ss.str() << "<" << fXML->GetNodeName(node) << std::flush; XMLAttrPointer_t attr = fXML->GetFirstAttr(node); while (attr) { std::cout << " " << fXML->GetAttrName(attr) << "=\"" << fXML->GetAttrValue(attr) << "\"" << std::flush; attr = fXML->GetNextAttr(attr); } if (!fXML->GetChild(node)) { std::cout << " />" << std::endl; return; } std::cout << " >" << std::endl; XMLNodePointer_t child = fXML->GetChild(node); while (child) { PrintXML(child, indent + 1); child = fXML->GetNext(child); } std::cout << ss.str() << "GetNodeName(node) << ">" << std::endl; } XMLNodePointer_t nuisconfig::CreateNode(std::string const &name) { return fXML->NewChild(fMainNode, 0, name.c_str()); } XMLNodePointer_t nuisconfig::CreateNode(XMLNodePointer_t node, std::string const &name) { return fXML->NewChild(node, 0, name.c_str()); } XMLNodePointer_t nuisconfig::GetNode(XMLNodePointer_t node, std::string const &type) { /// Loop over all children XMLNodePointer_t child = fXML->GetChild(node); while (child != 0) { /// Get nodes for given type (if type empty return all) if (std::string(fXML->GetNodeName(child)) == type.c_str() or type.empty()) { return child; } // Next child child = fXML->GetNext(child); } // Child not found return 0; } void nuisconfig::RemoveEmptyNodes() { std::vector nodelist = Config::Get().GetNodes(); for (size_t i = 0; i < nodelist.size(); i++) { if (fXML->IsEmptyNode(nodelist[i])) { + std::cout << "Removing empty node: " << fXML->GetNodeName(nodelist[i]) + << ", with child ?" << bool(fXML->GetChild(nodelist[i])) + << std::endl; RemoveNode(nodelist[i]); } } } void nuisconfig::RemoveIdenticalNodes() { std::vector removed; // Loop over all nodes and check for identical nodes std::vector nodelist = Config::Get().GetNodes(); for (size_t i = 0; i < nodelist.size(); i++) { for (size_t j = 0; j < nodelist.size(); j++) { if (i == j) continue; XMLNodePointer_t node1 = nodelist[i]; XMLNodePointer_t node2 = nodelist[j]; // Check node already removed. if (std::find(removed.begin(), removed.end(), node1) != removed.end()) { continue; } if (std::find(removed.begin(), removed.end(), node2) != removed.end()) { continue; } // Check matching if (!MatchingNodes(node1, node2)) { continue; } if (std::string(fXML->GetNodeName(node1)).compare("config") and fXML->IsEmptyNode(node1)) { // Matching so print out warning std::cout << "Matching nodes given! Removing node1!" << std::endl << "Node 1" << std::endl; PrintNode(node1); std::cout << "Node 2" << std::endl; PrintNode(node2); } // Remove node removed.push_back(node1); } } // Now go through and remove this node. for (size_t i = 0; i < removed.size(); i++) { RemoveNode(removed.at(i)); } return; } void nuisconfig::RemoveNode(XMLNodePointer_t node) { + std::cout << "[INFO]: Removing node: " << fXML->GetNodeName(node) + << std::endl; fXML->FreeAllAttr(node); fXML->CleanNode(node); fXML->FreeNode(node); fXML->UnlinkNode(node); } void nuisconfig::PrintNode(XMLNodePointer_t node) { // Print Node Name std::cout << fXML->GetNodeName(node) << std::endl; // Loop and print all attributes XMLAttrPointer_t attr = fXML->GetFirstAttr(node); while (attr != 0) { std::cout << " -> " << fXML->GetAttrName(attr) << " : " << fXML->GetAttrValue(attr) << std::endl; attr = fXML->GetNextAttr(attr); } } bool nuisconfig::MatchingNodes(XMLNodePointer_t node1, XMLNodePointer_t node2) { bool matching = true; XMLAttrPointer_t attr = fXML->GetFirstAttr(node1); while (attr != 0) { if (GetS(node2, fXML->GetAttrName(attr)) != fXML->GetAttrValue(attr)) matching = false; attr = fXML->GetNextAttr(attr); } return matching; } XMLNodePointer_t nuisconfig::GetNode(std::string const &type) { return GetNode(fMainNode, type); } std::vector nuisconfig::GetNodes(XMLNodePointer_t node, std::string const &type) { // Create new vector for nodes std::vector nodelist; /// Loop over all children XMLNodePointer_t child = fXML->GetChild(node); while (child != 0) { /// Get nodes for given type (if type empty return all) if (std::string(fXML->GetNodeName(child)) == type.c_str() or type.empty()) { nodelist.push_back(child); } // Next child child = fXML->GetNext(child); } // return list return nodelist; } std::vector nuisconfig::GetNodes(std::string const &type) { return GetNodes(fMainNode, type); } void nuisconfig::Set(XMLNodePointer_t node, std::string const &name, std::string const &val) { // Remove and re-add attribute if (fXML->HasAttr(node, name.c_str())) { fXML->FreeAttr(node, name.c_str()); } fXML->NewAttr(node, 0, name.c_str(), val.c_str()); } void nuisconfig::Set(XMLNodePointer_t node, std::string const &name, char const *val) { Set(node, name, std::string(val)); } void nuisconfig::Set(XMLNodePointer_t node, std::string const &name, bool val) { Set(node, name, GeneralUtils::BoolToStr(val)); } void nuisconfig::Set(XMLNodePointer_t node, std::string const &name, int val) { Set(node, name, GeneralUtils::IntToStr(val)); } void nuisconfig::Set(XMLNodePointer_t node, std::string const &name, float val) { Set(node, name, GeneralUtils::DblToStr(val)); } void nuisconfig::Set(XMLNodePointer_t node, std::string const &name, double val) { Set(node, name, GeneralUtils::DblToStr(val)); } void nuisconfig::SetS(XMLNodePointer_t node, std::string const &name, std::string const &val) { Set(node, name, val); } void nuisconfig::SetB(XMLNodePointer_t node, std::string const &name, bool val) { Set(node, name, GeneralUtils::BoolToStr(val)); } void nuisconfig::SetI(XMLNodePointer_t node, std::string const &name, int val) { Set(node, name, GeneralUtils::IntToStr(val)); } void nuisconfig::SetF(XMLNodePointer_t node, std::string const &name, float val) { Set(node, name, GeneralUtils::DblToStr(val)); } void nuisconfig::SetD(XMLNodePointer_t node, std::string const &name, double val) { Set(node, name, GeneralUtils::DblToStr(val)); } bool nuisconfig::Has(XMLNodePointer_t node, std::string const &name) { // If node empty return empty if (node == 0) return false; // Search attributes XMLAttrPointer_t attr = fXML->GetFirstAttr(node); bool found = false; // Loop over all attributes while (attr != 0) { // Find value of correct name if (std::string(fXML->GetAttrName(attr)) == name.c_str()) { found = true; break; } // Next Attribute attr = fXML->GetNextAttr(attr); } return found; } std::string nuisconfig::Get(XMLNodePointer_t node, std::string const &name) { // If node empty return empty if (node == 0) return ""; // Get Attribute from child with name XMLAttrPointer_t attr = fXML->GetFirstAttr(node); std::string temp = ""; // Loop over all attributes while (attr != 0) { // If valid match then save if (std::string(fXML->GetAttrName(attr)) == name.c_str()) { temp = fXML->GetAttrValue(attr); } // Next Attribute attr = fXML->GetNextAttr(attr); } return temp; } std::string nuisconfig::GetS(XMLNodePointer_t node, std::string const &name) { return Get(node, name); } bool nuisconfig::GetB(XMLNodePointer_t node, std::string const &name) { std::string tempattr = Get(node, name); return GeneralUtils::StrToBool(tempattr); } int nuisconfig::GetI(XMLNodePointer_t node, std::string const &name) { std::string tempattr = Get(node, name); return GeneralUtils::StrToInt(tempattr); } float nuisconfig::GetF(XMLNodePointer_t node, std::string const &name) { std::string tempattr = Get(node, name); return GeneralUtils::StrToDbl(tempattr); } double nuisconfig::GetD(XMLNodePointer_t node, std::string const &name) { std::string tempattr = Get(node, name); return GeneralUtils::StrToDbl(tempattr); } std::vector nuisconfig::GetVS(XMLNodePointer_t node, std::string const &name, const char *del) { std::string tempattr = Get(node, name); return GeneralUtils::ParseToStr(tempattr, del); } // std::vector nuisconfig::GetVB(XMLNodePointer_t node, // std::string name, // const char* del) { // std::string tempattr = Get(node, name); // return GeneralUtils::ParseToBool(tempattr, del); // } std::vector nuisconfig::GetVI(XMLNodePointer_t node, std::string const &name, const char *del) { std::string tempattr = Get(node, name); return GeneralUtils::ParseToInt(tempattr, del); } // std::vector nuisconfig::GetVF(XMLNodePointer_t node, // std::string name, // const char* del) { // std::string tempattr = Get(node, name); // return GeneralUtils::ParseToDouble(tempattr, del); // } std::vector nuisconfig::GetVD(XMLNodePointer_t node, std::string const &name, char const *del) { std::string tempattr = Get(node, name); return GeneralUtils::ParseToDbl(tempattr, del); } std::vector nuisconfig::GetAllKeysForNode(XMLNodePointer_t node) { bool matching = true; XMLAttrPointer_t attr = fXML->GetFirstAttr(node); std::vector keys; while (attr != 0) { if (!std::string(fXML->GetAttrName(attr)).empty()) { keys.push_back(std::string(fXML->GetAttrName(attr))); } attr = fXML->GetNextAttr(attr); } return keys; } XMLNodePointer_t nuisconfig::GetConfigNode(std::string const &name) { // Loop over children and look for name XMLNodePointer_t child = fXML->GetChild(fMainNode); while (child != 0) { // Select only config parameters if (!std::string(fXML->GetNodeName(child)).compare("config")) { // Loop over config attributes and search for name XMLAttrPointer_t attr = fXML->GetFirstAttr(child); while (attr != 0) { // Save name value if (std::string(fXML->GetAttrName(attr)) == name.c_str()) { return child; } // Get Next Attribute attr = fXML->GetNextAttr(attr); } } // Next Child child = fXML->GetNext(child); } return 0; } void nuisconfig::SetConfig(std::string const &name, std::string const &val) { XMLNodePointer_t node = GetConfigNode(name); if (!node) node = CreateNode("config"); Set(node, name, val); } void nuisconfig::SetConfig(std::string const &name, char const *val) { SetConfig(name, std::string(val)); } void nuisconfig::SetConfig(std::string const &name, bool val) { XMLNodePointer_t node = GetConfigNode(name); if (!node) node = CreateNode("config"); Set(node, name, val); } void nuisconfig::SetConfig(std::string const &name, int val) { XMLNodePointer_t node = GetConfigNode(name); if (!node) node = CreateNode("config"); Set(node, name, val); } void nuisconfig::SetConfig(std::string const &name, float val) { XMLNodePointer_t node = GetConfigNode(name); if (!node) node = CreateNode("config"); Set(node, name, val); } void nuisconfig::SetConfig(std::string const &name, double val) { XMLNodePointer_t node = GetConfigNode(name); if (!node) node = CreateNode("config"); Set(node, name, val); } void nuisconfig::OverrideConfig(std::string const &conf) { std::vector opts = GeneralUtils::ParseToStr(conf, "="); SetConfig(opts[0], opts[1]); } std::string nuisconfig::GetConfig(std::string const &name) { XMLNodePointer_t node = GetConfigNode(name); if (!node) return ""; XMLAttrPointer_t attr = fXML->GetFirstAttr(node); std::string temp = ""; // Loop config attributes while (attr != 0) { // Find match if (std::string(fXML->GetAttrName(attr)) == name.c_str()) { temp = fXML->GetAttrValue(attr); } // Get Next Attribute attr = fXML->GetNextAttr(attr); } return temp; } bool nuisconfig::HasConfig(std::string const &name) { return bool(GetConfigNode(name)); } std::string nuisconfig::GetConfigS(std::string const &name) { return GetConfig(name); } bool nuisconfig::GetConfigB(std::string const &name) { std::string pars = GetConfig(name); return GeneralUtils::StrToBool(pars); } int nuisconfig::GetConfigI(std::string const &name) { std::string pars = GetConfig(name); return GeneralUtils::StrToInt(pars); } float nuisconfig::GetConfigF(std::string const &name) { std::string pars = GetConfig(name); return GeneralUtils::StrToDbl(pars); } double nuisconfig::GetConfigD(std::string const &name) { std::string pars = GetConfig(name); return GeneralUtils::StrToDbl(pars); } std::string nuisconfig::GetParDIR(std::string const &parName) { std::string outstr = this->GetParS(parName); // Make replacements in the string const int nfiletypes = 2; const std::string filetypes[nfiletypes] = {"@data", "@nuisance"}; std::string filerepl[nfiletypes] = {FitPar::GetDataBase(), FitPar::GetDataBase() + "/../"}; for (int i = 0; i < nfiletypes; i++) { std::string findstring = filetypes[i]; std::string replstring = filerepl[i]; if (outstr.find(findstring) != std::string::npos) { outstr.replace(outstr.find(findstring), findstring.size(), filerepl[i]); break; } } return outstr; }; diff --git a/src/FCN/JointFCN.cxx b/src/FCN/JointFCN.cxx index f3eb4e6..0f42d55 100755 --- a/src/FCN/JointFCN.cxx +++ b/src/FCN/JointFCN.cxx @@ -1,1136 +1,1136 @@ #include "JointFCN.h" #include #include "FitUtils.h" //*************************************************** JointFCN::JointFCN(TFile* outfile) { //*************************************************** fOutputDir = gDirectory; if (outfile) Config::Get().out = outfile; std::vector samplekeys = Config::QueryKeys("sample"); LoadSamples(samplekeys); std::vector 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 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(); iter++) { MeasurementBase* exp = *iter; std::string name = exp->GetName(); std::string liketag = name + "_likelihood"; fNameValues.push_back(liketag); fCurrentValues.push_back(0.0); std::string ndoftag = name + "_ndof"; fNameValues.push_back(ndoftag); fCurrentValues.push_back(0.0); } // Add Pull terms for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull* pull = *iter; std::string name = pull->GetName(); std::string liketag = name + "_likelihood"; fNameValues.push_back(liketag); fCurrentValues.push_back(0.0); std::string ndoftag = name + "_ndof"; fNameValues.push_back(ndoftag); fCurrentValues.push_back(0.0); } // Add Likelihoods fNameValues.push_back("total_likelihood"); fCurrentValues.push_back(0.0); fNameValues.push_back("total_ndof"); fCurrentValues.push_back(0.0); // Setup Containers fSampleN = fSamples.size() + fPulls.size(); fSampleLikes = new double[fSampleN]; fSampleNDOF = new int[fSampleN]; // Add Dials std::vector dials = rw->GetDialNames(); for (size_t i = 0; i < dials.size(); i++) { fNameValues.push_back( dials[i] ); fCurrentValues.push_back( 0.0 ); } fNDials = dials.size(); fDialVals = new double[fNDials]; // Set IterationTree Flag fIterationTree = true; } //*************************************************** void JointFCN::DestroyIterationTree() { //*************************************************** fIterationCount.clear(); fCurrentValues.clear(); fNameValues.clear(); fIterationValues.clear(); } //*************************************************** void JointFCN::WriteIterationTree() { //*************************************************** LOG(FIT) << "Writing iteration tree" << std::endl; // Make a new TTree TTree* itree = new TTree(fIterationTreeName.c_str(), fIterationTreeName.c_str()); double* vals = new double[fNameValues.size()]; int count = 0; itree->Branch("iteration", &count, "Iteration/I"); for (int i = 0; i < fNameValues.size(); i++) { itree->Branch( fNameValues[i].c_str(), &vals[i], (fNameValues[i] + "/D").c_str() ); } // Fill Iterations for (size_t i = 0; i < fIterationValues.size(); i++) { std::vector itervals = fIterationValues[i]; // Fill iteration state count = fIterationCount[i]; for (size_t j = 0; j < itervals.size(); j++) { vals[j] = itervals[j]; } // Save to TTree itree->Fill(); } // Write to file itree->Write(); } //*************************************************** void JointFCN::FillIterationTree(FitWeight* rw) { //*************************************************** // Loop over samples count int count = 0; for (int i = 0; i < fSampleN; i++) { fCurrentValues[count++] = fSampleLikes[i]; fCurrentValues[count++] = double(fSampleNDOF[i]); } // Fill Totals fCurrentValues[count++] = fLikelihood; fCurrentValues[count++] = double(fNDOF); // Loop Over Parameter Counts rw->GetAllDials(fDialVals, fNDials); for (int i = 0; i < fNDials; i++) { fCurrentValues[count++] = double(fDialVals[i]); } // Push Back Into Container fIterationCount.push_back( fCurIter ); fIterationValues.push_back(fCurrentValues); } //*************************************************** double JointFCN::DoEval(const double* x) { //*************************************************** // WEIGHT ENGINE fDialChanged = FitBase::GetRW()->HasRWDialChanged(x); FitBase::GetRW()->UpdateWeightEngine(x); if (fDialChanged) { FitBase::GetRW()->Reconfigure(); FitBase::EvtManager().ResetWeightFlags(); } if (LOG_LEVEL(REC)) { FitBase::GetRW()->Print(); } // SORT SAMPLES ReconfigureSamples(); // GET TEST STAT fLikelihood = GetLikelihood(); fNDOF = GetNDOF(); // PRINT PROGRESS LOG(FIT) << "Current Stat (iter. " << this->fCurIter << ") = " << fLikelihood << std::endl; // UPDATE TREE if (fIterationTree) FillIterationTree(FitBase::GetRW()); return fLikelihood; } //*************************************************** int JointFCN::GetNDOF() { //*************************************************** int totaldof = 0; int count = 0; // Total number of Free bins in each MC prediction for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase* exp = *iter; int dof = exp->GetNDOF(); // Save Seperate DOF if (fIterationTree) { fSampleNDOF[count] = dof; } // Add to total totaldof += dof; count++; } // Loop over pulls for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull* pull = *iter; double dof = pull->GetLikelihood(); // Save seperate DOF if (fIterationTree) { fSampleNDOF[count] = dof; } // Add to total totaldof += dof; count++; } // Set Data Variable if (fIterationTree) { fSampleNDOF[count] = totaldof; } return totaldof; } //*************************************************** double JointFCN::GetLikelihood() { //*************************************************** LOG(MIN) << std::left << std::setw(43) << "Getting likelihoods..." << " : " << "-2logL" << std::endl; // Loop and add up likelihoods in an uncorrelated way double like = 0.0; int count = 0; for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase* exp = *iter; double newlike = exp->GetLikelihood(); int ndof = exp->GetNDOF(); // Save seperate likelihoods if (fIterationTree) { fSampleLikes[count] = newlike; } LOG(MIN) << "-> " << std::left << std::setw(40) << exp->GetName() << " : " << newlike << "/" << ndof << std::endl; // Add Weight Scaling // like *= FitBase::GetRW()->GetSampleLikelihoodWeight(exp->GetName()); // Add to total like += newlike; count++; } // Loop over pulls for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull* pull = *iter; double newlike = pull->GetLikelihood(); // Save seperate likelihoods if (fIterationTree) { fSampleLikes[count] = newlike; } // Add to total like += newlike; count++; } // Set Data Variable fLikelihood = like; if (fIterationTree) { fSampleLikes[count] = fLikelihood; } return like; }; void JointFCN::LoadSamples(std::vector 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 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 JointFCN::GetInputList() { std::vector InputList; fIsAllSplines = true; MeasListConstIter iterSam = fSamples.begin(); for (; iterSam != fSamples.end(); iterSam++) { MeasurementBase* exp = (*iterSam); std::vector 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 JointFCN::GetSubSampleList() { std::vector SampleList; MeasListConstIter iterSam = fSamples.begin(); for (; iterSam != fSamples.end(); iterSam++) { MeasurementBase* exp = (*iterSam); std::vector 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::iterator inp_iter = fInputList.begin(); if (fIsAllSplines) { for (; inp_iter != fInputList.end(); inp_iter++) { InputHandlerBase* curinput = (*inp_iter); // Tell reader in each BaseEvent it needs a Reconfigure next weight calc. BaseFitEvt* curevent = curinput->FirstBaseEvent(); if (curevent->fSplineRead) { curevent->fSplineRead->SetNeedsReconfigure(true); } } } // MAIN INPUT LOOP ==================== int fillcount = 0; int inputcount = 0; inp_iter = fInputList.begin(); // Loop over each input in manager for (; inp_iter != fInputList.end(); inp_iter++) { InputHandlerBase* curinput = (*inp_iter); // Get event information FitEvent* curevent = curinput->FirstNuisanceEvent(); curinput->CreateCache(); int i = 0; int nevents = curinput->GetNEvents(); int countwidth = nevents / 5; // Start event loop iterating until we get a NULL pointer. while (curevent) { // Get Event Weight curevent->RWWeight = FitBase::GetRW()->CalcWeight(curevent); curevent->Weight = curevent->RWWeight * curevent->InputWeight; double rwweight = curevent->Weight; // std::cout << "RWWeight = " << curevent->RWWeight << " " << // curevent->InputWeight << std::endl; // Logging // std::cout << CHECKLOG(1) << std::endl; if (LOGGING(REC)) { if (i % countwidth == 0) { QLOG(REC, curinput->GetName() << " : Processed " << i << " events. [M, W] = [" << curevent->Mode << ", " << rwweight << "]"); } } // Setup flag for if signal found in at least one sample bool foundsignal = false; // Create a new signal bitset for this event std::vector signalbitset(fSubSampleList.size()); // Create a new signal box vector for this event std::vector signalboxes; // Start measurement iterator size_t measitercount = 0; std::vector::iterator meas_iter = fSubSampleList.begin(); // Loop over all subsamples (sub in JointMeas) for (; meas_iter != fSubSampleList.end(); meas_iter++) { MeasurementBase* curmeas = (*meas_iter); // Compare input pointers, to current input, skip if not. // Pointer tells us if it matches without doing ID checks. if (curinput != curmeas->GetInput()) { if (savesignal) { // Set bit to 0 as definitely not signal signalbitset[measitercount] = 0; } // Count up what measurement we are on. measitercount++; // Skip sample as input not signal. continue; } // Fill events for matching inputs. MeasurementVariableBox* box = curmeas->FillVariableBox(curevent); bool signal = curmeas->isSignal(curevent); curmeas->SetSignal(signal); curmeas->FillHistograms(curevent->Weight); // If its Signal tally up fills if (signal) { fillcount++; } // If we are saving signal/splines fill the bitset if (savesignal) { signalbitset[measitercount] = signal; } // If signal save a clone of the event box for use later. if (savesignal and signal) { foundsignal = true; signalboxes.push_back(box->CloneSignalBox()); } // Keep track of Measurement we are on. measitercount++; } // Once we've filled the measurements, if saving signal // push back if any sample flagged this event as signal if (savesignal) { fSignalEventFlags.push_back(foundsignal); } // Save the vector of signal boxes for this event if (savesignal and foundsignal) { fSignalEventBoxes.push_back(signalboxes); fSampleSignalFlags.push_back(signalbitset); } // If all inputs are splines we can save the spline coefficients // for fast in memory reconfigures later. if (fIsAllSplines and savesignal and foundsignal) { // Make temp vector to push back with std::vector coeff; for (size_t l = 0; l < (UInt_t)curevent->fSplineRead->GetNPar(); l++) { coeff.push_back(curevent->fSplineCoeff[l]); } // Push back to signal event splines. Kept in sync with // fSignalEventBoxes size. // int splinecount = fSignalEventSplines.size(); fSignalEventSplines.push_back(coeff); // if (splinecount % 1000 == 0) { // std::cout << "Pushed Back Coeff " << splinecount << " : "; // for (size_t l = 0; l < fSignalEventSplines[splinecount].size(); l++) // { // std::cout << " " << fSignalEventSplines[splinecount][l]; // } // std::cout << std::endl; // } } // Clean up vectors once done with this event signalboxes.clear(); signalbitset.clear(); // Iterate to the next event. curevent = curinput->NextNuisanceEvent(); i++; } // curinput->RemoveCache(); // Keep track of what input we are on. inputcount++; } // End of Event Loop =============================== // Now event loop is finished loop over all Measurements // Converting Binned events to XSec Distributions iterSam = fSamples.begin(); for (; iterSam != fSamples.end(); iterSam++) { MeasurementBase* exp = (*iterSam); exp->ConvertEventRates(); } // Print out statements on approximate memory usage for profiling. LOG(REC) << "Filled " << fillcount << " signal events." << std::endl; if (savesignal) { int mem = ( // sizeof(fSignalEventBoxes) + // fSignalEventBoxes.size() * sizeof(fSignalEventBoxes.at(0)) + sizeof(MeasurementVariableBox1D) * fillcount) * 1E-6; LOG(REC) << " -> Saved " << fillcount << " signal boxes for faster access. (~" << mem << " MB)" << std::endl; if (fIsAllSplines and !fSignalEventSplines.empty()) { int splmem = sizeof(float) * fSignalEventSplines.size() * fSignalEventSplines[0].size() * 1E-6; LOG(REC) << " -> Saved " << fillcount << " " << fSignalEventSplines.size() << " spline sets into memory. (~" << splmem << " MB)" << std::endl; } } LOG(REC) << "Time taken ReconfigureUsingManager() : " << time(NULL) - timestart << std::endl; // Check SignalReconfigures works for all samples if (savesignal) { double likefull = GetLikelihood(); ReconfigureFastUsingManager(); double likefast = GetLikelihood(); if (fabs(likefull - likefast) > 0.0001) { ERROR(FTL, "Fast and Full Likelihoods DIFFER! : " << likefull << " : " << likefast); ERROR(FTL, "This means some samples you are using are not setup to use SignalReconfigures=1"); ERROR(FTL, "Please turn OFF signal reconfigures."); throw; } else { LOG(FIT) << "Likelihoods for FULL and FAST match. Will use FAST next time." << std::endl; } } // End of reconfigure return; }; //*************************************************** void JointFCN::ReconfigureFastUsingManager() { //*************************************************** LOG(FIT) << " -> Doing FAST using manager" << std::endl; // Get Start time for profilling int timestart = time(NULL); // Reset all samples MeasListConstIter iterSam = fSamples.begin(); for (; iterSam != fSamples.end(); iterSam++) { MeasurementBase* exp = (*iterSam); exp->ResetAll(); } // Check for saved variables if not do a full reconfigure. if (fSignalEventFlags.empty()) { ERR(WRN) << "Signal Flags Empty! Using normal manager." << std::endl; ReconfigureUsingManager(); return; } bool fFillNuisanceEvent = FitPar::Config().GetParB("FullEventOnSignalReconfigure"); // Setup fast vector iterators. std::vector::iterator inpsig_iter = fSignalEventFlags.begin(); std::vector >::iterator box_iter = fSignalEventBoxes.begin(); std::vector >::iterator spline_iter = fSignalEventSplines.begin(); std::vector >::iterator samsig_iter = fSampleSignalFlags.begin(); int splinecount = 0; // Setup stuff for logging int fillcount = 0; int nevents = fSignalEventFlags.size(); int countwidth = nevents / 20; // If All Splines tell splines they need a reconfigure. std::vector::iterator inp_iter = fInputList.begin(); if (fIsAllSplines) { LOG(REC) << "All Spline Inputs so using fast spline loop." << std::endl; for (; inp_iter != fInputList.end(); inp_iter++) { InputHandlerBase* curinput = (*inp_iter); // Tell each fSplineRead in BaseFitEvent to reconf next weight calc BaseFitEvt* curevent = curinput->FirstBaseEvent(); if (curevent->fSplineRead) curevent->fSplineRead->SetNeedsReconfigure(true); } } // Loop over all possible spline inputs double* coreeventweights = new double[fSignalEventBoxes.size()]; splinecount = 0; inp_iter = fInputList.begin(); inpsig_iter = fSignalEventFlags.begin(); spline_iter = fSignalEventSplines.begin(); // Loop over all signal flags // For each valid signal flag add one to splinecount // Get Splines from that count and add to weight // Add splinecount int sigcount = 0; splinecount = 0; // #pragma omp parallel for shared(splinecount,sigcount) for (uint iinput = 0; iinput < fInputList.size(); iinput++) { InputHandlerBase* curinput = fInputList[iinput]; BaseFitEvt* curevent = curinput->FirstBaseEvent(); for (int i = 0; i < curinput->GetNEvents(); i++) { double rwweight = 0.0; if (fSignalEventFlags[sigcount]) { // Get Event Info if (!fIsAllSplines) { if (fFillNuisanceEvent) - curinput->GetNuisanceEvent(i); + 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; 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::iterator subsamsig_iter = (*samsig_iter).begin(); std::vector::iterator subbox_iter = (*box_iter).begin(); // Loop over all sub measurements. std::vector::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 likes; std::vector ndofs; std::vector names; for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase* exp = *iter; double like = exp->GetLikelihood(); double ndof = exp->GetNDOF(); std::string name = exp->GetName(); likes.push_back(like); ndofs.push_back(ndof); names.push_back(name); } TH1D likehist = TH1D("likelihood_hist", "likelihood_hist", likes.size(), 0.0, double(likes.size())); TH1D ndofhist = TH1D("ndof_hist", "ndof_hist", ndofs.size(), 0.0, double(ndofs.size())); TH1D divhist = TH1D("likedivndof_hist", "likedivndof_hist", likes.size(), 0.0, double(likes.size())); for (size_t i = 0; i < likehist.GetNbinsX(); i++) { likehist.SetBinContent(i + 1, likes[i]); ndofhist.SetBinContent(i + 1, ndofs[i]); if (ndofs[i] != 0.0) { divhist.SetBinContent(i + 1, likes[i] / ndofs[i]); } likehist.GetXaxis()->SetBinLabel(i + 1, names[i].c_str()); ndofhist.GetXaxis()->SetBinLabel(i + 1, names[i].c_str()); divhist.GetXaxis()->SetBinLabel(i + 1, names[i].c_str()); } likehist.Write(); ndofhist.Write(); divhist.Write(); // Loop over individual experiments and call Write LOG(MIN) << "Writing each of the data classes..." << std::endl; for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase* exp = *iter; exp->Write(); } // Save Pull Terms for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull* pull = *iter; pull->Write(); } if (FitPar::Config().GetParB("EventManager")) { // Get list of inputs std::map fInputs = FitBase::EvtManager().GetInputs(); std::map::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 JointFCN::GetAllNames() { //*************************************************** // Vect of all likelihoods and total std::vector namevect; // Loop over samples first 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++) { ParamPull* pull = *iter; // Push back to vector namevect.push_back(pull->GetName()); } // Finally add the total namevect.push_back("total"); return namevect; } //*************************************************** std::vector JointFCN::GetAllLikelihoods() { //*************************************************** // Vect of all likelihoods and total std::vector likevect; double total_likelihood = 0.0; LOG(MIN) << "Likelihoods : " << std::endl; // Loop over samples first 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++) { 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 JointFCN::GetAllNDOF() { //*************************************************** // Vect of all ndof and total std::vector ndofvect; int total_ndof = 0; // Loop over samples first 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++) { 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/FCN/SampleList.cxx b/src/FCN/SampleList.cxx index 857b9fb..36b1668 100644 --- a/src/FCN/SampleList.cxx +++ b/src/FCN/SampleList.cxx @@ -1,1307 +1,1307 @@ #include "SampleList.h" #ifndef __NO_ANL__ #include "ANL_CCQE_Evt_1DQ2_nu.h" #include "ANL_CCQE_XSec_1DEnu_nu.h" // ANL CC1ppip #include "ANL_CC1ppip_Evt_1DQ2_nu.h" #include "ANL_CC1ppip_Evt_1DcosmuStar_nu.h" #include "ANL_CC1ppip_Evt_1DcosmuStar_nu.h" #include "ANL_CC1ppip_Evt_1DcosthAdler_nu.h" #include "ANL_CC1ppip_Evt_1Dphi_nu.h" #include "ANL_CC1ppip_Evt_1Dppi_nu.h" #include "ANL_CC1ppip_Evt_1Dthpr_nu.h" #include "ANL_CC1ppip_XSec_1DEnu_nu.h" #include "ANL_CC1ppip_XSec_1DQ2_nu.h" // ANL CC1npip #include "ANL_CC1npip_Evt_1DQ2_nu.h" #include "ANL_CC1npip_Evt_1DcosmuStar_nu.h" #include "ANL_CC1npip_Evt_1Dppi_nu.h" #include "ANL_CC1npip_XSec_1DEnu_nu.h" // ANL CC1pi0 #include "ANL_CC1pi0_Evt_1DQ2_nu.h" #include "ANL_CC1pi0_Evt_1DcosmuStar_nu.h" #include "ANL_CC1pi0_XSec_1DEnu_nu.h" // ANL NC1npip (mm, exotic!) #include "ANL_NC1npip_Evt_1Dppi_nu.h" // ANL NC1ppim (mm, exotic!) #include "ANL_NC1ppim_Evt_1DcosmuStar_nu.h" #include "ANL_NC1ppim_XSec_1DEnu_nu.h" // ANL CC2pi 1pim1pip (mm, even more exotic!) #include "ANL_CC2pi_1pim1pip_Evt_1Dpmu_nu.h" #include "ANL_CC2pi_1pim1pip_Evt_1Dppim_nu.h" #include "ANL_CC2pi_1pim1pip_Evt_1Dppip_nu.h" #include "ANL_CC2pi_1pim1pip_Evt_1Dpprot_nu.h" #include "ANL_CC2pi_1pim1pip_XSec_1DEnu_nu.h" // ANL CC2pi 1pip1pip (mm, even more exotic!) #include "ANL_CC2pi_1pip1pip_Evt_1Dpmu_nu.h" #include "ANL_CC2pi_1pip1pip_Evt_1Dpneut_nu.h" #include "ANL_CC2pi_1pip1pip_Evt_1DppipHigh_nu.h" #include "ANL_CC2pi_1pip1pip_Evt_1DppipLow_nu.h" #include "ANL_CC2pi_1pip1pip_XSec_1DEnu_nu.h" // ANL CC2pi 1pip1pi0 (mm, even more exotic!) #include "ANL_CC2pi_1pip1pi0_Evt_1Dpmu_nu.h" #include "ANL_CC2pi_1pip1pi0_Evt_1Dppi0_nu.h" #include "ANL_CC2pi_1pip1pi0_Evt_1Dppip_nu.h" #include "ANL_CC2pi_1pip1pi0_Evt_1Dpprot_nu.h" #include "ANL_CC2pi_1pip1pi0_XSec_1DEnu_nu.h" #endif #ifndef __NO_ArgoNeuT__ // ArgoNeuT CC-inclusive #include "ArgoNeuT_CCInc_XSec_1Dpmu_antinu.h" #include "ArgoNeuT_CCInc_XSec_1Dpmu_nu.h" #include "ArgoNeuT_CCInc_XSec_1Dthetamu_antinu.h" #include "ArgoNeuT_CCInc_XSec_1Dthetamu_nu.h" #endif #ifndef __NO_BNL__ // BNL CCQE #include "BNL_CCQE_Evt_1DQ2_nu.h" #include "BNL_CCQE_XSec_1DEnu_nu.h" // BNL CC1ppip #include "BNL_CC1ppip_Evt_1DQ2_nu.h" #include "BNL_CC1ppip_Evt_1DQ2_nu.h" #include "BNL_CC1ppip_Evt_1DcosthAdler_nu.h" #include "BNL_CC1ppip_Evt_1Dphi_nu.h" #include "BNL_CC1ppip_XSec_1DEnu_nu.h" // BNL CC1npip #include "BNL_CC1npip_Evt_1DQ2_nu.h" #include "BNL_CC1npip_XSec_1DEnu_nu.h" // BNL CC1pi0 #include "BNL_CC1pi0_Evt_1DQ2_nu.h" #include "BNL_CC1pi0_XSec_1DEnu_nu.h" #endif #ifndef __NO_FNAL__ // FNAL CCQE #include "FNAL_CCQE_Evt_1DQ2_nu.h" // FNAL CC1ppip #include "FNAL_CC1ppip_Evt_1DQ2_nu.h" #include "FNAL_CC1ppip_XSec_1DEnu_nu.h" #include "FNAL_CC1ppip_XSec_1DQ2_nu.h" // FNAL CC1ppim #include "FNAL_CC1ppim_XSec_1DEnu_antinu.h" #endif #ifndef __NO_BEBC__ // BEBC CCQE #include "BEBC_CCQE_XSec_1DQ2_nu.h" // BEBC CC1ppip #include "BEBC_CC1ppip_XSec_1DEnu_nu.h" #include "BEBC_CC1ppip_XSec_1DQ2_nu.h" // BEBC CC1npip #include "BEBC_CC1npip_XSec_1DEnu_nu.h" #include "BEBC_CC1npip_XSec_1DQ2_nu.h" // BEBC CC1pi0 #include "BEBC_CC1pi0_XSec_1DEnu_nu.h" #include "BEBC_CC1pi0_XSec_1DQ2_nu.h" // BEBC CC1npim #include "BEBC_CC1npim_XSec_1DEnu_antinu.h" #include "BEBC_CC1npim_XSec_1DQ2_antinu.h" // BEBC CC1ppim #include "BEBC_CC1ppim_XSec_1DEnu_antinu.h" #include "BEBC_CC1ppim_XSec_1DQ2_antinu.h" #endif #ifndef __NO_GGM__ // GGM CC1ppip #include "GGM_CC1ppip_Evt_1DQ2_nu.h" #include "GGM_CC1ppip_XSec_1DEnu_nu.h" #endif #ifndef __NO_MiniBooNE__ // MiniBooNE CCQE #include "MiniBooNE_CCQE_XSec_1DQ2_antinu.h" #include "MiniBooNE_CCQE_XSec_1DQ2_nu.h" #include "MiniBooNE_CCQE_XSec_2DTcos_antinu.h" #include "MiniBooNE_CCQE_XSec_2DTcos_antinu.h" #include "MiniBooNE_CCQE_XSec_2DTcos_nu.h" // MiniBooNE CC1pi+ 1D #include "MiniBooNE_CC1pip_XSec_1DEnu_nu.h" #include "MiniBooNE_CC1pip_XSec_1DQ2_nu.h" #include "MiniBooNE_CC1pip_XSec_1DTpi_nu.h" #include "MiniBooNE_CC1pip_XSec_1DTu_nu.h" // MiniBooNE CC1pi+ 2D #include "MiniBooNE_CC1pip_XSec_2DQ2Enu_nu.h" #include "MiniBooNE_CC1pip_XSec_2DTpiCospi_nu.h" #include "MiniBooNE_CC1pip_XSec_2DTpiEnu_nu.h" #include "MiniBooNE_CC1pip_XSec_2DTuCosmu_nu.h" #include "MiniBooNE_CC1pip_XSec_2DTuEnu_nu.h" // MiniBooNE CC1pi0 #include "MiniBooNE_CC1pi0_XSec_1DEnu_nu.h" #include "MiniBooNE_CC1pi0_XSec_1DQ2_nu.h" #include "MiniBooNE_CC1pi0_XSec_1DTu_nu.h" #include "MiniBooNE_CC1pi0_XSec_1Dcosmu_nu.h" #include "MiniBooNE_CC1pi0_XSec_1Dcospi0_nu.h" #include "MiniBooNE_CC1pi0_XSec_1Dppi0_nu.h" #include "MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu.h" #include "MiniBooNE_NC1pi0_XSec_1Dcospi0_nu.h" #include "MiniBooNE_NC1pi0_XSec_1Dppi0_antinu.h" #include "MiniBooNE_NC1pi0_XSec_1Dppi0_nu.h" // MiniBooNE NC1pi0 //#include "MiniBooNE_NCpi0_XSec_1Dppi0_nu.h" // MiniBooNE NCEL #include "MiniBooNE_NCEL_XSec_Treco_nu.h" #endif #ifndef __NO_MINERvA__ // MINERvA CCQE #include "MINERvA_CCQE_XSec_1DQ2_antinu.h" #include "MINERvA_CCQE_XSec_1DQ2_joint.h" #include "MINERvA_CCQE_XSec_1DQ2_nu.h" // MINERvA CC0pi #include "MINERvA_CC0pi_XSec_1DEe_nue.h" #include "MINERvA_CC0pi_XSec_1DQ2_nu_proton.h" #include "MINERvA_CC0pi_XSec_1DQ2_nue.h" #include "MINERvA_CC0pi_XSec_1DThetae_nue.h" // MINERvA CC1pi+ #include "MINERvA_CC1pip_XSec_1DTpi_20deg_nu.h" #include "MINERvA_CC1pip_XSec_1DTpi_nu.h" #include "MINERvA_CC1pip_XSec_1Dth_20deg_nu.h" #include "MINERvA_CC1pip_XSec_1Dth_nu.h" // 2017 data update #include "MINERvA_CC1pip_XSec_1D_2017Update.h" // MINERvA CCNpi+ #include "MINERvA_CCNpip_XSec_1DEnu_nu.h" #include "MINERvA_CCNpip_XSec_1DQ2_nu.h" #include "MINERvA_CCNpip_XSec_1DTpi_nu.h" #include "MINERvA_CCNpip_XSec_1Dpmu_nu.h" #include "MINERvA_CCNpip_XSec_1Dth_nu.h" #include "MINERvA_CCNpip_XSec_1Dthmu_nu.h" // MINERvA CC1pi0 #include "MINERvA_CC1pi0_XSec_1DEnu_antinu.h" #include "MINERvA_CC1pi0_XSec_1DQ2_antinu.h" #include "MINERvA_CC1pi0_XSec_1DTpi0_antinu.h" #include "MINERvA_CC1pi0_XSec_1Dpmu_antinu.h" #include "MINERvA_CC1pi0_XSec_1Dppi0_antinu.h" #include "MINERvA_CC1pi0_XSec_1Dth_antinu.h" #include "MINERvA_CC1pi0_XSec_1Dthmu_antinu.h" // MINERvA CC1pi0 neutrino #include "MINERvA_CC1pi0_XSec_1D_nu.h" // MINERvA CCINC #include "MINERvA_CCinc_XSec_1DEnu_ratio.h" #include "MINERvA_CCinc_XSec_1Dx_ratio.h" #include "MINERvA_CCinc_XSec_2DEavq3_nu.h" // MINERvA CCDIS #include "MINERvA_CCDIS_XSec_1DEnu_ratio.h" #include "MINERvA_CCDIS_XSec_1Dx_ratio.h" // MINERvA CCCOH pion #include "MINERvA_CCCOHPI_XSec_1DEnu_antinu.h" #include "MINERvA_CCCOHPI_XSec_1DEnu_antinu.h" #include "MINERvA_CCCOHPI_XSec_1DEpi_antinu.h" #include "MINERvA_CCCOHPI_XSec_1DQ2_antinu.h" #include "MINERvA_CCCOHPI_XSec_1DEpi_nu.h" #include "MINERvA_CCCOHPI_XSec_1DQ2_nu.h" #include "MINERvA_CCCOHPI_XSec_1Dth_nu.h" #include "MINERvA_CCCOHPI_XSec_1Dth_nu.h" #include "MINERvA_CCCOHPI_XSec_joint.h" #include "MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu.h" #include "MINERvA_CC0pi_XSec_1DQ2_Tgt_nu.h" #include "MINERvA_CC0pi_XSec_2Dptpx_antinu.h" #include "MINERvA_CC0pi_XSec_2Dptpx_nu.h" #endif #ifndef __NO_T2K__ // T2K CC0pi #include "T2K_CC0pi_XSec_2DPcos_nu.h" // T2K CC1pi+ on CH #include "T2K_CC1pip_CH_XSec_1DQ2_nu.h" #include "T2K_CC1pip_CH_XSec_1DWrec_nu.h" #include "T2K_CC1pip_CH_XSec_1Dpmu_nu.h" #include "T2K_CC1pip_CH_XSec_1Dppi_nu.h" #include "T2K_CC1pip_CH_XSec_1Dq3_nu.h" #include "T2K_CC1pip_CH_XSec_1Dthmupi_nu.h" #include "T2K_CC1pip_CH_XSec_1Dthpi_nu.h" #include "T2K_CC1pip_CH_XSec_1Dthq3pi_nu.h" // T2K CC1pi+ on H2O #include "T2K_CC1pip_H2O_XSec_1DEnuDelta_nu.h" #include "T2K_CC1pip_H2O_XSec_1DEnuMB_nu.h" #include "T2K_CC1pip_H2O_XSec_1Dcosmu_nu.h" #include "T2K_CC1pip_H2O_XSec_1Dcosmupi_nu.h" #include "T2K_CC1pip_H2O_XSec_1Dcospi_nu.h" #include "T2K_CC1pip_H2O_XSec_1Dpmu_nu.h" #include "T2K_CC1pip_H2O_XSec_1Dppi_nu.h" // T2K STV CC0pi #include "T2K_CC0pinp_STV_XSec_1Ddpt_nu.h" #include "T2K_CC0pi_XSec_2DPcos_nu_nonuniform.h" #endif #ifndef __NO_SciBooNE__ // SciBooNE COH studies #include "SciBooNE_CCCOH_1TRK_1DQ2_nu.h" #include "SciBooNE_CCCOH_MuPiNoVA_1DQ2_nu.h" #include "SciBooNE_CCCOH_MuPiNoVA_1Dthetapi_nu.h" #include "SciBooNE_CCCOH_MuPiNoVA_1Dthetapr_nu.h" #include "SciBooNE_CCCOH_MuPiVA_1DQ2_nu.h" #include "SciBooNE_CCCOH_MuPr_1DQ2_nu.h" #include "SciBooNE_CCCOH_STOPFINAL_1DQ2_nu.h" #include "SciBooNE_CCCOH_STOP_NTrks_nu.h" #endif #ifndef __NO_K2K__ // K2K NC1pi0 #include "K2K_NC1pi0_Evt_1Dppi0_nu.h" #endif // MC Studies #include "ExpMultDist_CCQE_XSec_1DVar_FakeStudy.h" #include "ExpMultDist_CCQE_XSec_2DVar_FakeStudy.h" #include "MCStudy_CCQEHistograms.h" #include "GenericFlux_Tester.h" #include "GenericFlux_Vectors.h" #include "ElectronFlux_FlatTree.h" #include "ElectronScattering_DurhamData.h" #include "MCStudy_KaonPreSelection.h" #include "MCStudy_MuonValidation.h" #include "OfficialNIWGPlots.h" #include "T2K2017_FakeData.h" #include "Simple_Osc.h" #include "Smear_SVDUnfold_Propagation_Osc.h" #include "FitWeight.h" #include "NuisConfig.h" #include "NuisKey.h" #ifdef __USE_DYNSAMPLES__ #include "TRegexp.h" #include // linux #include DynamicSampleFactory::DynamicSampleFactory() : NSamples(0), NManifests(0) { LoadPlugins(); QLOG(FIT, "Loaded " << NSamples << " from " << NManifests << " shared object libraries."); } DynamicSampleFactory* DynamicSampleFactory::glblDSF = NULL; DynamicSampleFactory::PluginManifest::~PluginManifest() { for (size_t i_it = 0; i_it < Instances.size(); ++i_it) { (*(DSF_DestroySample))(Instances[i_it]); } } std::string EnsureTrailingSlash(std::string const& inp) { if (!inp.length()) { return "/"; } if (inp[inp.length() - 1] == '/') { return inp; } return inp + "/"; } void DynamicSampleFactory::LoadPlugins() { std::vector SearchDirectories; if (Config::HasPar("dynamic_sample.path")) { SearchDirectories = GeneralUtils::ParseToStr(Config::GetParS("dynamic_sample.path"), ":"); } char const* envPath = getenv("NUISANCE_DS_PATH"); if (envPath) { std::vector envPaths = GeneralUtils::ParseToStr(envPath, ":"); for (size_t ep_it = 0; ep_it < envPaths.size(); ++ep_it) { SearchDirectories.push_back(envPaths[ep_it]); } } if (!SearchDirectories.size()) { char const* pwdPath = getenv("PWD"); if (pwdPath) { SearchDirectories.push_back(pwdPath); } } for (size_t sp_it = 0; sp_it < SearchDirectories.size(); ++sp_it) { std::string dirpath = EnsureTrailingSlash(SearchDirectories[sp_it]); QLOG(FIT, "Searching for dynamic sample manifests in: " << dirpath); Ssiz_t len = 0; DIR* dir; struct dirent* ent; dir = opendir(dirpath.c_str()); if (dir != NULL) { TRegexp matchExp("*.so", true); while ((ent = readdir(dir)) != NULL) { if (matchExp.Index(TString(ent->d_name), &len) != Ssiz_t(-1)) { QLOG(FIT, "\tFound shared object: " << ent->d_name << " checking for relevant methods..."); void* dlobj = dlopen((dirpath + ent->d_name).c_str(), RTLD_NOW | RTLD_GLOBAL); char const* dlerr_cstr = dlerror(); std::string dlerr; if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "\tDL Load Error: " << dlerr); continue; } PluginManifest plgManif; plgManif.dllib = dlobj; plgManif.soloc = (dirpath + ent->d_name); plgManif.DSF_NSamples = reinterpret_cast(dlsym(dlobj, "DSF_NSamples")); dlerr = ""; dlerr_cstr = dlerror(); if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "\tFailed to load symbol \"DSF_NSamples\" from " << (dirpath + ent->d_name) << ": " << dlerr); dlclose(dlobj); continue; } plgManif.DSF_GetSampleName = reinterpret_cast( dlsym(dlobj, "DSF_GetSampleName")); dlerr = ""; dlerr_cstr = dlerror(); if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "\tFailed to load symbol \"DSF_GetSampleName\" from " << (dirpath + ent->d_name) << ": " << dlerr); dlclose(dlobj); continue; } plgManif.DSF_GetSample = reinterpret_cast( dlsym(dlobj, "DSF_GetSample")); dlerr = ""; dlerr_cstr = dlerror(); if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "\tFailed to load symbol \"DSF_GetSample\" from " << (dirpath + ent->d_name) << ": " << dlerr); dlclose(dlobj); continue; } plgManif.DSF_DestroySample = reinterpret_cast( dlsym(dlobj, "DSF_DestroySample")); dlerr = ""; dlerr_cstr = dlerror(); if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "Failed to load symbol \"DSF_DestroySample\" from " << (dirpath + ent->d_name) << ": " << dlerr); dlclose(dlobj); continue; } plgManif.NSamples = (*(plgManif.DSF_NSamples))(); QLOG(FIT, "\tSuccessfully loaded dynamic sample manifest: " << plgManif.soloc << ". Contains " << plgManif.NSamples << " samples."); for (size_t smp_it = 0; smp_it < plgManif.NSamples; ++smp_it) { char const* smp_name = (*(plgManif.DSF_GetSampleName))(smp_it); if (!smp_name) { THROW("Could not load sample " << smp_it << " / " << plgManif.NSamples << " from " << plgManif.soloc); } if (Samples.count(smp_name)) { ERROR(WRN, "Already loaded a sample named: \"" << smp_name << "\". cannot load duplciates. This " "sample will be skipped."); continue; } plgManif.SamplesProvided.push_back(smp_name); Samples[smp_name] = std::make_pair(plgManif.soloc, smp_it); QLOG(FIT, "\t\t" << smp_name); } if (plgManif.SamplesProvided.size()) { Manifests[plgManif.soloc] = plgManif; NSamples += plgManif.SamplesProvided.size(); NManifests++; } else { dlclose(dlobj); } } } closedir(dir); } else { ERROR(WRN, "Tried to open non-existant directory."); } } } DynamicSampleFactory& DynamicSampleFactory::Get() { if (!glblDSF) { glblDSF = new DynamicSampleFactory(); } return *glblDSF; } void DynamicSampleFactory::Print() { std::map > ManifestSamples; for (std::map >::iterator smp_it = Samples.begin(); smp_it != Samples.end(); ++smp_it) { if (!ManifestSamples.count(smp_it->second.first)) { ManifestSamples[smp_it->second.first] = std::vector(); } ManifestSamples[smp_it->second.first].push_back(smp_it->first); } QLOG(FIT, "Dynamic sample manifest: "); for (std::map >::iterator m_it = ManifestSamples.begin(); m_it != ManifestSamples.end(); ++m_it) { QLOG(FIT, "\tLibrary " << m_it->first << " contains: "); for (size_t s_it = 0; s_it < m_it->second.size(); ++s_it) { QLOG(FIT, "\t\t" << m_it->second[s_it]); } } } bool DynamicSampleFactory::HasSample(std::string const& name) { return Samples.count(name); } bool DynamicSampleFactory::HasSample(nuiskey& samplekey) { return HasSample(samplekey.GetS("name")); } MeasurementBase* DynamicSampleFactory::CreateSample(nuiskey& samplekey) { if (!HasSample(samplekey)) { ERROR(WRN, "Asked to load unknown sample: \"" << samplekey.GetS("name") << "\"."); return NULL; } std::pair sample = Samples[samplekey.GetS("name")]; QLOG(SAM, "\tLoading sample " << sample.second << " from " << sample.first); return (*(Manifests[sample.first].DSF_GetSample))(sample.second, &samplekey); } DynamicSampleFactory::~DynamicSampleFactory() { Manifests.clear(); } #endif //! Functions to make it easier for samples to be created and handled. namespace SampleUtils { //! Create a given sample given its name, file, type, fakdata(fkdt) file and the //! current rw engine and push it back into the list fChain. MeasurementBase* CreateSample(std::string name, std::string file, std::string type, std::string fkdt, FitWeight* rw) { nuiskey samplekey = Config::CreateKey("sample"); samplekey.Set("name", name); samplekey.Set("input", file); samplekey.Set("type", type); return CreateSample(samplekey); } MeasurementBase* CreateSample(nuiskey samplekey) { #ifdef __USE_DYNSAMPLES__ if (DynamicSampleFactory::Get().HasSample(samplekey)) { QLOG(SAM, "Instantiating dynamic sample..."); MeasurementBase* ds = DynamicSampleFactory::Get().CreateSample(samplekey); if (ds) { QLOG(SAM, "Done."); return ds; } THROW("Failed to instantiate dynamic sample."); } #endif FitWeight* rw = FitBase::GetRW(); std::string name = samplekey.GetS("name"); std::string file = samplekey.GetS("input"); std::string type = samplekey.GetS("type"); std::string fkdt = ""; /* ANL CCQE Samples */ #ifndef __NO_ANL__ if (!name.compare("ANL_CCQE_XSec_1DEnu_nu") || !name.compare("ANL_CCQE_XSec_1DEnu_nu_PRD26") || !name.compare("ANL_CCQE_XSec_1DEnu_nu_PRL31") || !name.compare("ANL_CCQE_XSec_1DEnu_nu_PRD16")) { return (new ANL_CCQE_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CCQE_Evt_1DQ2_nu") || !name.compare("ANL_CCQE_Evt_1DQ2_nu_PRL31") || !name.compare("ANL_CCQE_Evt_1DQ2_nu_PRD26") || !name.compare("ANL_CCQE_Evt_1DQ2_nu_PRD16")) { return (new ANL_CCQE_Evt_1DQ2_nu(samplekey)); /* ANL CC1ppip samples */ } else if (!name.compare("ANL_CC1ppip_XSec_1DEnu_nu") || !name.compare("ANL_CC1ppip_XSec_1DEnu_nu_W14Cut") || !name.compare("ANL_CC1ppip_XSec_1DEnu_nu_Uncorr") || !name.compare("ANL_CC1ppip_XSec_1DEnu_nu_W14Cut_Uncorr") || !name.compare("ANL_CC1ppip_XSec_1DEnu_nu_W16Cut_Uncorr")) { return (new ANL_CC1ppip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_XSec_1DQ2_nu")) { return (new ANL_CC1ppip_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_Evt_1DQ2_nu") || !name.compare("ANL_CC1ppip_Evt_1DQ2_nu_W14Cut")) { return (new ANL_CC1ppip_Evt_1DQ2_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_Evt_1Dppi_nu")) { return (new ANL_CC1ppip_Evt_1Dppi_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_Evt_1Dthpr_nu")) { return (new ANL_CC1ppip_Evt_1Dthpr_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_Evt_1DcosmuStar_nu")) { return (new ANL_CC1ppip_Evt_1DcosmuStar_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_Evt_1DcosthAdler_nu")) { return (new ANL_CC1ppip_Evt_1DcosthAdler_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_Evt_1Dphi_nu")) { return (new ANL_CC1ppip_Evt_1Dphi_nu(samplekey)); /* ANL CC1npip sample */ } else if (!name.compare("ANL_CC1npip_XSec_1DEnu_nu") || !name.compare("ANL_CC1npip_XSec_1DEnu_nu_W14Cut") || !name.compare("ANL_CC1npip_XSec_1DEnu_nu_Uncorr") || !name.compare("ANL_CC1npip_XSec_1DEnu_nu_W14Cut_Uncorr") || !name.compare("ANL_CC1npip_XSec_1DEnu_nu_W16Cut_Uncorr")) { return (new ANL_CC1npip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CC1npip_Evt_1DQ2_nu") || !name.compare("ANL_CC1npip_Evt_1DQ2_nu_W14Cut")) { return (new ANL_CC1npip_Evt_1DQ2_nu(samplekey)); } else if (!name.compare("ANL_CC1npip_Evt_1Dppi_nu")) { return (new ANL_CC1npip_Evt_1Dppi_nu(samplekey)); } else if (!name.compare("ANL_CC1npip_Evt_1DcosmuStar_nu")) { return (new ANL_CC1npip_Evt_1DcosmuStar_nu(samplekey)); /* ANL CC1pi0 sample */ } else if (!name.compare("ANL_CC1pi0_XSec_1DEnu_nu") || !name.compare("ANL_CC1pi0_XSec_1DEnu_nu_W14Cut") || !name.compare("ANL_CC1pi0_XSec_1DEnu_nu_Uncorr") || !name.compare("ANL_CC1pi0_XSec_1DEnu_nu_W14Cut_Uncorr") || !name.compare("ANL_CC1pi0_XSec_1DEnu_nu_W16Cut_Uncorr")) { return (new ANL_CC1pi0_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CC1pi0_Evt_1DQ2_nu") || !name.compare("ANL_CC1pi0_Evt_1DQ2_nu_W14Cut")) { return (new ANL_CC1pi0_Evt_1DQ2_nu(samplekey)); } else if (!name.compare("ANL_CC1pi0_Evt_1DcosmuStar_nu")) { return (new ANL_CC1pi0_Evt_1DcosmuStar_nu(samplekey)); /* ANL NC1npip sample */ } else if (!name.compare("ANL_NC1npip_Evt_1Dppi_nu")) { return (new ANL_NC1npip_Evt_1Dppi_nu(samplekey)); /* ANL NC1ppim sample */ } else if (!name.compare("ANL_NC1ppim_XSec_1DEnu_nu")) { return (new ANL_NC1ppim_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_NC1ppim_Evt_1DcosmuStar_nu")) { return (new ANL_NC1ppim_Evt_1DcosmuStar_nu(samplekey)); /* ANL CC2pi sample */ } else if (!name.compare("ANL_CC2pi_1pim1pip_XSec_1DEnu_nu")) { return (new ANL_CC2pi_1pim1pip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pim1pip_Evt_1Dpmu_nu")) { return (new ANL_CC2pi_1pim1pip_Evt_1Dpmu_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pim1pip_Evt_1Dppip_nu")) { return (new ANL_CC2pi_1pim1pip_Evt_1Dppip_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pim1pip_Evt_1Dppim_nu")) { return (new ANL_CC2pi_1pim1pip_Evt_1Dppim_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pim1pip_Evt_1Dpprot_nu")) { return (new ANL_CC2pi_1pim1pip_Evt_1Dpprot_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pip_XSec_1DEnu_nu")) { return (new ANL_CC2pi_1pip1pip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pip_Evt_1Dpmu_nu")) { return (new ANL_CC2pi_1pip1pip_Evt_1Dpmu_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pip_Evt_1Dpneut_nu")) { return (new ANL_CC2pi_1pip1pip_Evt_1Dpneut_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pip_Evt_1DppipHigh_nu")) { return (new ANL_CC2pi_1pip1pip_Evt_1DppipHigh_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pip_Evt_1DppipLow_nu")) { return (new ANL_CC2pi_1pip1pip_Evt_1DppipLow_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pi0_XSec_1DEnu_nu")) { return (new ANL_CC2pi_1pip1pi0_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pi0_Evt_1Dpmu_nu")) { return (new ANL_CC2pi_1pip1pi0_Evt_1Dpmu_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pi0_Evt_1Dppip_nu")) { return (new ANL_CC2pi_1pip1pi0_Evt_1Dppip_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pi0_Evt_1Dppi0_nu")) { return (new ANL_CC2pi_1pip1pi0_Evt_1Dppi0_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pi0_Evt_1Dpprot_nu")) { return (new ANL_CC2pi_1pip1pi0_Evt_1Dpprot_nu(samplekey)); /* ArgoNeut Samples */ } else #endif #ifndef __NO_ArgoNeuT__ if (!name.compare("ArgoNeuT_CCInc_XSec_1Dpmu_antinu")) { return (new ArgoNeuT_CCInc_XSec_1Dpmu_antinu(samplekey)); } else if (!name.compare("ArgoNeuT_CCInc_XSec_1Dpmu_nu")) { return (new ArgoNeuT_CCInc_XSec_1Dpmu_nu(samplekey)); } else if (!name.compare("ArgoNeuT_CCInc_XSec_1Dthetamu_antinu")) { return (new ArgoNeuT_CCInc_XSec_1Dthetamu_antinu(samplekey)); } else if (!name.compare("ArgoNeuT_CCInc_XSec_1Dthetamu_nu")) { return (new ArgoNeuT_CCInc_XSec_1Dthetamu_nu(samplekey)); /* BNL Samples */ } else #endif #ifndef __NO_BNL__ if (!name.compare("BNL_CCQE_XSec_1DEnu_nu")) { return (new BNL_CCQE_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BNL_CCQE_Evt_1DQ2_nu")) { return (new BNL_CCQE_Evt_1DQ2_nu(samplekey)); /* BNL CC1ppip samples */ } else if (!name.compare("BNL_CC1ppip_XSec_1DEnu_nu") || !name.compare("BNL_CC1ppip_XSec_1DEnu_nu_Uncorr") || !name.compare("BNL_CC1ppip_XSec_1DEnu_nu_W14Cut") || !name.compare("BNL_CC1ppip_XSec_1DEnu_nu_W14Cut_Uncorr")) { return (new BNL_CC1ppip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BNL_CC1ppip_Evt_1DQ2_nu") || !name.compare("BNL_CC1ppip_Evt_1DQ2_nu_W14Cut")) { return (new BNL_CC1ppip_Evt_1DQ2_nu(samplekey)); } else if (!name.compare("BNL_CC1ppip_Evt_1DcosthAdler_nu")) { return (new BNL_CC1ppip_Evt_1DcosthAdler_nu(samplekey)); } else if (!name.compare("BNL_CC1ppip_Evt_1Dphi_nu")) { return (new BNL_CC1ppip_Evt_1Dphi_nu(samplekey)); /* BNL CC1npip samples */ } else if (!name.compare("BNL_CC1npip_XSec_1DEnu_nu") || !name.compare("BNL_CC1npip_XSec_1DEnu_nu_Uncorr")) { return (new BNL_CC1npip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BNL_CC1npip_Evt_1DQ2_nu")) { return (new BNL_CC1npip_Evt_1DQ2_nu(samplekey)); /* BNL CC1pi0 samples */ } else if (!name.compare("BNL_CC1pi0_XSec_1DEnu_nu")) { return (new BNL_CC1pi0_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BNL_CC1pi0_Evt_1DQ2_nu")) { return (new BNL_CC1pi0_Evt_1DQ2_nu(samplekey)); /* FNAL Samples */ } else #endif #ifndef __NO_FNAL__ if (!name.compare("FNAL_CCQE_Evt_1DQ2_nu")) { return (new FNAL_CCQE_Evt_1DQ2_nu(samplekey)); /* FNAL CC1ppip */ } else if (!name.compare("FNAL_CC1ppip_XSec_1DEnu_nu")) { return (new FNAL_CC1ppip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("FNAL_CC1ppip_XSec_1DQ2_nu")) { return (new FNAL_CC1ppip_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("FNAL_CC1ppip_Evt_1DQ2_nu")) { return (new FNAL_CC1ppip_Evt_1DQ2_nu(samplekey)); /* FNAL CC1ppim */ } else if (!name.compare("FNAL_CC1ppim_XSec_1DEnu_antinu")) { return (new FNAL_CC1ppim_XSec_1DEnu_antinu(samplekey)); /* BEBC Samples */ } else #endif #ifndef __NO_BEBC__ if (!name.compare("BEBC_CCQE_XSec_1DQ2_nu")) { return (new BEBC_CCQE_XSec_1DQ2_nu(samplekey)); /* BEBC CC1ppip samples */ } else if (!name.compare("BEBC_CC1ppip_XSec_1DEnu_nu")) { return (new BEBC_CC1ppip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BEBC_CC1ppip_XSec_1DQ2_nu")) { return (new BEBC_CC1ppip_XSec_1DQ2_nu(samplekey)); /* BEBC CC1npip samples */ } else if (!name.compare("BEBC_CC1npip_XSec_1DEnu_nu")) { return (new BEBC_CC1npip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BEBC_CC1npip_XSec_1DQ2_nu")) { return (new BEBC_CC1npip_XSec_1DQ2_nu(samplekey)); /* BEBC CC1pi0 samples */ } else if (!name.compare("BEBC_CC1pi0_XSec_1DEnu_nu")) { return (new BEBC_CC1pi0_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BEBC_CC1pi0_XSec_1DQ2_nu")) { return (new BEBC_CC1pi0_XSec_1DQ2_nu(samplekey)); /* BEBC CC1npim samples */ } else if (!name.compare("BEBC_CC1npim_XSec_1DEnu_antinu")) { return (new BEBC_CC1npim_XSec_1DEnu_antinu(samplekey)); } else if (!name.compare("BEBC_CC1npim_XSec_1DQ2_antinu")) { return (new BEBC_CC1npim_XSec_1DQ2_antinu(samplekey)); /* BEBC CC1ppim samples */ } else if (!name.compare("BEBC_CC1ppim_XSec_1DEnu_antinu")) { return (new BEBC_CC1ppim_XSec_1DEnu_antinu(samplekey)); } else if (!name.compare("BEBC_CC1ppim_XSec_1DQ2_antinu")) { return (new BEBC_CC1ppim_XSec_1DQ2_antinu(samplekey)); /* GGM CC1ppip samples */ } else #endif #ifndef __NO_GGM__ if (!name.compare("GGM_CC1ppip_XSec_1DEnu_nu")) { return (new GGM_CC1ppip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("GGM_CC1ppip_Evt_1DQ2_nu")) { return (new GGM_CC1ppip_Evt_1DQ2_nu(samplekey)); /* MiniBooNE Samples */ /* CCQE */ } else #endif #ifndef __NO_MiniBooNE__ if (!name.compare("MiniBooNE_CCQE_XSec_1DQ2_nu") || !name.compare("MiniBooNE_CCQELike_XSec_1DQ2_nu")) { return (new MiniBooNE_CCQE_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("MiniBooNE_CCQE_XSec_1DQ2_antinu") || !name.compare("MiniBooNE_CCQELike_XSec_1DQ2_antinu") || !name.compare("MiniBooNE_CCQE_CTarg_XSec_1DQ2_antinu")) { return (new MiniBooNE_CCQE_XSec_1DQ2_antinu(samplekey)); } else if (!name.compare("MiniBooNE_CCQE_XSec_2DTcos_nu") || !name.compare("MiniBooNE_CCQELike_XSec_2DTcos_nu")) { return (new MiniBooNE_CCQE_XSec_2DTcos_nu(samplekey)); } else if (!name.compare("MiniBooNE_CCQE_XSec_2DTcos_antinu") || !name.compare("MiniBooNE_CCQELike_XSec_2DTcos_antinu")) { return (new MiniBooNE_CCQE_XSec_2DTcos_antinu(samplekey)); /* MiniBooNE CC1pi+ */ // 1D } else if (!name.compare("MiniBooNE_CC1pip_XSec_1DEnu_nu")) { return (new MiniBooNE_CC1pip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_1DQ2_nu")) { return (new MiniBooNE_CC1pip_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_1DTpi_nu")) { return (new MiniBooNE_CC1pip_XSec_1DTpi_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_1DTu_nu")) { return (new MiniBooNE_CC1pip_XSec_1DTu_nu(samplekey)); // 2D } else if (!name.compare("MiniBooNE_CC1pip_XSec_2DQ2Enu_nu")) { return (new MiniBooNE_CC1pip_XSec_2DQ2Enu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_2DTpiCospi_nu")) { return (new MiniBooNE_CC1pip_XSec_2DTpiCospi_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_2DTpiEnu_nu")) { return (new MiniBooNE_CC1pip_XSec_2DTpiEnu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_2DTuCosmu_nu")) { return (new MiniBooNE_CC1pip_XSec_2DTuCosmu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_2DTuEnu_nu")) { return (new MiniBooNE_CC1pip_XSec_2DTuEnu_nu(samplekey)); /* MiniBooNE CC1pi0 */ } else if (!name.compare("MiniBooNE_CC1pi0_XSec_1DEnu_nu")) { return (new MiniBooNE_CC1pi0_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pi0_XSec_1DQ2_nu")) { return (new MiniBooNE_CC1pi0_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pi0_XSec_1DTu_nu")) { return (new MiniBooNE_CC1pi0_XSec_1DTu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pi0_XSec_1Dcosmu_nu")) { return (new MiniBooNE_CC1pi0_XSec_1Dcosmu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pi0_XSec_1Dcospi0_nu")) { return (new MiniBooNE_CC1pi0_XSec_1Dcospi0_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pi0_XSec_1Dppi0_nu")) { return (new MiniBooNE_CC1pi0_XSec_1Dppi0_nu(samplekey)); } else if (!name.compare("MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu") || !name.compare("MiniBooNE_NC1pi0_XSec_1Dcospi0_rhc")) { return (new MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu(samplekey)); } else if (!name.compare("MiniBooNE_NC1pi0_XSec_1Dcospi0_nu") || !name.compare("MiniBooNE_NC1pi0_XSec_1Dcospi0_fhc")) { return (new MiniBooNE_NC1pi0_XSec_1Dcospi0_nu(samplekey)); } else if (!name.compare("MiniBooNE_NC1pi0_XSec_1Dppi0_antinu") || !name.compare("MiniBooNE_NC1pi0_XSec_1Dppi0_rhc")) { return (new MiniBooNE_NC1pi0_XSec_1Dppi0_antinu(samplekey)); } else if (!name.compare("MiniBooNE_NC1pi0_XSec_1Dppi0_nu") || !name.compare("MiniBooNE_NC1pi0_XSec_1Dppi0_fhc")) { return (new MiniBooNE_NC1pi0_XSec_1Dppi0_nu(samplekey)); /* MiniBooNE NCEL */ } else if (!name.compare("MiniBooNE_NCEL_XSec_Treco_nu")) { return (new MiniBooNE_NCEL_XSec_Treco_nu(samplekey)); /* MINERvA Samples */ } else #endif #ifndef __NO_MINERvA__ if (!name.compare("MINERvA_CCQE_XSec_1DQ2_nu") || !name.compare("MINERvA_CCQE_XSec_1DQ2_nu_20deg") || !name.compare("MINERvA_CCQE_XSec_1DQ2_nu_oldflux") || !name.compare("MINERvA_CCQE_XSec_1DQ2_nu_20deg_oldflux")) { return (new MINERvA_CCQE_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("MINERvA_CCQE_XSec_1DQ2_antinu") || !name.compare("MINERvA_CCQE_XSec_1DQ2_antinu_20deg") || !name.compare("MINERvA_CCQE_XSec_1DQ2_antinu_oldflux") || !name.compare("MINERvA_CCQE_XSec_1DQ2_antinu_20deg_oldflux")) { return (new MINERvA_CCQE_XSec_1DQ2_antinu(samplekey)); } else if (!name.compare("MINERvA_CCQE_XSec_1DQ2_joint_oldflux") || !name.compare("MINERvA_CCQE_XSec_1DQ2_joint_20deg_oldflux") || !name.compare("MINERvA_CCQE_XSec_1DQ2_joint") || !name.compare("MINERvA_CCQE_XSec_1DQ2_joint_20deg")) { return (new MINERvA_CCQE_XSec_1DQ2_joint(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_1DEe_nue")) { return (new MINERvA_CC0pi_XSec_1DEe_nue(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_1DQ2_nue")) { return (new MINERvA_CC0pi_XSec_1DQ2_nue(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_1DThetae_nue")) { return (new MINERvA_CC0pi_XSec_1DThetae_nue(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_1DQ2_nu_proton")) { return (new MINERvA_CC0pi_XSec_1DQ2_nu_proton(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtC_nu") || !name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtCH_nu") || !name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtFe_nu") || !name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtPb_nu")) { return (new MINERvA_CC0pi_XSec_1DQ2_Tgt_nu(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtRatioC_nu") || !name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtRatioFe_nu") || !name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtRatioPb_nu")) { return (new MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_2Dptpx_nu")) { return (new MINERvA_CC0pi_XSec_2Dptpx_nu(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_2Dptpx_antinu")) { return (new MINERvA_CC0pi_XSec_2Dptpx_antinu(samplekey)); /* CC1pi+ */ // DONE } else if (!name.compare("MINERvA_CC1pip_XSec_1DTpi_nu") || !name.compare("MINERvA_CC1pip_XSec_1DTpi_nu_20deg") || !name.compare("MINERvA_CC1pip_XSec_1DTpi_nu_fluxcorr") || !name.compare("MINERvA_CC1pip_XSec_1DTpi_nu_20deg_fluxcorr")) { return (new MINERvA_CC1pip_XSec_1DTpi_nu(samplekey)); // DONE } else if (!name.compare("MINERvA_CC1pip_XSec_1Dth_nu") || !name.compare("MINERvA_CC1pip_XSec_1Dth_nu_20deg") || !name.compare("MINERvA_CC1pip_XSec_1Dth_nu_fluxcorr") || !name.compare("MINERvA_CC1pip_XSec_1Dth_nu_20deg_fluxcorr")) { return (new MINERvA_CC1pip_XSec_1Dth_nu(samplekey)); } else if (!name.compare("MINERvA_CC1pip_XSec_1DTpi_nu_2017") || !name.compare("MINERvA_CC1pip_XSec_1Dth_nu_2017") || !name.compare("MINERvA_CC1pip_XSec_1Dpmu_nu_2017") || !name.compare("MINERvA_CC1pip_XSec_1Dthmu_nu_2017") || !name.compare("MINERvA_CC1pip_XSec_1DQ2_nu_2017") || !name.compare("MINERvA_CC1pip_XSec_1DEnu_nu_2017")) { return (new MINERvA_CC1pip_XSec_1D_2017Update(samplekey)); /* CCNpi+ */ } else if (!name.compare("MINERvA_CCNpip_XSec_1Dth_nu") || !name.compare("MINERvA_CCNpip_XSec_1Dth_nu_2015") || !name.compare("MINERvA_CCNpip_XSec_1Dth_nu_2016") || !name.compare("MINERvA_CCNpip_XSec_1Dth_nu_2015_20deg") || !name.compare("MINERvA_CCNpip_XSec_1Dth_nu_2015_fluxcorr") || !name.compare("MINERvA_CCNpip_XSec_1Dth_nu_2015_20deg_fluxcorr")) { return (new MINERvA_CCNpip_XSec_1Dth_nu(samplekey)); } else if (!name.compare("MINERvA_CCNpip_XSec_1DTpi_nu") || !name.compare("MINERvA_CCNpip_XSec_1DTpi_nu_2015") || !name.compare("MINERvA_CCNpip_XSec_1DTpi_nu_2016") || !name.compare("MINERvA_CCNpip_XSec_1DTpi_nu_2015_20deg") || !name.compare("MINERvA_CCNpip_XSec_1DTpi_nu_2015_fluxcorr") || !name.compare( "MINERvA_CCNpip_XSec_1DTpi_nu_2015_20deg_fluxcorr")) { return (new MINERvA_CCNpip_XSec_1DTpi_nu(samplekey)); // Done } else if (!name.compare("MINERvA_CCNpip_XSec_1Dthmu_nu")) { return (new MINERvA_CCNpip_XSec_1Dthmu_nu(samplekey)); // Done } else if (!name.compare("MINERvA_CCNpip_XSec_1Dpmu_nu")) { return (new MINERvA_CCNpip_XSec_1Dpmu_nu(samplekey)); // Done } else if (!name.compare("MINERvA_CCNpip_XSec_1DQ2_nu")) { return (new MINERvA_CCNpip_XSec_1DQ2_nu(samplekey)); // Done } else if (!name.compare("MINERvA_CCNpip_XSec_1DEnu_nu")) { return (new MINERvA_CCNpip_XSec_1DEnu_nu(samplekey)); /* MINERvA CC1pi0 anti-nu */ // Done } else if (!name.compare("MINERvA_CC1pi0_XSec_1Dth_antinu") || !name.compare("MINERvA_CC1pi0_XSec_1Dth_antinu_2015") || !name.compare("MINERvA_CC1pi0_XSec_1Dth_antinu_2016") || !name.compare("MINERvA_CC1pi0_XSec_1Dth_antinu_fluxcorr") || !name.compare("MINERvA_CC1pi0_XSec_1Dth_antinu_2015_fluxcorr") || !name.compare("MINERvA_CC1pi0_XSec_1Dth_antinu_2016_fluxcorr")) { return (new MINERvA_CC1pi0_XSec_1Dth_antinu(samplekey)); } else if (!name.compare("MINERvA_CC1pi0_XSec_1Dppi0_antinu") || !name.compare("MINERvA_CC1pi0_XSec_1Dppi0_antinu_fluxcorr")) { return (new MINERvA_CC1pi0_XSec_1Dppi0_antinu(samplekey)); } else if (!name.compare("MINERvA_CC1pi0_XSec_1DTpi0_antinu")) { return (new MINERvA_CC1pi0_XSec_1DTpi0_antinu(samplekey)); // Done } else if (!name.compare("MINERvA_CC1pi0_XSec_1DQ2_antinu")) { return (new MINERvA_CC1pi0_XSec_1DQ2_antinu(samplekey)); // Done } else if (!name.compare("MINERvA_CC1pi0_XSec_1Dthmu_antinu")) { return (new MINERvA_CC1pi0_XSec_1Dthmu_antinu(samplekey)); // Done } else if (!name.compare("MINERvA_CC1pi0_XSec_1Dpmu_antinu")) { return (new MINERvA_CC1pi0_XSec_1Dpmu_antinu(samplekey)); // Done } else if (!name.compare("MINERvA_CC1pi0_XSec_1DEnu_antinu")) { return (new MINERvA_CC1pi0_XSec_1DEnu_antinu(samplekey)); // MINERvA CC1pi0 nu } else if (!name.compare("MINERvA_CC1pi0_XSec_1DTpi_nu") || !name.compare("MINERvA_CC1pi0_XSec_1Dth_nu") || !name.compare("MINERvA_CC1pi0_XSec_1Dpmu_nu") || !name.compare("MINERvA_CC1pi0_XSec_1Dthmu_nu") || !name.compare("MINERvA_CC1pi0_XSec_1DQ2_nu") || !name.compare("MINERvA_CC1pi0_XSec_1DEnu_nu") || !name.compare("MINERvA_CC1pi0_XSec_1DWexp_nu") || !name.compare("MINERvA_CC1pi0_XSec_1DPPi0Mass_nu") || !name.compare("MINERvA_CC1pi0_XSec_1DPPi0MassDelta_nu") || !name.compare("MINERvA_CC1pi0_XSec_1DCosAdler_nu") || !name.compare("MINERvA_CC1pi0_XSec_1DPhiAdler_nu")) { return (new MINERvA_CC1pi0_XSec_1D_nu(samplekey)); /* CCINC */ } else if (!name.compare("MINERvA_CCinc_XSec_2DEavq3_nu")) { return (new MINERvA_CCinc_XSec_2DEavq3_nu(samplekey)); } else if (!name.compare("MINERvA_CCinc_XSec_1Dx_ratio_C12_CH") || !name.compare("MINERvA_CCinc_XSec_1Dx_ratio_Fe56_CH") || !name.compare("MINERvA_CCinc_XSec_1Dx_ratio_Pb208_CH")) { return (new MINERvA_CCinc_XSec_1Dx_ratio(samplekey)); } else if (!name.compare("MINERvA_CCinc_XSec_1DEnu_ratio_C12_CH") || !name.compare("MINERvA_CCinc_XSec_1DEnu_ratio_Fe56_CH") || !name.compare("MINERvA_CCinc_XSec_1DEnu_ratio_Pb208_CH")) { return (new MINERvA_CCinc_XSec_1DEnu_ratio(samplekey)); /* CCDIS */ } else if (!name.compare("MINERvA_CCDIS_XSec_1Dx_ratio_C12_CH") || !name.compare("MINERvA_CCDIS_XSec_1Dx_ratio_Fe56_CH") || !name.compare("MINERvA_CCDIS_XSec_1Dx_ratio_Pb208_CH")) { return (new MINERvA_CCDIS_XSec_1Dx_ratio(samplekey)); } else if (!name.compare("MINERvA_CCDIS_XSec_1DEnu_ratio_C12_CH") || !name.compare("MINERvA_CCDIS_XSec_1DEnu_ratio_Fe56_CH") || !name.compare("MINERvA_CCDIS_XSec_1DEnu_ratio_Pb208_CH")) { return (new MINERvA_CCDIS_XSec_1DEnu_ratio(samplekey)); /* CC-COH */ } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DEnu_nu")) { return (new MINERvA_CCCOHPI_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DEpi_nu")) { return (new MINERvA_CCCOHPI_XSec_1DEpi_nu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1Dth_nu")) { return (new MINERvA_CCCOHPI_XSec_1Dth_nu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DQ2_nu")) { return (new MINERvA_CCCOHPI_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DEnu_antinu")) { return (new MINERvA_CCCOHPI_XSec_1DEnu_antinu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DEpi_antinu")) { return (new MINERvA_CCCOHPI_XSec_1DEpi_antinu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1Dth_antinu")) { return (new MINERvA_CCCOHPI_XSec_1Dth_antinu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DQ2_antinu")) { return (new MINERvA_CCCOHPI_XSec_1DQ2_antinu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DEnu_joint")) { return (new MINERvA_CCCOHPI_XSec_joint(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DEpi_joint")) { return (new MINERvA_CCCOHPI_XSec_joint(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1Dth_joint")) { return (new MINERvA_CCCOHPI_XSec_joint(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DQ2_joint")) { return (new MINERvA_CCCOHPI_XSec_joint(samplekey)); /* T2K Samples */ } else #endif #ifndef __NO_T2K__ if (!name.compare("T2K_CC0pi_XSec_2DPcos_nu") || !name.compare("T2K_CC0pi_XSec_2DPcos_nu_I") || !name.compare("T2K_CC0pi_XSec_2DPcos_nu_II")) { return (new T2K_CC0pi_XSec_2DPcos_nu(samplekey)); } else if (!name.compare("T2K_CC0pi_XSec_2DPcos_nu_nonuniform")) { return (new T2K_CC0pi_XSec_2DPcos_nu_nonuniform(samplekey)); /* T2K CC1pi+ CH samples */ // Comment these out for now because we don't have the proper data - + } else if (!name.compare("T2K_CC1pip_CH_XSec_1Dpmu_nu")) { return (new T2K_CC1pip_CH_XSec_1Dpmu_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1Dppi_nu")) { return (new T2K_CC1pip_CH_XSec_1Dppi_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1DQ2_nu")) { return (new T2K_CC1pip_CH_XSec_1DQ2_nu(file, rw, type, fkdt)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1Dq3_nu")) { return (new T2K_CC1pip_CH_XSec_1Dq3_nu(file, rw, type, fkdt)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1Dthmupi_nu")) { return (new T2K_CC1pip_CH_XSec_1Dthmupi_nu(file, rw, type, fkdt)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1Dthpi_nu")) { return (new T2K_CC1pip_CH_XSec_1Dthpi_nu(file, rw, type, fkdt)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1Dthq3pi_nu")) { return (new T2K_CC1pip_CH_XSec_1Dthq3pi_nu(file, rw, type, fkdt)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1DWrec_nu")) { return (new T2K_CC1pip_CH_XSec_1DWrec_nu(file, rw, type, fkdt)); /* T2K CC1pi+ H2O samples */ } else if (!name.compare("T2K_CC1pip_H2O_XSec_1DEnuDelta_nu")) { return (new T2K_CC1pip_H2O_XSec_1DEnuDelta_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_H2O_XSec_1DEnuMB_nu")) { return (new T2K_CC1pip_H2O_XSec_1DEnuMB_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_H2O_XSec_1Dcosmu_nu")) { return (new T2K_CC1pip_H2O_XSec_1Dcosmu_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_H2O_XSec_1Dcosmupi_nu")) { return (new T2K_CC1pip_H2O_XSec_1Dcosmupi_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_H2O_XSec_1Dcospi_nu")) { return (new T2K_CC1pip_H2O_XSec_1Dcospi_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_H2O_XSec_1Dpmu_nu")) { return (new T2K_CC1pip_H2O_XSec_1Dpmu_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_H2O_XSec_1Dppi_nu")) { return (new T2K_CC1pip_H2O_XSec_1Dppi_nu(samplekey)); /* T2K CC0pi + np CH samples */ } else if (!name.compare("T2K_CC0pinp_STV_XSec_1Ddpt_nu")) { return (new T2K_CC0pinp_STV_XSec_1Ddpt_nu(samplekey)); // SciBooNE COH studies } else #endif #ifndef __NO_SciBooNE__ if (!name.compare("SciBooNE_CCCOH_STOP_NTrks_nu")) { return (new SciBooNE_CCCOH_STOP_NTrks_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_1TRK_1DQ2_nu")) { return (new SciBooNE_CCCOH_1TRK_1DQ2_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPr_1DQ2_nu")) { return (new SciBooNE_CCCOH_MuPr_1DQ2_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPiVA_1DQ2_nu")) { return (new SciBooNE_CCCOH_MuPiVA_1DQ2_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPiNoVA_1DQ2_nu")) { return (new SciBooNE_CCCOH_MuPiNoVA_1DQ2_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPiNoVA_1Dthetapr_nu")) { return (new SciBooNE_CCCOH_MuPiNoVA_1Dthetapr_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPiNoVA_1Dthetapi_nu")) { return (new SciBooNE_CCCOH_MuPiNoVA_1Dthetapi_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_STOPFINAL_1DQ2_nu")) { return (new SciBooNE_CCCOH_STOPFINAL_1DQ2_nu(samplekey)); /* K2K Samples */ /* NC1pi0 */ } else #endif #ifndef __NO_K2K__ if (!name.compare("K2K_NC1pi0_Evt_1Dppi0_nu")) { return (new K2K_NC1pi0_Evt_1Dppi0_nu(samplekey)); /* Fake Studies */ } else #endif if (name.find("ExpMultDist_CCQE_XSec_1D") != std::string::npos && name.find("_FakeStudy") != std::string::npos) { return ( new ExpMultDist_CCQE_XSec_1DVar_FakeStudy(name, file, rw, type, fkdt)); } else if (name.find("ExpMultDist_CCQE_XSec_2D") != std::string::npos && name.find("_FakeStudy") != std::string::npos) { return ( new ExpMultDist_CCQE_XSec_2DVar_FakeStudy(name, file, rw, type, fkdt)); } else if (name.find("GenericFlux_") != std::string::npos) { return (new GenericFlux_Tester(name, file, rw, type, fkdt)); } else if (name.find("GenericVectors_") != std::string::npos) { return (new GenericFlux_Vectors(name, file, rw, type, fkdt)); } else if (!name.compare("T2K2017_FakeData")) { return (new T2K2017_FakeData(samplekey)); } else if (!name.compare("MCStudy_CCQE")) { return (new MCStudy_CCQEHistograms(name, file, rw, type, fkdt)); } else if (!name.compare("ElectronFlux_FlatTree")) { return (new ElectronFlux_FlatTree(name, file, rw, type, fkdt)); } else if (name.find("ElectronData_") != std::string::npos) { return new ElectronScattering_DurhamData(samplekey); } else if (name.find("MuonValidation_") != std::string::npos) { return (new MCStudy_MuonValidation(name, file, rw, type, fkdt)); } else if (!name.compare("NIWGOfficialPlots")) { return (new OfficialNIWGPlots(samplekey)); } else if (!name.compare("Simple_Osc")) { return (new Simple_Osc(samplekey)); } else if (!name.compare("Smear_SVDUnfold_Propagation_Osc")) { return (new Smear_SVDUnfold_Propagation_Osc(samplekey)); } else { ERR(FTL) << "Error: No such sample: " << name << std::endl; exit(-1); return NULL; } // Return NULL if no sample loaded. return NULL; } } diff --git a/src/FitBase/CustomVariableBoxes.h b/src/FitBase/CustomVariableBoxes.h index 8bb8b41..66e409b 100644 --- a/src/FitBase/CustomVariableBoxes.h +++ b/src/FitBase/CustomVariableBoxes.h @@ -1,21 +1,28 @@ #ifndef CUSTOM_VARIABLES_BOX_H #define CUSTOM_VARIABLES_BOX_H #include "MeasurementVariableBox.h" #include "MeasurementVariableBox1D.h" #include "MeasurementVariableBox2D.h" /*! * \addtogroup FitBase * @{ */ /// Custom box used to also save Q2 for each event. class Q2VariableBox1D : public MeasurementVariableBox1D { public: inline Q2VariableBox1D() { Reset(); }; inline void Reset() { fQ2 = -999.9; } + inline MeasurementVariableBox* CloneSignalBox(){ + Q2VariableBox1D* box = new Q2VariableBox1D(); + box->fX = this->fX; + box->fSampleWeight = this->fSampleWeight; + box->fQ2 = this->fQ2; + return box; + }; double fQ2; }; #endif diff --git a/src/MCStudies/GenericFlux_Tester.cxx b/src/MCStudies/GenericFlux_Tester.cxx index 5834274..424a3c1 100644 --- a/src/MCStudies/GenericFlux_Tester.cxx +++ b/src/MCStudies/GenericFlux_Tester.cxx @@ -1,564 +1,582 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "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 = 100.; // 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"); // 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. this->fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38 / (fNEvents + 0.)) / 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; sleep(20); } // 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 eventVariables->Branch("MLep", &MLep, "MLep/F"); eventVariables->Branch("ELep", &ELep, "ELep/F"); +// 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 Samples" << 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::FillEventVariables(FitEvent *event) { - //******************************************************************** - // Fill Signal Variables - FillSignalFlags(event); - LOG(DEB) << "Filling signal" << std::endl; - // Function used to extract any variables of interest to the event - Mode = event->Mode; - Nleptons = 0; - Nparticles = 0; +//******************************************************************** +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__; + + // Reset particle counters + Nparticles = Nleptons = Nother = Nprotons = Nneutrons = Npiplus = Npineg = Npi0 = 0; + + // Reset Lepton PDG PDGLep = 0; + // Reset Lepton variables + TLep = CosLep = ELep = PLep = MLep = __BAD_FLOAT__; - Enu_true = Enu_QE = Q2_true = Q2_QE = TLep = TPr = TNe = TPiP = TPiN = TPi0 = - -999.9; + // Rset proton variables + PPr = CosPr = EPr = TPr = MPr = __BAD_FLOAT__; - Nprotons = 0; - PPr = EPr = MPr = CosPr = -999.9; + // Reset neutron variables + PNe = CosNe = ENe = TNe = MNe = __BAD_FLOAT__; - Nneutrons = 0; - PNe = ENe = MNe = CosNe = -999.9; + // Reset pi+ variables + PPiP = CosPiP = EPiP = TPiP = MPiP = __BAD_FLOAT__; - Npiplus = 0; - PPiP = EPiP = MPiP = CosPiP = -999.9; + // Reset pi- variables + PPiN = CosPiN = EPiN = TPiN = MPiN = __BAD_FLOAT__; - Npineg = 0; - PPiN = EPiN = MPiN = CosPiN = -999.9; + // Reset pi0 variables + PPi0 = CosPi0 = EPi0 = TPi0 = MPi0 = __BAD_FLOAT__; - Npi0 = 0; - PPi0 = EPi0 = MPi0 = CosPi0 = -999.9; + // Reset the cos angles + 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; - // All of the angles Clarence added - CosPmuPpip = CosPmuPpim = CosPmuPpi0 = CosPmuPprot = CosPmuPneut = - CosPpipPprot = CosPpipPneut = CosPpipPpim = CosPpipPpi0 = CosPpimPprot = - CosPpimPneut = CosPpimPpi0 = CosPi0Pprot = CosPi0Pneut = - CosPprotPneut = -999.9; + // Reset the private variables (see header) + ResetVariables(); + + // Function used to extract any variables of interest to the event + Mode = event->Mode; - float proton_highmom = -999.9; - float neutron_highmom = -999.9; - float piplus_highmom = -999.9; - float pineg_highmom = -999.9; - float pi0_highmom = -999.9; + // 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(); xsecScaling = fScaleFactor; if (fScaleFactor <= 0.0) { ERR(WRN) << "SCALE FACTOR TOO LOW " << std::endl; sleep(20); } // 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_Tester.h b/src/MCStudies/GenericFlux_Tester.h index 9a2b69d..d050aa5 100644 --- a/src/MCStudies/GenericFlux_Tester.h +++ b/src/MCStudies/GenericFlux_Tester.h @@ -1,188 +1,201 @@ // 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 . *******************************************************************************/ #ifndef GenericFlux_Tester_H_SEEN #define GenericFlux_Tester_H_SEEN #include "Measurement1D.h" +#ifndef __BAD__FLOAT__ +#define __BAD_FLOAT__ -999.99 +#endif + //******************************************************************** class GenericFlux_Tester : public Measurement1D { //******************************************************************** public: GenericFlux_Tester(std::string name, std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile); virtual ~GenericFlux_Tester() {}; + //! Clear private variables + inline void ResetVariables(); + //! Grab info from event void FillEventVariables(FitEvent *event); //! 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(); //! Fill all signal flags we currently have void FillSignalFlags(FitEvent *event); void AddEventVariablesToTree(); void AddSignalFlagsToTree(); private: // Lighter flat trees that don't include vectors bool liteMode; TTree* eventVariables; TLorentzVector *nu_4mom; TLorentzVector *pmu; TLorentzVector *ppip; TLorentzVector *ppim; TLorentzVector *ppi0; TLorentzVector *pprot; TLorentzVector *pneut; // Saved Variables float Enu_true; float Enu_QE; int PDGnu; + // Auxillairies float Q2_true; float Q2_QE; float W_nuc_rest; float bjorken_x; float bjorken_y; + float q0_true; + float q3_true; + float Erecoil_true; + float Erecoil_charged; + float Erecoil_minerva; + // Interaction mode int Mode; + // Particle counters + int Nparticles; + int Nleptons; + int Nother; int Nprotons; int Nneutrons; int Npiplus; int Npineg; int Npi0; + // Lepton variables int PDGLep; float TLep; float CosLep; float ELep; float PLep; float MLep; + // Proton variables float PPr; //!< Highest Mom Proton float CosPr; //!< Highest Mom Proton float EPr; float TPr; float MPr; - + // Neutron variables float PNe; float CosNe; float ENe; float TNe; float MNe; + // Pi+ variables float PPiP; float CosPiP; float EPiP; float TPiP; float MPiP; + // Pi- variables float PPiN; float CosPiN; float EPiN; float TPiN; float MPiN; float PPi0; float CosPi0; float EPi0; float TPi0; float MPi0; + // Angular variables float CosPmuPpip; float CosPmuPpim; float CosPmuPpi0; float CosPmuPprot; float CosPmuPneut; float CosPpipPprot; float CosPpipPneut; float CosPpipPpim; float CosPpipPpi0; float CosPpimPprot; float CosPpimPneut; float CosPpimPpi0; float CosPi0Pprot; float CosPi0Pneut; float CosPprotPneut; - float q0_true; - float q3_true; - - int Nparticles; - int Nleptons; - int Nother; - - float Erecoil_true; - float Erecoil_charged; - float Erecoil_minerva; - + // Weights float Weight; float RWWeight; float InputWeight; float FluxWeight; // 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; float xsecScaling; }; #endif diff --git a/src/MCStudies/Smearceptance_Tester.cxx b/src/MCStudies/Smearceptance_Tester.cxx index 072f2bd..e19e54b 100644 --- a/src/MCStudies/Smearceptance_Tester.cxx +++ b/src/MCStudies/Smearceptance_Tester.cxx @@ -1,884 +1,881 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "Smearceptance_Tester.h" #include "SmearceptanceUtils.h" #include "Smearcepterton.h" //#define DEBUG_SMEARTESTER //******************************************************************** /// @brief Class to perform smearceptance MC Studies on a custom measurement Smearceptance_Tester::Smearceptance_Tester(nuiskey samplekey) { //******************************************************************** samplekey.Print(); // Sample overview --------------------------------------------------- std::string descrip = "Simple measurement class for producing an event summary tree of smeared " "events.\n"; if (Config::HasPar("NPOT")) { samplekey.SetS("NPOT", Config::GetParS("NPOT")); } if (Config::HasPar("FluxIntegralOverride")) { samplekey.SetS("FluxIntegralOverride", Config::GetParS("FluxIntegralOverride")); } if (Config::HasPar("TargetVolume")) { samplekey.SetS("TargetVolume", Config::GetParS("TargetVolume")); } if (Config::HasPar("TargetMaterialDensity")) { samplekey.SetS("TargetMaterialDensity", Config::GetParS("TargetMaterialDensity")); } OutputSummaryTree = true; if (Config::HasPar("smear.OutputSummaryTree")) { OutputSummaryTree = Config::GetParI("smear.OutputSummaryTree"); } // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetTitle("Smearceptance Studies"); fSettings.SetDescription(descrip); fSettings.SetXTitle("XXX"); fSettings.SetYTitle("Number of events"); fSettings.SetEnuRange(0.0, 1E5); fSettings.SetAllowedTypes("EVT/SHAPE/DIAG", "EVT/SHAPE/DIAG"); fSettings.DefineAllowedTargets("*"); fSettings.DefineAllowedSpecies("*"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38 / (fNEvents + 0.)) / TotalIntegratedFlux(); // Measurement Details std::vector splitName = GeneralUtils::ParseToStr(fName, "_"); size_t firstUS = fName.find_first_of("_"); std::string smearceptorName = samplekey.GetS("smearceptor"); QLOG(SAM, "Using smearceptor: " << smearceptorName << " (parsed from: " << fName << ")."); fDataHist = new TH1D(("empty_data"), ("empty-data"), 1, 0, 1); SetupDefaultHist(); fFullCovar = StatUtils::MakeDiagonalCovarMatrix(fDataHist); covar = StatUtils::GetInvert(fFullCovar); eventVariables = NULL; QLOG(SAM, "Smearceptance Flux Scaling Factor = " << fScaleFactor); if (fScaleFactor <= 0.0) { ERROR(WRN, "SCALE FACTOR TOO LOW "); sleep(20); } // Setup our TTrees AddEventVariablesToTree(); smearceptor = &Smearcepterton::Get().GetSmearcepter(smearceptorName); Int_t RecNBins = 20, TrueNBins = 20; double RecBinL = 0xdeadbeef, TrueBinL = 0, RecBinH = 10, TrueBinH = 10; if (Config::HasPar("smear.reconstructed.binning")) { std::vector args = GeneralUtils::ParseToStr( Config::GetParS("smear.reconstructed.binning"), ","); RecNBins = GeneralUtils::StrToInt(args[0]); RecBinL = GeneralUtils::StrToDbl(args[1]); RecBinH = GeneralUtils::StrToDbl(args[2]); TrueNBins = RecNBins; TrueBinL = RecBinL; TrueBinH = RecBinH; } if (Config::HasPar("smear.true.binning")) { std::vector args = GeneralUtils::ParseToStr(Config::GetParS("smear.true.binning"), ","); TrueNBins = GeneralUtils::StrToInt(args[0]); TrueBinL = GeneralUtils::StrToDbl(args[1]); TrueBinH = GeneralUtils::StrToDbl(args[2]); } SVDTruncation = 0; if (Config::HasPar("smear.true.binning")) { SVDTruncation = Config::GetParI("smear.SVD.truncation"); QLOG(SAM, "Applying SVD truncation of: " << SVDTruncation) } ETrueDistrib = NULL; ETrueDistrib_noweight = NULL; ERecDistrib = NULL; RecoSmear = NULL; if (RecBinL != 0xdeadbeef) { QLOG(SAM, "Using binning True: " << TrueNBins << ", [" << TrueBinL << " -- " << TrueBinH << "], Rec: " << RecNBins << ", [" << RecBinL << " -- " << RecBinH << "]"); ETrueDistrib = new TH1D("ELep_rate", ";True E_{#nu};Count", TrueNBins, TrueBinL, TrueBinH); ETrueDistrib_noweight = new TH1D("ELep_rate_noweight", ";True E_{#nu};Count", TrueNBins, TrueBinL, TrueBinH); ERecDistrib = new TH1D("ELepRec_rate", ";Rec E_{#nu};Count", RecNBins, RecBinL, RecBinH); ETrueDistrib->Sumw2(); ERecDistrib->Sumw2(); RecoSmear = new TH2D("ELepHadVis_Recon", ";True E_{#nu};Recon. E_{#nu}", RecNBins, RecBinL, RecBinH, TrueNBins, TrueBinL, TrueBinH); RecoSmear->Sumw2(); } // Final setup --------------------------------------------------- FinaliseMeasurement(); } void Smearceptance_Tester::AddEventVariablesToTree() { if (OutputSummaryTree) { // Setup the TTree to save everything if (!eventVariables) { Config::Get().out->cd(); eventVariables = new TTree((fName + "_VARS").c_str(), (fName + "_VARS").c_str()); } LOG(SAM) << "Adding Event Variables" << std::endl; eventVariables->Branch("Omega_true", &Omega_true, "Omega_true/F"); eventVariables->Branch("Q2_true", &Q2_true, "Q2_true/F"); eventVariables->Branch("Mode_true", &Mode_true, "Mode_true/I"); eventVariables->Branch("EISLep_true", &EISLep_true, "EISLep_true/F"); eventVariables->Branch("HMFS_clep_true", &HMFS_clep_true); eventVariables->Branch("HMFS_pip_true", &HMFS_pip_true); eventVariables->Branch("HMFS_pim_true", &HMFS_pim_true); eventVariables->Branch("HMFS_cpi_true", &HMFS_cpi_true); eventVariables->Branch("HMFS_pi0_true", &HMFS_pi0_true); eventVariables->Branch("HMFS_cK_true", &HMFS_cK_true); eventVariables->Branch("HMFS_K0_true", &HMFS_K0_true); eventVariables->Branch("HMFS_p_true", &HMFS_p_true); eventVariables->Branch("KEFSHad_cpip_true", &KEFSHad_cpip_true, "KEFSHad_cpip_true/F"); eventVariables->Branch("KEFSHad_cpim_true", &KEFSHad_cpim_true, "KEFSHad_cpim_true/F"); eventVariables->Branch("KEFSHad_cpi_true", &KEFSHad_cpi_true, "KEFSHad_cpi_true/F"); eventVariables->Branch("TEFSHad_pi0_true", &TEFSHad_pi0_true, "TEFSHad_pi0_true/F"); eventVariables->Branch("KEFSHad_cK_true", &KEFSHad_cK_true, "KEFSHad_cK_true/F"); eventVariables->Branch("KEFSHad_K0_true", &KEFSHad_K0_true, "KEFSHad_K0_true/F"); eventVariables->Branch("KEFSHad_p_true", &KEFSHad_p_true, "KEFSHad_p_true/F"); eventVariables->Branch("KEFSHad_n_true", &KEFSHad_n_true, "KEFSHad_n_true/F"); eventVariables->Branch("EFSHad_true", &EFSHad_true, "EFSHad_true/F"); eventVariables->Branch("EFSChargedEMHad_true", &EFSChargedEMHad_true, "EFSChargedEMHad_true/F"); eventVariables->Branch("EFSLep_true", &EFSLep_true, "EFSLep_true/F"); eventVariables->Branch("EFSgamma_true", &EFSgamma_true, "EFSgamma_true/F"); eventVariables->Branch("PDGISLep_true", &PDGISLep_true, "PDGISLep_true/I"); eventVariables->Branch("PDGFSLep_true", &PDGFSLep_true, "PDGFSLep_true/I"); eventVariables->Branch("Nprotons_true", &Nprotons_true, "Nprotons_true/I"); eventVariables->Branch("Nneutrons_true", &Nneutrons_true, "Nneutrons_true/I"); eventVariables->Branch("Ncpiplus_true", &Ncpiplus_true, "Ncpiplus_true/I"); eventVariables->Branch("Ncpiminus_true", &Ncpiminus_true, "Ncpiminus_true/I"); eventVariables->Branch("Ncpi_true", &Ncpi_true, "Ncpi_true/I"); eventVariables->Branch("Npi0_true", &Npi0_true, "Npi0_true/I"); eventVariables->Branch("NcK_true", &NcK_true, "NcK_true/I"); eventVariables->Branch("NK0_true", &NK0_true, "NK0_true/I"); eventVariables->Branch("HMFS_clep_rec", &HMFS_clep_rec); eventVariables->Branch("HMFS_pip_rec", &HMFS_pip_rec); eventVariables->Branch("HMFS_pim_rec", &HMFS_pim_rec); eventVariables->Branch("HMFS_cpi_rec", &HMFS_cpi_rec); eventVariables->Branch("HMFS_pi0_rec", &HMFS_pi0_rec); eventVariables->Branch("HMFS_cK_rec", &HMFS_cK_rec); eventVariables->Branch("HMFS_K0_rec", &HMFS_K0_rec); eventVariables->Branch("HMFS_p_rec", &HMFS_p_rec); eventVariables->Branch("KEFSHad_cpip_rec", &KEFSHad_cpip_rec, "KEFSHad_cpip_rec/F"); eventVariables->Branch("KEFSHad_cpim_rec", &KEFSHad_cpim_rec, "KEFSHad_cpim_rec/F"); eventVariables->Branch("KEFSHad_cpi_rec", &KEFSHad_cpi_rec, "KEFSHad_cpi_rec/F"); eventVariables->Branch("TEFSHad_pi0_rec", &TEFSHad_pi0_rec, "TEFSHad_pi0_rec/F"); eventVariables->Branch("KEFSHad_cK_rec", &KEFSHad_cK_rec, "KEFSHad_cK_rec/F"); eventVariables->Branch("KEFSHad_K0_rec", &KEFSHad_K0_rec, "KEFSHad_K0_rec/F"); eventVariables->Branch("KEFSHad_p_rec", &KEFSHad_p_rec, "KEFSHad_p_rec/F"); eventVariables->Branch("KEFSHad_n_rec", &KEFSHad_n_rec, "KEFSHad_n_rec/F"); eventVariables->Branch("EFSHad_rec", &EFSHad_rec, "EFSHad_rec/F"); eventVariables->Branch("EFSLep_rec", &EFSLep_rec, "EFSLep_rec/F"); eventVariables->Branch("EFSVis_cpip", &EFSVis_cpip, "EFSVis_cpip/F"); eventVariables->Branch("EFSVis_cpim", &EFSVis_cpim, "EFSVis_cpim/F"); eventVariables->Branch("EFSVis_cpi", &EFSVis_cpi, "EFSVis_cpi/F"); eventVariables->Branch("EFSVis_pi0", &EFSVis_pi0, "EFSVis_pi0/F"); eventVariables->Branch("EFSVis_cK", &EFSVis_cK, "EFSVis_cK/F"); eventVariables->Branch("EFSVis_K0", &EFSVis_K0, "EFSVis_K0/F"); eventVariables->Branch("EFSVis_p", &EFSVis_p, "EFSVis_p/F"); eventVariables->Branch("EFSVis_n", &EFSVis_n, "EFSVis_n/F"); eventVariables->Branch("EFSVis_gamma", &EFSVis_gamma, "EFSVis_gamma/F"); eventVariables->Branch("EFSVis_other", &EFSVis_other, "EFSVis_other/F"); eventVariables->Branch("EFSVis", &EFSVis, "EFSVis/F"); eventVariables->Branch("FSCLep_seen", &FSCLep_seen, "FSCLep_seen/I"); eventVariables->Branch("Nprotons_seen", &Nprotons_seen, "Nprotons_seen/I"); eventVariables->Branch("Nneutrons_seen", &Nneutrons_seen, "Nneutrons_seen/I"); eventVariables->Branch("Ncpip_seen", &Ncpip_seen, "Ncpip_seen/I"); eventVariables->Branch("Ncpim_seen", &Ncpim_seen, "Ncpim_seen/I"); eventVariables->Branch("Ncpi_seen", &Ncpi_seen, "Ncpi_seen/I"); eventVariables->Branch("Npi0_seen", &Npi0_seen, "Npi0_seen/I"); eventVariables->Branch("NcK_seen", &NcK_seen, "NcK_seen/I"); eventVariables->Branch("NK0_seen", &NK0_seen, "NK0_seen/I"); eventVariables->Branch("Nothers_seen", &Nothers_seen, "Nothers_seen/I"); eventVariables->Branch("EISLep_QE_rec", &EISLep_QE_rec, "EISLep_QE_rec/F"); eventVariables->Branch("EISLep_LepHad_rec", &EISLep_LepHad_rec, "EISLep_LepHad_rec/F"); eventVariables->Branch("EISLep_LepHadVis_rec", &EISLep_LepHadVis_rec, "EISLep_LepHadVis_rec/F"); eventVariables->Branch("Nprotons_contributed", &Nprotons_contributed, "Nprotons_contributed/I"); eventVariables->Branch("Nneutrons_contributed", &Nneutrons_contributed, "Nneutrons_contributed/I"); eventVariables->Branch("Ncpip_contributed", &Ncpip_contributed, "Ncpip_contributed/I"); eventVariables->Branch("Ncpim_contributed", &Ncpim_contributed, "Ncpim_contributed/I"); eventVariables->Branch("Ncpi_contributed", &Ncpi_contributed, "Ncpi_contributed/I"); eventVariables->Branch("Npi0_contributed", &Npi0_contributed, "Npi0_contributed/I"); eventVariables->Branch("NcK_contributed", &NcK_contributed, "NcK_contributed/I"); eventVariables->Branch("NK0_contributed", &NK0_contributed, "NK0_contributed/I"); eventVariables->Branch("Ngamma_contributed", &Ngamma_contributed, "Ngamma_contributed/I"); eventVariables->Branch("Nothers_contibuted", &Nothers_contibuted, "Nothers_contibuted/I"); eventVariables->Branch("Weight", &Weight, "Weight/F"); eventVariables->Branch("RWWeight", &RWWeight, "RWWeight/F"); eventVariables->Branch("InputWeight", &InputWeight, "InputWeight/F"); eventVariables->Branch("FluxWeight", &FluxWeight, "FluxWeight/F"); eventVariables->Branch("EffWeight", &EffWeight, "EffWeight/F"); xsecScaling = fScaleFactor; eventVariables->Branch("xsecScaling", &xsecScaling, "xsecScaling/F"); eventVariables->Branch("flagCCINC_true", &flagCCINC_true, "flagCCINC_true/O"); - eventVariables->Branch("flagCC0K_true", &flagCC0K_true, - "flagCC0K_true/O"); + eventVariables->Branch("flagCC0K_true", &flagCC0K_true, "flagCC0K_true/O"); eventVariables->Branch("flagCC0Pi_true", &flagCC0Pi_true, "flagCC0Pi_true/O"); eventVariables->Branch("flagCC1Pi_true", &flagCC1Pi_true, "flagCC1Pi_true/O"); eventVariables->Branch("flagCCINC_rec", &flagCCINC_rec, "flagCCINC_rec/O"); eventVariables->Branch("flagCC0K_rec", &flagCC0K_rec, "flagCC0K_rec/O"); eventVariables->Branch("flagCC0Pi_rec", &flagCC0Pi_rec, "flagCC0Pi_rec/O"); eventVariables->Branch("flagCC1Pi_rec", &flagCC1Pi_rec, "flagCC1Pi_rec/O"); } PredEvtRateWeight = 1; if (fEvtRateScaleFactor != 0xdeadbeef) { if (OutputSummaryTree) { eventVariables->Branch("PredEvtRateWeight", &PredEvtRateWeight, "PredEvtRateWeight/F"); } PredEvtRateWeight = fScaleFactor * fEvtRateScaleFactor; } } template int CountNPdgsSeen(RecoInfo ri, int const (&pdgs)[N]) { int sum = 0; for (size_t pdg_it = 0; pdg_it < N; ++pdg_it) { sum += std::count(ri.RecObjClass.begin(), ri.RecObjClass.end(), pdgs[pdg_it]); } return sum; } template int CountNNotPdgsSeen(RecoInfo ri, int const (&pdgs)[N]) { int sum = 0; - for (size_t pdg_it = 0; pdg_it < N; ++pdg_it) { - sum += - (std::count(ri.RecObjClass.begin(), ri.RecObjClass.end(), pdgs[pdg_it]) - ? 0 - : 1); + for (size_t p_it = 0; p_it < ri.RecObjClass.size(); ++p_it) { + if (!std::count(pdgs, pdgs + N, ri.RecObjClass[p_it])) { + sum++; + } } return sum; } template int CountNPdgsContributed(RecoInfo ri, int const (&pdgs)[N]) { int sum = 0; for (size_t pdg_it = 0; pdg_it < N; ++pdg_it) { sum += std::count(ri.TrueContribPDGs.begin(), ri.TrueContribPDGs.end(), pdgs[pdg_it]); } return sum; } template int CountNNotPdgsContributed(RecoInfo ri, int const (&pdgs)[N]) { int sum = 0; - for (size_t pdg_it = 0; pdg_it < N; ++pdg_it) { - sum += (std::count(ri.TrueContribPDGs.begin(), ri.TrueContribPDGs.end(), - pdgs[pdg_it]) - ? 0 - : 1); + for (size_t p_it = 0; p_it < ri.TrueContribPDGs.size(); ++p_it) { + if (!std::count(pdgs, pdgs + N, ri.TrueContribPDGs[p_it])) { + sum++; + } } return sum; } TLorentzVector GetHMFSRecParticles(RecoInfo ri, int pdg) { TLorentzVector mom(0, 0, 0, 0); for (size_t p_it = 0; p_it < ri.RecObjMom.size(); ++p_it) { if ((ri.RecObjClass[p_it] == pdg) && (mom.Mag() < ri.RecObjMom[p_it].Mag())) { mom.SetXYZM(ri.RecObjMom[p_it].X(), ri.RecObjMom[p_it].Y(), ri.RecObjMom[p_it].Z(), PhysConst::GetMass(ri.RecObjClass[p_it]) * 1.0E3); } } return mom; } template double SumKE_RecoInfo(RecoInfo ri, int const (&pdgs)[N], double mass) { double sum = 0; for (size_t p_it = 0; p_it < ri.RecObjMom.size(); ++p_it) { if (!std::count(pdgs, pdgs + N, ri.RecObjClass[p_it])) { // If we don't care about this // particle type. continue; } sum += sqrt(ri.RecObjMom[p_it].Mag2() + mass * mass) - mass; } return sum; } template double SumTE_RecoInfo(RecoInfo ri, int const (&pdgs)[N], double mass) { double sum = 0; for (size_t p_it = 0; p_it < ri.RecObjMom.size(); ++p_it) { if (!std::count(pdgs, pdgs + N, ri.RecObjClass[p_it])) { // If we don't care about this // particle type. continue; } sum += sqrt(ri.RecObjMom[p_it].Mag2() + mass * mass); } return sum; } template double SumVisE_RecoInfo(RecoInfo ri, int const (&pdgs)[N]) { double sum = 0; for (size_t p_it = 0; p_it < ri.RecVisibleEnergy.size(); ++p_it) { if (!std::count(pdgs, pdgs + N, ri.TrueContribPDGs[p_it])) { // If we don't care about this // particle type. continue; } sum += ri.RecVisibleEnergy[p_it]; } return sum; } template double SumVisE_RecoInfo_NotPdgs(RecoInfo ri, int const (&pdgs)[N]) { double sum = 0; for (size_t p_it = 0; p_it < ri.RecVisibleEnergy.size(); ++p_it) { if (std::count(pdgs, pdgs + N, ri.TrueContribPDGs[p_it])) { // If we know about this // particle type. continue; } sum += ri.RecVisibleEnergy[p_it]; } return sum; } //******************************************************************** void Smearceptance_Tester::FillEventVariables(FitEvent *event) { //******************************************************************** static int const cpipPDG[] = {211}; static int const cpimPDG[] = {-211}; static int const pi0PDG[] = {111}; static int const cKPDG[] = {321, -321}; static int const K0PDG[] = {311, 310, 130}; static int const ProtonPDG[] = {2212}; static int const NeutronPDG[] = {2112}; static int const GammaPDG[] = {22}; static int const CLeptonPDGs[] = {11, 13, 15, -11, -13, -15}; static int const ExplicitPDGs[] = {211, -211, 111, 321, -321, 311, 310, 130, 2212, 2112, 22, 11, 13, 15, 12, 14, 16, -11, -13, -15, -12, -14, -16}; RecoInfo *ri = smearceptor->Smearcept(event); //** START Pions HMFS_clep_true = TLorentzVector(0, 0, 0, 0); HMFS_clep_rec = TLorentzVector(0, 0, 0, 0); FitParticle *fsCLep = event->GetHMFSParticle(CLeptonPDGs); if (fsCLep) { HMFS_clep_true = fsCLep->P4(); HMFS_clep_rec = GetHMFSRecParticles(*ri, fsCLep->PDG()); } //** END Charged leptons //** START Pions HMFS_pip_true = TLorentzVector(0, 0, 0, 0); HMFS_pip_rec = TLorentzVector(0, 0, 0, 0); FitParticle *fsPip = event->GetHMFSPiPlus(); if (fsPip) { HMFS_pip_true = fsPip->P4(); HMFS_pip_rec = GetHMFSRecParticles(*ri, fsPip->PDG()); } HMFS_pim_true = TLorentzVector(0, 0, 0, 0); HMFS_pim_rec = TLorentzVector(0, 0, 0, 0); FitParticle *fsPim = event->GetHMFSPiMinus(); if (fsPim) { HMFS_pim_true = fsPim->P4(); HMFS_pim_rec = GetHMFSRecParticles(*ri, fsPim->PDG()); } HMFS_cpi_true = TLorentzVector(0, 0, 0, 0); HMFS_cpi_rec = TLorentzVector(0, 0, 0, 0); if (fsPip || fsPim) { if (!fsPip) { HMFS_cpi_true = HMFS_pim_true; HMFS_cpi_rec = HMFS_pim_rec; } else if (!fsPim) { HMFS_cpi_true = HMFS_pip_true; HMFS_cpi_rec = HMFS_pip_rec; } else { HMFS_cpi_true = (fsPip->p2() > fsPim->p2()) ? HMFS_pip_true : HMFS_pim_true; HMFS_cpi_rec = (fsPip->p2() > fsPim->p2()) ? HMFS_pip_rec : HMFS_pim_rec; } } HMFS_pi0_true = TLorentzVector(0, 0, 0, 0); HMFS_pi0_rec = TLorentzVector(0, 0, 0, 0); FitParticle *fsPi0 = event->GetHMFSPiZero(); if (fsPi0) { HMFS_pi0_true = fsPi0->P4(); HMFS_pi0_rec = GetHMFSRecParticles(*ri, fsPi0->PDG()); } //** END Pions //** START Kaons HMFS_cK_true = TLorentzVector(0, 0, 0, 0); HMFS_cK_rec = TLorentzVector(0, 0, 0, 0); FitParticle *fscK = event->GetHMFSParticle(cKPDG); if (fscK) { HMFS_cK_true = fscK->P4(); HMFS_cK_rec = GetHMFSRecParticles(*ri, fscK->PDG()); } HMFS_K0_true = TLorentzVector(0, 0, 0, 0); HMFS_K0_rec = TLorentzVector(0, 0, 0, 0); FitParticle *fsK0 = event->GetHMFSParticle(K0PDG); if (fsK0) { HMFS_K0_true = fsK0->P4(); HMFS_K0_rec = GetHMFSRecParticles(*ri, fsK0->PDG()); } //** END Kaons //** START Nucleons HMFS_p_true = TLorentzVector(0, 0, 0, 0); HMFS_p_rec = TLorentzVector(0, 0, 0, 0); FitParticle *fsP = event->GetHMFSProton(); if (fsP) { HMFS_p_true = fsP->P4(); HMFS_p_rec = GetHMFSRecParticles(*ri, fsP->PDG()); } TLorentzVector FourMomentumTransfer = (event->GetHMISAnyLeptons()->P4() - event->GetHMFSAnyLeptons()->P4()); Omega_true = FourMomentumTransfer.E(); Q2_true = -1 * FourMomentumTransfer.Mag2(); Mode_true = event->Mode; EISLep_true = event->GetHMISAnyLeptons()->E(); KEFSHad_cpip_true = FitUtils::SumTE_PartVect(event->GetAllFSPiPlus()); KEFSHad_cpim_true = FitUtils::SumTE_PartVect(event->GetAllFSPiMinus()); KEFSHad_cpi_true = KEFSHad_cpip_true + KEFSHad_cpim_true; TEFSHad_pi0_true = FitUtils::SumTE_PartVect(event->GetAllFSPiZero()); KEFSHad_cK_true = FitUtils::SumTE_PartVect(event->GetAllFSParticle(cKPDG)); KEFSHad_K0_true = FitUtils::SumTE_PartVect(event->GetAllFSParticle(K0PDG)); KEFSHad_p_true = FitUtils::SumKE_PartVect(event->GetAllFSProton()); KEFSHad_n_true = FitUtils::SumKE_PartVect(event->GetAllFSNeutron()); EFSHad_true = KEFSHad_cpi_true + TEFSHad_pi0_true + KEFSHad_p_true + KEFSHad_n_true; EFSChargedEMHad_true = KEFSHad_cpi_true + TEFSHad_pi0_true + KEFSHad_p_true + KEFSHad_cK_true + KEFSHad_K0_true; EFSLep_true = event->GetHMFSAnyLeptons()->E(); EFSgamma_true = FitUtils::SumTE_PartVect(event->GetAllFSPhoton()); PDGISLep_true = event->GetHMISAnyLeptons()->PDG(); PDGFSLep_true = event->GetHMFSAnyLeptons()->PDG(); Nprotons_true = event->GetAllFSProton().size(); Nneutrons_true = event->GetAllFSNeutron().size(); Ncpiplus_true = event->GetAllFSPiPlus().size(); Ncpiminus_true = event->GetAllFSPiMinus().size(); Ncpi_true = Ncpiplus_true + Ncpiminus_true; Npi0_true = event->GetAllFSPiZero().size(); NcK_true = event->GetAllFSParticle(cKPDG).size(); NK0_true = event->GetAllFSParticle(K0PDG).size(); KEFSHad_cpip_rec = SumKE_RecoInfo(*ri, cpipPDG, PhysConst::mass_cpi * PhysConst::mass_MeV); KEFSHad_cpim_rec = SumKE_RecoInfo(*ri, cpimPDG, PhysConst::mass_cpi * PhysConst::mass_MeV); KEFSHad_cpi_rec = KEFSHad_cpip_rec + KEFSHad_cpim_rec; TEFSHad_pi0_rec = SumTE_RecoInfo(*ri, pi0PDG, PhysConst::mass_pi0 * PhysConst::mass_MeV); KEFSHad_cK_rec = SumKE_RecoInfo(*ri, cKPDG, PhysConst::mass_cK * PhysConst::mass_MeV); KEFSHad_K0_rec = SumKE_RecoInfo(*ri, K0PDG, PhysConst::mass_K0 * PhysConst::mass_MeV); KEFSHad_p_rec = SumKE_RecoInfo(*ri, ProtonPDG, PhysConst::mass_proton * PhysConst::mass_MeV); KEFSHad_n_rec = SumKE_RecoInfo(*ri, NeutronPDG, PhysConst::mass_neutron * PhysConst::mass_MeV); EFSHad_rec = KEFSHad_cpi_rec + TEFSHad_pi0_rec + KEFSHad_p_rec + KEFSHad_n_rec; TLorentzVector FSLepMom_rec(0, 0, 0, 0); if (event->GetHMFSAnyLeptons()) { FSLepMom_rec = GetHMFSRecParticles(*ri, event->GetHMFSAnyLeptons()->PDG()); EFSLep_rec = FSLepMom_rec.E(); } else { EFSLep_rec = 0; } EFSVis_cpip = SumVisE_RecoInfo(*ri, cpipPDG); EFSVis_cpim = SumVisE_RecoInfo(*ri, cpimPDG); EFSVis_cpi = EFSVis_cpip + EFSVis_cpim; EFSVis_pi0 = SumVisE_RecoInfo(*ri, pi0PDG); EFSVis_cK = SumVisE_RecoInfo(*ri, cKPDG); EFSVis_K0 = SumVisE_RecoInfo(*ri, K0PDG); EFSVis_p = SumVisE_RecoInfo(*ri, ProtonPDG); EFSVis_n = SumVisE_RecoInfo(*ri, NeutronPDG); EFSVis_gamma = SumVisE_RecoInfo(*ri, GammaPDG); EFSVis_other = SumVisE_RecoInfo_NotPdgs(*ri, ExplicitPDGs); EFSVis = EFSVis_cpi + EFSVis_pi0 + EFSVis_p + EFSVis_n + EFSVis_gamma + EFSVis_cK + EFSVis_K0; FSCLep_seen = CountNPdgsSeen(*ri, CLeptonPDGs); Nprotons_seen = CountNPdgsSeen(*ri, ProtonPDG); Nneutrons_seen = CountNPdgsSeen(*ri, NeutronPDG); Ncpip_seen = CountNPdgsSeen(*ri, cpipPDG); Ncpim_seen = CountNPdgsSeen(*ri, cpimPDG); Ncpi_seen = Ncpip_seen + Ncpim_seen; Npi0_seen = CountNPdgsSeen(*ri, pi0PDG); NcK_seen = CountNPdgsSeen(*ri, cKPDG); NK0_seen = CountNPdgsSeen(*ri, K0PDG); Nothers_seen = CountNNotPdgsSeen(*ri, ExplicitPDGs); if (FSCLep_seen && (FSLepMom_rec.Mag() > 1E-8)) { EISLep_QE_rec = FitUtils::EnuQErec(FSLepMom_rec.Mag() / 1000.0, FSLepMom_rec.CosTheta(), 34, PDGFSLep_true > 0) * 1000.0; } else { EISLep_QE_rec = 0; } EISLep_LepHad_rec = EFSLep_rec + EFSHad_rec; EISLep_LepHadVis_rec = EFSLep_rec + EFSHad_rec + EFSVis; Nprotons_contributed = CountNPdgsContributed(*ri, ProtonPDG); Nneutrons_contributed = CountNPdgsContributed(*ri, NeutronPDG); Ncpip_contributed = CountNPdgsContributed(*ri, cpipPDG); Ncpim_contributed = CountNPdgsContributed(*ri, cpimPDG); Ncpi_contributed = Ncpip_contributed + Ncpim_contributed; Npi0_contributed = CountNPdgsContributed(*ri, pi0PDG); NcK_contributed = CountNPdgsContributed(*ri, cKPDG); NK0_contributed = CountNPdgsContributed(*ri, K0PDG); Ngamma_contributed = CountNPdgsContributed(*ri, GammaPDG); Nothers_contibuted = CountNNotPdgsContributed(*ri, ExplicitPDGs); Weight = event->RWWeight * event->InputWeight; RWWeight = event->RWWeight; InputWeight = event->InputWeight; FluxWeight = GetFluxHistogram()->GetBinContent( GetFluxHistogram()->FindBin(EISLep_true)) / GetFluxHistogram()->Integral(); EffWeight = ri->Weight; flagCCINC_true = PDGFSLep_true & 1; flagCC0K_true = (NcK_true + NK0_true) == 0; flagCC0Pi_true = flagCCINC_true && flagCC0K_true && ((Ncpi_true + Npi0_true) == 0); flagCC1Pi_true = flagCCINC_true && flagCC0K_true && ((Ncpi_true + Npi0_true) == 1); flagCCINC_rec = FSCLep_seen && flagCCINC_true; flagCC0K_rec = (NcK_seen + NK0_seen) == 0; flagCC0Pi_rec = flagCCINC_rec && flagCC0K_rec && ((Ncpi_seen + Npi0_seen) == 0); flagCC1Pi_rec = flagCCINC_rec && flagCC0K_rec && ((Ncpi_seen + Npi0_seen) == 1); if (OutputSummaryTree) { // Fill the eventVariables Tree eventVariables->Fill(); } if (RecoSmear) { RecoSmear->Fill(EISLep_true / 1000.0, flagCCINC_rec ? EISLep_LepHadVis_rec / 1000.0 : -1, Weight); ETrueDistrib_noweight->Fill(EISLep_true / 1000.0, flagCCINC_true ? Weight : 0); ETrueDistrib->Fill(EISLep_true / 1000.0, flagCCINC_true ? Weight * PredEvtRateWeight : 0); ERecDistrib->Fill(EISLep_LepHadVis_rec / 1000.0, flagCCINC_rec ? Weight * PredEvtRateWeight : 0); } }; //******************************************************************** void Smearceptance_Tester::Write(std::string drawOpt) { //******************************************************************** if (OutputSummaryTree) { // First save the TTree eventVariables->Write(); } // Save Flux and Event Histograms too GetInput()->GetFluxHistogram()->Write(); GetInput()->GetEventHistogram()->Write(); if (!RecoSmear) { return; } TH2D *SmearMatrix_ev = static_cast(RecoSmear->Clone("ELepHadVis_Smear_ev")); for (Int_t trueAxis_it = 1; trueAxis_it < RecoSmear->GetXaxis()->GetNbins() + 1; ++trueAxis_it) { double NEISLep = ETrueDistrib_noweight->GetBinContent(trueAxis_it); for (Int_t recoAxis_it = 1; recoAxis_it < RecoSmear->GetYaxis()->GetNbins() + 1; ++recoAxis_it) { if (NEISLep > std::numeric_limits::epsilon()) { SmearMatrix_ev->SetBinContent( trueAxis_it, recoAxis_it, SmearMatrix_ev->GetBinContent(trueAxis_it, recoAxis_it) / NEISLep); } } } ETrueDistrib_noweight->Write(); ETrueDistrib->Write(); ERecDistrib->Write(); RecoSmear->Write(); SmearMatrix_ev->Write(); TH2D *ResponseMatrix_ev = SmearceptanceUtils::SVDGetInverse(SmearMatrix_ev, SVDTruncation); ResponseMatrix_ev->SetName("ResponseMatrix_ev"); ResponseMatrix_ev->Write(); #ifdef DEBUG_SMEARTESTER TMatrixD SmearMatrix_ev_md = SmearceptanceUtils::GetMatrix(SmearMatrix_ev); TH1D *SmearedEvt = static_cast(ERecDistrib->Clone()); SmearedEvt->SetNameTitle("SmearedEvt", ";Rec E_{#nu}; count"); SmearceptanceUtils::PushTH1ThroughMatrixWithErrors( ETrueDistrib, SmearedEvt, SmearMatrix_ev_md, 5000, false); SmearedEvt->Write(); SmearedEvt->Scale(1, "width"); SmearedEvt->SetName("SmearedEvt_bw"); SmearedEvt->Write(); #endif #ifdef __PROB3PP_ENABLED__ FitWeight *fw = FitBase::GetRW(); if (fw->HasRWEngine(kOSCILLATION)) { OscWeightEngine *oscWE = dynamic_cast(fw->GetRWEngine(kOSCILLATION)); TGraph POsc; POsc.Set(1E4 - 1); double min = ETrueDistrib->GetXaxis()->GetBinLowEdge(1); double step = (ETrueDistrib->GetXaxis()->GetBinUpEdge( ETrueDistrib->GetXaxis()->GetNbins()) - ETrueDistrib->GetXaxis()->GetBinLowEdge(1)) / double(1E4); for (size_t i = 1; i < 1E4; ++i) { double enu = min + i * step; double ow = oscWE->CalcWeight(enu, 14); if (ow != ow) { std::cout << "Bad osc weight for ENu: " << enu << std::endl; } POsc.SetPoint(i - 1, enu, ow); } POsc.Write("POsc", TObject::kOverwrite); } #endif TMatrixD ResponseMatrix_evt_md = SmearceptanceUtils::GetMatrix(ResponseMatrix_ev); TH1D *Unfolded_enu_obs = static_cast(ETrueDistrib->Clone()); Unfolded_enu_obs->SetNameTitle("UnfoldedENu_evt", ";True E_{#nu};count"); SmearceptanceUtils::PushTH1ThroughMatrixWithErrors( ERecDistrib, Unfolded_enu_obs, ResponseMatrix_evt_md, 5000, false); Unfolded_enu_obs->Write(); Unfolded_enu_obs->Scale(1, "width"); Unfolded_enu_obs->SetName("UnfoldedENu_evt_bw"); Unfolded_enu_obs->Write(); ETrueDistrib->Scale(1, "width"); ETrueDistrib->SetName("ELep_rate_bw"); ETrueDistrib->Write(); ERecDistrib->Scale(1, "width"); ERecDistrib->SetName("ELepRec_rate_bw"); ERecDistrib->Write(); } // ------------------------------------------------------------------- // Purely MC Plot // Following functions are just overrides to handle this // ------------------------------------------------------------------- //******************************************************************** /// Everything is classed as signal... bool Smearceptance_Tester::isSignal(FitEvent *event) { //******************************************************************** (void)event; return true; }; //******************************************************************** void Smearceptance_Tester::ScaleEvents() { //******************************************************************** // Saving everything to a TTree so no scaling required return; } //******************************************************************** void Smearceptance_Tester::ApplyNormScale(float norm) { //******************************************************************** // Saving everything to a TTree so no scaling required fCurrentNorm = norm; return; } //******************************************************************** void Smearceptance_Tester::FillHistograms() { //******************************************************************** // No Histograms need filling........ return; } //******************************************************************** void Smearceptance_Tester::ResetAll() { //******************************************************************** if (OutputSummaryTree) { eventVariables->Reset(); } return; } //******************************************************************** float Smearceptance_Tester::GetChi2() { //******************************************************************** // No Likelihood to test, purely MC return 0.0; } diff --git a/src/MINERvA/MINERvA_CC1pi0_XSec_1D_nu.cxx b/src/MINERvA/MINERvA_CC1pi0_XSec_1D_nu.cxx index 594a2c9..39fa194 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 . *******************************************************************************/ #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#thtea_{Adler} (cm^{2}/nucleon/0.1)"; + 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/MINERvA/MINERvA_CCinc_XSec_2DEavq3_nu.cxx b/src/MINERvA/MINERvA_CCinc_XSec_2DEavq3_nu.cxx index fde3809..fc41380 100755 --- a/src/MINERvA/MINERvA_CCinc_XSec_2DEavq3_nu.cxx +++ b/src/MINERvA/MINERvA_CCinc_XSec_2DEavq3_nu.cxx @@ -1,153 +1,153 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MINERvA_SignalDef.h" #include "MINERvA_CCinc_XSec_2DEavq3_nu.h" //******************************************************************** MINERvA_CCinc_XSec_2DEavq3_nu::MINERvA_CCinc_XSec_2DEavq3_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MINERvA_CCinc_XSec_2DEavq3_nu sample. \n" \ "Target: CH \n" \ "Flux: MINERvA Medium Energy FHC numu \n" \ "Signal: CC-inclusive with theta < 20deg \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("q_{3} (GeV)"); fSettings.SetYTitle("E_{avail} (GeV)"); fSettings.SetZTitle("d^{2}#sigma/dq_{3}dE_{avail} (cm^{2}/GeV^{2})"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/MASK", "FIX/FULL"); fSettings.SetEnuRange(2.0, 6.0); fSettings.DefineAllowedTargets("C,H"); // CCQELike plot information fSettings.SetTitle("MINERvA_CCinc_XSec_2DEavq3_nu"); fSettings.SetDataInput( FitPar::GetDataBase() + "/MINERvA/CCEavq3/data_2D.txt" ); fSettings.SetCovarInput( FitPar::GetDataBase() + "/MINERvA/CCEavq3/covar_2D.txt" ); fSettings.SetMapInput( FitPar::GetDataBase() + "/MINERvA/CCEavq3/map_2D.txt" ); fSettings.DefineAllowedSpecies("numu"); - hadroncut = FitPar::Config().GetParB("MINERvA_CCinc_XSec_2DEavq3_nu.hadron_cut"); - useq3true = FitPar::Config().GetParB("MINERvA_CCinc_XSec_2DEavq3_nu.useq3true"); - splitMEC_PN_NN = FitPar::Config().GetParB("Modes.split_PN_NN"); + hadroncut = FitPar::Config().GetParB("MINERvA_CCinc_XSec_2DEavq3_nu_hadron_cut"); + useq3true = FitPar::Config().GetParB("MINERvA_CCinc_XSec_2DEavq3_nu_useq3true"); + splitMEC_PN_NN = FitPar::Config().GetParB("Modes_split_PN_NN"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-42 / (fNEvents + 0.)) / this->TotalIntegratedFlux(); // Plot Setup ------------------------------------------------------- Double_t binx[7] = {0.0, 0.2, 0.3, 0.4, 0.5, 0.6, 0.8}; Double_t biny[17] = {0.0, 0.02, 0.04, 0.06, 0.08, 0.10, 0.12, 0.14, 0.16, 0.20, 0.25, 0.30, 0.35, 0.40, 0.50, 0.60, 0.80}; CreateDataHistogram(7, binx, 17, biny); SetDataValuesFromTextFile( fSettings.GetDataInput() ); ScaleData(1E-42); SetMapValuesFromText( fSettings.GetMapInput() ); SetCholDecompFromTextFile( fSettings.GetCovarInput(), 67); ScaleCovar(1E-16); StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, fMapHist, 1E-38); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; //******************************************************************** void MINERvA_CCinc_XSec_2DEavq3_nu::FillEventVariables(FitEvent *event) { //******************************************************************** // Seperate MEC if (splitMEC_PN_NN) { int npr = 0; int nne = 0; for (UInt_t j = 0; j < event->Npart(); j++) { if ((event->PartInfo(j))->fIsAlive) continue; if (event->PartInfo(j)->fPID == 2212) npr++; else if (event->PartInfo(j)->fPID == 2112) nne++; } if (event->Mode == 2 and npr == 1 and nne == 1) { event->Mode = 2; Mode = 2; } else if (event->Mode == 2 and npr == 0 and nne == 2) { event->Mode = 3; Mode = 3; } } // Set Defaults double Eav = -999.9; double q3 = -999.9; // If muon found get kinematics FitParticle* muon = event->GetHMFSParticle(13); FitParticle* neutrino = event->GetNeutrinoIn(); if (muon && neutrino) { // Set Q from Muon TLorentzVector q = neutrino->fP - muon->fP; double q0 = (q.E()) / 1.E3; //double q3_true = (q.Vect().Mag())/1.E3; double thmu = muon->fP.Vect().Angle(neutrino->fP.Vect()); double pmu = muon->fP.Vect().Mag() / 1.E3; double emu = muon->fP.E() / 1.E3; double mmu = muon->fP.Mag() / 1.E3; // Get Enu Rec double enu_rec = emu + q0; // Set Q2 QE double q2qe = 2 * enu_rec * (emu - pmu * cos(thmu)) - mmu * mmu; // Calc Q3 from Q2QE and EnuTree q3 = sqrt(q2qe + q0 * q0); // Get Eav too Eav = FitUtils::GetErecoil_MINERvA_LowRecoil(event) / 1.E3; } // Set Hist Variables fXVar = q3; fYVar = Eav; return; } //******************************************************************** bool MINERvA_CCinc_XSec_2DEavq3_nu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCCincLowRecoil_MINERvA(event, EnuMin, EnuMax); } diff --git a/src/Reweight/GENIEWeightEngine.cxx b/src/Reweight/GENIEWeightEngine.cxx index 8e0aab6..4586ae4 100644 --- a/src/Reweight/GENIEWeightEngine.cxx +++ b/src/Reweight/GENIEWeightEngine.cxx @@ -1,244 +1,244 @@ #include "GENIEWeightEngine.h" GENIEWeightEngine::GENIEWeightEngine(std::string name) { #ifdef __GENIE_ENABLED__ // Setup the NEUT Reweight engien fCalcName = name; LOG(FIT) << "Setting up GENIE RW : " << fCalcName << std::endl; // Create RW Engine suppressing cout StopTalking(); fGenieRW = new genie::rew::GReWeight(); // Get List of Vetos (Just for debugging) - std::string rw_engine_list = FitPar::Config().GetParS("FitWeight.fGenieRW_veto"); + std::string rw_engine_list = FitPar::Config().GetParS("FitWeight_fGenieRW_veto"); bool xsec_ncel = rw_engine_list.find("xsec_ncel") == std::string::npos; bool xsec_ccqe = rw_engine_list.find("xsec_ccqe") == std::string::npos; bool xsec_coh = rw_engine_list.find("xsec_coh") == std::string::npos; bool xsec_nnres = rw_engine_list.find("xsec_nonresbkg") == std::string::npos; bool xsec_nudis = rw_engine_list.find("nuclear_dis") == std::string::npos; bool xsec_resdec = rw_engine_list.find("hadro_res_decay") == std::string::npos; bool xsec_fzone = rw_engine_list.find("hadro_intranuke") == std::string::npos; bool xsec_intra = rw_engine_list.find("hadro_fzone") == std::string::npos; bool xsec_agky = rw_engine_list.find("hadro_agky") == std::string::npos; bool xsec_qevec = rw_engine_list.find("xsec_ccqe_vec") == std::string::npos; bool xsec_dis = rw_engine_list.find("xsec_dis") == std::string::npos; bool xsec_nc = rw_engine_list.find("xsec_nc") == std::string::npos; bool xsec_ccres = rw_engine_list.find("xsec_ccres") == std::string::npos; bool xsec_ncres = rw_engine_list.find("xsec_ncres") == std::string::npos; bool xsec_nucqe = rw_engine_list.find("nuclear_qe") == std::string::npos; bool xsec_qeaxial = rw_engine_list.find("xsec_ccqe_axial") == std::string::npos; // Now actually add the RW Calcs if (xsec_ncel) fGenieRW->AdoptWghtCalc("xsec_ncel", new genie::rew::GReWeightNuXSecNCEL); if (xsec_ccqe){ fGenieRW->AdoptWghtCalc("xsec_ccqe", new genie::rew::GReWeightNuXSecCCQE); // (dynamic_cast (fGenieRW->WghtCalc("xsec_ccqe"))) // ->SetXSecModel( FitPar::Config().GetParS("GENIEXSecModelCCQE") ); } if (xsec_coh){ fGenieRW->AdoptWghtCalc("xsec_coh", new genie::rew::GReWeightNuXSecCOH()); // (dynamic_cast (fGenieRW->WghtCalc("xsec_coh"))) // ->SetXSecModel( FitPar::Config().GetParS("GENIEXSecModelCOH") ); } if (xsec_nnres) fGenieRW->AdoptWghtCalc("xsec_nonresbkg", new genie::rew::GReWeightNonResonanceBkg); if (xsec_nudis) fGenieRW->AdoptWghtCalc("nuclear_dis", new genie::rew::GReWeightDISNuclMod); if (xsec_resdec) fGenieRW->AdoptWghtCalc("hadro_res_decay", new genie::rew::GReWeightResonanceDecay); if (xsec_fzone) fGenieRW->AdoptWghtCalc("hadro_fzone", new genie::rew::GReWeightFZone); if (xsec_intra) fGenieRW->AdoptWghtCalc("hadro_intranuke", new genie::rew::GReWeightINuke); if (xsec_agky) fGenieRW->AdoptWghtCalc("hadro_agky", new genie::rew::GReWeightAGKY); if (xsec_qevec) fGenieRW->AdoptWghtCalc("xsec_ccqe_vec", new genie::rew::GReWeightNuXSecCCQEvec); #if __GENIE_VERSION__ >= 212 if (xsec_qeaxial) fGenieRW->AdoptWghtCalc("xsec_ccqe_axial", new genie::rew::GReWeightNuXSecCCQEaxial); #endif if (xsec_dis) fGenieRW->AdoptWghtCalc("xsec_dis", new genie::rew::GReWeightNuXSecDIS); if (xsec_nc) fGenieRW->AdoptWghtCalc("xsec_nc", new genie::rew::GReWeightNuXSecNC); if (xsec_ccres){ #if __GENIE_VERSION__ < 213 fGenieRW->AdoptWghtCalc("xsec_ccres", new genie::rew::GReWeightNuXSecCCRES); #else fGenieRW->AdoptWghtCalc("xsec_ccres", new genie::rew::GReWeightNuXSecCCRES( FitPar::Config().GetParS("GENIEXSecModelCCRES"), "Default")); #endif } if (xsec_ncres) fGenieRW->AdoptWghtCalc("xsec_ncres", new genie::rew::GReWeightNuXSecNCRES); if (xsec_nucqe) fGenieRW->AdoptWghtCalc("nuclear_qe", new genie::rew::GReWeightFGM); GReWeightNuXSecCCQE * rwccqe = dynamic_cast (fGenieRW->WghtCalc("xsec_ccqe")); rwccqe->SetMode(GReWeightNuXSecCCQE::kModeMa); // Default to include shape and normalization changes for CCRES (can be changed downstream if desired) GReWeightNuXSecCCRES * rwccres = dynamic_cast (fGenieRW->WghtCalc("xsec_ccres")); std::string marestype = FitPar::Config().GetParS("GENIEWeightEngine_CCRESMode"); if (!marestype.compare("kModeNormAndMaMvShape")){ rwccres->SetMode(GReWeightNuXSecCCRES::kModeNormAndMaMvShape); } else if (!marestype.compare("kModeMaMv")){ rwccres->SetMode(GReWeightNuXSecCCRES::kModeMaMv); } else { THROW("Unkown MARES Mode in GENIE Weight Engine : " << marestype ); } // Default to include shape and normalization changes for NCRES (can be changed downstream if desired) GReWeightNuXSecNCRES * rwncres = dynamic_cast (fGenieRW->WghtCalc("xsec_ncres")); rwncres->SetMode(GReWeightNuXSecNCRES::kModeMaMv); // Default to include shape and normalization changes for DIS (can be changed downstream if desired) GReWeightNuXSecDIS * rwdis = dynamic_cast (fGenieRW->WghtCalc("xsec_dis")); rwdis->SetMode(GReWeightNuXSecDIS::kModeABCV12u); // Set Abs Twk Config fIsAbsTwk = (FitPar::Config().GetParB("setabstwk")); // allow cout again StartTalking(); #else ERR(FTL) << "GENIE RW NOT ENABLED" << std::endl; #endif }; void GENIEWeightEngine::IncludeDial(std::string name, double startval) { #ifdef __GENIE_ENABLED__ // Get First enum int nuisenum = Reweight::ConvDial(name, kGENIE); // Setup Maps fEnumIndex[nuisenum];// = std::vector(0); fNameIndex[name]; // = std::vector(0); // Split by commas std::vector allnames = GeneralUtils::ParseToStr(name, ","); for (uint i = 0; i < allnames.size(); i++) { std::string singlename = allnames[i]; // Get RW genie::rew::GSyst_t rwsyst = GSyst::FromString(singlename); // Fill Maps int index = fValues.size(); fValues.push_back(0.0); fGENIESysts.push_back(rwsyst); // Initialize dial std::cout << "Registering " << singlename << " from " << name << std::endl; fGenieRW->Systematics().Init( fGENIESysts[index] ); // If Absolute if (fIsAbsTwk) { GSystUncertainty::Instance()->SetUncertainty( rwsyst, 1.0, 1.0 ); } // Setup index fEnumIndex[nuisenum].push_back(index); fNameIndex[name].push_back(index); } // Set Value if given if (startval != -999.9) { SetDialValue(nuisenum, startval); } #endif }; void GENIEWeightEngine::SetDialValue(int nuisenum, double val) { #ifdef __GENIE_ENABLED__ std::vector indices = fEnumIndex[nuisenum]; for (uint i = 0; i < indices.size(); i++) { fValues[indices[i]] = val; fGenieRW->Systematics().Set( fGENIESysts[indices[i]], val); } #endif } void GENIEWeightEngine::SetDialValue(std::string name, double val) { #ifdef __GENIE_ENABLED__ std::vector indices = fNameIndex[name]; for (uint i = 0; i < indices.size(); i++) { fValues[indices[i]] = val; fGenieRW->Systematics().Set(fGENIESysts[indices[i]], val); } #endif } void GENIEWeightEngine::Reconfigure(bool silent) { #ifdef __GENIE_ENABLED__ // Hush now... if (silent) StopTalking(); // Reconf fGenieRW->Reconfigure(); fGenieRW->Print(); // Shout again if (silent) StartTalking(); #endif } double GENIEWeightEngine::CalcWeight(BaseFitEvt* evt) { double rw_weight = 1.0; #ifdef __GENIE_ENABLED__ // Skip Non GENIE if (evt->fType != kGENIE) return 1.0; // Make nom weight if (!evt) { THROW("evt not found : " << evt); } if (!(evt->genie_event)) { THROW("evt->genie_event not found!" << evt->genie_event); } if (!(evt->genie_event->event)) { THROW("evt->genie_event->event GHepRecord not found!" << (evt->genie_event->event)); } if (!fGenieRW) { THROW("GENIE RW Not Found!" << fGenieRW); } rw_weight = fGenieRW->CalcWeight(*(evt->genie_event->event)); // std::cout << "Returning GENIE Weight for electron scattering = " << rw_weight << std::endl; #endif // Return rw_weight return rw_weight; } diff --git a/src/Reweight/NEUTWeightEngine.cxx b/src/Reweight/NEUTWeightEngine.cxx index 3bd0c2e..f9aaa78 100644 --- a/src/Reweight/NEUTWeightEngine.cxx +++ b/src/Reweight/NEUTWeightEngine.cxx @@ -1,186 +1,186 @@ #include "NEUTWeightEngine.h" NEUTWeightEngine::NEUTWeightEngine(std::string name) { #ifdef __NEUT_ENABLED__ // Setup the NEUT Reweight engien fCalcName = name; LOG(FIT) << "Setting up NEUT RW : " << fCalcName << std::endl; // Create RW Engine suppressing cout StopTalking(); fNeutRW = new neut::rew::NReWeight(); TDirectory* olddir = gDirectory; // get list of vetoed calc engines (just for debug really) - std::string rw_engine_list = FitPar::Config().GetParS("FitWeight.fNeutRW_veto"); + std::string rw_engine_list = FitPar::Config().GetParS("FitWeight_fNeutRW_veto"); bool xsec_ccqe = rw_engine_list.find("xsec_ccqe") == std::string::npos; bool xsec_res = rw_engine_list.find("xsec_res") == std::string::npos; bool xsec_ccres = rw_engine_list.find("xsec_ccres") == std::string::npos; bool xsec_coh = rw_engine_list.find("xsec_coh") == std::string::npos; bool xsec_dis = rw_engine_list.find("xsec_dis") == std::string::npos; bool xsec_ncel = rw_engine_list.find("xsec_ncel") == std::string::npos; bool xsec_nc = rw_engine_list.find("xsec_nc") == std::string::npos; bool xsec_ncres = rw_engine_list.find("xsec_ncres") == std::string::npos; bool nucl_casc = rw_engine_list.find("nucl_casc") == std::string::npos; bool nucl_piless = rw_engine_list.find("nucl_piless") == std::string::npos; // Activate each calc engine if (xsec_ccqe) fNeutRW->AdoptWghtCalc("xsec_ccqe", new neut::rew::NReWeightNuXSecCCQE); if (xsec_res) fNeutRW->AdoptWghtCalc("xsec_res", new neut::rew::NReWeightNuXSecRES); if (xsec_ccres) fNeutRW->AdoptWghtCalc("xsec_ccres", new neut::rew::NReWeightNuXSecCCRES); if (xsec_coh) fNeutRW->AdoptWghtCalc("xsec_coh", new neut::rew::NReWeightNuXSecCOH); if (xsec_dis) fNeutRW->AdoptWghtCalc("xsec_dis", new neut::rew::NReWeightNuXSecDIS); if (xsec_ncel) fNeutRW->AdoptWghtCalc("xsec_ncel", new neut::rew::NReWeightNuXSecNCEL); if (xsec_nc) fNeutRW->AdoptWghtCalc("xsec_nc", new neut::rew::NReWeightNuXSecNC); if (xsec_ncres) fNeutRW->AdoptWghtCalc("xsec_ncres", new neut::rew::NReWeightNuXSecNCRES); if (nucl_casc) fNeutRW->AdoptWghtCalc("nucl_casc", new neut::rew::NReWeightCasc); if (nucl_piless) fNeutRW->AdoptWghtCalc("nucl_piless", new neut::rew::NReWeightNuclPiless); fNeutRW->Reconfigure(); olddir->cd(); // Set Abs Twk Config fIsAbsTwk = (FitPar::Config().GetParB("setabstwk")); // allow cout again StartTalking(); #else THROW("NEUT RW NOT ENABLED!" ); #endif }; void NEUTWeightEngine::IncludeDial(std::string name, double startval) { #ifdef __NEUT_ENABLED__ // Get First enum int nuisenum = Reweight::ConvDial(name, kNEUT); // Setup Maps fEnumIndex[nuisenum];// = std::vector(0); fNameIndex[name]; // = std::vector(0); // Split by commas std::vector allnames = GeneralUtils::ParseToStr(name, ","); for (uint i = 0; i < allnames.size(); i++) { std::string singlename = allnames[i]; // Get Syst neut::rew::NSyst_t gensyst = NSyst::FromString(singlename); // Fill Maps int index = fValues.size(); fValues.push_back(0.0); fNEUTSysts.push_back(gensyst); // Initialize dial LOG(FIT) << "Registering " << singlename << " dial." << std::endl; fNeutRW->Systematics().Init( fNEUTSysts[index] ); // If Absolute if (fIsAbsTwk) { NSystUncertainty::Instance()->SetUncertainty( fNEUTSysts[index], 1.0, 1.0 ); } // Setup index fEnumIndex[nuisenum].push_back(index); fNameIndex[name].push_back(index); } // Set Value if given if (startval != -999.9) { SetDialValue(nuisenum, startval); } #endif } void NEUTWeightEngine::SetDialValue(int nuisenum, double val) { #ifdef __NEUT_ENABLED__ std::vector indices = fEnumIndex[nuisenum]; for (uint i = 0; i < indices.size(); i++) { fValues[indices[i]] = val; std::cout << "Setting Dial Value = " << nuisenum << " " << i << " " << indices[i] << " " << fValues[indices[i]] << " Enum=" << fNEUTSysts[indices[i]] << std::endl; fNeutRW->Systematics().Set(fNEUTSysts[indices[i]], val); } #endif } void NEUTWeightEngine::SetDialValue(std::string name, double val) { #ifdef __NEUT_ENABLED__ std::vector indices = fNameIndex[name]; for (uint i = 0; i < indices.size(); i++) { fValues[indices[i]] = val; std::cout << "Setting Dial Value = " << name << " = " << i << " " << indices[i] << " " << fValues[indices[i]] << " Enum=" << fNEUTSysts[indices[i]] << std::endl; fNeutRW->Systematics().Set(fNEUTSysts[indices[i]], val); } #endif } void NEUTWeightEngine::Reconfigure(bool silent) { #ifdef __NEUT_ENABLED__ // Hush now... if (silent) StopTalking(); // Reconf fNeutRW->Reconfigure(); //if (LOG_LEVEL(DEB)){ fNeutRW->Print(); // } // Shout again if (silent) StartTalking(); #endif } double NEUTWeightEngine::CalcWeight(BaseFitEvt* evt) { double rw_weight = 1.0; #ifdef __NEUT_ENABLED__ // Skip Non NEUT if (evt->fType != kNEUT) return 1.0; // Hush now StopTalking(); // Fill NEUT Common blocks NEUTUtils::FillNeutCommons(evt->fNeutVect); // Call Weight calculation rw_weight = fNeutRW->CalcWeight(); // Speak Now StartTalking(); #endif // Return rw_weight return rw_weight; } diff --git a/src/Reweight/NIWGWeightEngine.cxx b/src/Reweight/NIWGWeightEngine.cxx index 94c53ec..14691b9 100644 --- a/src/Reweight/NIWGWeightEngine.cxx +++ b/src/Reweight/NIWGWeightEngine.cxx @@ -1,220 +1,220 @@ #include "NIWGWeightEngine.h" NIWGWeightEngine::NIWGWeightEngine(std::string name) { #ifdef __NIWG_ENABLED__ #ifdef __NEUT_ENABLED__ // Setup the NEUT Reweight engien fCalcName = name; LOG(FIT) << "Setting up NIWG RW : " << fCalcName << std::endl; // Create RW Engine suppressing cout StopTalking(); fNIWGRW = new niwg::rew::NIWGReWeight(); // Get List of Veto Calcs (For Debugging) std::string rw_engine_list = - FitPar::Config().GetParS("FitWeight.fNIWGRW_veto"); + FitPar::Config().GetParS("FitWeight_fNIWGRW_veto"); bool niwg_2012a = rw_engine_list.find("niwg_2012a") == std::string::npos; bool niwg_2014a = rw_engine_list.find("niwg_2014a") == std::string::npos; bool niwg_pimult = rw_engine_list.find("niwg_pimult") == std::string::npos; bool niwg_mec = rw_engine_list.find("niwg_mec") == std::string::npos; bool niwg_rpa = rw_engine_list.find("niwg_rpa") == std::string::npos; bool niwg_eff_rpa = rw_engine_list.find("niwg_eff_rpa") == std::string::npos; bool niwg_proton = rw_engine_list.find("niwg_protonFSIbug") == std::string::npos; bool niwg_hadron = rw_engine_list.find("niwg_HadronMultSwitch") == std::string::npos; // Add the RW Calcs if (niwg_2012a) fNIWGRW->AdoptWghtCalc("niwg_2012a", new niwg::rew::NIWGReWeight2012a); if (niwg_2014a) fNIWGRW->AdoptWghtCalc("niwg_2014a", new niwg::rew::NIWGReWeight2014a); if (niwg_pimult) fNIWGRW->AdoptWghtCalc("niwg_pimult", new niwg::rew::NIWGReWeightPiMult); if (niwg_mec) fNIWGRW->AdoptWghtCalc("niwg_mec", new niwg::rew::NIWGReWeightMEC); if (niwg_rpa) fNIWGRW->AdoptWghtCalc("niwg_rpa", new niwg::rew::NIWGReWeightRPA); if (niwg_eff_rpa) fNIWGRW->AdoptWghtCalc("niwg_eff_rpa", new niwg::rew::NIWGReWeightEffectiveRPA); if (niwg_proton) fNIWGRW->AdoptWghtCalc("niwg_protonFSIbug", new niwg::rew::NIWGReWeightProtonFSIbug); if (niwg_hadron) fNIWGRW->AdoptWghtCalc("niwg_HadronMultSwitch", new niwg::rew::NIWGReWeightHadronMultSwitch); fNIWGRW->Reconfigure(); // Set Abs Twk Config fIsAbsTwk = (FitPar::Config().GetParB("setabstwk")); // allow cout again StartTalking(); #else ERR(FTL) << "NIWG RW Enabled but NEUT RW is not!" << std::endl; #endif #else ERR(FTL) << "NIWG RW NOT ENABLED!" << std::endl; #endif }; void NIWGWeightEngine::IncludeDial(std::string name, double startval) { #ifdef __NIWG_ENABLED__ #ifdef __NEUT_ENABLED__ // Get First enum int nuisenum = Reweight::ConvDial(name, kNIWG); // Setup Maps fEnumIndex[nuisenum];// = std::vector(0); fNameIndex[name]; // = std::vector(0); // Split by commas std::vector allnames = GeneralUtils::ParseToStr(name, ","); for (uint i = 0; i < allnames.size(); i++) { std::string singlename = allnames[i]; // Get RW niwg::rew::NIWGSyst_t gensyst = niwg::rew::NIWGSyst::FromString(name); // Fill Maps int index = fValues.size(); fValues.push_back(0.0); fNIWGSysts.push_back(gensyst); // Initialize dial LOG(FIT) << "Registering " << singlename << " from " << name << std::endl; fNIWGRW->Systematics().Init( fNIWGSysts[index] ); // If Absolute if (fIsAbsTwk) { niwg::rew::NIWGSystUncertainty::Instance()->SetUncertainty( fNIWGSysts[index], 1.0, 1.0 ); } // Setup index fEnumIndex[nuisenum].push_back(index); fNameIndex[name].push_back(index); } // Set Value if given if (startval != -999.9) { SetDialValue(nuisenum, startval); } #endif #endif } void NIWGWeightEngine::SetDialValue(int nuisenum, double val) { #ifdef __NIWG_ENABLED__ #ifdef __NEUT_ENABLED__ std::vector indices = fEnumIndex[nuisenum]; for (uint i = 0; i < indices.size(); i++) { fValues[indices[i]] = val; std::cout << "Setting NIWG Dial Value " << i << " " << indices[i] << " " << fNIWGSysts[indices[i]] << std::endl; fNIWGRW->Systematics().Set( fNIWGSysts[indices[i]], val); } #endif #endif } void NIWGWeightEngine::SetDialValue(std::string name, double val) { #ifdef __NIWG_ENABLED__ #ifdef __NEUT_ENABLED__ std::vector indices = fNameIndex[name]; for (uint i = 0; i < indices.size(); i++) { fValues[indices[i]] = val; fNIWGRW->Systematics().Set(fNIWGSysts[indices[i]], val); } #endif #endif } void NIWGWeightEngine::Reconfigure(bool silent) { #ifdef __NIWG_ENABLED__ #ifdef __NEUT_ENABLED__ // Hush now... if (silent) StopTalking(); // Reconf fNIWGRW->Reconfigure(); // Shout again if (silent) StartTalking(); #endif #endif } double NIWGWeightEngine::CalcWeight(BaseFitEvt* evt) { double rw_weight = 1.0; #ifdef __NEUT_ENABLED__ #ifdef __NIWG_ENABLED__ // Skip Non GENIE if (evt->fType != kNEUT) return 1.0; // Hush now StopTalking(); niwg::rew::NIWGEvent* niwg_event = NIWGWeightEngine::GetNIWGEventLocal(evt->fNeutVect); rw_weight *= fNIWGRW->CalcWeight(*niwg_event); delete niwg_event; // Speak Now StartTalking(); #endif #endif // Return rw_weight return rw_weight; } #ifdef __NEUT_ENABLED__ #ifdef __NIWG_ENABLED__ niwg::rew::NIWGEvent * NIWGWeightEngine::GetNIWGEventLocal(NeutVect* nvect) { niwg::rew::NIWGEvent * fDummyNIWGEvent = NULL; fDummyNIWGEvent = new niwg::rew::NIWGEvent(); fDummyNIWGEvent->detid = 1; // MiniBooNE (apply CCQE LowE variations) fDummyNIWGEvent->neutmode = nvect->Mode; fDummyNIWGEvent->targetA = nvect->TargetA; fDummyNIWGEvent->recenu_ccqe_sk = -1; if (nvect->Ibound == 0) fDummyNIWGEvent->targetA = 1; //RT: identifies as H, rather than O16 // Fill initial particle stack for (int ip = 0; ip < nvect->Npart(); ++ip) { niwg::rew::NIWGPartStack fDummyPartStack; fDummyPartStack.p = (nvect->PartInfo(ip)->fP) * 0.001; // Convert to GeV fDummyPartStack.pdg = nvect->PartInfo(ip)->fPID; fDummyPartStack.chase = nvect->PartInfo(ip)->fIsAlive; fDummyPartStack.parent = nvect->ParentIdx(ip) - 1; // WARNING: this needs to be tested with a NeutRoot file fDummyNIWGEvent->part_stack.push_back(fDummyPartStack); } fDummyNIWGEvent->CalcKinematics(); return fDummyNIWGEvent; } #endif #endif diff --git a/src/Reweight/NUISANCESyst.cxx b/src/Reweight/NUISANCESyst.cxx index 6063aa3..e6cde59 100644 --- a/src/Reweight/NUISANCESyst.cxx +++ b/src/Reweight/NUISANCESyst.cxx @@ -1,61 +1,65 @@ #include "NUISANCESyst.h" int Reweight::ConvertNUISANCEDial(std::string type) { for (int i = kUnkownNUISANCEDial + 1; i < kNUISANCEDial_LAST; i++) { if (!type.compare(ConvNUISANCEDial(i).c_str())) { return i; } } return kUnkownNUISANCEDial; }; std::string Reweight::ConvNUISANCEDial(int type) { switch (type) { case kGaussianCorr_CCQE_norm: { return "GaussianCorr_CCQE_norm"; } case kGaussianCorr_CCQE_tilt: { return "GaussianCorr_CCQE_tilt"; } case kGaussianCorr_CCQE_Pq0: { return "GaussianCorr_CCQE_Pq0"; } case kGaussianCorr_CCQE_Wq0: { return "GaussianCorr_CCQE_Wq0"; } case kGaussianCorr_CCQE_Pq3: { return "GaussianCorr_CCQE_Pq3"; } case kGaussianCorr_CCQE_Wq3: { return "GaussianCorr_CCQE_Wq3"; } case kGaussianCorr_2p2h_norm: { return "GaussianCorr_2p2h_norm"; } case kGaussianCorr_2p2h_tilt: { return "GaussianCorr_2p2h_tilt"; } case kGaussianCorr_2p2h_Pq0: { return "GaussianCorr_2p2h_Pq0"; } case kGaussianCorr_2p2h_Wq0: { return "GaussianCorr_2p2h_Wq0"; } case kGaussianCorr_2p2h_Pq3: { return "GaussianCorr_2p2h_Pq3"; } case kGaussianCorr_2p2h_Wq3: { return "GaussianCorr_2p2h_Wq3"; } case kGaussianCorr_2p2h_PPandNN_norm: { return "GaussianCorr_2p2h_PPandNN_norm"; } case kGaussianCorr_2p2h_PPandNN_tilt: { return "GaussianCorr_2p2h_PPandNN_tilt"; } case kGaussianCorr_2p2h_PPandNN_Pq0: { return "GaussianCorr_2p2h_PPandNN_Pq0"; } case kGaussianCorr_2p2h_PPandNN_Wq0: { return "GaussianCorr_2p2h_PPandNN_Wq0"; } case kGaussianCorr_2p2h_PPandNN_Pq3: { return "GaussianCorr_2p2h_PPandNN_Pq3"; } case kGaussianCorr_2p2h_PPandNN_Wq3: { return "GaussianCorr_2p2h_PPandNN_Wq3"; } case kGaussianCorr_2p2h_NP_norm: { return "GaussianCorr_2p2h_NP_norm"; } case kGaussianCorr_2p2h_NP_tilt: { return "GaussianCorr_2p2h_NP_tilt"; } case kGaussianCorr_2p2h_NP_Pq0: { return "GaussianCorr_2p2h_NP_Pq0"; } case kGaussianCorr_2p2h_NP_Wq0: { return "GaussianCorr_2p2h_NP_Wq0"; } case kGaussianCorr_2p2h_NP_Pq3: { return "GaussianCorr_2p2h_NP_Pq3"; } case kGaussianCorr_2p2h_NP_Wq3: { return "GaussianCorr_2p2h_NP_Wq3"; } case kGaussianCorr_CC1pi_norm: { return "GaussianCorr_CC1pi_norm"; } case kGaussianCorr_CC1pi_tilt: { return "GaussianCorr_CC1pi_tilt"; } case kGaussianCorr_CC1pi_Pq0: { return "GaussianCorr_CC1pi_Pq0"; } case kGaussianCorr_CC1pi_Wq0: { return "GaussianCorr_CC1pi_Wq0"; } case kGaussianCorr_CC1pi_Pq3: { return "GaussianCorr_CC1pi_Pq3"; } case kGaussianCorr_CC1pi_Wq3: { return "GaussianCorr_CC1pi_Wq3"; } case kGaussianCorr_AllowSuppression: { return "GaussianCorr_AllowSuppression"; } case kModeNorm_NormRES: { return "NormRES"; } case kMINERvARW_NormCCQE: { return "MINERvARW_NormCCQE"; } case kMINERvARW_NormCCMEC: { return "MINERvARW_NormCCMEC"; } case kMINERvARW_NormCCRES: { return "MINERvARW_NormCCRES"; } case kMINERvARW_RikRPA_ApplyRPA: { return "MINERvARW_RikRPA_ApplyRPA"; } case kMINERvARW_RikRPA_LowQ2: { return "MINERvARW_RikRPA_LowQ2"; } case kMINERvARW_RikRPA_HighQ2: { return "MINERvARW_RikRPA_HighQ2"; } + case kSBLOsc_Distance: { return "SBLOsc_Distance"; } + case kSBLOsc_MassSplitting: { return "SBLOsc_MassSplitting"; } + case kSBLOsc_Sin2Theta: { return "SBLOsc_Sin2Theta"; } + default: return "unknown_nuisance_dial"; } }; diff --git a/src/Reweight/NUISANCESyst.h b/src/Reweight/NUISANCESyst.h index dfc84e2..7d7e1c1 100644 --- a/src/Reweight/NUISANCESyst.h +++ b/src/Reweight/NUISANCESyst.h @@ -1,62 +1,66 @@ #ifndef NUISANCESyst_H #define NUISANCESyst_H #include "GeneralUtils.h" namespace Reweight { enum NUISANCESyst { kUnkownNUISANCEDial = 0, kGaussianCorr_CCQE_norm, kGaussianCorr_CCQE_tilt, kGaussianCorr_CCQE_Pq0, kGaussianCorr_CCQE_Wq0, kGaussianCorr_CCQE_Pq3, kGaussianCorr_CCQE_Wq3, kGaussianCorr_2p2h_norm, kGaussianCorr_2p2h_tilt, kGaussianCorr_2p2h_Pq0, kGaussianCorr_2p2h_Wq0, kGaussianCorr_2p2h_Pq3, kGaussianCorr_2p2h_Wq3, kGaussianCorr_2p2h_PPandNN_norm, kGaussianCorr_2p2h_PPandNN_tilt, kGaussianCorr_2p2h_PPandNN_Pq0, kGaussianCorr_2p2h_PPandNN_Wq0, kGaussianCorr_2p2h_PPandNN_Pq3, kGaussianCorr_2p2h_PPandNN_Wq3, kGaussianCorr_2p2h_NP_norm, kGaussianCorr_2p2h_NP_tilt, kGaussianCorr_2p2h_NP_Pq0, kGaussianCorr_2p2h_NP_Wq0, kGaussianCorr_2p2h_NP_Pq3, kGaussianCorr_2p2h_NP_Wq3, kGaussianCorr_CC1pi_norm, kGaussianCorr_CC1pi_tilt, kGaussianCorr_CC1pi_Pq0, kGaussianCorr_CC1pi_Wq0, kGaussianCorr_CC1pi_Pq3, kGaussianCorr_CC1pi_Wq3, kGaussianCorr_AllowSuppression, kModeNorm_NormRES, kMINERvARW_NormCCQE, kMINERvARW_NormCCMEC, kMINERvARW_NormCCRES, kMINERvARW_RikRPA_ApplyRPA, kMINERvARW_RikRPA_LowQ2, kMINERvARW_RikRPA_HighQ2, kMINERvARW_RikRESRPA_ApplyRPA, - kMINERvARW_RikRESRPA_LowQ2, + kMINERvARW_RikRESRPA_LowQ2, kMINERvARW_RikRESRPA_HighQ2, + kSBLOsc_Distance, + kSBLOsc_MassSplitting, + kSBLOsc_Sin2Theta, + kNUISANCEDial_LAST }; int ConvertNUISANCEDial(std::string type); std::string ConvNUISANCEDial(int type); }; #endif diff --git a/src/Reweight/NUISANCEWeightCalcs.cxx b/src/Reweight/NUISANCEWeightCalcs.cxx index 4a70d6b..d21637b 100644 --- a/src/Reweight/NUISANCEWeightCalcs.cxx +++ b/src/Reweight/NUISANCEWeightCalcs.cxx @@ -1,346 +1,394 @@ #include "NUISANCEWeightCalcs.h" #include "GeneralUtils.h" #include "FitEvent.h" #include "WeightUtils.h" #include "NUISANCESyst.h" using namespace Reweight; 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(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_MassSplitting) fMassSplitting = 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; + } +} + +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); +} + + GaussianModeCorr::GaussianModeCorr() { // 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(evt); double rw_weight = 1.0; // Get Neutrino if (!fevt->Npart()){ THROW("NO particles found in stack!"); } FitParticle* pnu = fevt->PartInfo(0); if (!pnu){ THROW("NO Starting particle found in stack!"); } int pdgnu = pnu->fPID; FitParticle* plep = fevt->GetHMFSParticle(abs(pdgnu) - 1); 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++; } // std::cout << "PN State = " << npr << " " << nne << std::endl; if (fevt->Mode == 2 and npr == 1 and nne == 1) { initialstate = 2; } else if (fevt->Mode == 2 and ((npr == 0 and nne == 2) or (npr == 2 and nne == 0))) { initialstate = 1; } } // std::cout << "Got q0 q3 = " << q0 << " " << q3 << std::endl; // Apply weighting if (fApply_CCQE and 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 (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 (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 (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 (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; return rw_weight; } double GaussianModeCorr::GetGausWeight(double q0, double q3, double vals[]) { // // 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); double 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 || isnan(w) || w < 0.0){ w = 0.0; } if (w < 1.0 and !fAllowSuppression){ w = 1.0; } 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/NUISANCEWeightCalcs.h b/src/Reweight/NUISANCEWeightCalcs.h index 15e2c6b..640842e 100644 --- a/src/Reweight/NUISANCEWeightCalcs.h +++ b/src/Reweight/NUISANCEWeightCalcs.h @@ -1,90 +1,108 @@ #ifndef NUISANCE_WEIGHT_CALCS #define NUISANCE_WEIGHT_CALCS #include "BaseFitEvt.h" class NUISANCEWeightCalc { public: NUISANCEWeightCalc() {}; virtual ~NUISANCEWeightCalc() {}; virtual double CalcWeight(BaseFitEvt* evt){return 1.0;}; virtual void SetDialValue(std::string name, double val){}; virtual void SetDialValue(int rwenum, double val){}; virtual bool IsHandled(int rwenum){return false;}; virtual void Print(){}; std::map fDialNameIndex; std::map fDialEnumIndex; std::vector fDialValues; std::string fName; }; class ModeNormCalc : public NUISANCEWeightCalc { public: ModeNormCalc(); ~ModeNormCalc(){}; double CalcWeight(BaseFitEvt* evt); void SetDialValue(std::string name, double val); void SetDialValue(int rwenum, double val); bool IsHandled(int rwenum); double fNormRES; }; +class SBLOscWeightCalc : public NUISANCEWeightCalc { + public: + SBLOscWeightCalc(); + ~SBLOscWeightCalc(){}; + + double CalcWeight(BaseFitEvt* evt); + void SetDialValue(std::string name, double val); + void SetDialValue(int rwenum, double val); + bool IsHandled(int rwenum); + + double GetSBLOscWeight(double E); + + double fDistance; + double fMassSplitting; + double fSin2Theta; + + }; + class GaussianModeCorr : public NUISANCEWeightCalc { public: GaussianModeCorr(); ~GaussianModeCorr(){}; double CalcWeight(BaseFitEvt* evt); void SetDialValue(std::string name, double val); void SetDialValue(int rwenum, double val); bool IsHandled(int rwenum); double GetGausWeight(double q0, double q3, double vals[]); // 5 pars describe the Gaussain // 0 norm. // 1 q0 pos // 2 q0 width // 3 q3 pos // 4 q3 width static const int kPosNorm = 0; static const int kPosTilt = 1; static const int kPosPq0 = 2; static const int kPosWq0 = 3; static const int kPosPq3 = 4; static const int kPosWq3 = 5; bool fApply_CCQE; double fGausVal_CCQE[6]; bool fApply_2p2h; double fGausVal_2p2h[6]; bool fApply_2p2h_PPandNN; double fGausVal_2p2h_PPandNN[6]; bool fApply_2p2h_NP; double fGausVal_2p2h_NP[6]; bool fApply_CC1pi; double fGausVal_CC1pi[6]; bool fAllowSuppression; bool fDebugStatements; }; #endif diff --git a/src/Reweight/NUISANCEWeightEngine.cxx b/src/Reweight/NUISANCEWeightEngine.cxx index 116385c..39eb1f9 100644 --- a/src/Reweight/NUISANCEWeightEngine.cxx +++ b/src/Reweight/NUISANCEWeightEngine.cxx @@ -1,110 +1,111 @@ #include "NUISANCEWeightEngine.h" #include "NUISANCEWeightCalcs.h" #ifdef __MINERVA_RW_ENABLED__ #ifdef __GENIE_ENABLED__ #include "MINERvAWeightCalcs.h" #endif #endif NUISANCEWeightEngine::NUISANCEWeightEngine(std::string name) { // Setup the NUISANCE Reweight engine fCalcName = name; LOG(FIT) << "Setting up NUISANCE Custom RW : " << fCalcName << std::endl; // Load in all Weight Calculations fWeightCalculators.push_back(new GaussianModeCorr()); fWeightCalculators.push_back(new ModeNormCalc()); + fWeightCalculators.push_back(new SBLOscWeightCalc()); #ifdef __MINERVA_RW_ENABLED__ #ifdef __GENIE_ENABLED__ fWeightCalculators.push_back(new nuisance::reweight::MINERvAReWeight_MEC()); fWeightCalculators.push_back(new nuisance::reweight::MINERvAReWeight_RES()); fWeightCalculators.push_back(new nuisance::reweight::RikRPA()); #endif #endif // Set Abs Twk Config fIsAbsTwk = true; }; void NUISANCEWeightEngine::IncludeDial(std::string name, double startval) { // Get First enum int nuisenum = Reweight::ConvDial(name, kCUSTOM); // Setup Maps fEnumIndex[nuisenum]; // = std::vector(0); fNameIndex[name]; // = std::vector(0); // Split by commas std::vector allnames = GeneralUtils::ParseToStr(name, ","); for (uint i = 0; i < allnames.size(); i++) { std::string singlename = allnames[i]; // Get RW int singleenum = Reweight::ConvDial(singlename, kCUSTOM); // Fill Maps int index = fValues.size(); fValues.push_back(0.0); fNUISANCEEnums.push_back(singleenum); // Initialize dial std::cout << "Registering " << singlename << " from " << name << std::endl; // Setup index fEnumIndex[nuisenum].push_back(index); fNameIndex[name].push_back(index); } // Set Value if given if (startval != -999.9) { SetDialValue(nuisenum, startval); } }; void NUISANCEWeightEngine::SetDialValue(int nuisenum, double val) { std::vector indices = fEnumIndex[nuisenum]; for (uint i = 0; i < indices.size(); i++) { fValues[indices[i]] = val; } } void NUISANCEWeightEngine::SetDialValue(std::string name, double val) { std::vector indices = fNameIndex[name]; for (uint i = 0; i < indices.size(); i++) { fValues[indices[i]] = val; } } void NUISANCEWeightEngine::Reconfigure(bool silent) { for (size_t i = 0; i < fNUISANCEEnums.size(); i++) { for (std::vector::iterator calciter = fWeightCalculators.begin(); calciter != fWeightCalculators.end(); calciter++) { NUISANCEWeightCalc* nuiscalc = static_cast(*calciter); if (nuiscalc->IsHandled(fNUISANCEEnums[i])) { nuiscalc->SetDialValue(fNUISANCEEnums[i], fValues[i]); } } } } double NUISANCEWeightEngine::CalcWeight(BaseFitEvt* evt) { double rw_weight = 1.0; // Cast as usable class for (std::vector::iterator iter = fWeightCalculators.begin(); iter != fWeightCalculators.end(); iter++) { NUISANCEWeightCalc* nuiscalc = static_cast(*iter); rw_weight *= nuiscalc->CalcWeight(evt); } // Return rw_weight return rw_weight; } diff --git a/src/Reweight/NuWroWeightEngine.cxx b/src/Reweight/NuWroWeightEngine.cxx index 149e23a..c9dcc95 100644 --- a/src/Reweight/NuWroWeightEngine.cxx +++ b/src/Reweight/NuWroWeightEngine.cxx @@ -1,136 +1,136 @@ #include "NuWroWeightEngine.h" NuWroWeightEngine::NuWroWeightEngine(std::string name) { #ifdef __NUWRO_REWEIGHT_ENABLED__ // Setup the NEUT Reweight engien fCalcName = name; LOG(FIT) << "Setting up NuWro RW : " << fCalcName << std::endl; // Create RW Engine suppressing cout StopTalking(); // Create the engine fNuwroRW = new nuwro::rew::NuwroReWeight(); // Get List of Veto Calcs (For Debugging) std::string rw_engine_list = - FitPar::Config().GetParS("FitWeight.fNuwroRW_veto"); + FitPar::Config().GetParS("FitWeight_fNuwroRW_veto"); bool xsec_qel = rw_engine_list.find("nuwro_QEL") == std::string::npos; bool xsec_flag = rw_engine_list.find("nuwro_FlagNorm") == std::string::npos; bool xsec_res = rw_engine_list.find("nuwro_RES") == std::string::npos; // Add the RW Calcs if (xsec_qel) fNuwroRW->AdoptWghtCalc("nuwro_QEL", new nuwro::rew::NuwroReWeight_QEL); if (xsec_flag) fNuwroRW->AdoptWghtCalc("nuwro_FlagNorm", new nuwro::rew::NuwroReWeight_FlagNorm); if (xsec_res) fNuwroRW->AdoptWghtCalc("nuwro_RES", new nuwro::rew::NuwroReWeight_SPP); // Set Abs Twk Config fIsAbsTwk = (FitPar::Config().GetParB("setabstwk")); // allow cout again StartTalking(); #else ERR(FTL) << "NUWRO RW NOT ENABLED! " << std::endl; #endif }; void NuWroWeightEngine::IncludeDial(std::string name, double startval) { #ifdef __NUWRO_REWEIGHT_ENABLED__ // Get RW Enum and name int nuisenum = Reweight::ConvDial(name, kNUWRO); // Initialise new vector fEnumIndex[nuisenum]; fNameIndex[name]; // Split by commas std::vector allnames = GeneralUtils::ParseToStr(name, ","); for (uint i = 0; i < allnames.size(); i++) { std::string singlename = allnames[i]; // Get Syst nuwro::rew::NuwroSyst_t gensyst = nuwro::rew::NuwroSyst::FromString(name); // Fill Maps int index = fValues.size(); fValues.push_back(0.0); fNUWROSysts.push_back(gensyst); // Initialise Dial LOG(FIT) << "Adding NuWro Syst " << fNUWROSysts[index] << std::endl; fNuwroRW->Systematics().Add(fNUWROSysts[index]); if (fIsAbsTwk) { nuwro::rew::NuwroSystUncertainty::Instance()->SetUncertainty( fNUWROSysts[index], 1.0, 1.0); } // Setup index fEnumIndex[nuisenum].push_back(index); fNameIndex[name].push_back(index); } // Set Value if given if (startval != -999.9) { SetDialValue(name, startval); } #endif }; void NuWroWeightEngine::SetDialValue(int nuisenum, double val) { #ifdef __NUWRO_REWEIGHT_ENABLED__ std::vector indices = fEnumIndex[nuisenum]; for (uint i = 0; i < indices.size(); i++) { fValues[indices[i]] = val; fNuwroRW->Systematics().SetSystVal(fNUWROSysts[indices[i]], val); } #endif } void NuWroWeightEngine::SetDialValue(std::string name, double val) { #ifdef __NUWRO_REWEIGHT_ENABLED__ std::vector indices = fNameIndex[name]; for (uint i = 0; i < indices.size(); i++) { fValues[indices[i]] = val; fNuwroRW->Systematics().SetSystVal(fNUWROSysts[indices[i]], val); } #endif } void NuWroWeightEngine::Reconfigure(bool silent) { #ifdef __NUWRO_REWEIGHT_ENABLED__ // Hush now... if (silent) StopTalking(); // Reconf fNuwroRW->Reconfigure(); // Shout again if (silent) StartTalking(); #endif } double NuWroWeightEngine::CalcWeight(BaseFitEvt* evt) { double rw_weight = 1.0; #ifdef __NUWRO_REWEIGHT_ENABLED__ // Skip Non GENIE if (evt->fType != kNUWRO) return 1.0; #ifdef __USE_NUWRO_SRW_EVENTS__ rw_weight = fNuwroRW->CalcWeight(evt->fNuwroSRWEvent, *evt->fNuwroParams); #else // Call Weight calculation rw_weight = fNuwroRW->CalcWeight(evt->fNuwroEvent); #endif #endif // Return rw_weight return rw_weight; } diff --git a/src/Routines/MinimizerRoutines.cxx b/src/Routines/MinimizerRoutines.cxx index ee3e995..24cd30d 100755 --- a/src/Routines/MinimizerRoutines.cxx +++ b/src/Routines/MinimizerRoutines.cxx @@ -1,1506 +1,1506 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "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(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 xmlcmds; std::vector configargs; // Make easier to handle arguments. std::vector 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 (!fOutputFile.empty()) fCompKey.Set("outputfile", fOutputFile); if (!fStrategy.empty()) fCompKey.Set("strategy", fStrategy); // Load XML 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 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) { parnom = FitBase::RWAbsToSigma(partype, parname, parnom); parlow = FitBase::RWAbsToSigma(partype, parname, parlow); parhigh = FitBase::RWAbsToSigma(partype, parname, parhigh); parstep = FitBase::RWAbsToSigma(partype, parname, parstep); } 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 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 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("minimizer.maxcalls")); + 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("minimizer.maxiterations")); - fMinimizer->SetTolerance(FitPar::Config().GetParD("minimizer.tolerance")); - fMinimizer->SetStrategy(FitPar::Config().GetParI("minimizer.strategy")); + 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& 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("minimizer.lowstatevents"); - int maxevents = FitPar::Config().GetParI("input.maxevents"); + 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("input.maxevents", lowstatsevents); + Config::SetPar("MAXEVENTS", lowstatsevents); Config::SetPar("VERBOSITY", 3); SetupFCN(); RunFitRoutine(trueroutine); - Config::SetPar("input.maxevents", maxevents); + 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 nameVect; std::vector valVect; std::vector errVect; std::vector minVect; std::vector maxVect; std::vector startVect; std::vector endfixVect; std::vector 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 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 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/Smearceptance/Smearcepterton.cxx b/src/Smearceptance/Smearcepterton.cxx index 192a1e9..005644e 100644 --- a/src/Smearceptance/Smearcepterton.cxx +++ b/src/Smearceptance/Smearcepterton.cxx @@ -1,345 +1,352 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "Smearcepterton.h" #include "EfficiencyApplicator.h" #include "GaussianSmearer.h" #include "MetaSimpleSmearcepter.h" #include "ThresholdAccepter.h" #include "TrackedMomentumMatrixSmearer.h" #include "VisECoalescer.h" #include #ifdef __USE_DYNSAMPLES__ #include "TRegexp.h" #include // linux #include DynamicSmearceptorFactory::DynamicSmearceptorFactory() : NSmearceptors(0), NManifests(0) { LoadPlugins(); QLOG(FIT, "Loaded " << NSmearceptors << " from " << NManifests << " shared object libraries."); } DynamicSmearceptorFactory* DynamicSmearceptorFactory::glblDSF = NULL; DynamicSmearceptorFactory::PluginManifest::~PluginManifest() { for (size_t i_it = 0; i_it < Instances.size(); ++i_it) { (*(DSF_DestroySmearceptor))(Instances[i_it]); } } std::string EnsureTrailingSlash(std::string const& inp) { if (!inp.length()) { return "/"; } if (inp[inp.length() - 1] == '/') { return inp; } return inp + "/"; } void DynamicSmearceptorFactory::LoadPlugins() { std::vector SearchDirectories; if (Config::HasPar("dynamic_smearceptor.path")) { SearchDirectories = GeneralUtils::ParseToStr( Config::GetParS("dynamic_smearceptor.path"), ":"); } char const* envPath = getenv("NUISANCE_DS_PATH"); if (envPath) { std::vector envPaths = GeneralUtils::ParseToStr(envPath, ":"); for (size_t ep_it = 0; ep_it < envPaths.size(); ++ep_it) { SearchDirectories.push_back(envPaths[ep_it]); } } if (!SearchDirectories.size()) { char const* pwdPath = getenv("PWD"); if (pwdPath) { SearchDirectories.push_back(pwdPath); } } for (size_t sp_it = 0; sp_it < SearchDirectories.size(); ++sp_it) { std::string dirpath = EnsureTrailingSlash(SearchDirectories[sp_it]); QLOG(FIT, "Searching for dynamic smearceptor manifests in: " << dirpath); Ssiz_t len = 0; DIR* dir; struct dirent* ent; dir = opendir(dirpath.c_str()); if (dir != NULL) { TRegexp matchExp("*.so", true); while ((ent = readdir(dir)) != NULL) { if (matchExp.Index(TString(ent->d_name), &len) != Ssiz_t(-1)) { QLOG(FIT, "\tFound shared object: " << ent->d_name << " checking for relevant methods..."); void* dlobj = dlopen((dirpath + ent->d_name).c_str(), RTLD_NOW | RTLD_GLOBAL); char const* dlerr_cstr = dlerror(); std::string dlerr; if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "\tDL Load Error: " << dlerr); continue; } PluginManifest plgManif; plgManif.dllib = dlobj; plgManif.soloc = (dirpath + ent->d_name); plgManif.DSF_NSmearceptors = reinterpret_cast( dlsym(dlobj, "DSF_NSmearceptors")); dlerr = ""; dlerr_cstr = dlerror(); if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "\tFailed to load symbol \"DSF_NSmearceptors\" from " << (dirpath + ent->d_name) << ": " << dlerr); dlclose(dlobj); continue; } plgManif.DSF_GetSmearceptorName = reinterpret_cast( dlsym(dlobj, "DSF_GetSmearceptorName")); dlerr = ""; dlerr_cstr = dlerror(); if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "\tFailed to load symbol \"DSF_GetSmearceptorName\" from " << (dirpath + ent->d_name) << ": " << dlerr); dlclose(dlobj); continue; } plgManif.DSF_GetSmearceptor = reinterpret_cast( dlsym(dlobj, "DSF_GetSmearceptor")); dlerr = ""; dlerr_cstr = dlerror(); if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "\tFailed to load symbol \"DSF_GetSmearceptor\" from " << (dirpath + ent->d_name) << ": " << dlerr); dlclose(dlobj); continue; } plgManif.DSF_DestroySmearceptor = reinterpret_cast( dlsym(dlobj, "DSF_DestroySmearceptor")); dlerr = ""; dlerr_cstr = dlerror(); if (dlerr_cstr) { dlerr = dlerr_cstr; } if (dlerr.length()) { ERROR(WRN, "Failed to load symbol \"DSF_DestroySmearceptor\" from " << (dirpath + ent->d_name) << ": " << dlerr); dlclose(dlobj); continue; } plgManif.NSmearceptors = (*(plgManif.DSF_NSmearceptors))(); QLOG(FIT, "\tSuccessfully loaded dynamic smearceptor manifest: " << plgManif.soloc << ". Contains " << plgManif.NSmearceptors << " smearceptors."); for (size_t smp_it = 0; smp_it < plgManif.NSmearceptors; ++smp_it) { char const* smp_name = (*(plgManif.DSF_GetSmearceptorName))(smp_it); if (!smp_name) { THROW("Could not load smearceptor " << smp_it << " / " << plgManif.NSmearceptors << " from " << plgManif.soloc); } if (Smearceptors.count(smp_name)) { ERROR(WRN, "Already loaded a smearceptor named: \"" << smp_name << "\". cannot load duplciates. This " "smearceptor will be skipped."); continue; } plgManif.SmearceptorsProvided.push_back(smp_name); Smearceptors[smp_name] = std::make_pair(plgManif.soloc, smp_it); QLOG(FIT, "\t\t" << smp_name); } if (plgManif.SmearceptorsProvided.size()) { Manifests[plgManif.soloc] = plgManif; NSmearceptors += plgManif.SmearceptorsProvided.size(); NManifests++; } else { dlclose(dlobj); } } } closedir(dir); } else { ERROR(WRN, "Tried to open non-existant directory."); } } } DynamicSmearceptorFactory& DynamicSmearceptorFactory::Get() { if (!glblDSF) { glblDSF = new DynamicSmearceptorFactory(); } return *glblDSF; } void DynamicSmearceptorFactory::Print() { std::map > ManifestSmearceptors; for (std::map >::iterator smp_it = Smearceptors.begin(); smp_it != Smearceptors.end(); ++smp_it) { if (!ManifestSmearceptors.count(smp_it->second.first)) { ManifestSmearceptors[smp_it->second.first] = std::vector(); } ManifestSmearceptors[smp_it->second.first].push_back(smp_it->first); } QLOG(FIT, "Dynamic smearceptor manifest: "); for (std::map >::iterator m_it = ManifestSmearceptors.begin(); m_it != ManifestSmearceptors.end(); ++m_it) { QLOG(FIT, "\tLibrary " << m_it->first << " contains: "); for (size_t s_it = 0; s_it < m_it->second.size(); ++s_it) { QLOG(FIT, "\t\t" << m_it->second[s_it]); } } } bool DynamicSmearceptorFactory::HasSmearceptor(std::string const& name) { return Smearceptors.count(name); } bool DynamicSmearceptorFactory::HasSmearceptor(nuiskey& smearceptorkey) { return HasSmearceptor(smearceptorkey.GetElementName()); } ISmearcepter* DynamicSmearceptorFactory::CreateSmearceptor( nuiskey& smearceptorkey) { if (!HasSmearceptor(smearceptorkey)) { ERROR(WRN, "Asked to load unknown smearceptor: \"" << smearceptorkey.GetElementName() << "\"."); return NULL; } std::pair smearceptor = Smearceptors[smearceptorkey.GetElementName()]; QLOG(SAM, "\tLoading smearceptor " << smearceptor.second << " from " << smearceptor.first); ISmearcepter* smear = (*(Manifests[smearceptor.first].DSF_GetSmearceptor))( smearceptor.second, &smearceptorkey); return smear; } DynamicSmearceptorFactory::~DynamicSmearceptorFactory() { Manifests.clear(); } #endif Smearcepterton* Smearcepterton::_inst = NULL; Smearcepterton& Smearcepterton::Get() { if (!_inst) { _inst = new Smearcepterton(); } return *_inst; } Smearcepterton::Smearcepterton() { InitialiserSmearcepters(); } void Smearcepterton::InitialiserSmearcepters() { // hard coded list of tag name -> smearcepter factories, add here to add your // own. std::map factories; factories["ThresholdAccepter"] = &BuildSmearcepter; factories["EfficiencyApplicator"] = &BuildSmearcepter; factories["GaussianSmearer"] = &BuildSmearcepter; factories["TrackedMomentumMatrixSmearer"] = &BuildSmearcepter; factories["VisECoalescer"] = &BuildSmearcepter; factories["MetaSimpleSmearcepter"] = &BuildSmearcepter; + Config::Get().PrintXML(NULL); + std::vector smearcepterBlocks = Config::QueryKeys("smearcepters"); + // std::cout << "[INFO]: " << nodelist.size() << " smearcepter nodes." << std::endl; + // for(size_t i = 0; i < nodelist.size(); ++i){ + // Config::Get().PrintXML(nodelist[i]); + // } + for (size_t smearB_it = 0; smearB_it < smearcepterBlocks.size(); ++smearB_it) { std::vector smearcepters = smearcepterBlocks[smearB_it].GetListOfChildNodes(); for (size_t smear_it = 0; smear_it < smearcepters.size(); ++smear_it) { std::string const& smearType = smearcepters[smear_it].GetElementName(); ISmearcepter* smearer = NULL; #ifdef __USE_DYNSAMPLES__ if (DynamicSmearceptorFactory::Get().HasSmearceptor(smearType)) { smearer = DynamicSmearceptorFactory::Get().CreateSmearceptor( smearcepters[smear_it]); } else #endif { if (!factories.count(smearType)) { ERROR(WRN, "No known smearer accepts elements named: \"" << smearType << "\""); continue; } smearer = factories[smearType](smearcepters[smear_it]); } if (!smearer) { THROW("Failed to load smearceptor."); } if (!smearer->GetName().length()) { THROW("Smearcepter type " << smearer->GetElementName() << " had no instance name."); } Smearcepters[smearer->GetName()] = smearer; QLOG(FIT, "Configured smearer named: " << smearer->GetName() << " of type: " << smearer->GetElementName()); } } } diff --git a/src/Smearceptance/ThresholdAccepter.cxx b/src/Smearceptance/ThresholdAccepter.cxx index adc7239..7cb716d 100644 --- a/src/Smearceptance/ThresholdAccepter.cxx +++ b/src/Smearceptance/ThresholdAccepter.cxx @@ -1,330 +1,330 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "ThresholdAccepter.h" namespace { ThresholdAccepter::KineVar GetKineType(nuiskey &nk) { if (nk.Has("RecoThresholdMomentum_MeV")) { return ThresholdAccepter::kMomentum; } else if (nk.Has("RecoThresholdKE_MeV")) { return ThresholdAccepter::kKE; } else if (nk.Has("RecoThresholdCosTheta_Max")) { return ThresholdAccepter::kCosTheta_Max; } else if (nk.Has("RecoThresholdCosTheta_Min")) { return ThresholdAccepter::kCosTheta_Min; } else if (nk.Has("RecoThresholdAbsCosTheta_Max")) { return ThresholdAccepter::kAbsCosTheta_Max; } else if (nk.Has("RecoThresholdAbsCosTheta_Min")) { return ThresholdAccepter::kAbsCosTheta_Min; } else { THROW("Cannot determine the threshold type for Smearcepter element."); } return ThresholdAccepter::kNoVar; } std::string GetKineTypeName(ThresholdAccepter::KineVar kv) { switch (kv) { case ThresholdAccepter::kMomentum: return "Momentum"; case ThresholdAccepter::kKE: return "KE"; case ThresholdAccepter::kCosTheta_Max: return "CosTheta_Max"; case ThresholdAccepter::kCosTheta_Min: return "CosTheta_Min"; case ThresholdAccepter::kAbsCosTheta_Max: return "AbsCosTheta_Max"; case ThresholdAccepter::kAbsCosTheta_Min: return "CosTheta_Min"; default: return "NoVar"; } } double GetKineThreshold(nuiskey &nk, ThresholdAccepter::KineVar kv) { switch (kv) { case ThresholdAccepter::kMomentum: return nk.GetD("RecoThresholdMomentum_MeV"); case ThresholdAccepter::kKE: return nk.GetD("RecoThresholdKE_MeV"); case ThresholdAccepter::kCosTheta_Max: return nk.GetD("RecoThresholdCosTheta_Max"); case ThresholdAccepter::kCosTheta_Min: return nk.GetD("RecoThresholdCosTheta_Min"); case ThresholdAccepter::kAbsCosTheta_Max: return nk.GetD("RecoThresholdAbsCosTheta_Max"); case ThresholdAccepter::kAbsCosTheta_Min: return nk.GetD("RecoThresholdAbsCosTheta_Min"); default: return 0; } } double GetKineVal(FitParticle *fp, ThresholdAccepter::Thresh &rt) { switch (rt.ThresholdType) { case ThresholdAccepter::kMomentum: return fp->P3().Mag(); case ThresholdAccepter::kKE: return fp->KE(); case ThresholdAccepter::kCosTheta_Max: return fp->P3().CosTheta(); case ThresholdAccepter::kCosTheta_Min: return fp->P3().CosTheta(); case ThresholdAccepter::kAbsCosTheta_Max: return fabs(fp->P3().CosTheta()); case ThresholdAccepter::kAbsCosTheta_Min: return fabs(fp->P3().CosTheta()); default: return 0; } } bool PassesThreshold(FitParticle *fp, ThresholdAccepter::Thresh &rt) { switch (rt.ThresholdType) { case ThresholdAccepter::kMomentum: return (fp->P3().Mag() > rt.ThresholdVal); case ThresholdAccepter::kKE: return (fp->KE() > rt.ThresholdVal); case ThresholdAccepter::kCosTheta_Max: return (fp->P3().CosTheta() < rt.ThresholdVal); case ThresholdAccepter::kCosTheta_Min: return (fp->P3().CosTheta() > rt.ThresholdVal); case ThresholdAccepter::kAbsCosTheta_Max: return (fabs(fp->P3().CosTheta()) < rt.ThresholdVal); case ThresholdAccepter::kAbsCosTheta_Min: return (fabs(fp->P3().CosTheta()) > rt.ThresholdVal); default: return 0; } } } /// Reads particle threshold nodes /// /// Nodes look like: /// /// /// /// /// /// /// /// void ThresholdAccepter::SpecifcSetup(nuiskey &nk) { std::vector recoThresholdDescriptors = nk.GetListOfChildNodes("RecoThreshold"); for (size_t t_it = 0; t_it < recoThresholdDescriptors.size(); ++t_it) { std::string pdgs_s = recoThresholdDescriptors[t_it].GetS("PDG"); std::vector pdgs_i = GeneralUtils::ParseToInt(pdgs_s, ","); for (size_t pdg_it = 0; pdg_it < pdgs_i.size(); ++pdg_it) { Thresh t; t.ThresholdType = GetKineType(recoThresholdDescriptors[t_it]); t.ThresholdVal = GetKineThreshold(recoThresholdDescriptors[t_it], t.ThresholdType); ReconThresholds[pdgs_i[pdg_it]].push_back(t); QLOG(FIT, "Added reconstruction threshold of type: " << ReconThresholds[pdgs_i[pdg_it]].back().ThresholdVal << " " << GetKineTypeName( ReconThresholds[pdgs_i[pdg_it]].back().ThresholdType) << ", for PDG: " << pdgs_i[pdg_it]); } } std::vector visThresholdDescriptors = nk.GetListOfChildNodes("VisThreshold"); for (size_t t_it = 0; t_it < visThresholdDescriptors.size(); ++t_it) { std::string pdgs_s = visThresholdDescriptors[t_it].GetS("PDG"); std::vector pdgs_i = GeneralUtils::ParseToInt(pdgs_s, ","); for (size_t pdg_it = 0; pdg_it < pdgs_i.size(); ++pdg_it) { if (VisThresholds.count(pdgs_i[pdg_it])) { ERROR(WRN, "Smearceptor " << ElementName << ":" << InstanceName << " already has a threshold for PDG: " << pdgs_i[pdg_it]); } VisThresh vt; vt.UseKE = visThresholdDescriptors[t_it].Has("Contrib") ? (visThresholdDescriptors[t_it].GetS("Contrib") == "K") : false; vt.Fraction = visThresholdDescriptors[t_it].Has("Fraction") ? visThresholdDescriptors[t_it].GetD("Fraction") : 1; if (visThresholdDescriptors[t_it].Has("VisThresholdKE_MeV")) { vt.ThresholdType = ThresholdAccepter::kKE; vt.ThresholdVal = visThresholdDescriptors[t_it].GetD("VisThresholdKE_MeV"); } else if (visThresholdDescriptors[t_it].Has( "VisThresholdMomentum_MeV")) { vt.ThresholdType = ThresholdAccepter::kMomentum; vt.ThresholdVal = visThresholdDescriptors[t_it].GetD("VisThresholdMomentum_MeV"); ; } else { ERROR(WRN, "Smearceptor " << ElementName << ":" << InstanceName << " cannot find threshold information for PDG: " << pdgs_i[pdg_it]); continue; } VisThresholds[pdgs_i[pdg_it]] = vt; QLOG(FIT, "Added visibility threshold of MeV " << VisThresholds[pdgs_i[pdg_it]].ThresholdVal << " " << GetKineTypeName(VisThresholds[pdgs_i[pdg_it]].ThresholdType) << ", for PDG: " << pdgs_i[pdg_it] << ". If visible, particle deposits: " << (VisThresholds[pdgs_i[pdg_it]].UseKE ? "KE" : "TE")); } } } void ThresholdAccepter::SmearceptOneParticle(RecoInfo *ri, FitParticle *fp #ifdef DEBUG_THRESACCEPT , size_t p_it #endif ) { #ifdef DEBUG_THRESACCEPT std::cout << std::endl; std::cout << "[" << p_it << " = " << fp << "]: " << fp->PDG() << ", " << fp->Status() << ", " << fp->E() << " -- KE:" << fp->KE() << " Mom: " << fp->P3().Mag() << std::flush; #endif if (fp->Status() != kFinalState) { #ifdef DEBUG_THRESACCEPT std::cout << " -- Not final state." << std::flush; #endif return; } if ((ReconThresholds.count(fp->PDG()) + VisThresholds.count(fp->PDG())) == 0) { #ifdef DEBUG_THRESACCEPT std::cout << " -- Undetectable." << std::flush; #endif return; } // If no reco thresholds it should fall through to EVis bool Passes = ReconThresholds[fp->PDG()].size(); bool FailEnergyThresh = !ReconThresholds[fp->PDG()].size(); for (size_t rt_it = 0; rt_it < ReconThresholds[fp->PDG()].size(); ++rt_it) { bool Passed = PassesThreshold(fp, ReconThresholds[fp->PDG()][rt_it]); if (!Passed) { #ifdef DEBUG_THRESACCEPT std::cout << "\n\t -- Rejected. (" << GetKineTypeName( ReconThresholds[fp->PDG()][rt_it].ThresholdType) << " Threshold: " << ReconThresholds[fp->PDG()][rt_it].ThresholdVal << " | " << GetKineVal(fp, ReconThresholds[fp->PDG()][rt_it]) << ")" << std::flush; +#endif if ((ReconThresholds[fp->PDG()][rt_it].ThresholdType == ThresholdAccepter::kMomentum) || (ReconThresholds[fp->PDG()][rt_it].ThresholdType == ThresholdAccepter::kKE)) { FailEnergyThresh = true; } -#endif } else { #ifdef DEBUG_THRESACCEPT std::cout << "\n\t -- Accepted. (" << GetKineTypeName( ReconThresholds[fp->PDG()][rt_it].ThresholdType) << " Threshold: " << ReconThresholds[fp->PDG()][rt_it].ThresholdVal << " | " << GetKineVal(fp, ReconThresholds[fp->PDG()][rt_it]) << ")" << std::flush; #endif } Passes = Passes && Passed; } if (Passes) { #ifdef DEBUG_THRESACCEPT std::cout << " -- Reconstructed." << std::flush; #endif ri->RecObjMom.push_back(fp->P3()); ri->RecObjClass.push_back(fp->PDG()); return; } else if (!FailEnergyThresh) { #ifdef DEBUG_THRESACCEPT std::cout << " -- Failed non-Energy threshold, no chance for EVis." << std::flush; #endif return; } if (((VisThresholds[fp->PDG()].ThresholdType == ThresholdAccepter::kKE) && (VisThresholds[fp->PDG()].ThresholdVal < fp->KE())) // Above KE-style threshold || ((VisThresholds[fp->PDG()].ThresholdType == ThresholdAccepter::kMomentum) && (VisThresholds[fp->PDG()].ThresholdVal < fp->P3().Mag())) // Above mom-style threshold ) { #ifdef DEBUG_THRESACCEPT std::cout << " -- Contributed to VisE. (" << GetKineTypeName(VisThresholds[fp->PDG()].ThresholdType) << ": " << VisThresholds[fp->PDG()].ThresholdVal << ")" << std::flush; #endif ri->RecVisibleEnergy.push_back( VisThresholds[fp->PDG()].Fraction * (VisThresholds[fp->PDG()].UseKE ? fp->KE() : fp->E())); ri->TrueContribPDGs.push_back(fp->PDG()); return; } else { #ifdef DEBUG_THRESACCEPT std::cout << " -- Rejected. " << " Vis: (" << GetKineTypeName(VisThresholds[fp->PDG()].ThresholdType) << ": " << VisThresholds[fp->PDG()].ThresholdVal << ")" << std::flush; #endif } } RecoInfo *ThresholdAccepter::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); SmearceptOneParticle(ri, fp #ifdef DEBUG_THRESACCEPT , p_it #endif ); } #ifdef DEBUG_THRESACCEPT std::cout << std::endl; #endif return ri; } diff --git a/src/Statistical/StatUtils.cxx b/src/Statistical/StatUtils.cxx index 2648470..1af6e2e 100644 --- a/src/Statistical/StatUtils.cxx +++ b/src/Statistical/StatUtils.cxx @@ -1,1303 +1,1303 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "TH1D.h" #include "StatUtils.h" #include "NuisConfig.h" #include "GeneralUtils.h" //******************************************************************* Double_t StatUtils::GetChi2FromDiag(TH1D* data, TH1D* mc, TH1I* mask) { //******************************************************************* Double_t Chi2 = 0.0; TH1D* calc_data = (TH1D*)data->Clone(); TH1D* calc_mc = (TH1D*)mc->Clone(); // Add MC Error to data if required - if (FitPar::Config().GetParB("statutils.addmcerror")) { + 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); } // Iterate over bins in X for (int i = 0; i < calc_data->GetNbinsX(); i++) { // Ignore bins with zero data or zero bin error if (calc_data->GetBinError(i + 1) <= 0.0 || calc_data->GetBinContent(i + 1) == 0.0) continue; // Take mc data difference double diff = calc_data->GetBinContent(i + 1) - calc_mc->GetBinContent(i + 1); double err = calc_data->GetBinError(i + 1); Chi2 += (diff * diff) / (err * err); } // cleanup delete calc_data; delete calc_mc; return Chi2; }; //******************************************************************* Double_t StatUtils::GetChi2FromDiag(TH2D* data, TH2D* mc, TH2I* map, TH2I* mask) { //******************************************************************* // Generate a simple map if (!map) map = GenerateMap(data); // Convert to 1D Histograms TH1D* data_1D = MapToTH1D(data, map); TH1D* mc_1D = MapToTH1D(mc, map); TH1I* mask_1D = MapToMask(mask, map); // Calculate 1D chi2 from 1D Plots Double_t Chi2 = StatUtils:: GetChi2FromDiag(data_1D, mc_1D, mask_1D); // CleanUp delete data_1D; delete mc_1D; delete mask_1D; return Chi2; }; //******************************************************************* Double_t StatUtils::GetChi2FromCov(TH1D* data, TH1D* mc, TMatrixDSym* invcov, TH1I* mask, double data_scale, double covar_scale) { //******************************************************************* Double_t Chi2 = 0.0; TMatrixDSym* calc_cov = (TMatrixDSym*) invcov->Clone(); TH1D* calc_data = (TH1D*) data->Clone(); TH1D* calc_mc = (TH1D*) mc->Clone(); // If a mask if applied we need to apply it before the matrix is inverted if (mask) { calc_cov = ApplyInvertedMatrixMasking(invcov, mask); calc_data = ApplyHistogramMasking(data, mask); calc_mc = ApplyHistogramMasking(mc, mask); } // Add MC Error to data if required - if (FitPar::Config().GetParB("statutils.addmcerror")) { + if (FitPar::Config().GetParB("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; (*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_cov) *= covar_scale; // iterate over bins in X (i,j) for (int i = 0; i < calc_data->GetNbinsX(); i++) { for (int j = 0; j < calc_data->GetNbinsX(); j++) { if (calc_data->GetBinContent(i + 1) != 0 || calc_mc->GetBinContent(i + 1) != 0) { LOG(DEB) << "i j = " << i << " " << j << std::endl; LOG(DEB) << "Calc_data mc i = " << calc_data->GetBinContent(i + 1) << " " << calc_mc->GetBinContent(i + 1) << " Dif = " << ( calc_data->GetBinContent(i + 1) - calc_mc->GetBinContent(i + 1) ) << std::endl; LOG(DEB) << "Calc_data mc i = " << calc_data->GetBinContent(j + 1) << " " << calc_mc->GetBinContent(j + 1) << " Dif = " << ( calc_data->GetBinContent(j + 1) - calc_mc->GetBinContent(j + 1) ) << std::endl; LOG(DEB) << "Covar = " << (*calc_cov)(i, j) << std::endl; LOG(DEB) << "Cont chi2 = " \ << ( ( calc_data->GetBinContent(i + 1) - calc_mc->GetBinContent(i + 1) ) \ * (*calc_cov)(i, j) \ * ( calc_data->GetBinContent(j + 1) - calc_mc->GetBinContent(j + 1))) << " " << Chi2 << std::endl; Chi2 += ( ( calc_data->GetBinContent(i + 1) - calc_mc->GetBinContent(i + 1) ) \ * (*calc_cov)(i, j) \ * ( calc_data->GetBinContent(j + 1) - calc_mc->GetBinContent(j + 1) ) ); } else { LOG(DEB) << "Error on bin (i,j) = (" << i << "," << j << ")" << std::endl; LOG(DEB) << "data->GetBinContent(i+1) = " << calc_data->GetBinContent(i + 1) << std::endl; LOG(DEB) << "mc->GetBinContent(i+1) = " << calc_mc->GetBinContent(i + 1) << std::endl; LOG(DEB) << "Adding zero to chi2 instead of dying horrifically " << std::endl; Chi2 += 0.; } } } // Cleanup delete calc_cov; delete calc_data; delete calc_mc; return Chi2; } //******************************************************************* Double_t StatUtils::GetChi2FromCov( TH2D* data, TH2D* mc, TMatrixDSym* invcov, TH2I* map, TH2I* mask) { //******************************************************************* // Generate a simple map if (!map) { map = StatUtils::GenerateMap(data); } // Convert to 1D Histograms TH1D* data_1D = MapToTH1D(data, map); TH1D* mc_1D = MapToTH1D(mc, map); TH1I* mask_1D = MapToMask(mask, map); // Calculate 1D chi2 from 1D Plots Double_t Chi2 = StatUtils::GetChi2FromCov(data_1D, mc_1D, invcov, mask_1D); // CleanUp delete data_1D; delete mc_1D; delete mask_1D; return Chi2; } //******************************************************************* Double_t StatUtils::GetChi2FromSVD( TH1D* data, TH1D* mc, TMatrixDSym* cov, TH1I* mask) { //******************************************************************* Double_t Chi2 = 0.0; TMatrixDSym* calc_cov = (TMatrixDSym*) cov->Clone(); TH1D* calc_data = (TH1D*) data->Clone(); TH1D* calc_mc = (TH1D*) mc->Clone(); // If a mask if applied we need to apply it before the matrix is inverted if (mask) { calc_cov = StatUtils::ApplyMatrixMasking(cov, mask); calc_data = StatUtils::ApplyHistogramMasking(data, mask); calc_mc = StatUtils::ApplyHistogramMasking(mc, mask); } // Decompose matrix TDecompSVD LU = TDecompSVD((*calc_cov)); LU.Decompose(); TMatrixDSym* cov_U = new TMatrixDSym(calc_data->GetNbinsX(), LU .GetU().GetMatrixArray(), ""); TVectorD* cov_S = new TVectorD( LU.GetSig() ); // Apply basis rotation before adding up chi2 Double_t rotated_difference = 0.0; for (int i = 0; i < calc_data->GetNbinsX(); i++) { rotated_difference = 0.0; // Rotate basis of Data - MC for (int j = 0; j < calc_data->GetNbinsY(); j++) rotated_difference += ( calc_data->GetBinContent(j + 1) - calc_mc ->GetBinContent(j + 1) ) * (*cov_U)(j, i) ; // Divide by rotated error cov_S Chi2 += rotated_difference * rotated_difference * 1E76 / (*cov_S)(i); } // Cleanup delete calc_cov; delete calc_data; delete calc_mc; delete cov_U; delete cov_S; return Chi2; } //******************************************************************* Double_t StatUtils::GetChi2FromSVD( TH2D* data, TH2D* mc, TMatrixDSym* cov, TH2I* map, TH2I* mask) { //******************************************************************* // Generate a simple map if (!map) map = StatUtils::GenerateMap(data); // Convert to 1D Histograms TH1D* data_1D = MapToTH1D(data, map); TH1D* mc_1D = MapToTH1D(mc, map); TH1I* mask_1D = MapToMask(mask, map); // Calculate from 1D Double_t Chi2 = StatUtils::GetChi2FromSVD(data_1D, mc_1D, cov, mask_1D); // CleanUp delete data_1D; delete mc_1D; delete mask_1D; return Chi2; } //******************************************************************* double StatUtils::GetChi2FromEventRate(TH1D* data, TH1D* mc, TH1I* mask) { //******************************************************************* // If just an event rate, for chi2 just use Poission Likelihood to calculate the chi2 component double chi2 = 0.0; TH1D* calc_data = (TH1D*)data->Clone(); TH1D* calc_mc = (TH1D*)mc->Clone(); // Apply masking if required if (mask) { calc_data = ApplyHistogramMasking(data, mask); calc_mc = ApplyHistogramMasking(mc, mask); } // Iterate over bins in X for (int i = 0; i < calc_data->GetNbinsX(); i++) { double dt = calc_data->GetBinContent(i + 1); double mc = calc_mc->GetBinContent(i + 1); if (mc <= 0) continue; if (dt <= 0) { // Only add difference chi2 += 2 * (mc - dt); } else { // Do the chi2 for Poisson distributions chi2 += 2 * (mc - dt + (dt * log(dt / mc))); } /* LOG(REC)<<"Evt Chi2 cont = "<Clone(); // If a mask is provided we need to apply it before getting NDOF if (mask) { calc_hist = StatUtils::ApplyHistogramMasking(hist, mask); } // NDOF is defined as total number of bins with non-zero errors Int_t NDOF = 0; for (int i = 0; i < calc_hist->GetNbinsX(); i++) { if (calc_hist->GetBinError(i + 1) > 0.0) NDOF++; } delete calc_hist; return NDOF; }; //******************************************************************* Int_t StatUtils::GetNDOF(TH2D* hist, TH2I* map, TH2I* mask) { //******************************************************************* Int_t NDOF = 0; if (!map) map = StatUtils::GenerateMap(hist); for (int i = 0; i < hist->GetNbinsX(); i++) { for (int j = 0; j < hist->GetNbinsY(); j++) { if (mask->GetBinContent(i + 1, j + 1)) continue; if (map->GetBinContent(i + 1, j + 1) <= 0) continue; NDOF++; } } return NDOF; }; //******************************************************************* TH1D* StatUtils::ThrowHistogram(TH1D* hist, TMatrixDSym* cov, bool throwdiag, TH1I* mask) { //******************************************************************* TH1D* calc_hist = (TH1D*) hist->Clone( (std::string(hist->GetName()) + "_THROW" ).c_str() ); TMatrixDSym* calc_cov = (TMatrixDSym*) cov->Clone(); Double_t correl_val = 0.0; // If a mask if applied we need to apply it before the matrix is decomposed if (mask) { calc_cov = ApplyMatrixMasking(cov, mask); calc_hist = ApplyHistogramMasking(calc_hist, mask); } // If a covariance is provided we need a preset random vector and a decomp std::vector rand_val; TMatrixDSym* decomp_cov; if (cov) { for (int i = 0; i < hist->GetNbinsX(); i++) { rand_val.push_back(gRandom->Gaus(0.0, 1.0)); } // Decomp the matrix decomp_cov = StatUtils::GetDecomp(calc_cov); } // iterate over bins for (int i = 0; i < hist->GetNbinsX(); i++) { // By Default the errors on the histogram are thrown uncorrelated to the other errors // if (throwdiag) { // calc_hist->SetBinContent(i + 1, (calc_hist->GetBinContent(i + 1) + \ // gRandom->Gaus(0.0, 1.0) * calc_hist->GetBinError(i + 1)) ); // } // If a covariance is provided that is also thrown if (cov) { correl_val = 0.0; for (int j = 0; j < hist->GetNbinsX(); j++) { correl_val += rand_val[j] * (*decomp_cov)(j, i) ; } calc_hist->SetBinContent(i + 1, (calc_hist->GetBinContent(i + 1) + correl_val * 1E-38)); } } delete calc_cov; delete decomp_cov; // return this new thrown data return calc_hist; }; //******************************************************************* TH2D* StatUtils::ThrowHistogram(TH2D* hist, TMatrixDSym* cov, TH2I* map, bool throwdiag, TH2I* mask) { //******************************************************************* // PLACEHOLDER!!!!!!!!! // Currently no support for throwing 2D Histograms from a covariance (void) hist; (void) cov; (void) map; (void) throwdiag; (void) mask; // /todo // Sort maps if required // Throw the covariance for a 1D plot // Unmap back to 2D Histogram return hist; } //******************************************************************* TH1D* StatUtils::ApplyHistogramMasking(TH1D* hist, TH1I* mask) { //******************************************************************* if (!mask) return ( (TH1D*)hist->Clone() ); // This masking is only sufficient for chi2 calculations, and will have dodgy bin edges. // Get New Bin Count Int_t NBins = 0; for (int i = 0; i < hist->GetNbinsX(); i++) { if (mask->GetBinContent(i + 1)) continue; NBins++; } // Make new hist std::string newmaskname = std::string(hist->GetName()) + "_MSKD"; TH1D* calc_hist = new TH1D( newmaskname.c_str(), newmaskname.c_str(), NBins, 0, NBins); // fill new hist int binindex = 0; for (int i = 0; i < hist->GetNbinsX(); i++) { if (mask->GetBinContent(i + 1)) { LOG(REC) << "Applying mask to bin " << i + 1 << " " << hist->GetName() << std::endl; continue; } calc_hist->SetBinContent(binindex + 1, hist->GetBinContent(i + 1)); calc_hist->SetBinError(binindex + 1, hist->GetBinError(i + 1)); binindex++; } return calc_hist; }; //******************************************************************* TH2D* StatUtils::ApplyHistogramMasking(TH2D* hist, TH2I* mask) { //******************************************************************* TH2D* newhist = (TH2D*) hist->Clone(); if (!mask) return newhist; for (int i = 0; i < hist->GetNbinsX(); i++) { for (int j = 0; j < hist->GetNbinsY(); j++) { if (mask->GetBinContent(i + 1, j + 1) > 0) { newhist->SetBinContent(i + 1, j + 1, 0.0); newhist->SetBinContent(i + 1, j + 1, 0.0); } } } return newhist; } //******************************************************************* TMatrixDSym* StatUtils::ApplyMatrixMasking(TMatrixDSym* mat, TH1I* mask) { //******************************************************************* if (!mask) return (TMatrixDSym*)(mat->Clone()); // Get New Bin Count Int_t NBins = 0; for (int i = 0; i < mask->GetNbinsX(); i++) { if (mask->GetBinContent(i + 1)) continue; NBins++; } // make new matrix TMatrixDSym* calc_mat = new TMatrixDSym(NBins); int col, row; // Need to mask out bins in the current matrix row = 0; for (int i = 0; i < mask->GetNbinsX(); i++) { col = 0; // skip if masked if (mask->GetBinContent(i + 1) > 0.5) continue; for (int j = 0; j < mask->GetNbinsX(); j++) { // skip if masked if (mask->GetBinContent(j + 1) > 0.5) continue; (*calc_mat)(row, col) = (*mat)(i, j); col++; } row++; } return calc_mat; }; //******************************************************************* TMatrixDSym* StatUtils::ApplyMatrixMasking(TMatrixDSym* mat, TH2D* data, TH2I* mask, TH2I* map) { //******************************************************************* if (!map) map = StatUtils::GenerateMap(data); TH1I* mask_1D = StatUtils::MapToMask(mask, map); TMatrixDSym* newmat = StatUtils::ApplyMatrixMasking(mat, mask_1D); delete mask_1D; return newmat; } //******************************************************************* TMatrixDSym* StatUtils::ApplyInvertedMatrixMasking(TMatrixDSym* mat, TH1I* mask) { //******************************************************************* TMatrixDSym* new_mat = GetInvert(mat); TMatrixDSym* masked_mat = ApplyMatrixMasking(new_mat, mask); TMatrixDSym* inverted_mat = GetInvert(masked_mat); delete masked_mat; delete new_mat; return inverted_mat; }; //******************************************************************* TMatrixDSym* StatUtils::ApplyInvertedMatrixMasking(TMatrixDSym* mat, TH2D* data, TH2I* mask, TH2I* map) { //******************************************************************* if (!map) map = StatUtils::GenerateMap(data); TH1I* mask_1D = StatUtils::MapToMask(mask, map); TMatrixDSym* newmat = ApplyInvertedMatrixMasking(mat, mask_1D); delete mask_1D; return newmat; } //******************************************************************* TMatrixDSym* StatUtils::GetInvert(TMatrixDSym* mat) { //******************************************************************* TMatrixDSym* new_mat = (TMatrixDSym*)mat->Clone(); // Check for diagonal bool non_diagonal = false; for (int i = 0; i < new_mat->GetNrows(); i++) { for (int j = 0; j < new_mat->GetNrows(); j++) { if (i == j) continue; if ((*new_mat)(i, j) != 0.0) { non_diagonal = true; break; } } } // If diag, just flip the diag if (!non_diagonal or new_mat->GetNrows() == 1) { for (int i = 0; i < new_mat->GetNrows(); i++) { if ((*new_mat)(i, i) != 0.0) (*new_mat)(i, i) = 1.0 / (*new_mat)(i, i); else (*new_mat)(i, i) = 0.0; } return new_mat; } // Invert full matrix TDecompSVD LU = TDecompSVD((*new_mat)); new_mat = new TMatrixDSym(new_mat->GetNrows(), LU.Invert().GetMatrixArray(), ""); return new_mat; } //******************************************************************* TMatrixDSym* StatUtils::GetDecomp(TMatrixDSym* mat) { //******************************************************************* TMatrixDSym* new_mat = (TMatrixDSym*)mat->Clone(); int nrows = new_mat->GetNrows(); // Check for diagonal bool diagonal = true; for (int i = 0; i < nrows; i++) { for (int j = 0; j < nrows; j++) { if (i == j) continue; if ((*new_mat)(i, j) != 0.0) { diagonal = false; break; } } } // If diag, just flip the diag if (diagonal or nrows == 1) { for (int i = 0; i < nrows; i++) { if ((*new_mat)(i, i) > 0.0) (*new_mat)(i, i) = sqrt((*new_mat)(i, i)); else (*new_mat)(i, i) = 0.0; } return new_mat; } TDecompChol LU = TDecompChol(*new_mat); LU.Decompose(); delete new_mat; TMatrixDSym* dec_mat = new TMatrixDSym(nrows, LU.GetU().GetMatrixArray(), ""); return dec_mat; } //******************************************************************* void StatUtils::ForceNormIntoCovar(TMatrixDSym* mat, TH1D* hist, double norm) { //******************************************************************* if (!mat) mat = MakeDiagonalCovarMatrix(hist); int nbins = mat->GetNrows(); TMatrixDSym* new_mat = new TMatrixDSym(nbins); for (int i = 0; i < nbins; i++) { for (int j = 0; j < nbins; j++) { double valx = hist->GetBinContent(i + 1) * 1E38; double valy = hist->GetBinContent(j + 1) * 1E38; (*new_mat)(i, j) = (*mat)(i, j) + norm * norm * valx * valy; } } // Swap the two delete mat; mat = new_mat; return; }; //******************************************************************* void StatUtils::ForceNormIntoCovar(TMatrixDSym* mat, TH2D* data, double norm, TH2I* map ) { //******************************************************************* if (!map) map = StatUtils::GenerateMap(data); TH1D* data_1D = MapToTH1D(data, map); StatUtils::ForceNormIntoCovar(mat, data_1D, norm); delete data_1D; return; } //******************************************************************* TMatrixDSym* StatUtils::MakeDiagonalCovarMatrix(TH1D* data, double scaleF) { //******************************************************************* TMatrixDSym* newmat = new TMatrixDSym(data->GetNbinsX()); for (int i = 0; i < data->GetNbinsX(); i++) { (*newmat)(i, i) = data->GetBinError(i + 1) * data->GetBinError(i + 1) * scaleF * scaleF; } return newmat; } //******************************************************************* TMatrixDSym* StatUtils::MakeDiagonalCovarMatrix(TH2D* data, TH2I* map, double scaleF) { //******************************************************************* if (!map) map = StatUtils::GenerateMap(data); TH1D* data_1D = MapToTH1D(data, map); return StatUtils::MakeDiagonalCovarMatrix(data_1D, scaleF); }; //******************************************************************* void StatUtils::SetDataErrorFromCov(TH1D* data, TMatrixDSym* cov, double scale) { //******************************************************************* // Check if (cov->GetNrows() != data->GetNbinsX()) { ERR(WRN) << "Nrows in cov don't match nbins in data for SetDataErrorFromCov" << std::endl; } // Set bin errors form cov diag for (int i = 0; i < data->GetNbinsX(); i++) { data->SetBinError(i + 1, sqrt((*cov)(i, i)) * scale ); } return; } //******************************************************************* void StatUtils::SetDataErrorFromCov(TH2D* data, TMatrixDSym* cov, TH2I* map, double scale) { //******************************************************************* // Create map if required if (!map) map = StatUtils::GenerateMap(data); // Set Bin Errors from cov diag int count = 0; for (int i = 0; i < data->GetNbinsX(); i++) { for (int j = 0; j < data->GetNbinsY(); j++) { if (data->GetBinContent(i + 1, j + 1) == 0.0) continue; count = map->GetBinContent(i + 1, j + 1) - 1; data->SetBinError(i + 1, j + 1, sqrt((*cov)(count, count)) * scale ); } } return; } TMatrixDSym* StatUtils::ExtractShapeOnlyCovar(TMatrixDSym* full_covar, TH1* data_hist, double data_scale){ int nbins = full_covar->GetNrows(); TMatrixDSym* shape_covar = new TMatrixDSym(nbins); // Check nobody is being silly if (data_hist->GetNbinsX() != nbins){ ERR(WRN) << "Inconsistent matrix and data histogram passed to StatUtils::ExtractShapeOnlyCovar!" << std::endl; ERR(WRN) << "data_hist has " << data_hist->GetNbinsX() << " matrix has " << nbins << std::endl; int err_bins = data_hist->GetNbinsX(); if (nbins > err_bins) err_bins = nbins; for (int i = 0; i < err_bins; ++i){ ERR(WRN) << "Matrix diag. = " << (*full_covar)(i, i) << " data = " << data_hist->GetBinContent(i+1) << std::endl; } return NULL; } double total_data = 0; double total_covar = 0; // Initial loop to calculate some constants for (int i = 0; i < nbins; ++i) { total_data += data_hist->GetBinContent(i+1)*data_scale; for (int j = 0; j < nbins; ++j) { total_covar += (*full_covar)(i,j); } } if (total_data == 0 || total_covar == 0){ ERR(WRN) << "Stupid matrix or data histogram passed to StatUtils::ExtractShapeOnlyCovar! Ignoring..." << std::endl; return NULL; } LOG(SAM) << "Norm error = " << sqrt(total_covar)/total_data << std::endl; // Now loop over and calculate the shape-only matrix for (int i = 0; i < nbins; ++i) { double data_i = data_hist->GetBinContent(i+1)*data_scale; for (int j = 0; j < nbins; ++j) { double data_j = data_hist->GetBinContent(j+1)*data_scale; double norm_term = data_i*data_j*total_covar/total_data/total_data; double mix_sum1 = 0; double mix_sum2 = 0; for (int k = 0; k < nbins; ++k){ mix_sum1 += (*full_covar)(k,j); mix_sum2 += (*full_covar)(i,k); } double mix_term1 = data_i*(mix_sum1/total_data - total_covar*data_j/total_data/total_data); double mix_term2 = data_j*(mix_sum2/total_data - total_covar*data_i/total_data/total_data); (*shape_covar)(i, j) = (*full_covar)(i, j) - mix_term1 - mix_term2 - norm_term; } } return shape_covar; } //******************************************************************* TH2I* StatUtils::GenerateMap(TH2D* hist) { //******************************************************************* std::string maptitle = std::string(hist->GetName()) + "_MAP"; TH2I* map = new TH2I( maptitle.c_str(), maptitle.c_str(), hist->GetNbinsX(), 0, hist->GetNbinsX(), hist->GetNbinsY(), 0, hist->GetNbinsY()); Int_t index = 1; for (int i = 0; i < hist->GetNbinsX(); i++) { for (int j = 0; j < hist->GetNbinsY(); j++) { if (hist->GetBinContent(i + 1, j + 1) > 0 && hist->GetBinError(i + 1, j + 1) > 0) { map->SetBinContent(i + 1, j + 1, index); index++; } else { map->SetBinContent(i + 1, j + 1, 0); } } } return map; } //******************************************************************* TH1D* StatUtils::MapToTH1D(TH2D* hist, TH2I* map) { //******************************************************************* if (!hist) return NULL; // Get N bins for 1D plot Int_t Nbins = map->GetMaximum(); std::string name1D = std::string(hist->GetName()) + "_1D"; // Make new 1D Hist TH1D* newhist = new TH1D(name1D.c_str(), name1D.c_str(), Nbins, 0, Nbins); // map bin contents for (int i = 0; i < map->GetNbinsX(); i++) { for (int j = 0; j < map->GetNbinsY(); j++) { if (map->GetBinContent(i + 1, j + 1) == 0) continue; newhist->SetBinContent(map->GetBinContent(i + 1, j + 1), hist->GetBinContent(i + 1, j + 1)); newhist->SetBinError(map->GetBinContent(i + 1, j + 1), hist->GetBinError(i + 1, j + 1)); } } // return return newhist; } //******************************************************************* TH1I* StatUtils::MapToMask(TH2I* hist, TH2I* map) { //******************************************************************* TH1I* newhist = NULL; if (!hist) return newhist; // Get N bins for 1D plot Int_t Nbins = map->GetMaximum(); std::string name1D = std::string(hist->GetName()) + "_1D"; // Make new 1D Hist newhist = new TH1I(name1D.c_str(), name1D.c_str(), Nbins, 0, Nbins); // map bin contents for (int i = 0; i < map->GetNbinsX(); i++) { for (int j = 0; j < map->GetNbinsY(); j++) { if (map->GetBinContent(i + 1, j + 1) == 0) continue; newhist->SetBinContent(map->GetBinContent(i + 1, j + 1), hist->GetBinContent(i + 1, j + 1)); } } // return return newhist; } TMatrixDSym* StatUtils::GetCovarFromCorrel(TMatrixDSym* correl, TH1D* data) { int nbins = correl->GetNrows(); TMatrixDSym* covar = new TMatrixDSym(nbins); for (int i = 0; i < nbins; i++) { for (int j = 0; j < nbins; j++) { (*covar)(i, j) = (*correl)(i, j) * data->GetBinError(i + 1) * data->GetBinError(j + 1); } } return covar; } //******************************************************************* TMatrixD* StatUtils::GetMatrixFromTextFile(std::string covfile, int dimx, int dimy) { //******************************************************************* // Determine dim if (dimx == -1 and dimy == -1) { std::string line; std::ifstream covar(covfile.c_str(), std::ifstream::in); int row = 0; while (std::getline(covar >> std::ws, line, '\n')) { int column = 0; std::vector entries = GeneralUtils::ParseToDbl(line, " "); if (entries.size() <= 1) { ERR(WRN) << "StatUtils::GetMatrixFromTextFile, matrix only has <= 1 " "entries on this line: " << row << std::endl; } for (std::vector::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 entries = GeneralUtils::ParseToDbl(line, " "); if (entries.size() <= 1) { ERR(WRN) << "StatUtils::GetMatrixFromTextFile, matrix only has <= 1 " "entries on this line: " << row << std::endl; } for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { // Check Rows //assert(row > mat->GetNrows() && " covar rows doesn't match matrix rows."); //assert(column > mat->GetNcols() && " covar cols doesn't match matrix cols."); // Fill Matrix (*mat)(row, column) = (*iter); column++; } row++; } return mat; } //******************************************************************* TMatrixD* StatUtils::GetMatrixFromRootFile(std::string covfile, std::string histname) { //******************************************************************* std::string inputfile = covfile + ";" + histname; std::vector 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(obj); if (mat) { TMatrixD* newmat = (TMatrixD*)mat->Clone(); delete mat; tempfile->Close(); return newmat; } TMatrixDSym* matsym = dynamic_cast(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(obj); if (mathist) { TMatrixD* newmat = new TMatrixD(mathist->GetNbinsX(), mathist->GetNbinsX()); for (int i = 0; i < mathist->GetNbinsX(); i++) { for (int j = 0; j < mathist->GetNbinsX(); j++) { (*newmat)(i, j) = mathist->GetBinContent(i + 1, j + 1); } } delete mathist; tempfile->Close(); return newmat; } return NULL; } //******************************************************************* TMatrixDSym* StatUtils::GetCovarFromTextFile(std::string covfile, int dim){ //******************************************************************* // Delete TempMat TMatrixD* tempmat = GetMatrixFromTextFile(covfile, dim, dim); // Make a symmetric covariance TMatrixDSym* newmat = new TMatrixDSym(tempmat->GetNrows()); for (int i = 0; i < tempmat->GetNrows(); i++){ for (int j = 0; j < tempmat->GetNrows(); j++){ (*newmat)(i,j) = (*tempmat)(i,j); } } delete tempmat; return newmat; } //******************************************************************* TMatrixDSym* StatUtils::GetCovarFromRootFile(std::string covfile, std::string histname){ //******************************************************************* TMatrixD* tempmat = GetMatrixFromRootFile(covfile, histname); TMatrixDSym* newmat = new TMatrixDSym(tempmat->GetNrows()); for (int i = 0; i < tempmat->GetNrows(); i++){ for (int j = 0; j < tempmat->GetNrows(); j++){ (*newmat)(i,j) = (*tempmat)(i,j); } } delete tempmat; return newmat; } diff --git a/src/T2K/T2K_CC0pi_XSec_2DPcos_nu_nonuniform.h b/src/T2K/T2K_CC0pi_XSec_2DPcos_nu_nonuniform.h index e3b2d00..fa0b8c9 100644 --- a/src/T2K/T2K_CC0pi_XSec_2DPcos_nu_nonuniform.h +++ b/src/T2K/T2K_CC0pi_XSec_2DPcos_nu_nonuniform.h @@ -1,82 +1,86 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #ifndef T2K_CC0PI_2DPCOS_NU_NONUNIFORM_H_SEEN #define T2K_CC0PI_2DPCOS_NU_NONUNIFORM_H_SEEN #include "Measurement1D.h" #include "TH2Poly.h" +#include "MeasurementVariableBox2D.h" class T2K_CC0pi_XSec_2DPcos_nu_nonuniform : public Measurement1D { public: /// Basic Constructor. /// /brief Parses two different measurements. /// /// T2K_CC0pi_XSec_2DPcos_nu_nonuniform -> T2K CC0PI Analysis 2 /// T2K_CC0pi_XSec_2DPcos_nu_nonuniform_I -> T2K CC0PI Analysis 1 /// T2K_CC0pi_XSec_2DPcos_nu_nonuniform_II -> T2K CC0PI Analysis 2 T2K_CC0pi_XSec_2DPcos_nu_nonuniform(nuiskey samplekey); /// Virtual Destructor ~T2K_CC0pi_XSec_2DPcos_nu_nonuniform() {}; /// Numu CC0PI Signal Definition /// /// /item bool isSignal(FitEvent *nvect); /// Read histograms in a special way because format is different. /// Read from FitPar::GetDataBase()+"/T2K/CC0pi/T2K_CC0PI_2DPmuCosmu_Data.root" void SetHistograms(); /// Bin Tmu CosThetaMu void FillEventVariables(FitEvent* customEvent); // Fill Histograms void FillHistograms(); /// Have to do a weird event scaling for analysis 1 void ConvertEventRates(); + /// \brief Create Q2 Box to save correction info + inline MeasurementVariableBox* CreateBox(){ return new MeasurementVariableBox2D(); }; + private: bool forwardgoing; bool only_allowed_particles; bool numu_event; double numu_energy; int particle_pdg; double pmu, CosThetaMu; int fAnalysis; bool fIsSystCov, fIsStatCov, fIsNormCov; TH2Poly* fDataPoly; TH2Poly* fMCPoly; TFile* fInputFile; TH2D* fMCHist_Fine2D; std::vector fMCHist_Slices; std::vector fDataHist_Slices; void FillMCSlice(double x, double y, double w); }; #endif