diff --git a/CMakeLists.txt b/CMakeLists.txt index f7bf32c..e198417 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,190 +1,196 @@ # 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 + 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}) install(PROGRAMS "${PROJECT_SOURCE_DIR}/scripts/nuiscardgen" DESTINATION bin) install(PROGRAMS "${PROJECT_SOURCE_DIR}/scripts/nuissamples" DESTINATION bin) diff --git a/VERSION b/VERSION index f3677eb..8f6d685 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -Fitter Version Tag: v2r7 \ No newline at end of file +Fitter Version Tag: v2r8 \ No newline at end of file diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index c260ba6..1d488e3 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -1,192 +1,217 @@ # 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 . ################################################################################ set(TARGETS_TO_BUILD) if(USE_MINIMIZER) add_executable(nuismin nuismin.cxx) set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuismin) target_link_libraries(nuismin ${MODULETargets}) target_link_libraries(nuismin ${CMAKE_DEPENDLIB_FLAGS}) # target_link_libraries(nuismin ${ROOT_LIBS}) if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "") set_target_properties(nuismin PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS}) endif() add_executable(nuissplines nuissplines.cxx) set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuissplines) target_link_libraries(nuissplines ${MODULETargets}) target_link_libraries(nuissplines ${CMAKE_DEPENDLIB_FLAGS}) # target_link_libraries(nuissplines ${ROOT_LIBS}) if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "") set_target_properties(nuissplines PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS}) endif() endif() include_directories(${RWENGINE_INCLUDE_DIRECTORIES}) include_directories(${CMAKE_SOURCE_DIR}/src/Routines) include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler) include_directories(${CMAKE_SOURCE_DIR}/src/Genie) include_directories(${CMAKE_SOURCE_DIR}/src/FitBase) +include_directories(${CMAKE_SOURCE_DIR}/src/Statistical) include_directories(${CMAKE_SOURCE_DIR}/src/Utils) +include_directories(${CMAKE_SOURCE_DIR}/src/Config) +include_directories(${CMAKE_SOURCE_DIR}/src/Logger) include_directories(${CMAKE_SOURCE_DIR}/src/Splines) include_directories(${CMAKE_SOURCE_DIR}/src/Reweight) include_directories(${CMAKE_SOURCE_DIR}/src/FCN) include_directories(${CMAKE_SOURCE_DIR}/src/MCStudies) include_directories(${CMAKE_SOURCE_DIR}/src/Smearceptance) include_directories(${EXP_INCLUDE_DIRECTORIES}) if (USE_NuWro AND NOT NUWRO_BUILT_FROM_FILE) add_executable(nuwro_nuisance nuwro_NUISANCE.cxx) set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuwro_nuisance) target_link_libraries(nuwro_nuisance ${MODULETargets}) target_link_libraries(nuwro_nuisance ${CMAKE_DEPENDLIB_FLAGS}) # target_link_libraries(nuwro_nuisance ${ROOT_LIBS}) include_directories(${CMAKE_SOURCE_DIR}/src/FitBase) if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "") set_target_properties(nuwro_nuisance PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS}) endif() endif() if (USE_NEUT) add_executable(neut_nuisance neut_NUISANCE.cxx) set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};neut_nuisance) target_link_libraries(neut_nuisance ${MODULETargets}) target_link_libraries(neut_nuisance ${CMAKE_DEPENDLIB_FLAGS}) target_link_libraries(neut_nuisance ${ROOT_LIBS}) include_directories(${CMAKE_SOURCE_DIR}/src/FitBase) if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "") set_target_properties(neut_nuisance PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS}) endif() endif() if (BUILD_GEVGEN) add_executable(gevgen_nuisance gEvGen_NUISANCE.cxx) set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};gevgen_nuisance) target_link_libraries(gevgen_nuisance ${MODULETargets}) target_link_libraries(gevgen_nuisance ${CMAKE_DEPENDLIB_FLAGS}) # target_link_libraries(gevgen_nuisance ${ROOT_LIBS}) include_directories(${CMAKE_SOURCE_DIR}/src/FitBase) include_directories(${GENIE_INCLUDES}/Apps) include_directories(${GENIE_INCLUDES}/FluxDrivers) include_directories(${GENIE_INCLUDES}/EVGDrivers) if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "") set_target_properties(gevgen_nuisance PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS}) endif() add_executable(gevgen_nuisance_mixed gEvGen_NUISANCE_MIXED.cxx) set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};gevgen_nuisance_mixed) target_link_libraries(gevgen_nuisance_mixed ${MODULETargets}) target_link_libraries(gevgen_nuisance_mixed ${CMAKE_DEPENDLIB_FLAGS}) # target_link_libraries(gevgen_nuisance_mixed ${ROOT_LIBS}) include_directories(${CMAKE_SOURCE_DIR}/src/FitBase) include_directories(${GENIE_INCLUDES}/Apps) include_directories(${GENIE_INCLUDES}/FluxDrivers) include_directories(${GENIE_INCLUDES}/EVGDrivers) if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "") set_target_properties(gevgen_nuisance_mixed PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS}) endif() endif() if (USE_GiBUU) add_executable(DumpGiBUUEvents DumpGiBUUEvents.cxx) set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};DumpGiBUUEvents) target_link_libraries(DumpGiBUUEvents ${MODULETargets}) target_link_libraries(DumpGiBUUEvents ${CMAKE_DEPENDLIB_FLAGS}) # target_link_libraries(DumpGiBUUEvents ${ROOT_LIBS}) include_directories(${CMAKE_SOURCE_DIR}/src/FitBase) if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "") set_target_properties(DumpGiBUUEvents PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS}) endif() endif() add_executable(nuiscomp nuiscomp.cxx) set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuiscomp) target_link_libraries(nuiscomp ${MODULETargets}) target_link_libraries(nuiscomp ${CMAKE_DEPENDLIB_FLAGS}) # target_link_libraries(nuiscomp ${ROOT_LIBS}) if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "") set_target_properties(nuiscomp PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS}) endif() add_executable(nuisflat nuisflat.cxx) set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuisflat) target_link_libraries(nuisflat ${MODULETargets}) target_link_libraries(nuisflat ${CMAKE_DEPENDLIB_FLAGS}) # target_link_libraries(nuisflat ${ROOT_LIBS}) if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "") set_target_properties(nuisflat PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS}) endif() add_executable(nuissmear nuissmear.cxx) set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuissmear) target_link_libraries(nuissmear ${MODULETargets}) target_link_libraries(nuissmear ${CMAKE_DEPENDLIB_FLAGS}) # target_link_libraries(nuissmear ${ROOT_LIBS}) if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "") set_target_properties(nuissmear PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS}) endif() add_executable(nuissyst nuissyst.cxx) set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuissyst) target_link_libraries(nuissyst ${MODULETargets}) target_link_libraries(nuissyst ${CMAKE_DEPENDLIB_FLAGS}) # target_link_libraries(nuissyst ${ROOT_LIBS}) if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "") set_target_properties(nuissyst PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS}) endif() +add_executable(nuisbayes nuisbayes.cxx) +set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuisbayes) +target_link_libraries(nuisbayes ${MODULETargets}) +target_link_libraries(nuisbayes ${CMAKE_DEPENDLIB_FLAGS}) +# target_link_libraries(nuisbayes ${ROOT_LIBS}) +if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "") + set_target_properties(nuisbayes PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS}) +endif() + if(USE_GENIE) add_executable(PrepareGENIE PrepareGENIE.cxx) set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};PrepareGENIE) target_link_libraries(PrepareGENIE ${MODULETargets}) target_link_libraries(PrepareGENIE ${CMAKE_DEPENDLIB_FLAGS}) # target_link_libraries(PrepareGENIE ${ROOT_LIBS}) if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "") set_target_properties(PrepareGENIE PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS}) endif() endif() if(USE_NEUT) add_executable(PrepareNEUT PrepareNEUT.cxx) set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};PrepareNEUT) target_link_libraries(PrepareNEUT ${MODULETargets}) target_link_libraries(PrepareNEUT ${CMAKE_DEPENDLIB_FLAGS}) # target_link_libraries(PrepareNEUT ${ROOT_LIBS}) if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "") set_target_properties(PrepareNEUT PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS}) endif() endif() # PREPARE NUWRO # Commented out for the time being until it is finished.. if(USE_NuWro) add_executable(PrepareNuwro PrepareNuwroEvents.cxx) set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};PrepareNuwro) target_link_libraries(PrepareNuwro ${MODULETargets}) target_link_libraries(PrepareNuwro ${CMAKE_DEPENDLIB_FLAGS}) # target_link_libraries(PrepareNuwro ${ROOT_LIBS}) if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "") set_target_properties(PrepareNuwro PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS}) endif() endif() install(TARGETS ${TARGETS_TO_BUILD} DESTINATION bin) + +#add_executable(DumpROOTClassesFromVector DumpROOTClassesFromVector.cxx) +# #Strip out -lNuWro_event1 +# string(REPLACE "-lNuWro_event1" "" NWEVSTRIPPED_CDF ${CMAKE_DEPENDLIB_FLAGS}) +# cmessage(DEBUG "Attempted to strip out nuwro library: \"${CMAKE_DEPENDLIB_FLAGS}\" -> \"${NWEVSTRIPPED_CDF}\"") +# add_executable(PrepareNEUT PrepareNEUT.cxx) +# target_link_libraries(DumpROOTClassesFromVector ${MODULETargets}) +# target_link_libraries(DumpROOTClassesFromVector ${NWEVSTRIPPED_CDF}) +# if(NOT CMAKE_LINK_FLAGS STREQUAL "") +# set_target_properties(DumpROOTClassesFromVector PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS}) +# endif() +#install(TARGETS DumpROOTClassesFromVector DESTINATION bin) + diff --git a/src/Utils/DumpROOTClassesFromVector.cxx b/app/DumpROOTClassesFromVector.cxx similarity index 100% rename from src/Utils/DumpROOTClassesFromVector.cxx rename to app/DumpROOTClassesFromVector.cxx diff --git a/app/PrepareNEUT.cxx b/app/PrepareNEUT.cxx index a4c31ed..3b37e40 100644 --- a/app/PrepareNEUT.cxx +++ b/app/PrepareNEUT.cxx @@ -1,237 +1,238 @@ #include #include #include "TFile.h" #include "TH1D.h" #include "TTree.h" #include "PlotUtils.h" +#include "StatUtils.h" #include "FitLogger.h" // If you don't have NEUT enabled, you shouldn't compile this... #include "neutpart.h" #include "neutvect.h" std::string fInputFiles = ""; std::string fOutputFile = ""; std::string fFluxFile = ""; bool fFluxInGeV = false; void PrintOptions(); void ParseOptions(int argc, char* argv[]); void CreateRateHistogram(std::string inputList, std::string flux, std::string output); //******************************* int main(int argc, char* argv[]){ //******************************* LOG_VERB(FitPar::Config().GetParI("VERBOSITY")); ERR_VERB(FitPar::Config().GetParI("ERROR")); ParseOptions(argc, argv); LOG(FIT) << "Running PrepareNEUT" << std::endl; CreateRateHistogram(fInputFiles, fFluxFile, fOutputFile); }; //******************************* void CreateRateHistogram(std::string inputList, std::string flux, std::string output){ //******************************* // Need to allow for more than one file... will do soon TChain* tn = new TChain("neuttree"); std::vector inputs = GeneralUtils::ParseToStr(inputList,","); for (std::vector::iterator it = inputs.begin(); it != inputs.end(); ++it){ LOG(FIT) << "Adding " << *it << " to the output" << std::endl; tn->AddFile((*it).c_str()); } if (inputs.size() > 1 && output.empty()){ ERR(FTL) << "You must provide a new output file name if you want to have more than 1 input file!" << std::endl; throw; } int nevts = tn->GetEntries(); if (!nevts){ ERR(FTL) << "Either the input file is not from NEUT, or it's empty..." <SetBranchAddress("vectorbranch", &fNeutVect); // Get Flux Hist std::vector fluxvect = GeneralUtils::ParseToStr(flux,","); TH1D* fluxHist = NULL; if (fluxvect.size() > 1){ TFile* fluxfile = new TFile(fluxvect[0].c_str(),"READ"); fluxHist = (TH1D*) fluxfile->Get(fluxvect[1].c_str()); fluxHist->SetDirectory(0); } else { ERR(FTL) << "NO FLUX SPECIFIED" << std::endl; throw; } // Decide what type of flux was given if (fFluxInGeV) LOG(FIT) << "Assuming flux histogram is in GeV" << std::endl; else LOG(FIT) << "Assuming flux histogram is in MeV" << std::endl; // Make Event Hist TH1D* xsecHist = (TH1D*)fluxHist->Clone(); xsecHist->Reset(); // Make a total cross section hist for shits and giggles TH1D* entryHist = (TH1D*) xsecHist->Clone(); for (int i = 0; i < nevts; ++i){ tn->GetEntry(i); NeutPart* part = fNeutVect->PartInfo(0); double E = part->fP.E(); double xsec = fNeutVect->Totcrs; // Unit conversion if (fFluxInGeV) E*=1E-3; xsecHist ->Fill(E, xsec); entryHist->Fill(E); if (i % (nevts/20) == 0){ LOG(FIT) << "Processed " << i << "/" << nevts << " NEUT events." << std::endl; } } LOG(FIT) << "Processed all events" << std::endl; xsecHist ->Divide(entryHist); // This will be the evtrt histogram TH1D* evtHist = NULL; // If the integral of xsecHist is 0 the input file used a really old version of NEUT without Totcrs if (!xsecHist->Integral(0, -1)){ ERR(WRN) << "Old NEUT input file: events will not be correctly normalized" << std::endl; evtHist = (TH1D*)entryHist->Clone(); if (evtHist->Integral() != 0) evtHist ->Scale(fluxHist->Integral()/float(evtHist->Integral())); } else { evtHist = (TH1D*)xsecHist->Clone(); evtHist ->Multiply(fluxHist); } // Check whether the overflow is empty. If not, advise that either the wrong flux histogram or units were used... // If the events were generated with a limited range of the flux histogram, this may be benign if (evtHist->Integral(0, -1) != evtHist->Integral() || evtHist->Integral(0, -1) == 0){ ERR(WRN) << "The input file and flux histogram provided do not match... " << std::endl; ERR(WRN) << "Are the units correct? Did you provide the correct flux file?" << std::endl; ERR(WRN) << "Use output with caution..." << std::endl; } // Pick where the output should go TFile *outFile = NULL; if (!output.empty()){ LOG(FIT) << "Saving histograms in " << output << std::endl; outFile = new TFile(output.c_str(), "RECREATE"); } else { LOG(FIT) << "Saving histograms in " << inputs[0] << std::endl; outFile = new TFile(inputs[0].c_str(), "UPDATE"); } outFile->cd(); std::string xsec_name = "xsec_PrepareNeut"; std::string flux_name = "flux_PrepareNeut"; std::string rate_name = "evtrt_PrepareNeut"; if (output.empty()){ // Check whether we should overwrite existing histograms std::string input_xsec = PlotUtils::GetObjectWithName(outFile, "xsec"); std::string input_flux = PlotUtils::GetObjectWithName(outFile, "flux"); std::string input_rate = PlotUtils::GetObjectWithName(outFile, "evtrt"); if (!input_xsec.empty()) { LOG(FIT) << "Updating histogram: " << input_xsec << std::endl; xsec_name = input_xsec; } if (!input_flux.empty()) { LOG(FIT) << "Updating histogram: " << input_flux << std::endl; flux_name = input_flux; } if (!input_rate.empty()) { LOG(FIT) << "Updating histogram: " << input_rate << std::endl; rate_name = input_rate; } } else { LOG(FIT) << "Cloning neuttree into output file." << std::endl; StopTalking(); TTree* newtree = (TTree*)tn->CloneTree(-1, "fast"); StartTalking(); newtree->Write(); } xsecHist->Write(xsec_name.c_str(), TObject::kOverwrite); fluxHist->Write(flux_name.c_str(), TObject::kOverwrite); evtHist ->Write(rate_name.c_str(), TObject::kOverwrite); outFile ->Close(); return; } void PrintOptions(){ std::cout << "PrepareNEUT NUISANCE app. " << std::endl << "Produces or recalculates evtrt and flux histograms necessary for NUISANCE normalization." << std::endl; std::cout << "PrepareNEUT: " << std::endl; std::cout << " [-h,-help,--h,--help]" << std::endl; std::cout << " -i inputfile1.root,inputfile2.root,inputfile3.root,..." << std::endl; std::cout << " Takes any number of files, but assumes all are produced with a single flux" << std::endl; std::cout << " -f flux_root_file.root,flux_hist_name" << std::endl; std::cout << " Path to root file containing the flux histogram used when generating the NEUT files" << std::endl; std::cout << " [-o outputfile.root] " << std::endl; std::cout << " If an output file is not given, the input file will be used" << std::endl; std::cout << " If more than one input file is given, an output file must be given" << std::endl; std::cout << " [-G]" << std::endl; std::cout << " Flux is assumed to be in MeV. This switch indicates the input flux is in GeV" << std::endl << std::endl; } void ParseOptions(int argc, char* argv[]){ bool flagopt = false; // If No Arguments print commands for (int i = 1; i< argc; ++i){ if (!std::strcmp(argv[i], "-h")) { flagopt = true; break; } else if (!std::strcmp(argv[i], "-G")) { fFluxInGeV = true; } if (i+1 != argc){ // Cardfile if (!std::strcmp(argv[i], "-h")) { flagopt = true; break; } else if (!std::strcmp(argv[i], "-i")) { fInputFiles = argv[i+1]; ++i; } else if (!std::strcmp(argv[i], "-o")) { fOutputFile = argv[i+1]; ++i; } else if (!std::strcmp(argv[i], "-f")) { fFluxFile = argv[i+1]; ++i; } else { ERR(FTL) << "ERROR: unknown command line option given! - '" <. +*******************************************************************************/ + +// Author: Patrick Stowell 09/2016 +/* + Usage: ./nuissyst -c card file -o output file, where the results of the throws are stored + where: +*/ + +#include "BayesianRoutines.h" + +//******************************* +void printInputCommands(){ +//******************************* + + exit(-1); + +}; + +//******************************* +int main(int argc, char* argv[]){ +//******************************* + + // Program status; + int status = 0; + + // If No Arguments print commands + if (argc == 1) printInputCommands(); + + for (int i = 1; i< argc; ++i){ + // Cardfile + if (!std::strcmp(argv[i], "-h")) printInputCommands(); + else break; + } + + // Read input arguments such as card file, parameter arguments, and fit routines + LOG(FIT)<<"Starting nuissyst"<Run(); + + + // Show Final Status + LOG(FIT)<<"-------------------------------------"<. *******************************************************************************/ #include "ComparisonRoutines.h" #include "InputUtils.h" #include "MeasurementBase.h" #include "GenericFlux_Tester.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 " "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 " << "\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!"); } 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.LoadConfig(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.AddS("name", "FlatTree"); - samplekey.AddS("input", gOptInputFile); - samplekey.AddS("type", gOptType); + samplekey.Set("name", "FlatTree"); + samplekey.Set("input", gOptInputFile); + samplekey.Set("type", gOptType); flattreecreator = new GenericFlux_Tester("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/app/nuissmear.cxx b/app/nuissmear.cxx index 878f0d5..c558d1f 100644 --- a/app/nuissmear.cxx +++ b/app/nuissmear.cxx @@ -1,222 +1,223 @@ // 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 "Smearceptance_Tester.h" // Global Arguments std::string gOptInputFile = ""; std::string gOptOutputFile = ""; std::string gOptType = "DEFAULT"; std::string gOptNumberEvents = "NULL"; std::string gOptCardInput = ""; std::string gOptOptions = ""; //******************************* void PrintSyntax() { //******************************* std::cout << "nuisflat -i input [-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[-c crd.xml]: Input card file to override configs or define " "smearcepters." << "\n\t " << "\n\t[-o outfile]: Optional output file path. " << "\n\t " << "\n\t If none given, input.smear.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 smearception 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; gOptInputFile = InputUtils::PrependGuessedInputTypeToName(gOptInputFile); } // Get Output File ParserUtils::ParseArgument(args, "-o", gOptOutputFile, false); if (gOptOutputFile == "") { gOptOutputFile = gOptInputFile + ".smear.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.LoadConfig(gOptCardInput, ""); + configuration.LoadSettings(gOptCardInput, ""); } ParserUtils::ParseArgument(args, "-t", gOptOptions, false); if (gOptOptions != "") { QLOG(FIT, "Read options: \"" << gOptOptions << "\'"); } return; } void SetupRW() { std::vector parkeys = Config::QueryKeys("parameter"); if (!parkeys.empty()) { LOG(FIT) << "Number of parameters : " << parkeys.size() << std::endl; } std::vector Params; std::map TypeVals; std::map CurrVals; 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; ERR(FTL) << "type='PARAMETER_TYPE'" << std::endl; throw; } else if (!key.Has("name")) { ERR(FTL) << "No name given for parameter " << i << std::endl; ERR(FTL) << "name='SAMPLE_NAME'" << std::endl; throw; } else if (!key.Has("nominal")) { ERR(FTL) << "No nominal given for parameter " << i << std::endl; ERR(FTL) << "nominal='NOMINAL_VALUE'" << std::endl; throw; } // Get Inputs std::string partype = key.GetS("type"); std::string parname = key.GetS("name"); double parnom = key.GetD("nominal"); // Push into vectors Params.push_back(parname); TypeVals[parname] = FitBase::ConvDialType(partype); CurrVals[parname] = parnom; } for (UInt_t i = 0; i < Params.size(); i++) { FitBase::GetRW()->IncludeDial(Params[i], TypeVals[Params[i]]); FitBase::GetRW()->SetDialValue(Params[i], CurrVals[Params[i]]); } FitBase::GetRW()->Reconfigure(); } //******************************* 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; + Config::Get().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"); - samplekey.SetS("name", std::string("FlatTree_") + gOptOptions); - samplekey.SetS("input", gOptInputFile); - samplekey.SetS("type", gOptType); + samplekey.Set("name", "FlatTree"); + samplekey.Set("smearceptor", gOptOptions); + samplekey.Set("input", gOptInputFile); + samplekey.Set("type", gOptType); if (gOptOptions == "") { THROW( "Attempting to flatten with Smearceptor, but no Smearceptor given. " "Please supply a -t option."); } if (gOptCardInput == "") { THROW( "Attempting to flatten with Smearceptor, but no card passed with " "Smearceptors configured. Please supply a -c option."); } SetupRW(); flattreecreator = new Smearceptance_Tester(samplekey); // 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/GENIESetup.cmake b/cmake/GENIESetup.cmake index 148d685..7c0b2c5 100644 --- a/cmake/GENIESetup.cmake +++ b/cmake/GENIESetup.cmake @@ -1,155 +1,157 @@ # 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 . ################################################################################ # TODO # check system for libxml2 # check whether we need the includes # check if we can use a subset of the GENIE libraries ################################################################################ # Check Dependencies ################################################################################ ################################# GENIE ###################################### if(GENIE STREQUAL "") cmessage(FATAL_ERROR "Variable GENIE is not defined. " "The location of a pre-built GENIE install must be defined either as" " $ cmake -DGENIE=/path/to/GENIE or as and environment vairable" " $ export GENIE=/path/to/GENIE") endif() if (BUILD_GEVGEN) cmessage(STATUS "Building custom gevgen") LIST(APPEND EXTRA_CXX_FLAGS -D__GEVGEN_ENABLED__) endif() # Extract GENIE VERSION -execute_process (COMMAND ${CMAKE_SOURCE_DIR}/cmake/getgenieversion.sh ${GENIE} - OUTPUT_VARIABLE GENIE_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) +if (GENIE_VERSION STREQUAL "AUTO") + execute_process (COMMAND ${CMAKE_SOURCE_DIR}/cmake/getgenieversion.sh ${GENIE} + OUTPUT_VARIABLE GENIE_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) +endif() execute_process (COMMAND genie-config --libs OUTPUT_VARIABLE GENIE_LD_FLAGS_STR OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process (COMMAND genie-config --topsrcdir OUTPUT_VARIABLE GENIE_INCLUDES_DIR OUTPUT_STRIP_TRAILING_WHITESPACE) string(REGEX MATCH "-L\([^ ]+\) \(.*\)$" PARSE_GENIE_LIBS_MATCH ${GENIE_LD_FLAGS_STR}) cmessage(DEBUG "genie-config --libs: ${GENIE_LD_FLAGS_STR}") if(NOT PARSE_GENIE_LIBS_MATCH) cmessage(FATAL_ERROR "Expected to be able to parse the result of genie-config --libs to a lib directory and a list of libraries to include, but got: \"${GENIE_LD_FLAGS_STR}\"") endif() set(GENIE_LIB_DIR ${CMAKE_MATCH_1}) set(GENIE_LIBS_RAW ${CMAKE_MATCH_2}) string(REPLACE "-l" "" GENIE_LIBS_STRIPED "${GENIE_LIBS_RAW}") cmessage(STATUS "GENIE version : ${GENIE_VERSION}") cmessage(STATUS "GENIE libdir : ${GENIE_LIB_DIR}") cmessage(STATUS "GENIE libs : ${GENIE_LIBS_STRIPED}") string(REGEX MATCH "ReinSeghal" WASMATCHED ${GENIE_LIBS_STRIPED}) if(WASMATCHED AND GENIE_VERSION STREQUAL "210") set(GENIE_SEHGAL ${GENIE_LIBS_STRIPED}) STRING(REPLACE "ReinSeghal" "ReinSehgal" GENIE_LIBS_STRIPED ${GENIE_SEHGAL}) cmessage(DEBUG "Fixed inconsistency in library naming: ${GENIE_LIBS_STRIPED}") endif() string(REGEX MATCH "ReWeight" WASMATCHED ${GENIE_LIBS_STRIPED}) if(NOT WASMATCHED) set(GENIE_LIBS_STRIPED "GReWeight ${GENIE_LIBS_STRIPED}") cmessage(DEBUG "Force added ReWeight library: ${GENIE_LIBS_STRIPED}") endif() string(REPLACE " " ";" GENIE_LIBS_LIST "${GENIE_LIBS_STRIPED}") cmessage(DEBUG "genie-config --libs -- MATCH1: ${CMAKE_MATCH_1}") cmessage(DEBUG "genie-config --libs -- MATCH2: ${CMAKE_MATCH_2}") cmessage(DEBUG "genie-config --libs -- libs stripped: ${GENIE_LIBS_STRIPED}") cmessage(DEBUG "genie-config --libs -- libs list: ${GENIE_LIBS_LIST}") ################################ LHAPDF ###################################### if(LHAPDF_LIB STREQUAL "") cmessage(FATAL_ERROR "Variable LHAPDF_LIB is not defined. The location of a pre-built lhapdf install must be defined either as $ cmake -DLHAPDF_LIB=/path/to/LHAPDF_libraries or as and environment vairable $ export LHAPDF_LIB=/path/to/LHAPDF_libraries") endif() if(LHAPDF_INC STREQUAL "") cmessage(FATAL_ERROR "Variable LHAPDF_INC is not defined. The location of a pre-built lhapdf install must be defined either as $ cmake -DLHAPDF_INC=/path/to/LHAPDF_includes or as and environment vairable $ export LHAPDF_INC=/path/to/LHAPDF_includes") endif() if(LHAPATH STREQUAL "") cmessage(FATAL_ERROR "Variable LHAPATH is not defined. The location of a the LHAPATH directory must be defined either as $ cmake -DLHAPATH=/path/to/LHAPATH or as and environment variable $ export LHAPATH=/path/to/LHAPATH") endif() ################################ LIBXML ###################################### if(LIBXML2_LIB STREQUAL "") cmessage(FATAL_ERROR "Variable LIBXML2_LIB is not defined. The location of a pre-built libxml2 install must be defined either as $ cmake -DLIBXML2_LIB=/path/to/LIBXML2_libraries or as and environment vairable $ export LIBXML2_LIB=/path/to/LIBXML2_libraries") endif() if(LIBXML2_INC STREQUAL "") cmessage(FATAL_ERROR "Variable LIBXML2_INC is not defined. The location of a pre-built libxml2 install must be defined either as $ cmake -DLIBXML2_INC=/path/to/LIBXML2_includes or as and environment vairable $ export LIBXML2_INC=/path/to/LIBXML2_includes") endif() ############################### log4cpp ###################################### if(LOG4CPP_LIB STREQUAL "") cmessage(FATAL_ERROR "Variable LOG4CPP_LIB is not defined. The location of a pre-built log4cpp install must be defined either as $ cmake -DLOG4CPP_LIB=/path/to/LOG4CPP_libraries or as and environment vairable $ export LOG4CPP_LIB=/path/to/LOG4CPP_libraries") endif() if(LOG4CPP_INC STREQUAL "") cmessage(FATAL_ERROR "Variable LOG4CPP_INC is not defined. The location of a pre-built log4cpp install must be defined either as $ cmake -DGENIE_LOG4CPP_INC=/path/to/LOG4CPP_includes or as and environment vairable $ export LOG4CPP_INC=/path/to/LOG4CPP_includes") endif() ################################################################################ LIST(APPEND EXTRA_CXX_FLAGS -D__GENIE_ENABLED__ -D__GENIE_VERSION__=${GENIE_VERSION}) LIST(APPEND RWENGINE_INCLUDE_DIRECTORIES ${GENIE_INCLUDES_DIR} ${GENIE_INCLUDES_DIR}/GHEP ${GENIE_INCLUDES_DIR}/Ntuple ${GENIE_INCLUDES_DIR}/ReWeight ${GENIE_INCLUDES_DIR}/Apps ${GENIE_INCLUDES_DIR}/FluxDrivers ${GENIE_INCLUDES_DIR}/EVGDrivers ${LHAPDF_INC} ${LIBXML2_INC} ${LOG4CPP_INC}) SAYVARS() LIST(APPEND EXTRA_LINK_DIRS ${GENIE_LIB_DIR} ${LHAPDF_LIB} ${LIBXML2_LIB} ${LOG4CPP_LIB}) #LIST(REVERSE EXTRA_LIBS) #LIST(REVERSE GENIE_LIBS_LIST) LIST(APPEND EXTRA_LIBS ${GENIE_LIBS_LIST}) #LIST(REVERSE EXTRA_LIBS) LIST(APPEND EXTRA_LIBS LHAPDF xml2 log4cpp) if(USE_PYTHIA8) set(NEED_PYTHIA8 TRUE) set(NEED_ROOTPYTHIA8 TRUE) else() set(NEED_PYTHIA6 TRUE) set(NEED_ROOTPYTHIA6 TRUE) endif() set(NEED_ROOTEVEGEN TRUE) SET(USE_GENIE TRUE CACHE BOOL "Whether to enable GENIE (reweight) support. Requires external libraries. " FORCE) diff --git a/cmake/cacheVariables.cmake b/cmake/cacheVariables.cmake index 1c75a96..9aa2f08 100644 --- a/cmake/cacheVariables.cmake +++ b/cmake/cacheVariables.cmake @@ -1,208 +1,209 @@ # 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 . ################################################################################ function(CheckAndSetDefaultEnv VARNAME DEFAULT CACHETYPE DOCSTRING ENVNAME) #cmessage(DEBUG "Trying to assign variable ${VARNAME} into the cache.") if(NOT DEFINED ${VARNAME}) if(DEFINED ENV{${ENVNAME}} AND NOT $ENV{${ENVNAME}} STREQUAL "") set(${VARNAME} $ENV{${ENVNAME}} CACHE ${CACHETYPE} ${DOCSTRING}) cmessage(DEBUG " Read ${VARNAME} from ENVVAR ${ENVNAME} as $ENV{${ENVNAME}}.") else() set(${VARNAME} ${DEFAULT} CACHE ${CACHETYPE} ${DOCSTRING}) endif() else() set(${VARNAME} ${${VARNAME}} CACHE ${CACHETYPE} ${DOCSTRING}) unset(${VARNAME}) endif() cmessage(CACHE "--Set cache variable: \"${VARNAME}\" to \"${${VARNAME}}\", in cache ${CACHETYPE}.") endfunction() function(CheckAndSetDefaultCache VARNAME DEFAULT CACHETYPE DOCSTRING) # cmessage(DEBUG "Trying to assign variable ${VARNAME} into the cache.") if(NOT DEFINED ${VARNAME}) set(${VARNAME} ${DEFAULT} CACHE ${CACHETYPE} ${DOCSTRING}) else() set(${VARNAME} ${${VARNAME}} CACHE ${CACHETYPE} ${DOCSTRING}) unset(${VARNAME}) endif() cmessage(CACHE "--Set cache variable: \"${VARNAME}\" to \"${${VARNAME}}\", in cache ${CACHETYPE}.") endfunction() function(CheckAndSetDefault VARNAME DEFAULT) # cmessage(DEBUG "Trying to assign variable ${VARNAME}.") if(NOT DEFINED ${VARNAME}) set(${VARNAME} ${DEFAULT} PARENT_SCOPE) set(${VARNAME} ${DEFAULT}) endif() cmessage(CACHE "--Set variable: \"${VARNAME}\" to \"${${VARNAME}}\".") endfunction() CheckAndSetDefaultCache(VERBOSE TRUE BOOL "Whether to configure loudly.") set (CMAKE_SKIP_BUILD_RPATH TRUE) #Changes default install path to be a subdirectory of the build dir. #Can set build dir at configure time with -DCMAKE_INSTALL_PREFIX=/install/path if(CMAKE_INSTALL_PREFIX STREQUAL "" OR CMAKE_INSTALL_PREFIX STREQUAL "/usr/local") set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/${CMAKE_SYSTEM_NAME}") elseif(NOT DEFINED CMAKE_INSTALL_PREFIX) set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/${CMAKE_SYSTEM_NAME}") endif() if(CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_BUILD_TYPE DEBUG) elseif(NOT DEFINED CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE DEBUG) endif() CheckAndSetDefaultCache(USE_MINIMIZER TRUE INTERNAL "Whether we are using the ROOT minimization libraries. ") CheckAndSetDefaultCache(USE_HEPMC FALSE BOOL "Whether to enable HepMC input support. ") CheckAndSetDefaultEnv(HEPMC "" PATH "Path to HepMC source tree root directory. Overrides environment variable \$HEPMC <>" HEPMC) CheckAndSetDefaultCache(HEPMC_MOMUNIT "GEV" STRING "HepMC momentum units [MEV|GEV]. ") CheckAndSetDefaultCache(HEPMC_LENUNIT "CM" STRING "HepMC momentum units [MM|CM]. ") CheckAndSetDefaultCache(HEPMC_USED_EP FALSE INTERNAL "Whether we built HepMC or not. ") CheckAndSetDefaultCache(USE_NEUT FALSE BOOL "Whether to enable NEUT (reweight) support. Requires external libraries. ") CheckAndSetDefaultEnv(NEUT_ROOT "" PATH "Path to NEUT source tree root directory. Overrides environment variable \$NEUT_ROOT <>" NEUT_ROOT) CheckAndSetDefaultEnv(CERN "" PATH "Path to CERNLIB source tree root directory that NEUT was built against. Overrides environment variable \$CERN <>" CERN) CheckAndSetDefaultEnv(CERN_LEVEL "" STRING "CERNLIB Library version. Overrides environment variable \$CERN_LEVEL <>" CERN_LEVEL) CheckAndSetDefaultCache(USE_NuWro FALSE BOOL "Whether to enable NuWro support. ") CheckAndSetDefaultEnv(NUWRO "" PATH "Path to NuWro source tree root directory. Overrides environment variable \$NUWRO <>" NUWRO) CheckAndSetDefaultEnv(NUWRO_INC "" PATH "Path to NuWro installed includes directory, needs to contain \"params_all.h\". Overrides environment variable \$NUWRO_INC <>" NUWRO_INC) CheckAndSetDefaultCache(NUWRO_INPUT_FILE "" FILEPATH "Path to an input NuWro event vector, which can be used to build NuWro i/o libraries. <>") CheckAndSetDefaultCache(NUWRO_BUILT_FROM_FILE FALSE INTERNAL "Whether the NuWro libraries were built by NUISANCE. ") CheckAndSetDefaultCache(USE_NuWro_RW FALSE BOOL "Whether to try and build support for NuWro reweighting. ") CheckAndSetDefaultCache(USE_NuWro_SRW_Event FALSE BOOL "Whether to use cut down NuWro reweight event format. Requires NuWro reweight. ") CheckAndSetDefaultCache(USE_GENIE FALSE BOOL "Whether to enable GENIE (reweight) support. Requires external libraries. ") +CheckAndSetDefaultCache(GENIE_VERSION "AUTO" STRING "GENIE Version ") CheckAndSetDefaultEnv(GENIE "" PATH "Path to GENIE source tree root directory. Overrides environment variable \$GENIE <>" GENIE) CheckAndSetDefaultEnv(LHAPDF_LIB "" PATH "Path to pre-built LHAPDF libraries. Overrides environment variable \$LHAPDF_LIB. <>" LHAPDF_LIB) CheckAndSetDefaultEnv(LHAPDF_INC "" PATH "Path to installed LHAPDF headers. Overrides environment variable \$LHAPDF_INC. <>" LHAPDF_INC) CheckAndSetDefaultEnv(LHAPATH "" PATH "Path to LHA PDF inputs. Overrides environment variable \$LHAPATH. <>" LHAPATH) CheckAndSetDefaultEnv(LIBXML2_LIB "" PATH "Path to pre-built LIBXML2 libraries. Overrides environment variable \$LIBXML2_LIB. <>" LIBXML2_LIB) CheckAndSetDefaultEnv(LIBXML2_INC "" PATH "Path to installed LIBXML2 headers. Overrides environment variable \$LIBXML2_INC. <>" LIBXML2_INC) CheckAndSetDefaultEnv(LOG4CPP_LIB "" PATH "Path to pre-built LOG4CPP libraries. Overrides environment variable \$LOG4CPP_LIB. <>" LOG4CPP_LIB) CheckAndSetDefaultEnv(LOG4CPP_INC "" PATH "Path to installed LOG4CPP headers. Overrides environment variable \$LOG4CPP_INC. <>" LOG4CPP_INC) CheckAndSetDefaultCache(BUILD_GEVGEN FALSE BOOL "Whether to build nuisance_gevgen app.") CheckAndSetDefaultCache(USE_T2K FALSE BOOL "Whether to enable T2KReWeight support. Requires external libraries. ") CheckAndSetDefaultEnv(T2KREWEIGHT "" PATH "Path to installed T2KREWEIGHTReWeight. Overrides environment variable \$T2KREWEIGHT. <>" T2KREWEIGHT) CheckAndSetDefaultCache(USE_NIWG FALSE BOOL "Whether to enable (T2K) NIWG ReWeight support. Requires external libraries. ") CheckAndSetDefaultEnv(NIWG_ROOT "" PATH "Path to installed NIWGReWeight. Overrides environment variable \$NIWG. <>" NIWG) CheckAndSetDefaultCache(USE_MINERvA_RW FALSE BOOL "Whether to enable MINERvA ReWeight support. ") CheckAndSetDefaultEnv(PYTHIA6 "" PATH "Path to directory containing libPythia6.so. Overrides environment variable \$PYTHIA6 <>" PYTHIA6) CheckAndSetDefaultEnv(PYTHIA8 "" PATH "Path to directory containing libPythia8.so. Overrides environment variable \$PYTHIA8 <>" PYTHIA8) CheckAndSetDefaultCache(USE_PYTHIA8 FALSE BOOL "Whether to enable PYTHIA8 event support. ") CheckAndSetDefaultCache(USE_GiBUU TRUE BOOL "Whether to enable GiBUU event support. ") CheckAndSetDefaultCache(BUILD_GiBUU FALSE BOOL "Whether to build supporting GiBUU event tools along with a patched version of GiBUU. ") CheckAndSetDefaultCache(USE_NUANCE TRUE BOOL "Whether to enable NUANCE event support. ") CheckAndSetDefaultCache(USE_PROB3PP FALSE BOOL "Whether to download and compile in Prob3++ support. ") CheckAndSetDefaultCache(NO_EXTERNAL_UPDATE TRUE BOOL "Whether to perform the update target for external dependencies. ") CheckAndSetDefaultCache(USE_GPERFTOOLS FALSE BOOL "Whether to compile in google performance tools. ") CheckAndSetDefault(NEED_PYTHIA6 FALSE) CheckAndSetDefault(NEED_PYTHIA8 FALSE) CheckAndSetDefault(NEED_ROOTEVEGEN FALSE) CheckAndSetDefault(NEED_ROOTPYTHIA6 FALSE) CheckAndSetDefaultCache(USE_OMP FALSE BOOL "Whether to enable multicore features (there currently are none...). ") CheckAndSetDefault(NO_EXPERIMENTS FALSE) cmessage(STATUS "NO_EXPERIMENTS: ${NO_EXPERIMENTS}") CheckAndSetDefaultCache(NO_ANL ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build ANL samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_ArgoNeuT ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build ArgoNeuT samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_BEBC ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build BEBC samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_BNL ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build BNL samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_FNAL ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build FNAL samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_GGM ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build GGM samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_K2K ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build K2K samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_MINERvA ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build MINERvA samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_MiniBooNE ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build MiniBooNE samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_T2K ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build T2K samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_SciBooNE ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build SciBooNE samples. <-DNO_EXPERIMENTS=FALSE>") function(SAYVARS) LIST(APPEND VARS USE_HEPMC HEPMC HEPMC_MOMUNIT HEPMC_LENUNIT HEPMC_USED_EP USE_NEUT NEUT_ROOT CERN CERN_LEVEL USE_NuWro NUWRO NUWRO_INC NUWRO_INPUT_FILE NUWRO_BUILT_FROM_FILE USE_GENIE GENIE LHAPDF_LIB LHAPDF_INC LIBXML2_LIB LIBXML2_INC LOG4CPP_LIB GENIE_LOG4CPP_INC BUILD_GEVGEN USE_T2K USE_NIWG USE_GiBUU BUILD_GiBUU USE_NUANCE NO_EXTERNAL_UPDATE USE_GPERFTOOLS NO_ANL NO_ArgoNeuT NO_BEBC NO_BNL NO_FNAL NO_GGM NO_K2K NO_MINERvA NO_MiniBooNE NO_T2K NO_SciBooNE) foreach(v ${VARS}) if(DEFINED ${v}) cmessage(DEBUG "VARIABLE: \"${v}\" = \"${${v}}\"") endif() endforeach(v) endfunction() diff --git a/parameters/config.xml b/parameters/config.xml index 8ad5bc2..4e103d0 100644 --- a/parameters/config.xml +++ b/parameters/config.xml @@ -1,200 +1,214 @@ + + + + + + + + + + diff --git a/scripts/dumpgenieconfig.py b/scripts/dumpgenieconfig.py new file mode 100644 index 0000000..b5c98c3 --- /dev/null +++ b/scripts/dumpgenieconfig.py @@ -0,0 +1,35 @@ +from ROOT import TFile, TFolder, TObjString +import sys + +def PrintKey(obj, indent): + splitkey = obj.GetName().split(";") + keydict = {} + for val in reversed(splitkey): + splitval = val.split(":") + if (len(splitval) < 2): splitval = val.split("=") + keydict[splitval[0].strip()] = ''.join(splitval[1:]).strip() + + print indent, keydict + +def ExpandKeys(keydir, indent): + for obj in keydir.GetListOfFolders(): + if "TFolder" in str(type(obj)): + print indent, obj.GetName() + ExpandKeys(obj, indent + " -> ") + if "TObjString" in str(type(obj)): + PrintKey(obj, indent ) + +def ExpandGlobalList(keydir): + for obj in keydir.GetListOfFolders(): + if str(obj.GetName()) != "GlobalParameterList": continue + print "GLOBAL : ", obj.GetName() + ExpandKeys(obj,"GLOBAL : ") + +if __name__=="__main__": + + myfile = TFile(sys.argv[1],"READ") + configs = myfile.Get("gconfig") + ExpandKeys(configs,"") + + print "\n# Global List #\n" + ExpandGlobalList(configs) diff --git a/scripts/nuissamples b/scripts/nuissamples index a80432a..7721fe5 100755 --- a/scripts/nuissamples +++ b/scripts/nuissamples @@ -1,20 +1,19 @@ #!/bin/sh -for line in $(grep compare $NUISANCE/src/FCN/SampleList.cxx) -do - if [[ $line != *"compare"* ]]; - then - continue - fi - line=${line//\!name\.compare\(/} - line=${line//\(/} - line=${line//\)/} - line=${line//\"/} +for line in $(grep compare $NUISANCE/src/FCN/SampleList.cxx); do + if [[ $line != *"compare"* ]]; then + continue + fi + line=${line//\!name\.compare\(/} + line=${line//\(/} + line=${line//\)/} + line=${line//\"/} + line=${line//\{} - if [[ $line != *"$1"* ]]; - then - continue - fi + if [[ $line != *"$1"* ]]; + then + continue + fi - echo ${2}${line}${3} + echo ${2}${line}${3} done diff --git a/src/Routines/CMakeLists.txt b/src/Config/CMakeLists.txt similarity index 79% copy from src/Routines/CMakeLists.txt copy to src/Config/CMakeLists.txt index 2c5cf1c..7577b9d 100644 --- a/src/Routines/CMakeLists.txt +++ b/src/Config/CMakeLists.txt @@ -1,66 +1,52 @@ # 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 . ################################################################################ -set(IMPLFILES -ComparisonRoutines.cxx -SystematicRoutines.cxx -SplineRoutines.cxx -) - -if(USE_MINIMIZER) - set(IMPLFILES ${IMPLFILES};MinimizerRoutines.cxx) -endif() - set(HEADERFILES -ComparisonRoutines.h -SystematicRoutines.h -SplineRoutines.h +NuisConfig.h +NuisKey.h ) -if(USE_MINIMIZER) - set(HEADERFILES ${HEADERFILES};MinimizerRoutines.h) -endif() +set(IMPLFILES +NuisConfig.cxx +NuisKey.cxx +) -set(LIBNAME Routines) +set(LIBNAME Config) if(CMAKE_BUILD_TYPE MATCHES DEBUG) add_library(${LIBNAME} STATIC ${IMPLFILES}) else(CMAKE_BUILD_TYPE MATCHES RELEASE) add_library(${LIBNAME} SHARED ${IMPLFILES}) endif() -include_directories(${EXP_INCLUDE_DIRECTORIES}) - include_directories(${MINIMUM_INCLUDE_DIRECTORIES}) -include_directories(${CMAKE_SOURCE_DIR}/src/FCN) -include_directories(${CMAKE_SOURCE_DIR}/src/MCStudies) - set_target_properties(${LIBNAME} PROPERTIES VERSION "${NUISANCE_VERSION_MAJOR}.${NUISANCE_VERSION_MINOR}.${NUISANCE_VERSION_REVISION}") + #set_target_properties(${LIBNAME} PROPERTIES LINK_FLAGS ${ROOT_LD_FLAGS}) if(DEFINED PROJECTWIDE_EXTRA_DEPENDENCIES) add_dependencies(${LIBNAME} ${PROJECTWIDE_EXTRA_DEPENDENCIES}) endif() install(TARGETS ${LIBNAME} DESTINATION lib) #Can uncomment this to install the headers... but is it really neccessary? #install(FILES ${HEADERFILES} DESTINATION include) set(MODULETargets ${MODULETargets} ${LIBNAME} PARENT_SCOPE) diff --git a/src/Config/NuisConfig.cxx b/src/Config/NuisConfig.cxx new file mode 100644 index 0000000..f1f1033 --- /dev/null +++ b/src/Config/NuisConfig.cxx @@ -0,0 +1,802 @@ +// 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()); + + // Add this child to the main config list + fXML->AddChild(fMainNode, copyNode); + + // 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) { + 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])) { + 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) { + 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/Config/NuisConfig.h b/src/Config/NuisConfig.h new file mode 100644 index 0000000..d95795e --- /dev/null +++ b/src/Config/NuisConfig.h @@ -0,0 +1,193 @@ +// 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 NUISCONFIG_H_SEEN +#define NUISCONFIG_H_SEEN + +#include +#include + +#include "TFile.h" +#include "TXMLEngine.h" + +/// NUISANCE Global Settings Class +class nuisconfig { + public: + /// Singleton Get Function + static nuisconfig &GetConfig(void); + + /// Constructor \n + /// Loads defaults from $NUISANCE/parameters/config.xml + nuisconfig(); + + /// Desctructor \n Frees XML Docs + virtual ~nuisconfig(); + + /// Adds a new configuration list + void LoadSettings(std::string const &filename, std::string const &state); + + /// Adds a new config from new xml file format + void LoadXMLSettings(std::string const &filename, + std::string const &state = ""); + + /// Adds a new config from old card file format + void LoadCardSettings(std::string const &filename, std::string const &state); + + /// Save the config to file + void WriteSettings(std::string const &filename); + + void PrintXML(XMLNodePointer_t node, int indent = 0); + + XMLNodePointer_t CreateNode(std::string const &name); + XMLNodePointer_t CreateNode(XMLNodePointer_t node, std::string const &name); + + void RemoveEmptyNodes(); + void RemoveIdenticalNodes(); + + bool MatchingNodes(XMLNodePointer_t node1, XMLNodePointer_t node2); + void PrintNode(XMLNodePointer_t node); + void RemoveNode(XMLNodePointer_t node); + + void FinaliseSettings(std::string const &name); + + XMLNodePointer_t CreateSampleNodeFromLine(std::string const &line); + XMLNodePointer_t CreateParameterNodeFromLine(std::string const &line); + XMLNodePointer_t CreatePullNodeFromLine(std::string const &line); + XMLNodePointer_t CreateOldConfigNodeFromLine(std::string const &line); + + // Get List of child nodes of nuisance element + std::vector GetNodes(std::string const &type = ""); + std::vector GetNodes(XMLNodePointer_t node, + std::string const &type = ""); + XMLNodePointer_t GetNode(std::string const &type = ""); + XMLNodePointer_t GetNode(XMLNodePointer_t node, std::string const &type = ""); + + std::vector GetAllKeysForNode(XMLNodePointer_t node); + + std::string GetElementName(XMLNodePointer_t node) { + return fXML->GetNodeName(node); + } + + /// Check node has key name + bool Has(XMLNodePointer_t node, std::string const &name); + + /// Add attribute to node + void Set(XMLNodePointer_t node, std::string const &name, + std::string const &val); + void Set(XMLNodePointer_t node, std::string const &name, + char const *val); + void Set(XMLNodePointer_t node, std::string const &name, bool val); + void Set(XMLNodePointer_t node, std::string const &name, int val); + void Set(XMLNodePointer_t node, std::string const &name, float val); + void Set(XMLNodePointer_t node, std::string const &name, double val); + + void SetS(XMLNodePointer_t node, std::string const &name, + std::string const &val); + void SetB(XMLNodePointer_t node, std::string const &name, bool val); + void SetI(XMLNodePointer_t node, std::string const &name, int val); + void SetF(XMLNodePointer_t node, std::string const &name, float val); + void SetD(XMLNodePointer_t node, std::string const &name, double val); + + /// Get String from a given node + std::string Get(XMLNodePointer_t node, std::string const &name); + std::string GetS(XMLNodePointer_t node, std::string const &name); + bool GetB(XMLNodePointer_t node, std::string const &name); + int GetI(XMLNodePointer_t node, std::string const &name); + float GetF(XMLNodePointer_t node, std::string const &name); + double GetD(XMLNodePointer_t node, std::string const &name); + + // Get values parsed into a vector + std::vector GetVS(XMLNodePointer_t node, std::string const &name, + const char *del); + std::vector GetVI(XMLNodePointer_t node, std::string const &name, + const char *del); + std::vector GetVD(XMLNodePointer_t node, std::string const &name, + const char *del); + + /// Set an already set config value to something else + void OverrideConfig(std::string const &conf); + + /// Return the node of a given config parameter + XMLNodePointer_t GetConfigNode(std::string const &name); + + void SetConfig(std::string const &name, std::string const &val); + void SetConfig(std::string const &name, char const *val); + void SetConfig(std::string const &name, bool val); + void SetConfig(std::string const &name, int val); + void SetConfig(std::string const &name, float val); + void SetConfig(std::string const &name, double val); + + void SetParS(std::string const &name, std::string const &val); + void SetParB(std::string const &name, bool val); + void SetParI(std::string const &name, int val); + void SetParD(std::string const &name, double val); + + std::string GetConfig(std::string const &name); + bool HasConfig(std::string const &name); + std::string GetConfigS(std::string const &name); + bool GetConfigB(std::string const &name); + int GetConfigI(std::string const &name); + float GetConfigF(std::string const &name); + double GetConfigD(std::string const &name); + + std::string GetPar(std::string const &name) { return GetConfig(name); }; + std::string GetParS(std::string const &name) { return GetConfigS(name); }; + bool GetParB(std::string const &name) { return GetConfigB(name); }; + int GetParI(std::string const &name) { return GetConfigI(name); }; + float GetParF(std::string const &name) { return GetConfigF(name); }; + double GetParD(std::string const &name) { return GetConfigD(name); }; + + std::string GetParDIR(std::string const &parName); + + TFile *out; + + private: + XMLNodePointer_t fMainNode; ///< Main XML Parent Node + TXMLEngine *fXML; ///< ROOT XML Engine + std::vector fXMLDocs; ///< List of all XML document inputs + + protected: + static nuisconfig *m_nuisconfigInstance; +}; + +namespace Config { +nuisconfig &Get(); + +std::string GetPar(std::string const &name); +bool HasPar(std::string const &name); +std::string GetParS(std::string const &name); +bool GetParB(std::string const &name); +int GetParI(std::string const &name); +float GetParF(std::string const &name); +double GetParD(std::string const &name); + +void SetPar(std::string const &name, std::string const &val); +void SetPar(std::string const &name, char const *val); +void SetPar(std::string const &name, bool val); +void SetPar(std::string const &name, int val); +void SetPar(std::string const &name, float val); +void SetPar(std::string const &name, double val); +} + +namespace FitPar { +nuisconfig &Config(); +std::string GetDataBase(); +} + +/*! @} */ +#endif diff --git a/src/Config/NuisKey.cxx b/src/Config/NuisKey.cxx new file mode 100644 index 0000000..75b90ff --- /dev/null +++ b/src/Config/NuisKey.cxx @@ -0,0 +1,140 @@ +#include "NuisKey.h" +#include "GeneralUtils.h" +#include "NuisConfig.h" + +nuiskey::nuiskey(std::string const &name) { + fNode = Config::Get().CreateNode(name); +} + +std::string nuiskey::GetS(std::string const &name) { + return Config::Get().GetS(fNode, name); +}; + +void nuiskey::Print() { Config::Get().PrintXML(fNode); } + +int nuiskey::GetI(std::string const &name) { + return Config::Get().GetI(fNode, name); +}; + +double nuiskey::GetD(std::string const &name) { + return Config::Get().GetD(fNode, name); +}; + +bool nuiskey::GetB(std::string const &name) { + return Config::Get().GetB(fNode, name); +}; + +void nuiskey::Set(std::string const &name, std::string const &newval) { + Config::Get().SetS(fNode, name, newval); +} +void nuiskey::Set(std::string const &name, int newval) { + Config::Get().SetI(fNode, name, newval); +} +void nuiskey::Set(std::string const &name, double newval) { + Config::Get().SetD(fNode, name, newval); +} +void nuiskey::Set(std::string const &name, bool newval) { + Config::Get().SetB(fNode, name, newval); +} + +void nuiskey::SetS(std::string const &name, std::string const &newval) { + Config::Get().SetS(fNode, name, newval); +} +void nuiskey::Set(std::string const &name, char const *newval) { + Config::Get().SetS(fNode, name, newval); +} +void nuiskey::SetI(std::string const &name, int newval) { + Config::Get().SetI(fNode, name, newval); +} +void nuiskey::SetD(std::string const &name, double newval) { + Config::Get().SetD(fNode, name, newval); +} +void nuiskey::SetB(std::string const &name, bool newval) { + Config::Get().SetB(fNode, name, newval); +} + +std::vector nuiskey::GetAllKeys() { + return Config::Get().GetAllKeysForNode(fNode); +} + +std::vector nuiskey::GetListOfChildNodes(std::string const &filter) { + std::vector nodelist = + Config::Get().GetNodes(fNode, filter); + std::vector keylist; + for (size_t n_it = 0; n_it < nodelist.size(); ++n_it) { + keylist.push_back(nuiskey(nodelist[n_it])); + } + return keylist; +} + +std::vector nuiskey::GetVS(std::string const &name, + const char *del) { + return Config::Get().GetVS(fNode, name, del); +}; + +std::vector nuiskey::GetVI(std::string const &name, const char *del) { + return Config::Get().GetVI(fNode, name, del); +}; + +std::vector nuiskey::GetVD(std::string const &name, const char *del) { + return Config::Get().GetVD(fNode, name, del); +}; + +std::vector Config::QueryKeys(std::string const &type, + std::string const &test1) { + // Get Vector of nodes + std::vector nodelist = Config::Get().GetNodes(type); + + // Convert List into a key list for easier access + std::vector keylist; + for (std::vector::const_iterator iter = nodelist.begin(); + iter != nodelist.end(); iter++) { + // Create new key + nuiskey newkey = nuiskey(*iter); + + // Add test1 + if (!test1.empty()) { + std::vector testvect = GeneralUtils::ParseToStr(test1, "="); + if (testvect.size() < 2) continue; + if (newkey.GetS(testvect[0]) != testvect[1]) continue; + } + + // Save node as nuiskey + keylist.push_back(newkey); + } + + // Return list of keys + return keylist; +} + +nuiskey Config::QueryLastKey(std::string const &type, + std::string const &test1) { + // Loop over all for now because I'm lazy... + std::vector allkeys = Config::QueryKeys(type, test1); + if (allkeys.size() < 1) + return nuiskey(); + else + return allkeys[allkeys.size() - 1]; +} + +nuiskey Config::QueryFirstKey(std::string const &type, + std::string const &test1) { + // Loop over all for now because I'm lazy... + std::vector allkeys = Config::QueryKeys(type, test1); + if (allkeys.size() < 1) + return nuiskey(); + else + return allkeys[allkeys.size() - 1]; +} + +bool nuiskey::Has(std::string const &name) { + return Config::Get().Has(fNode, name); +} + +std::string nuiskey::GetElementName() { + return Config::Get().GetElementName(fNode); +} + +nuiskey Config::CreateKey(std::string const &name) { + return nuiskey(Config::Get().CreateNode(name)); +} diff --git a/src/Config/NuisKey.h b/src/Config/NuisKey.h new file mode 100644 index 0000000..38d3165 --- /dev/null +++ b/src/Config/NuisKey.h @@ -0,0 +1,62 @@ +#ifndef NUISKEY_H +#define NUISKEY_H + +#include +#include + +#include "TFile.h" +#include "TXMLEngine.h" + +class nuiskey { + public: + nuiskey(){}; + + nuiskey(XMLNodePointer_t node) { fNode = node; }; + nuiskey(std::string const &name); + + void Print(); + + ~nuiskey(){}; + + std::string GetS(std::string const &name); + int GetI(std::string const &name); + double GetD(std::string const &name); + bool GetB(std::string const &name); + + std::vector GetVS(std::string const &name, const char *del); + std::vector GetVI(std::string const &name, const char *del); + std::vector GetVD(std::string const &name, const char *del); + + void SetS(std::string const &name, std::string const &newval); + void SetI(std::string const &name, int newval); + void SetD(std::string const &name, double newval); + void SetB(std::string const &name, bool newval); + + void Set(std::string const &name, std::string const &newval); + void Set(std::string const &name, char const *newval); + void Set(std::string const &name, int newval); + void Set(std::string const &name, double newval); + void Set(std::string const &name, bool newval); + + bool Has(std::string const &name); + + std::string GetElementName(); + + std::vector GetAllKeys(); + + std::vector GetListOfChildNodes(std::string const &filter = ""); + + XMLNodePointer_t fNode; ///< XML Node in Config::Get().fXML for this key +}; + +namespace Config { + +// Return a vector of keys for use +std::vector QueryKeys(std::string const &name, + std::string const &test1 = ""); +nuiskey QueryFirstKey(std::string const &name, std::string const &test1 = ""); +nuiskey QueryLastKey(std::string const &name, std::string const &test1 = ""); + +nuiskey CreateKey(std::string const &name); +} +#endif diff --git a/src/FCN/JointFCN.cxx b/src/FCN/#JointFCN.cxx# similarity index 99% copy from src/FCN/JointFCN.cxx copy to src/FCN/#JointFCN.cxx# index dee225c..cc31fe4 100755 --- a/src/FCN/JointFCN.cxx +++ b/src/FCN/#JointFCN.cxx# @@ -1,1014 +1,1016 @@ #include "JointFCN.h" #include #include "FitUtils.h" //*************************************************** JointFCN::JointFCN(TFile* outfile) { //*************************************************** fOutputDir = gDirectory; if (outfile) FitPar::Config().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) FitPar::Config().out = outfile; LoadSamples(samplekeys); fCurIter = 0; fMCFilled = false; fOutputDir->cd(); fIterationTree = false; fDialVals = NULL; fNDials = 0; fUsingEventManager = FitPar::Config().GetParB("EventManager"); fOutputDir->cd(); } //*************************************************** JointFCN::~JointFCN() { //*************************************************** // Delete Samples for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase* exp = *iter; delete exp; } for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull* pull = *iter; delete pull; } // Sort Tree if (fIterationTree) DestroyIterationTree(); if (fDialVals) delete fDialVals; if (fSampleLikes) delete fSampleLikes; }; //*************************************************** void JointFCN::CreateIterationTree(std::string name, FitWeight* rw) { //*************************************************** LOG(FIT) << " Creating new iteration container! " << std::endl; DestroyIterationTree(); fIterationTreeName = name; // Add sample likelihoods and ndof for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase* exp = *iter; std::string name = exp->GetName(); std::string liketag = name + "_likelihood"; fNameValues.push_back(liketag); fCurrentValues.push_back(0.0); std::string ndoftag = name + "_ndof"; fNameValues.push_back(ndoftag); fCurrentValues.push_back(0.0); } // Add Pull terms for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull* pull = *iter; std::string name = pull->GetName(); std::string liketag = name + "_likelihood"; fNameValues.push_back(liketag); fCurrentValues.push_back(0.0); std::string ndoftag = name + "_ndof"; fNameValues.push_back(ndoftag); fCurrentValues.push_back(0.0); } // Add Likelihoods fNameValues.push_back("total_likelihood"); fCurrentValues.push_back(0.0); fNameValues.push_back("total_ndof"); fCurrentValues.push_back(0.0); - // Setup Containers + // 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]; + 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 + std::cout << "Writing iteration tree" << std::endl; itree->Write(); + std::cout << "Written iteration tree" << std::endl; } //*************************************************** 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(); + // 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); 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)) { + if (splinecount % countwidth == 0) { LOG(REC) << "Processed " << splinecount << " event weights. W = " << rwweight << std::endl; } // #pragma omp atomic splinecount++; } // #pragma omp atomic sigcount++; } } LOG(SAM) << "Processed event weights." << std::endl; // #pragma omp barrier // Reset Iterators inpsig_iter = fSignalEventFlags.begin(); spline_iter = fSignalEventSplines.begin(); box_iter = fSignalEventBoxes.begin(); samsig_iter = fSampleSignalFlags.begin(); int nsplineweights = splinecount; splinecount = 0; // Start of Fast Event Loop ============================ // Start input iterators // Loop over number of inputs for (int ispline = 0; ispline < nsplineweights; ispline++) { double rwweight = coreeventweights[ispline]; // Get iterators for this event std::vector::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; } diff --git a/src/FCN/JointFCN.cxx b/src/FCN/JointFCN.cxx index dee225c..f3eb4e6 100755 --- a/src/FCN/JointFCN.cxx +++ b/src/FCN/JointFCN.cxx @@ -1,1014 +1,1136 @@ #include "JointFCN.h" #include #include "FitUtils.h" //*************************************************** JointFCN::JointFCN(TFile* outfile) { //*************************************************** fOutputDir = gDirectory; - if (outfile) FitPar::Config().out = outfile; + 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) FitPar::Config().out = outfile; + 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++){ + 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"); + 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++){ + 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++){ + 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++){ + 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++){ + 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; + 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){ + 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(); + // 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); 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/JointFCN.h b/src/FCN/JointFCN.h index bf87424..1f47f28 100755 --- a/src/FCN/JointFCN.h +++ b/src/FCN/JointFCN.h @@ -1,176 +1,180 @@ #ifndef _JOINT_FCN_H_ #define _JOINT_FCN_H_ /*! * \addtogroup FCN * @{ */ #include #include #include #include // ROOT headers #include "TTree.h" #include "TH1D.h" #include "TH2D.h" #include #include "TGraphErrors.h" #include #include #include "FitUtils.h" // External fitter headers #include "MeasurementBase.h" #include "SampleList.h" #define GetCurrentDir getcwd #include "EventManager.h" #include "Math/Functor.h" #include "ParamPull.h" #include "NuisConfig.h" #include "NuisKey.h" #include "MeasurementVariableBox.h" #include "MeasurementVariableBox1D.h" using namespace FitUtils; using namespace FitBase; //! Main FCN Class which ROOT's joint function needs to evaulate the chi2 at each stage of the fit. class JointFCN { - public: +public: //! Constructor //! cardfile = Path to input card file listing samples - JointFCN(std::vector samplekeys, TFile* outfile=NULL); - JointFCN(TFile* outfile=NULL); // Loads from global config + JointFCN(std::vector samplekeys, TFile* outfile = NULL); + JointFCN(TFile* outfile = NULL); // Loads from global config //! Destructor ~JointFCN(); //! Create sample list from cardfile void LoadSamples(std::vector samplekeys); void LoadPulls(std::vector pullkeys); //! Main Likelihood evaluation FCN double DoEval(const double *x); //! Func Wrapper for ROOT inline double operator() (const std::vector & x) { double* x_array = new double[x.size()]; return this->DoEval(x_array); }; //! Func Wrapper for ROOT inline double operator() (const double *x) { return this->DoEval(x); }; //! Create a TTree to save all dial value iterations for this FCN void CreateIterationTree(std::string name, FitWeight* rw); //! Fills dial values and sample likelihoods into tree void FillIterationTree(FitWeight* rw); //! Writes TTree to fOutput directory void WriteIterationTree(); //! Deletes TTree void DestroyIterationTree(); //! Get Degrees of Freedom for samples (NBins) int GetNDOF(); //! Return NDOF wrapper inline unsigned int NDim() {return this->GetNDOF();}; //! Reconfigure samples where we force all events to be looped over. void ReconfigureAllEvents() ; //! Call Reconfigure on samples. //! Choice of reconfigure type depends on whether dials have changed //! and the MC has been filled. void ReconfigureSamples(bool fullconfig = false); //! Call reconfigure on only signal events (defaults to all events if CurIter=0) void ReconfigureSignal(); //! Gets likelihood for all samples in FCN (assuming uncorrelated) double GetLikelihood(); //! Returns list of pointers to the samples - inline std::list GetSampleList(){ return fSamples; } + inline std::list GetSampleList() { return fSamples; } //! Return list of pointers to all the pulls - inline std::list GetPullList(){ return fPulls; }; + inline std::list GetPullList() { return fPulls; }; //! Write all samples to output DIR void Write(); //! Set Fake data from file/MC void SetFakeData(std::string fakeinput); //! Reconfigure looping over duplicate inputs void ReconfigureUsingManager(); //! Reconfigure Fast looping over duplicate inputs void ReconfigureFastUsingManager(); /// Throws data according to current stats void ThrowDataToy(); -std::vector GetSubSampleList(); -std::vector GetInputList(); + std::vector GetSubSampleList(); + std::vector GetInputList(); - private: + std::vector GetAllNames(); + std::vector GetAllLikelihoods(); + std::vector GetAllNDOF(); + +private: //! Append the experiments to include in the fit to this list std::list fSamples; //! Append parameter pull terms to include penalties in the fit to this list std::list fPulls; TDirectory *fOutputDir; //!< Directory to save contents std::string fCardFile; //!< Input Card text file bool fDialChanged; //!< Flag for if RW dials changed UInt_t fCurIter; //!< Counter for how many times reconfigure called bool fMCFilled; //!< Check MC has at least been filled once bool fIterationTree; //!< Tree to save RW values on each function call int fNDials; //!< Number of RW Dials in FitWeight double* fDialVals; //!< Current Values of RW Dials double fLikelihood; //!< Current likelihood for joint sample likelihood double fNDOF; //!< Total NDOF double* fSampleLikes; //!< Likelihoods for each individual measurement in list int * fSampleNDOF; //!< NDOF for each individual measurement in list bool fUsingEventManager; //!< Flag for doing joint comparisons std::vector< std::vector > fSignalEventSplines; std::vector< std::vector > fSignalEventBoxes; std::vector< bool > fSignalEventFlags; std::vector< std::vector > fSampleSignalFlags; std::vector fInputList; std::vector fSubSampleList; bool fIsAllSplines; std::vector< int > fIterationCount; std::vector< double > fCurrentValues; std::vector< std::string > fNameValues; std::vector< std::vector > fIterationValues; int fSampleN; std::string fIterationTreeName; }; /*! @} */ #endif // _JOINT_FCN_H_ diff --git a/src/FCN/SampleList.cxx b/src/FCN/SampleList.cxx index 7de82f8..2e21eda 100644 --- a/src/FCN/SampleList.cxx +++ b/src/FCN/SampleList.cxx @@ -1,1046 +1,1056 @@ #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_nu.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_1Dth_antinu.h" +#include "MINERvA_CCCOHPI_XSec_1Dth_nu.h" #include "MINERvA_CCCOHPI_XSec_1Dth_nu.h" #include "MINERvA_CCCOHPI_XSec_1DQ2_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_nu.h" #include "MINERvA_CC0pi_XSec_2Dptpx_antinu.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" //! 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.AddS("name", name); - samplekey.AddS("input", file); - samplekey.AddS("type", type); + samplekey.Set("name", name); + samplekey.Set("input", file); + samplekey.Set("type", type); return CreateSample(samplekey); } MeasurementBase* CreateSample(nuiskey samplekey) { 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")) { + !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(file, rw, type, fkdt)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1Dppi_nu")) { return (new T2K_CC1pip_CH_XSec_1Dppi_nu(file, rw, type, fkdt)); } 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/CMakeLists.txt b/src/FitBase/CMakeLists.txt index 543bcb2..91bfe86 100644 --- a/src/FitBase/CMakeLists.txt +++ b/src/FitBase/CMakeLists.txt @@ -1,72 +1,76 @@ # 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 . ################################################################################ set(IMPLFILES ParamPull.cxx EventManager.cxx Measurement1D.cxx Measurement2D.cxx JointMeas1D.cxx MeasurementBase.cxx TemplateMeas1D.cxx SampleSettings.cxx MeasurementVariableBox.cxx MeasurementVariableBox2D.cxx MeasurementVariableBox1D.cxx CustomVariableBoxes.h +StandardStacks.cxx +StackBase.cxx ) set(HEADERFILES ParamPull.h JointMeas1D.h Measurement2D.h EventManager.h MeasurementBase.h Measurement1D.h TemplateMeas1D.h SampleSettings.h MeasurementVariableBox.h MeasurementVariableBox2D.h MeasurementVariableBox1D.h CustomVariableBoxes.h +StandardStacks.h +StackBase.h ) set(LIBNAME FitBase) if(CMAKE_BUILD_TYPE MATCHES DEBUG) add_library(${LIBNAME} STATIC ${IMPLFILES}) else(CMAKE_BUILD_TYPE MATCHES RELEASE) add_library(${LIBNAME} SHARED ${IMPLFILES}) endif() include_directories(${MINIMUM_INCLUDE_DIRECTORIES}) cmessage(DEBUG "FitBase includes: ${MINIMUM_INCLUDE_DIRECTORIES}") set_target_properties(${LIBNAME} PROPERTIES VERSION "${NUISANCE_VERSION_MAJOR}.${NUISANCE_VERSION_MINOR}.${NUISANCE_VERSION_REVISION}") #set_target_properties(${LIBNAME} PROPERTIES LINK_FLAGS ${ROOT_LD_FLAGS}) if(DEFINED PROJECTWIDE_EXTRA_DEPENDENCIES) add_dependencies(${LIBNAME} ${PROJECTWIDE_EXTRA_DEPENDENCIES}) endif() install(TARGETS ${LIBNAME} DESTINATION lib) #Can uncomment this to install the headers... but is it really neccessary? install(FILES ${HEADERFILES} DESTINATION include) set(MODULETargets ${MODULETargets} ${LIBNAME} PARENT_SCOPE) diff --git a/src/FitBase/JointMeas1D.h b/src/FitBase/JointMeas1D.h index cada32a..01a51b0 100644 --- a/src/FitBase/JointMeas1D.h +++ b/src/FitBase/JointMeas1D.h @@ -1,688 +1,688 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #ifndef JOINTMEASUREMENT_1D_H_SEEN #define JOINTMEASUREMENT_1D_H_SEEN /*! * \addtogroup FitBase * @{ */ #include #include #include #include #include #include #include #include #include // ROOT includes #include #include #include #include #include #include #include #include #include #include #include #include #include "Measurement1D.h" // External data fit includes #include "FitEvent.h" -#include "FitParameters.h" + #include "FitUtils.h" #include "MeasurementBase.h" #include "PlotUtils.h" #include "StatUtils.h" //******************************************************************** /// 1D Measurement base class. Histogram handling is done in this base layer. class JointMeas1D : public MeasurementBase { //******************************************************************** public: /* Constructor/Deconstuctor */ JointMeas1D(void); virtual ~JointMeas1D(void); /* Setup Functions */ SampleSettings LoadSampleSettings(nuiskey samplekey); /// \brief Setup all configs once initialised /// /// Should be called after all configs have been setup inside fSettings container. /// Handles the processing of inputs and setting up of types. /// Replaces the old 'SetupMeasurement' function. void FinaliseSampleSettings(); /// \brief Read 1D data inputs from a text file. /// /// Inputfile should have the format: \n /// low_binedge_1 bin_content_1 bin_error_1 \n /// low_binedge_2 bin_content_2 bin_error_2 \n /// .... .... .... \n /// high_bin_edge_N 0.0 0.0 virtual void SetDataFromTextFile(std::string datafile); /// \brief Read 1D data inputs from a root file. /// /// inhistfile specifies the path to the root file /// histname specifies the name of the histogram. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ';' so that: \n /// 'myhistfile.root;myhistname' \n /// will also work. virtual void SetDataFromRootFile(std::string inhistfile, std::string histname = ""); /// \brief Set data bin errors to sqrt(entries) /// /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST /// /// Sets the data errors as the sqrt of the bin contents /// Should be use for counting experiments virtual void SetPoissonErrors(); /// \brief Make diagonal covariance from data /// /// \warning If no histogram passed, data must be setup first! /// Setup the covariance inputs by taking the data histogram /// errors and setting up a diagonal covariance matrix. /// /// If no data is supplied, fDataHist is used if already set. virtual void SetCovarFromDiagonal(TH1D* data = NULL); /// \brief Read the data covariance from a text file. /// /// Inputfile should have the format: \n /// covariance_11 covariance_12 covariance_13 ... \n /// covariance_21 covariance_22 covariance_23 ... \n /// ... ... ... ... \n /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCovarFromTextFile(std::string covfile, int dim = -1); virtual void SetCovarFromMultipleTextFiles(std::string covfiles, int dim = -1); /// \brief Read the data covariance from a ROOT file. /// /// - covfile specifies the full path to the file /// - histname specifies the name of the covariance object. Both TMatrixDSym and TH2D are supported. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCovarFromRootFile(std::string covfile, std::string histname); /// \brief Read the inverted data covariance from a text file. /// /// Inputfile should have similar format to that shown /// in SetCovarFromTextFile. /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCovarInvertFromTextFile(std::string covfile, int dim = -1); /// \brief Read the inverted data covariance from a ROOT file. /// /// Inputfile should have similar format to that shown /// in SetCovarFromRootFile. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCovarInvertFromRootFile(std::string covfile, std::string histname); /// \brief Read the data correlations from a text file. /// /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST /// /// Inputfile should have similar format to that shown /// in SetCovarFromTextFile. /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCorrelationFromTextFile(std::string covfile, int dim = -1); /// \brief Read the data correlations from multiple text files. /// /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST /// /// Inputfile should have similar format to that shown /// in SetCovarFromTextFile. /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of first covfile. virtual void SetCorrelationFromMultipleTextFiles(std::string corrfiles, int dim = -1); /// \brief Read the data correlations from a ROOT file. /// /// \warning REQUIRES DATA TO BE SET FIRST /// /// Inputfile should have similar format to that shown /// in SetCovarFromRootFile. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCorrelationFromRootFile(std::string covfile, std::string histname); /// \brief Try to extract a shape-only matrix from the existing covariance virtual void SetShapeCovar(); /// \brief Read the cholesky decomposed covariance from a text file and turn it into a covariance /// /// Inputfile should have similar format to that shown /// in SetCovarFromTextFile. /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCholDecompFromTextFile(std::string covfile, int dim = -1); /// \brief Read the cholesky decomposed covariance from a ROOT file and turn it into a covariance /// /// Inputfile should have similar format to that shown /// in SetCovarFromRootFile. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCholDecompFromRootFile(std::string covfile, std::string histname); /// \brief Scale the data by some scale factor virtual void ScaleData(double scale); /// \brief Scale the covariaince and its invert/decomp by some scale factor. virtual void ScaleCovar(double scale); /// \brief Setup a bin masking histogram and apply masking to data /// /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST /// /// Reads in a list of bins in a text file to be masked. Format is: \n /// bin_index_1 1 \n /// bin_index_2 1 \n /// bin_index_3 1 \n /// /// If 0 is given then a bin entry will NOT be masked. So for example: \n\n /// 1 1 \n /// 2 1 \n /// 3 0 \n /// 4 1 \n\n /// Will mask only the 1st, 2nd, and 4th bins. /// /// Masking can be turned on by specifiying the MASK option when creating a sample. /// When this is passed NUISANCE will look in the following locations for the mask file: /// - FitPar::Config().GetParS(fName + ".mask") /// - "data/masks/" + fName + ".mask"; virtual void SetBinMask(std::string maskfile); /// \brief Final constructor setup /// \warning Should be called right at the end of the constructor. /// /// Contains a series of checks to ensure the data and inputs have been setup. /// Also creates the MC histograms needed for fitting. virtual void FinaliseMeasurement(); /// \brief Set the current fit options from a string. /// /// This is called twice for each sample, once to set the default /// and once to set the current setting (if anything other than default given) /// /// For this to work properly it requires the default and allowed types to be /// set correctly. These should be specified as a string listing options. /// /// To split up options so that NUISANCE can automatically detect ones that /// are conflicting. Any options seperated with the '/' symbol are non conflicting /// and can be given together, whereas any seperated with the ',' symbol cannot /// be specified by the end user at the same time. /// /// Default Type Examples: /// - DIAG/FIX = Default option will be a diagonal covariance, with FIXED norm. /// - MASK/SHAPE = Default option will be a masked hist, with SHAPE always on. /// /// Allowed Type examples: /// - 'FULL/DIAG/NORM/MASK' = Any of these options can be specified. /// - 'FULL,FREE,SHAPE/MASK/NORM' = User can give either FULL, FREE, or SHAPE as on option. /// MASK and NORM can also be included as options. virtual void SetFitOptions(std::string opt); /* Smearing */ /// \brief Read in smearing matrix from file /// /// Set the smearing matrix from a text file given the size of the matrix virtual void SetSmearingMatrix(std::string smearfile, int truedim, int recodim); /// \brief Apply smearing to MC true to get MC reco /// /// Apply smearing matrix to fMCHist using fSmearingMatrix virtual void ApplySmearingMatrix(void); /* Reconfigure Functions */ /// \brief Create a Measurement1D box /// /// Creates a new 1D variable box containing just fXVar. /// /// This box is the bare minimum required by the JointFCN when /// running fast reconfigures during a routine. /// If for some reason a sample needs extra variables to be saved then /// it should override this function creating its own MeasurementVariableBox /// that contains the extra variables. virtual MeasurementVariableBox* CreateBox() {return new MeasurementVariableBox1D();}; /// \brief Reset all MC histograms /// /// Resets all standard histograms and those registered to auto /// process to zero. /// /// If extra histograms are not included in auto processing, then they must be reset /// by overriding this function and doing it manually if required. virtual void ResetAll(void); /// \brief Fill MC Histograms from XVar /// /// Fill standard histograms using fXVar, Weight read from the variable box. /// /// WARNING : Any extra MC histograms need to be filled by overriding this function, /// even if they have been set to auto process. virtual void FillHistograms(void); // \brief Convert event rates to final histogram /// /// Apply standard scaling procedure to standard mc histograms to convert from /// raw events to xsec prediction. /// /// If any distributions have been set to auto process /// that is done during this function call, and a differential xsec is assumed. /// If that is not the case this function must be overriden. virtual void ScaleEvents(void); /// \brief Scale MC by a factor=1/norm /// /// Apply a simple normalisation scaling if the option FREE or a norm_parameter /// has been specified in the NUISANCE routine. virtual void ApplyNormScale(double norm); /* Statistical Functions */ /// \brief Get Number of degrees of freedom /// /// Returns the number bins inside the data histogram accounting for /// any bin masking applied. virtual int GetNDOF(void); /// \brief Return Data/MC Likelihood at current state /// /// Returns the likelihood of the data given the current MC prediction. /// Diferent likelihoods definitions are used depending on the FitOptions. virtual double GetLikelihood(void); /* Fake Data */ /// \brief Set the fake data values from either a file, or MC /// /// - Setting from a file "path": \n /// When reading from a file the full path must be given to a standard /// nuisance output. The standard MC histogram should have a name that matches /// this sample for it to be read in. /// \n\n /// - Setting from "MC": \n /// If the MC option is given the current MC prediction is used as fake data. virtual void SetFakeDataValues(std::string fakeOption); /// \brief Reset fake data back to starting fake data /// /// Reset the fake data back to original fake data (Reset back to before /// ThrowCovariance was first called) virtual void ResetFakeData(void); /// \brief Reset fake data back to original data /// /// Reset the data histogram back to the true original dataset for this sample /// before any fake data was defined. virtual void ResetData(void); /// \brief Generate fake data by throwing the covariance. /// /// Can be used on fake MC data or just the original dataset. /// Call ResetFakeData or ResetData to return to values before the throw. virtual void ThrowCovariance(void); /// \brief Throw the data by its assigned errors and assign this to MC /// /// Used when creating data toys by assign the MC to this thrown data /// so that the likelihood is calculated between data and thrown data virtual void ThrowDataToy(void); /* Access Functions */ /// \brief Returns nicely formatted MC Histogram /// /// Format options can also be given in the samplesettings: /// - linecolor /// - linestyle /// - linewidth /// - fillcolor /// - fillstyle /// /// So to have a sample line colored differently in the xml cardfile put: \n /// virtual TH1D* GetMCHistogram(void); /// \brief Returns nicely formatted data Histogram /// /// Format options can also be given in the samplesettings: /// - datacolor /// - datastyle /// - datawidth /// /// So to have a sample data colored differently in the xml cardfile put: \n /// virtual TH1D* GetDataHistogram(void); /// \brief Returns a list of all MC histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. virtual std::vector GetMCList(void); /// \brief Returns a list of all Data histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. virtual std::vector GetDataList(void); /// \brief Returns a list of all Mask histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. virtual std::vector GetMaskList(void); /// \brief Returns a list of all Fine histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. virtual std::vector GetFineList(void); /* Write Functions */ /// \brief Save the current state to the current TFile directory \n /// /// Data/MC are both saved by default. /// A range of other histograms can be saved by setting the /// config option 'drawopts'. /// /// Possible options: \n /// - FINE = Write Fine Histogram \n /// - WEIGHTS = Write Weighted MC Histogram (before scaling) \n /// - FLUX = Write Flux Histogram from MC Input \n /// - EVT = Write Event Histogram from MC Input \n /// - XSEC = Write XSec Histogram from MC Input \n /// - MASK = Write Mask Histogram \n /// - COV = Write Covariance Histogram \n /// - INVCOV = Write Inverted Covariance Histogram \n /// - DECMOP = Write Decomp. Covariance Histogram \n /// - RESIDUAL= Write Resudial Histograms \n /// - RATIO = Write Data/MC Ratio Histograms \n /// - SHAPE = Write MC Shape Histograms norm. to Data \n /// - CANVMC = Build MC Canvas Showing Data, MC, Shape \n /// - MODES = Write PDG Stack \n /// - CANVPDG = Build MC Canvas Showing Data, PDGStack \n /// /// So to save a range of these in parameters/config.xml set: \n /// virtual void Write(std::string drawOpt); virtual void WriteRatioPlot(); virtual void WriteShapePlot(); virtual void WriteShapeRatioPlot(); double TotalIntegratedFlux(std::string intOpt, double low, double high); //* // OLD DEFUNCTIONS // /// OLD FUNCTION virtual void SetupMeasurement(std::string input, std::string type, FitWeight* rw, std::string fkdt); /// OLD FUNCTION virtual void SetupDefaultHist(void); /// OLD FUNCTION virtual void SetDataValues(std::string dataFile); /// OLD FUNCTION virtual void SetDataFromFile(std::string inhistfile, std::string histname); /// OLD FUNCTION virtual void SetDataFromDatabase(std::string inhistfile, std::string histname); /// OLD FUNCTION virtual void SetCovarMatrix(std::string covarFile); /// OLD FUNCTION virtual void SetCovarMatrixFromText(std::string covarFile, int dim, double scale = 1.0); /// OLD FUNCTION virtual void SetCovarMatrixFromCorrText(std::string covarFile, int dim); /// OLD FUNCTION virtual void SetCovarFromDataFile(std::string covarFile, std::string covName, bool FullUnits = false); ////// JOINT MEAS1D Functions ////// /* Reconfigure Functions */ /// Call reconfigure on every sub sample virtual void Reconfigure(); /// Stitch the sub sample plots together to make a final fMCHist after /// reconfigure has been called virtual void MakePlots(); virtual std::vector GetSubSamples(); virtual void ConvertEventRates(); /* Access Functions */ virtual std::vector GetFluxList(); virtual std::vector GetEventRateList(); virtual std::vector GetXSecList(); //! Return a flux integrated across all sub samples virtual TH1D* GetCombinedFlux(); //! Return an event rate integrated across all sub samples virtual TH1D* GetCombinedEventRate(); virtual TH1D* GetEventHistogram() { return GetCombinedEventRate(); }; virtual TH1D* GetXSecHistogram() { ERR(WRN) << "XSec histogram not properly implemented for joint measurements."; return MeasurementBase::GetXSecHistogram(); }; virtual TH1D* GetFluxHistogram() { return GetCombinedFlux(); }; protected: // Data TH1D* fDataHist; ///< default data histogram TH1D* fDataOrig; ///< histogram to store original data before throws. TH1D* fDataTrue; ///< histogram to store true dataset std::string fPlotTitles; ///< Plot title x and y for the histograms // MC TH1D* fMCHist; ///< default MC Histogram used in the chi2 fits TH1D* fMCFine; ///< finely binned MC histogram TH1D* fMCStat; ///< histogram with unweighted events to properly calculate TH1D* fMCWeighted; ///< Weighted histogram before xsec scaling TH1I* fMaskHist; ///< Mask histogram for neglecting specific bins TMatrixD* fSmearMatrix; ///< Smearing matrix (note, this is not symmetric) TrueModeStack* fMCHist_Modes; ///< Optional True Mode Stack // Statistical TMatrixDSym* covar; ///< Inverted Covariance TMatrixDSym* fFullCovar; ///< Full Covariance TMatrixDSym* fDecomp; ///< Decomposed Covariance TMatrixDSym* fCorrel; ///< Correlation Matrix TMatrixDSym* fShapeCovar; ///< Shape-only covariance TMatrixDSym* fCovar; ///< New FullCovar TMatrixDSym* fInvert; ///< New covar double fNormError; ///< Sample norm error // Fake Data bool fIsFakeData; ///< Flag: is the current data fake from MC std::string fFakeDataInput; ///< Input fake data file path TFile* fFakeDataFile; ///< Input fake data file // Fit specific flags std::string fFitType; ///< Current fit type std::string fAllowedTypes; ///< Fit Types Possible std::string fDefaultTypes; ///< Starting Default Fit Types bool fIsShape; ///< Flag : Perform Shape-only fit bool fIsFree; ///< Flag : Perform normalisation free fit bool fIsDiag; ///< Flag : only include uncorrelated diagonal errors bool fIsMask; ///< Flag : Apply bin masking bool fIsRawEvents; ///< Flag : Are bin contents just event rates bool fIsEnu1D; ///< Flag : Perform Flux Unfolded Scaling bool fIsChi2SVD; ///< Flag : Use alternative Chi2 SVD Method (Do not use) bool fAddNormPen; ///< Flag : Add a normalisation penalty term to the chi2. bool fIsFix; ///< Flag : keeping norm fixed bool fIsFull; ///< Flag : using full covariaince bool fIsDifXSec; ///< Flag : creating a dif xsec bool fIsChi2; ///< Flag : using Chi2 over LL methods bool fIsSmeared; ///< Flag : Apply smearing? /// OLD STUFF TO REMOVE TH1D* fMCHist_PDG[61]; ///< REMOVE OLD MC PDG Plot // Arrays for data entries Double_t* fXBins; ///< REMOVE xBin edges Double_t* fDataValues; ///< REMOVE data bin contents Double_t* fDataErrors; ///< REMOVE data bin errors Int_t fNDataPointsX; ///< REMOVE number of data points //// JOINT MEAS1D OBJECTS //// std::vector fSubChain; //!< Vector of experimental classes //! that are the sub measurements std::vector fSubInFiles; //!< vector of input files for each of the sub measurements. bool fIsRatio; //!< Flag: is this sample a hist1/hist2 ratio sample bool fIsSummed; //!< Flag: is this sample a combination hist1 + hist2 bool fSaveSubMeas; //!< Flag: Save each of the histograms from the sub //! samples as well as this joint samples plots double fLikelihood; }; /*! @} */ #endif diff --git a/src/FitBase/Measurement1D.cxx b/src/FitBase/Measurement1D.cxx index e1c9936..0028d0f 100644 --- a/src/FitBase/Measurement1D.cxx +++ b/src/FitBase/Measurement1D.cxx @@ -1,1903 +1,1903 @@ // Copyright 2016 L. Pickering, P. Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This ile is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "Measurement1D.h" //******************************************************************** Measurement1D::Measurement1D(void) { //******************************************************************** // XSec Scalings fScaleFactor = -1.0; fCurrentNorm = 1.0; // Histograms fDataHist = NULL; fDataTrue = NULL; fMCHist = NULL; fMCFine = NULL; fMCWeighted = NULL; fMaskHist = NULL; // Covar covar = NULL; fFullCovar = NULL; fShapeCovar = NULL; fCovar = NULL; fInvert = NULL; fDecomp = NULL; // Fake Data fFakeDataInput = ""; fFakeDataFile = NULL; // Options fDefaultTypes = "FIX/FULL/CHI2"; fAllowedTypes = "FIX,FREE,SHAPE/FULL,DIAG/CHI2/NORM/ENUCORR/Q2CORR/ENU1D/MASK/NOWIDTH"; fIsFix = false; fIsShape = false; fIsFree = false; fIsDiag = false; fIsFull = false; fAddNormPen = false; fIsMask = false; fIsChi2SVD = false; fIsRawEvents = false; fIsNoWidth = false; fIsDifXSec = false; fIsEnu1D = false; // Inputs fInput = NULL; fRW = NULL; // Extra Histograms fMCHist_Modes = NULL; } //******************************************************************** Measurement1D::~Measurement1D(void) { //******************************************************************** if (fDataHist) delete fDataHist; if (fDataTrue) delete fDataTrue; if (fMCHist) delete fMCHist; if (fMCFine) delete fMCFine; if (fMCWeighted) delete fMCWeighted; if (fMaskHist) delete fMaskHist; if (covar) delete covar; if (fFullCovar) delete fFullCovar; if (fShapeCovar) delete fShapeCovar; if (fCovar) delete fCovar; if (fInvert) delete fInvert; if (fDecomp) delete fDecomp; } //******************************************************************** void Measurement1D::FinaliseSampleSettings() { //******************************************************************** MeasurementBase::FinaliseSampleSettings(); // Setup naming + renaming fName = fSettings.GetName(); fSettings.SetS("originalname", fName); if (fSettings.Has("rename")) { fName = fSettings.GetS("rename"); fSettings.SetS("name", fName); } // Setup all other options LOG(SAM) << "Finalising Sample Settings: " << fName << std::endl; if ((fSettings.GetS("originalname").find("Evt") != std::string::npos)) { fIsRawEvents = true; LOG(SAM) << "Found event rate measurement but using poisson likelihoods." << std::endl; } if (fSettings.GetS("originalname").find("XSec_1DEnu") != std::string::npos) { fIsEnu1D = true; LOG(SAM) << "::" << fName << "::" << std::endl; LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, " << "not flux averaged!" << std::endl; } if (fIsEnu1D && fIsRawEvents) { LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this " "really correct?!" << std::endl; LOG(SAM) << "Check experiment constructor for " << fName << " and correct this!" << std::endl; LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl; exit(-1); } if (!fRW) fRW = FitBase::GetRW(); if (!fInput and !fIsJoint) SetupInputs(fSettings.GetS("input")); // Setup options SetFitOptions(fDefaultTypes); // defaults SetFitOptions(fSettings.GetS("type")); // user specified EnuMin = GeneralUtils::StrToDbl(fSettings.GetS("enu_min")); EnuMax = GeneralUtils::StrToDbl(fSettings.GetS("enu_max")); if (fAddNormPen) { if (fNormError <= 0.0) { ERR(WRN) << "Norm error for class " << fName << " is 0.0!" << std::endl; ERR(WRN) << "If you want to use it please add fNormError=VAL" << std::endl; throw; } } } //******************************************************************** void Measurement1D::CreateDataHistogram(int dimx, double* binx) { //******************************************************************** if (fDataHist) delete fDataHist; fDataHist = new TH1D( (fSettings.GetName() + "_data").c_str(), (fSettings.GetFullTitles()).c_str(), dimx, binx) ; } //******************************************************************** void Measurement1D::SetDataFromTextFile(std::string datafile) { //******************************************************************** LOG(SAM) << "Reading data from text file: " << datafile << std::endl; fDataHist = PlotUtils::GetTH1DFromFile(datafile, fSettings.GetName() + "_data", fSettings.GetFullTitles()); } //******************************************************************** void Measurement1D::SetDataFromRootFile(std::string datafile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading data from root file: " << datafile << ";" << histname << std::endl; fDataHist = PlotUtils::GetTH1DFromRootFile(datafile, histname); fDataHist->SetNameTitle((fSettings.GetName() + "_data").c_str(), (fSettings.GetFullTitles()).c_str()); return; }; //******************************************************************** void Measurement1D::SetEmptyData(){ //******************************************************************** fDataHist = new TH1D("EMPTY_DATA","EMPTY_DATA",1,0.0,1.0); } //******************************************************************** void Measurement1D::SetPoissonErrors() { //******************************************************************** if (!fDataHist) { ERR(FTL) << "Need a data hist to setup possion errors! " << std::endl; ERR(FTL) << "Setup Data First!" << std::endl; throw; } for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) { fDataHist->SetBinError(i + 1, sqrt(fDataHist->GetBinContent(i + 1))); } } //******************************************************************** void Measurement1D::SetCovarFromDiagonal(TH1D* data) { //******************************************************************** if (!data and fDataHist) { data = fDataHist; } if (data) { LOG(SAM) << "Setting diagonal covariance for: " << data->GetName() << std::endl; fFullCovar = StatUtils::MakeDiagonalCovarMatrix(data); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } else { ERR(FTL) << "No data input provided to set diagonal covar from!" << std::endl; } // if (!fIsDiag) { // ERR(FTL) << "SetCovarMatrixFromDiag called for measurement " // << "that is not set as diagonal." << std::endl; // throw; // } } //******************************************************************** void Measurement1D::SetCovarFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) { dim = fDataHist->GetNbinsX(); } LOG(SAM) << "Reading covariance from text file: " << covfile << std::endl; fFullCovar = StatUtils::GetCovarFromTextFile(covfile, dim); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement1D::SetCovarFromMultipleTextFiles(std::string covfiles, int dim) { //******************************************************************** if (dim == -1) { dim = fDataHist->GetNbinsX(); } std::vector covList = GeneralUtils::ParseToStr(covfiles, ";"); fFullCovar = new TMatrixDSym(dim); for (uint i = 0; i < covList.size(); ++i){ LOG(SAM) << "Reading covariance from text file: " << covList[i] << std::endl; TMatrixDSym* temp_cov = StatUtils::GetCovarFromTextFile(covList[i], dim); (*fFullCovar) += (*temp_cov); delete temp_cov; } covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement1D::SetCovarFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading covariance from text file: " << covfile << ";" << histname << std::endl; fFullCovar = StatUtils::GetCovarFromRootFile(covfile, histname); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement1D::SetCovarInvertFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) { dim = fDataHist->GetNbinsX(); } LOG(SAM) << "Reading inverted covariance from text file: " << covfile << std::endl; covar = StatUtils::GetCovarFromTextFile(covfile, dim); fFullCovar = StatUtils::GetInvert(covar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement1D::SetCovarInvertFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading inverted covariance from text file: " << covfile << ";" << histname << std::endl; covar = StatUtils::GetCovarFromRootFile(covfile, histname); fFullCovar = StatUtils::GetInvert(covar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement1D::SetCorrelationFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) dim = fDataHist->GetNbinsX(); LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << dim << std::endl; TMatrixDSym* correlation = StatUtils::GetCovarFromTextFile(covfile, dim); if (!fDataHist) { ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n" << "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl; throw; } // Fill covar from data errors and correlations fFullCovar = new TMatrixDSym(dim); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { (*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76; } } // Fill other covars. covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete correlation; } //******************************************************************** void Measurement1D::SetCorrelationFromMultipleTextFiles(std::string corrfiles, int dim) { //******************************************************************** if (dim == -1) { dim = fDataHist->GetNbinsX(); } std::vector corrList = GeneralUtils::ParseToStr(corrfiles, ";"); fFullCovar = new TMatrixDSym(dim); for (uint i = 0; i < corrList.size(); ++i){ LOG(SAM) << "Reading covariance from text file: " << corrList[i] << std::endl; TMatrixDSym* temp_cov = StatUtils::GetCovarFromTextFile(corrList[i], dim); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { (*temp_cov)(i, j) = (*temp_cov)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76; } } (*fFullCovar) += (*temp_cov); delete temp_cov; } covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement1D::SetCorrelationFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << histname << std::endl; TMatrixDSym* correlation = StatUtils::GetCovarFromRootFile(covfile, histname); if (!fDataHist) { ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n" << "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl; throw; } // Fill covar from data errors and correlations fFullCovar = new TMatrixDSym(fDataHist->GetNbinsX()); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { (*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76; } } // Fill other covars. covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete correlation; } //******************************************************************** void Measurement1D::SetCholDecompFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) { dim = fDataHist->GetNbinsX(); } LOG(SAM) << "Reading cholesky from text file: " << covfile << std::endl; TMatrixD* temp = StatUtils::GetMatrixFromTextFile(covfile, dim, dim); TMatrixD* trans = (TMatrixD*)temp->Clone(); trans->T(); (*trans) *= (*temp); fFullCovar = new TMatrixDSym(dim, trans->GetMatrixArray(), ""); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete temp; delete trans; } //******************************************************************** void Measurement1D::SetCholDecompFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading cholesky decomp from root file: " << covfile << ";" << histname << std::endl; TMatrixD* temp = StatUtils::GetMatrixFromRootFile(covfile, histname); TMatrixD* trans = (TMatrixD*)temp->Clone(); trans->T(); (*trans) *= (*temp); fFullCovar = new TMatrixDSym(temp->GetNrows(), trans->GetMatrixArray(), ""); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete temp; delete trans; } void Measurement1D::SetShapeCovar(){ // Return if this is missing any pre-requisites if (!fFullCovar) return; if (!fDataHist) return; // Also return if it's bloody stupid under the circumstances if (fIsDiag) return; fShapeCovar = StatUtils::ExtractShapeOnlyCovar(fFullCovar, fDataHist); return; } //******************************************************************** void Measurement1D::ScaleData(double scale) { //******************************************************************** fDataHist->Scale(scale); } //******************************************************************** void Measurement1D::ScaleDataErrors(double scale) { //******************************************************************** for (int i = 0; i < fDataHist->GetNbinsX(); i++) { fDataHist->SetBinError(i + 1, fDataHist->GetBinError(i + 1) * scale); } } //******************************************************************** void Measurement1D::ScaleCovar(double scale) { //******************************************************************** (*fFullCovar) *= scale; (*covar) *= 1.0 / scale; (*fDecomp) *= sqrt(scale); } //******************************************************************** void Measurement1D::SetBinMask(std::string maskfile) { //******************************************************************** if (!fIsMask) return; LOG(SAM) << "Reading bin mask from file: " << maskfile << std::endl; // Create a mask histogram with dim of data int nbins = fDataHist->GetNbinsX(); fMaskHist = new TH1I((fSettings.GetName() + "_BINMASK").c_str(), (fSettings.GetName() + "_BINMASK; Bin; Mask?").c_str(), nbins, 0, nbins); std::string line; std::ifstream mask(maskfile.c_str(), ifstream::in); if (!mask.is_open()) { LOG(FTL) << " Cannot find mask file." << std::endl; throw; } while (std::getline(mask >> std::ws, line, '\n')) { std::vector entries = GeneralUtils::ParseToInt(line, " "); // Skip lines with poorly formatted lines if (entries.size() < 2) { LOG(WRN) << "Measurement1D::SetBinMask(), couldn't parse line: " << line << std::endl; continue; } // The first index should be the bin number, the second should be the mask // value. int val = 0; if (entries[1] > 0) val = 1; fMaskHist->SetBinContent(entries[0], val); } // Apply masking by setting masked data bins to zero PlotUtils::MaskBins(fDataHist, fMaskHist); return; } //******************************************************************** void Measurement1D::FinaliseMeasurement() { //******************************************************************** LOG(SAM) << "Finalising Measurement: " << fName << std::endl; if (fSettings.GetB("onlymc")){ if (fDataHist) delete fDataHist; fDataHist = new TH1D("empty_data","empty_data",1,0.0,1.0); } // Make sure data is setup if (!fDataHist) { ERR(FTL) << "No data has been setup inside " << fName << " constructor!" << std::endl; throw; } // Make sure covariances are setup if (!fFullCovar) { fIsDiag = true; SetCovarFromDiagonal(fDataHist); } if (!covar) { covar = StatUtils::GetInvert(fFullCovar); } if (!fDecomp) { fDecomp = StatUtils::GetDecomp(fFullCovar); } // Push the diagonals of fFullCovar onto the data histogram // Comment this out until the covariance/data scaling is consistent! StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, 1E-38); // If shape only, set covar and fDecomp using the shape-only matrix (if set) - if (fIsShape && fShapeCovar){ + if (fIsShape && fShapeCovar and FitPar::Config().GetParB("UseShapeCovar")){ if (covar) delete covar; covar = StatUtils::GetInvert(fShapeCovar); if (fDecomp) delete fDecomp; fDecomp = StatUtils::GetDecomp(fFullCovar); } // Setup fMCHist from data fMCHist = (TH1D*)fDataHist->Clone(); fMCHist->SetNameTitle((fSettings.GetName() + "_MC").c_str(), (fSettings.GetFullTitles()).c_str()); fMCHist->Reset(); // Setup fMCFine fMCFine = new TH1D("mcfine", "mcfine", fDataHist->GetNbinsX() * 8, fMCHist->GetBinLowEdge(1), fMCHist->GetBinLowEdge(fDataHist->GetNbinsX() + 1)); fMCFine->SetNameTitle((fSettings.GetName() + "_MC_FINE").c_str(), (fSettings.GetFullTitles()).c_str()); fMCFine->Reset(); // Setup MC Stat fMCStat = (TH1D*)fMCHist->Clone(); fMCStat->Reset(); // Search drawopts for possible types to include by default std::string drawopts = FitPar::Config().GetParS("drawopts"); if (drawopts.find("MODES") != std::string::npos) { fMCHist_Modes = new TrueModeStack( (fSettings.GetName() + "_MODES").c_str(), ("True Channels"), fMCHist); SetAutoProcessTH1(fMCHist_Modes, kCMD_Reset, kCMD_Norm, kCMD_Write); } // Setup bin masks using sample name if (fIsMask) { std::string curname = fName; std::string origname = fSettings.GetS("originalname"); // Check rename.mask std::string maskloc = FitPar::Config().GetParDIR(curname + ".mask"); // Check origname.mask if (maskloc.empty()) maskloc = FitPar::Config().GetParDIR(origname + ".mask"); // Check database if (maskloc.empty()) { maskloc = FitPar::GetDataBase() + "/masks/" + origname + ".mask"; } // Setup Bin Mask SetBinMask(maskloc); } if (fScaleFactor < 0) { ERR(FTL) << "I found a negative fScaleFactor in " << __FILE__ << ":" << __LINE__ << std::endl; ERR(FTL) << "fScaleFactor = " << fScaleFactor << std::endl; ERR(FTL) << "EXITING" << std::endl; throw; } // Create and fill Weighted Histogram if (!fMCWeighted) { fMCWeighted = (TH1D*)fMCHist->Clone(); fMCWeighted->SetNameTitle((fName + "_MCWGHTS").c_str(), (fName + "_MCWGHTS" + fPlotTitles).c_str()); fMCWeighted->GetYaxis()->SetTitle("Weighted Events"); } } //******************************************************************** void Measurement1D::SetFitOptions(std::string opt) { //******************************************************************** // Do nothing if default given if (opt == "DEFAULT") return; // CHECK Conflicting Fit Options std::vector fit_option_allow = GeneralUtils::ParseToStr(fAllowedTypes, "/"); for (UInt_t i = 0; i < fit_option_allow.size(); i++) { std::vector fit_option_section = GeneralUtils::ParseToStr(fit_option_allow.at(i), ","); bool found_option = false; for (UInt_t j = 0; j < fit_option_section.size(); j++) { std::string av_opt = fit_option_section.at(j); if (!found_option and opt.find(av_opt) != std::string::npos) { found_option = true; } else if (found_option and opt.find(av_opt) != std::string::npos) { ERR(FTL) << "ERROR: Conflicting fit options provided: " << opt << std::endl << "Conflicting group = " << fit_option_section.at(i) << std::endl << "You should only supply one of these options in card file." << std::endl; throw; } } } // Check all options are allowed std::vector fit_options_input = GeneralUtils::ParseToStr(opt, "/"); for (UInt_t i = 0; i < fit_options_input.size(); i++) { if (fAllowedTypes.find(fit_options_input.at(i)) == std::string::npos) { ERR(FTL) << "ERROR: Fit Option '" << fit_options_input.at(i) << "' Provided is not allowed for this measurement." << std::endl; ERR(FTL) << "Fit Options should be provided as a '/' seperated list " "(e.g. FREE/DIAG/NORM)" << std::endl; ERR(FTL) << "Available options for " << fName << " are '" << fAllowedTypes << "'" << std::endl; throw; } } // Set TYPE fFitType = opt; // FIX,SHAPE,FREE if (opt.find("FIX") != std::string::npos) { fIsFree = fIsShape = false; fIsFix = true; } else if (opt.find("SHAPE") != std::string::npos) { fIsFree = fIsFix = false; fIsShape = true; } else if (opt.find("FREE") != std::string::npos) { fIsFix = fIsShape = false; fIsFree = true; } // DIAG,FULL (or default to full) if (opt.find("DIAG") != std::string::npos) { fIsDiag = true; fIsFull = false; } else if (opt.find("FULL") != std::string::npos) { fIsDiag = false; fIsFull = true; } // CHI2/LL (OTHERS?) if (opt.find("LOG") != std::string::npos) { fIsChi2 = false; ERR(FTL) << "No other LIKELIHOODS properly supported!" << std::endl; ERR(FTL) << "Try to use a chi2!" << std::endl; throw; } else { fIsChi2 = true; } // EXTRAS if (opt.find("RAW") != std::string::npos) fIsRawEvents = true; if (opt.find("NOWIDTH") != std::string::npos) fIsNoWidth = true; if (opt.find("DIF") != std::string::npos) fIsDifXSec = true; if (opt.find("ENU1D") != std::string::npos) fIsEnu1D = true; if (opt.find("NORM") != std::string::npos) fAddNormPen = true; if (opt.find("MASK") != std::string::npos) fIsMask = true; return; }; //******************************************************************** void Measurement1D::SetSmearingMatrix(std::string smearfile, int truedim, int recodim) { //******************************************************************** // The smearing matrix describes the migration from true bins (rows) to reco // bins (columns) // Counter over the true bins! int row = 0; std::string line; std::ifstream smear(smearfile.c_str(), ifstream::in); // Note that the smearing matrix may be rectangular. fSmearMatrix = new TMatrixD(truedim, recodim); if (smear.is_open()) LOG(SAM) << "Reading smearing matrix from file: " << smearfile << std::endl; else ERR(FTL) << "Smearing matrix provided is incorrect: " << smearfile << std::endl; while (std::getline(smear >> std::ws, line, '\n')) { int column = 0; std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { (*fSmearMatrix)(row, column) = (*iter) / 100.; // Convert to fraction from // percentage (this may not be // general enough) column++; } row++; } return; } //******************************************************************** void Measurement1D::ApplySmearingMatrix() { //******************************************************************** if (!fSmearMatrix) { ERR(WRN) << fName << ": attempted to apply smearing matrix, but none was set" << std::endl; return; } TH1D* unsmeared = (TH1D*)fMCHist->Clone(); TH1D* smeared = (TH1D*)fMCHist->Clone(); smeared->Reset(); // Loop over reconstructed bins // true = row; reco = column for (int rbin = 0; rbin < fSmearMatrix->GetNcols(); ++rbin) { // Sum up the constributions from all true bins double rBinVal = 0; // Loop over true bins for (int tbin = 0; tbin < fSmearMatrix->GetNrows(); ++tbin) { rBinVal += (*fSmearMatrix)(tbin, rbin) * unsmeared->GetBinContent(tbin + 1); } smeared->SetBinContent(rbin + 1, rBinVal); } fMCHist = (TH1D*)smeared->Clone(); return; } /* Reconfigure LOOP */ //******************************************************************** void Measurement1D::ResetAll() { //******************************************************************** fMCHist->Reset(); fMCFine->Reset(); fMCStat->Reset(); return; }; //******************************************************************** void Measurement1D::FillHistograms() { //******************************************************************** if (Signal) { fMCHist->Fill(fXVar, Weight); fMCFine->Fill(fXVar, Weight); fMCStat->Fill(fXVar, 1.0); if (fMCHist_Modes) fMCHist_Modes->Fill(Mode, fXVar, Weight); } return; }; //******************************************************************** void Measurement1D::ScaleEvents() { //******************************************************************** // Fill MCWeighted; // for (int i = 0; i < fMCHist->GetNbinsX(); i++) { // fMCWeighted->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1)); // fMCWeighted->SetBinError(i + 1, fMCHist->GetBinError(i + 1)); // } // Setup Stat ratios for MC and MC Fine double* statratio = new double[fMCHist->GetNbinsX()]; for (int i = 0; i < fMCHist->GetNbinsX(); i++) { if (fMCHist->GetBinContent(i + 1) != 0) { statratio[i] = fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1); } else { statratio[i] = 0.0; } } double* statratiofine = new double[fMCFine->GetNbinsX()]; for (int i = 0; i < fMCFine->GetNbinsX(); i++) { if (fMCFine->GetBinContent(i + 1) != 0) { statratiofine[i] = fMCFine->GetBinError(i + 1) / fMCFine->GetBinContent(i + 1); } else { statratiofine[i] = 0.0; } } // Scaling for raw event rates if (fIsRawEvents) { double datamcratio = fDataHist->Integral() / fMCHist->Integral(); fMCHist->Scale(datamcratio); fMCFine->Scale(datamcratio); if (fMCHist_Modes) fMCHist_Modes->Scale(datamcratio); // Scaling for XSec as function of Enu } else if (fIsEnu1D) { PlotUtils::FluxUnfoldedScaling(fMCHist, GetFluxHistogram(), GetEventHistogram(), fScaleFactor, fNEvents); PlotUtils::FluxUnfoldedScaling(fMCFine, GetFluxHistogram(), GetEventHistogram(), fScaleFactor, fNEvents); // if (fMCHist_Modes) { // PlotUtils::FluxUnfoldedScaling(fMCHist_Modes, GetFluxHistogram(), // GetEventHistogram(), fScaleFactor, // fNEvents); // } } else if (fIsNoWidth) { fMCHist->Scale(fScaleFactor); fMCFine->Scale(fScaleFactor); if (fMCHist_Modes) fMCHist_Modes->Scale(fScaleFactor); // Any other differential scaling } else { fMCHist->Scale(fScaleFactor, "width"); fMCFine->Scale(fScaleFactor, "width"); if (fMCHist_Modes) fMCHist_Modes->Scale(fScaleFactor, "width"); } // Proper error scaling - ROOT Freaks out with xsec weights sometimes for (int i = 0; i < fMCStat->GetNbinsX(); i++) { fMCHist->SetBinError(i + 1, fMCHist->GetBinContent(i + 1) * statratio[i]); } for (int i = 0; i < fMCFine->GetNbinsX(); i++) { fMCFine->SetBinError(i + 1, fMCFine->GetBinContent(i + 1) * statratiofine[i]); } // Clean up delete statratio; delete statratiofine; return; }; //******************************************************************** void Measurement1D::ApplyNormScale(double norm) { //******************************************************************** fCurrentNorm = norm; fMCHist->Scale(1.0 / norm); fMCFine->Scale(1.0 / norm); return; }; /* Statistic Functions - Outsources to StatUtils */ //******************************************************************** int Measurement1D::GetNDOF() { //******************************************************************** int ndof = fDataHist->GetNbinsX(); if (fMaskHist and fIsMask) ndof -= fMaskHist->Integral(); return ndof; } //******************************************************************** double Measurement1D::GetLikelihood() { //******************************************************************** // If this is for a ratio, there is no data histogram to compare to! if (fNoData || !fDataHist) return 0.; // Apply Masking to MC if Required. if (fIsMask and fMaskHist) { PlotUtils::MaskBins(fMCHist, fMaskHist); } // Sort Shape Scaling double scaleF = 0.0; // TODO Include !fIsRawEvents if (fIsShape) { if (fMCHist->Integral(1, fMCHist->GetNbinsX(), "width")) { scaleF = fDataHist->Integral(1, fDataHist->GetNbinsX(), "width") / fMCHist->Integral(1, fMCHist->GetNbinsX(), "width"); fMCHist->Scale(scaleF); fMCFine->Scale(scaleF); } } // Likelihood Calculation double stat = 0.; if (fIsChi2) { if (fIsRawEvents) { stat = StatUtils::GetChi2FromEventRate(fDataHist, fMCHist, fMaskHist); } else if (fIsDiag) { stat = StatUtils::GetChi2FromDiag(fDataHist, fMCHist, fMaskHist); } else if (!fIsDiag and !fIsRawEvents) { stat = StatUtils::GetChi2FromCov(fDataHist, fMCHist, covar, fMaskHist); } } // Sort Penalty Terms if (fAddNormPen) { double penalty = (1. - fCurrentNorm) * (1. - fCurrentNorm) / (fNormError * fNormError); stat += penalty; } // Return to normal scaling if (fIsShape) { // and !FitPar::Config().GetParB("saveshapescaling")) { fMCHist->Scale(1. / scaleF); fMCFine->Scale(1. / scaleF); } fLikelihood = stat; return stat; } /* Fake Data Functions */ //******************************************************************** void Measurement1D::SetFakeDataValues(std::string fakeOption) { //******************************************************************** // Setup original/datatrue TH1D* tempdata = (TH1D*) fDataHist->Clone(); if (!fIsFakeData) { fIsFakeData = true; // Make a copy of the original data histogram. if (!fDataOrig) fDataOrig = (TH1D*)fDataHist->Clone((fName + "_data_original").c_str()); } else { ResetFakeData(); } // Setup Inputs fFakeDataInput = fakeOption; LOG(SAM) << "Setting fake data from : " << fFakeDataInput << std::endl; // From MC if (fFakeDataInput.compare("MC") == 0) { fDataHist = (TH1D*)fMCHist->Clone((fName + "_MC").c_str()); // Fake File } else { if (!fFakeDataFile) fFakeDataFile = new TFile(fFakeDataInput.c_str(), "READ"); fDataHist = (TH1D*)fFakeDataFile->Get((fName + "_MC").c_str()); } // Setup Data Hist fDataHist->SetNameTitle((fName + "_FAKE").c_str(), (fName + fPlotTitles).c_str()); // Replace Data True if (fDataTrue) delete fDataTrue; fDataTrue = (TH1D*)fDataHist->Clone(); fDataTrue->SetNameTitle((fName + "_FAKE_TRUE").c_str(), (fName + fPlotTitles).c_str()); // Make a new covariance for fake data hist. int nbins = fDataHist->GetNbinsX(); double alpha_i = 0.0; double alpha_j = 0.0; for (int i = 0; i < nbins; i++) { for (int j = 0; j < nbins; j++) { alpha_i = fDataHist->GetBinContent(i + 1) / tempdata->GetBinContent(i + 1); alpha_j = fDataHist->GetBinContent(j + 1) / tempdata->GetBinContent(j + 1); (*fFullCovar)(i, j) = alpha_i * alpha_j * (*fFullCovar)(i, j); } } // Setup Covariances if (covar) delete covar; covar = StatUtils::GetInvert(fFullCovar); if (fDecomp) delete fDecomp; fDecomp = StatUtils::GetInvert(fFullCovar); delete tempdata; return; }; //******************************************************************** void Measurement1D::ResetFakeData() { //******************************************************************** if (fIsFakeData) { if (fDataHist) delete fDataHist; fDataHist = (TH1D*)fDataTrue->Clone((fSettings.GetName() + "_FKDAT").c_str()); } } //******************************************************************** void Measurement1D::ResetData() { //******************************************************************** if (fIsFakeData) { if (fDataHist) delete fDataHist; fDataHist = (TH1D*)fDataOrig->Clone((fSettings.GetName() + "_data").c_str()); } fIsFakeData = false; } //******************************************************************** void Measurement1D::ThrowCovariance() { //******************************************************************** // Take a fDecomposition and use it to throw the current dataset. // Requires fDataTrue also be set incase used repeatedly. if (!fDataTrue) fDataTrue = (TH1D*) fDataHist->Clone(); if (fDataHist) delete fDataHist; fDataHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar); return; }; //******************************************************************** void Measurement1D::ThrowDataToy(){ //******************************************************************** if (!fDataTrue) fDataTrue = (TH1D*) fDataHist->Clone(); if (fMCHist) delete fMCHist; fMCHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar); } /* Access Functions */ //******************************************************************** TH1D* Measurement1D::GetMCHistogram() { //******************************************************************** if (!fMCHist) return fMCHist; std::ostringstream chi2; chi2 << std::setprecision(5) << this->GetLikelihood(); int linecolor = kRed; int linestyle = 1; int linewidth = 1; int fillcolor = 0; int fillstyle = 1001; // if (fSettings.Has("linecolor")) linecolor = fSettings.GetI("linecolor"); // if (fSettings.Has("linestyle")) linestyle = fSettings.GetI("linestyle"); // if (fSettings.Has("linewidth")) linewidth = fSettings.GetI("linewidth"); // if (fSettings.Has("fillcolor")) fillcolor = fSettings.GetI("fillcolor"); // if (fSettings.Has("fillstyle")) fillstyle = fSettings.GetI("fillstyle"); fMCHist->SetTitle(chi2.str().c_str()); fMCHist->SetLineColor(linecolor); fMCHist->SetLineStyle(linestyle); fMCHist->SetLineWidth(linewidth); fMCHist->SetFillColor(fillcolor); fMCHist->SetFillStyle(fillstyle); return fMCHist; }; //******************************************************************** TH1D* Measurement1D::GetDataHistogram() { //******************************************************************** if (!fDataHist) return fDataHist; int datacolor = kBlack; int datastyle = 1; int datawidth = 1; // if (fSettings.Has("datacolor")) datacolor = fSettings.GetI("datacolor"); // if (fSettings.Has("datastyle")) datastyle = fSettings.GetI("datastyle"); // if (fSettings.Has("datawidth")) datawidth = fSettings.GetI("datawidth"); fDataHist->SetLineColor(datacolor); fDataHist->SetLineWidth(datawidth); fDataHist->SetMarkerStyle(datastyle); return fDataHist; }; /* Write Functions */ // Save all the histograms at once //******************************************************************** void Measurement1D::Write(std::string drawOpt) { //******************************************************************** // Get Draw Options drawOpt = FitPar::Config().GetParS("drawopts"); // Write Settigns if (drawOpt.find("SETTINGS") != std::string::npos){ fSettings.Set("#chi^{2}",fLikelihood); fSettings.Set("NDOF", this->GetNDOF() ); fSettings.Set("#chi^{2}/NDOF", fLikelihood / this->GetNDOF() ); fSettings.Write(); } // Write Data/MC GetDataList().at(0)->Write(); GetMCList().at(0)->Write(); if(fEvtRateScaleFactor != 0xdeadbeef){ TH1D * PredictedEvtRate = static_cast(GetMCList().at(0)->Clone()); PredictedEvtRate->Scale(fEvtRateScaleFactor); PredictedEvtRate->GetYaxis()->SetTitle("Predicted event rate"); PredictedEvtRate->Write(); } // Write Fine Histogram if (drawOpt.find("FINE") != std::string::npos) GetFineList().at(0)->Write(); // Write Weighted Histogram if (drawOpt.find("WEIGHTS") != std::string::npos && fMCWeighted) fMCWeighted->Write(); // Save Flux/Evt if no event manager if (!FitPar::Config().GetParB("EventManager")) { if (drawOpt.find("FLUX") != std::string::npos && GetFluxHistogram()) GetFluxHistogram()->Write(); if (drawOpt.find("EVT") != std::string::npos && GetEventHistogram()) GetEventHistogram()->Write(); if (drawOpt.find("XSEC") != std::string::npos && GetEventHistogram()) GetXSecHistogram()->Write(); } // Write Mask if (fIsMask && (drawOpt.find("MASK") != std::string::npos)) { fMaskHist->Write(); } // Write Covariances if (drawOpt.find("COV") != std::string::npos && fFullCovar) { PlotUtils::GetFullCovarPlot(fFullCovar, fSettings.GetName()); } if (drawOpt.find("INVCOV") != std::string::npos && covar) { PlotUtils::GetInvCovarPlot(covar, fSettings.GetName()); } if (drawOpt.find("DECOMP") != std::string::npos && fDecomp) { PlotUtils::GetDecompCovarPlot(fDecomp, fSettings.GetName()); } // // Likelihood residual plots // if (drawOpt.find("RESIDUAL") != std::string::npos) { // WriteResidualPlots(); // } // Ratio and Shape Plots if (drawOpt.find("RATIO") != std::string::npos) { WriteRatioPlot(); } if (drawOpt.find("SHAPE") != std::string::npos) { WriteShapePlot(); if (drawOpt.find("RATIO") != std::string::npos) WriteShapeRatioPlot(); } // // RATIO // if (drawOpt.find("CANVMC") != std::string::npos) { // TCanvas* c1 = WriteMCCanvas(fDataHist, fMCHist); // c1->Write(); // delete c1; // } // // PDG // if (drawOpt.find("CANVPDG") != std::string::npos && fMCHist_Modes) { // TCanvas* c2 = WritePDGCanvas(fDataHist, fMCHist, fMCHist_Modes); // c2->Write(); // delete c2; // } // Write Extra Histograms AutoWriteExtraTH1(); WriteExtraHistograms(); // Returning LOG(SAM) << "Written Histograms: " << fName << std::endl; return; } //******************************************************************** void Measurement1D::WriteRatioPlot() { //******************************************************************** // Setup mc data ratios TH1D* dataRatio = (TH1D*)fDataHist->Clone((fName + "_data_RATIO").c_str()); TH1D* mcRatio = (TH1D*)fMCHist->Clone((fName + "_MC_RATIO").c_str()); // Extra MC Data Ratios for (int i = 0; i < mcRatio->GetNbinsX(); i++) { dataRatio->SetBinContent(i + 1, fDataHist->GetBinContent(i + 1) / fMCHist->GetBinContent(i + 1)); dataRatio->SetBinError(i + 1, fDataHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1)); mcRatio->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1) / fMCHist->GetBinContent(i + 1)); mcRatio->SetBinError(i + 1, fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1)); } // Write ratios mcRatio->Write(); dataRatio->Write(); delete mcRatio; delete dataRatio; } //******************************************************************** void Measurement1D::WriteShapePlot() { //******************************************************************** TH1D* mcShape = (TH1D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str()); TH1D* dataShape = (TH1D*)fDataHist->Clone((fName + "_data_SHAPE").c_str()); if (fShapeCovar) StatUtils::SetDataErrorFromCov(dataShape, fShapeCovar, 1E-38); double shapeScale = 1.0; if (fIsRawEvents) { shapeScale = fDataHist->Integral() / fMCHist->Integral(); } else { shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width"); } mcShape->Scale(shapeScale); std::stringstream ss; ss << shapeScale; mcShape->SetTitle(ss.str().c_str()); mcShape->SetLineWidth(3); mcShape->SetLineStyle(7); mcShape->Write(); dataShape->Write(); delete mcShape; } //******************************************************************** void Measurement1D::WriteShapeRatioPlot() { //******************************************************************** // Get a mcshape histogram TH1D* mcShape = (TH1D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str()); double shapeScale = 1.0; if (fIsRawEvents) { shapeScale = fDataHist->Integral() / fMCHist->Integral(); } else { shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width"); } mcShape->Scale(shapeScale); // Create shape ratio histograms TH1D* mcShapeRatio = (TH1D*)mcShape->Clone((fName + "_MC_SHAPE_RATIO").c_str()); TH1D* dataShapeRatio = (TH1D*)fDataHist->Clone((fName + "_data_SHAPE_RATIO").c_str()); // Divide the histograms mcShapeRatio->Divide(mcShape); dataShapeRatio->Divide(mcShape); // Colour the shape ratio plots mcShapeRatio->SetLineWidth(3); mcShapeRatio->SetLineStyle(7); mcShapeRatio->Write(); dataShapeRatio->Write(); delete mcShapeRatio; delete dataShapeRatio; } //// CRAP TO BE REMOVED //******************************************************************** void Measurement1D::SetupMeasurement(std::string inputfile, std::string type, FitWeight * rw, std::string fkdt) { //******************************************************************** nuiskey samplekey = Config::CreateKey("sample"); - samplekey.AddS("name", fName); - samplekey.AddS("type",type); - samplekey.AddS("input",inputfile); + samplekey.Set("name", fName); + samplekey.Set("type",type); + samplekey.Set("input",inputfile); fSettings = LoadSampleSettings(samplekey); // Reset everything to NULL // Init(); // Check if name contains Evt, indicating that it is a raw number of events // measurements and should thus be treated as once fIsRawEvents = false; if ((fName.find("Evt") != std::string::npos) && fIsRawEvents == false) { fIsRawEvents = true; LOG(SAM) << "Found event rate measurement but fIsRawEvents == false!" << std::endl; LOG(SAM) << "Overriding this and setting fIsRawEvents == true!" << std::endl; } fIsEnu1D = false; if (fName.find("XSec_1DEnu") != std::string::npos) { fIsEnu1D = true; LOG(SAM) << "::" << fName << "::" << std::endl; LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, " "not flux averaged!" << std::endl; } if (fIsEnu1D && fIsRawEvents) { LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this " "really correct?!" << std::endl; LOG(SAM) << "Check experiment constructor for " << fName << " and correct this!" << std::endl; LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl; exit(-1); } fRW = rw; if (!fInput and !fIsJoint) SetupInputs(inputfile); // Set Default Options SetFitOptions(fDefaultTypes); // Set Passed Options SetFitOptions(type); // Still adding support for flat flux inputs // // Set Enu Flux Scaling // if (isFlatFluxFolding) this->Input()->ApplyFluxFolding( // this->defaultFluxHist ); // FinaliseMeasurement(); } //******************************************************************** void Measurement1D::SetupDefaultHist() { //******************************************************************** // Setup fMCHist fMCHist = (TH1D*)fDataHist->Clone(); fMCHist->SetNameTitle((fName + "_MC").c_str(), (fName + "_MC" + fPlotTitles).c_str()); // Setup fMCFine Int_t nBins = fMCHist->GetNbinsX(); fMCFine = new TH1D( (fName + "_MC_FINE").c_str(), (fName + "_MC_FINE" + fPlotTitles).c_str(), nBins * 6, fMCHist->GetBinLowEdge(1), fMCHist->GetBinLowEdge(nBins + 1)); fMCStat = (TH1D*)fMCHist->Clone(); fMCStat->Reset(); fMCHist->Reset(); fMCFine->Reset(); // Setup the NEUT Mode Array PlotUtils::CreateNeutModeArray((TH1D*)fMCHist, (TH1**)fMCHist_PDG); PlotUtils::ResetNeutModeArray((TH1**)fMCHist_PDG); // Setup bin masks using sample name if (fIsMask) { std::string maskloc = FitPar::Config().GetParDIR(fName + ".mask"); if (maskloc.empty()) { maskloc = FitPar::GetDataBase() + "/masks/" + fName + ".mask"; } SetBinMask(maskloc); } fMCHist_Modes = new TrueModeStack( (fName + "_MODES").c_str(), ("True Channels"), fMCHist); SetAutoProcessTH1(fMCHist_Modes, kCMD_Reset, kCMD_Norm, kCMD_Write); return; } //******************************************************************** void Measurement1D::SetDataValues(std::string dataFile) { //******************************************************************** // Override this function if the input file isn't in a suitable format LOG(SAM) << "Reading data from: " << dataFile.c_str() << std::endl; fDataHist = PlotUtils::GetTH1DFromFile(dataFile, (fName + "_data"), fPlotTitles); fDataTrue = (TH1D*)fDataHist->Clone(); // Number of data points is number of bins fNDataPointsX = fDataHist->GetXaxis()->GetNbins(); return; }; //******************************************************************** void Measurement1D::SetDataFromDatabase(std::string inhistfile, std::string histname) { //******************************************************************** LOG(SAM) << "Filling histogram from " << inhistfile << "->" << histname << std::endl; fDataHist = PlotUtils::GetTH1DFromRootFile( (GeneralUtils::GetTopLevelDir() + "/data/" + inhistfile), histname); fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_data").c_str()); return; }; //******************************************************************** void Measurement1D::SetDataFromFile(std::string inhistfile, std::string histname) { //******************************************************************** LOG(SAM) << "Filling histogram from " << inhistfile << "->" << histname << std::endl; fDataHist = PlotUtils::GetTH1DFromRootFile((inhistfile), histname); fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_data").c_str()); return; }; //******************************************************************** void Measurement1D::SetCovarMatrix(std::string covarFile) { //******************************************************************** // Covariance function, only really used when reading in the MB Covariances. TFile* tempFile = new TFile(covarFile.c_str(), "READ"); TH2D* covarPlot = new TH2D(); // TH2D* decmpPlot = new TH2D(); TH2D* covarInvPlot = new TH2D(); TH2D* fFullCovarPlot = new TH2D(); std::string covName = ""; std::string covOption = FitPar::Config().GetParS("thrown_covariance"); if (fIsShape || fIsFree) covName = "shp_"; if (fIsDiag) covName += "diag"; else covName += "full"; covarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str()); covarInvPlot = (TH2D*)tempFile->Get((covName + "covinv").c_str()); if (!covOption.compare("SUB")) fFullCovarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str()); else if (!covOption.compare("FULL")) fFullCovarPlot = (TH2D*)tempFile->Get("fullcov"); else ERR(WRN) << "Incorrect thrown_covariance option in parameters." << std::endl; int dim = int(fDataHist->GetNbinsX()); //-this->masked->Integral()); int covdim = int(fDataHist->GetNbinsX()); this->covar = new TMatrixDSym(dim); fFullCovar = new TMatrixDSym(dim); fDecomp = new TMatrixDSym(dim); int row, column = 0; row = 0; column = 0; for (Int_t i = 0; i < covdim; i++) { // if (this->masked->GetBinContent(i+1) > 0) continue; for (Int_t j = 0; j < covdim; j++) { // if (this->masked->GetBinContent(j+1) > 0) continue; (*this->covar)(row, column) = covarPlot->GetBinContent(i + 1, j + 1); (*fFullCovar)(row, column) = fFullCovarPlot->GetBinContent(i + 1, j + 1); column++; } column = 0; row++; } // Set bin errors on data if (!fIsDiag) { StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar); } // Get Deteriminant and inverse matrix // fCovDet = this->covar->Determinant(); TDecompSVD LU = TDecompSVD(*this->covar); this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); return; }; //******************************************************************** // Sets the covariance matrix from a provided file in a text format // scale is a multiplicative pre-factor to apply in the case where the // covariance is given in some unit (e.g. 1E-38) void Measurement1D::SetCovarMatrixFromText(std::string covarFile, int dim, double scale) { //******************************************************************** // Make a counter to track the line number int row = 0; std::string line; std::ifstream covarread(covarFile.c_str(), ifstream::in); this->covar = new TMatrixDSym(dim); fFullCovar = new TMatrixDSym(dim); if (covarread.is_open()) LOG(SAM) << "Reading covariance matrix from file: " << covarFile << std::endl; else ERR(FTL) << "Covariance matrix provided is incorrect: " << covarFile << std::endl; // Loop over the lines in the file while (std::getline(covarread >> std::ws, line, '\n')) { int column = 0; // Loop over entries and insert them into matrix std::vector entries = GeneralUtils::ParseToDbl(line, " "); if (entries.size() <= 1) { ERR(WRN) << "SetCovarMatrixFromText -> Covariance matrix only has <= 1 " "entries on this line: " << row << std::endl; } for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { (*covar)(row, column) = *iter; (*fFullCovar)(row, column) = *iter; column++; } row++; } covarread.close(); // Scale the actualy covariance matrix by some multiplicative factor (*fFullCovar) *= scale; // Robust matrix inversion method TDecompSVD LU = TDecompSVD(*this->covar); // THIS IS ACTUALLY THE INVERSE COVARIANCE MATRIXA AAAAARGH delete this->covar; this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); // Now need to multiply by the scaling factor // If the covariance (*this->covar) *= 1. / (scale); return; }; //******************************************************************** void Measurement1D::SetCovarMatrixFromCorrText(std::string corrFile, int dim) { //******************************************************************** // Make a counter to track the line number int row = 0; std::string line; std::ifstream corr(corrFile.c_str(), ifstream::in); this->covar = new TMatrixDSym(dim); this->fFullCovar = new TMatrixDSym(dim); if (corr.is_open()) LOG(SAM) << "Reading and converting correlation matrix from file: " << corrFile << std::endl; else { ERR(FTL) << "Correlation matrix provided is incorrect: " << corrFile << std::endl; exit(-1); } while (std::getline(corr >> std::ws, line, '\n')) { int column = 0; // Loop over entries and insert them into matrix // Multiply by the errors to get the covariance, rather than the correlation // matrix std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { double val = (*iter) * this->fDataHist->GetBinError(row + 1) * 1E38 * this->fDataHist->GetBinError(column + 1) * 1E38; if (val == 0) { ERR(FTL) << "Found a zero value in the covariance matrix, assuming " "this is an error!" << std::endl; exit(-1); } (*this->covar)(row, column) = val; (*this->fFullCovar)(row, column) = val; column++; } row++; } // Robust matrix inversion method TDecompSVD LU = TDecompSVD(*this->covar); delete this->covar; this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); return; }; //******************************************************************** // FullUnits refers to if we have "real" unscaled units in the covariance matrix, e.g. 1E-76. // If this is the case we need to scale it so that the chi2 contribution is correct // NUISANCE internally assumes the covariance matrix has units of 1E76 void Measurement1D::SetCovarFromDataFile(std::string covarFile, std::string covName, bool FullUnits) { //******************************************************************** LOG(SAM) << "Getting covariance from " << covarFile << "->" << covName << std::endl; TFile* tempFile = new TFile(covarFile.c_str(), "READ"); TH2D* covPlot = (TH2D*)tempFile->Get(covName.c_str()); covPlot->SetDirectory(0); // Scale the covariance matrix if it comes in normal units if (FullUnits) { covPlot->Scale(1.E76); } int dim = covPlot->GetNbinsX(); fFullCovar = new TMatrixDSym(dim); for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { (*fFullCovar)(i, j) = covPlot->GetBinContent(i + 1, j + 1); } } this->covar = (TMatrixDSym*)fFullCovar->Clone(); fDecomp = (TMatrixDSym*)fFullCovar->Clone(); TDecompSVD LU = TDecompSVD(*this->covar); this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); TDecompChol LUChol = TDecompChol(*fDecomp); LUChol.Decompose(); fDecomp = new TMatrixDSym(dim, LU.GetU().GetMatrixArray(), ""); return; }; // //******************************************************************** // void Measurement1D::SetBinMask(std::string maskFile) { // //******************************************************************** // // Create a mask histogram. // int nbins = fDataHist->GetNbinsX(); // fMaskHist = // new TH1I((fName + "_fMaskHist").c_str(), // (fName + "_fMaskHist; Bin; Mask?").c_str(), nbins, 0, nbins); // std::string line; // std::ifstream mask(maskFile.c_str(), ifstream::in); // if (mask.is_open()) // LOG(SAM) << "Reading bin mask from file: " << maskFile << std::endl; // else // LOG(FTL) << " Cannot find mask file." << std::endl; // while (std::getline(mask >> std::ws, line, '\n')) { // std::vector entries = GeneralUtils::ParseToInt(line, " "); // // Skip lines with poorly formatted lines // if (entries.size() < 2) { // LOG(WRN) << "Measurement1D::SetBinMask(), couldn't parse line: " << line // << std::endl; // continue; // } // // The first index should be the bin number, the second should be the mask // // value. // fMaskHist->SetBinContent(entries[0], entries[1]); // } // // Set masked data bins to zero // PlotUtils::MaskBins(fDataHist, fMaskHist); // return; // } // //******************************************************************** // void Measurement1D::GetBinContents(std::vector& cont, // std::vector& err) { // //******************************************************************** // // Return a vector of the main bin contents // for (int i = 0; i < fMCHist->GetNbinsX(); i++) { // cont.push_back(fMCHist->GetBinContent(i + 1)); // err.push_back(fMCHist->GetBinError(i + 1)); // } // return; // }; /* XSec Functions */ // //******************************************************************** // void Measurement1D::SetFluxHistogram(std::string fluxFile, int minE, int // maxE, // double fluxNorm) { // //******************************************************************** // // Note this expects the flux bins to be given in terms of MeV // LOG(SAM) << "Reading flux from file: " << fluxFile << std::endl; // TGraph f(fluxFile.c_str(), "%lg %lg"); // fFluxHist = // new TH1D((fName + "_flux").c_str(), (fName + "; E_{#nu} (GeV)").c_str(), // f.GetN() - 1, minE, maxE); // Double_t* yVal = f.GetY(); // for (int i = 0; i < fFluxHist->GetNbinsX(); ++i) // fFluxHist->SetBinContent(i + 1, yVal[i] * fluxNorm); // }; // //******************************************************************** // double Measurement1D::TotalIntegratedFlux(std::string intOpt, double low, // double high) { // //******************************************************************** // if (fInput->GetType() == kGiBUU) { // return 1.0; // } // // The default case of low = -9999.9 and high = -9999.9 // if (low == -9999.9) low = this->EnuMin; // if (high == -9999.9) high = this->EnuMax; // int minBin = fFluxHist->GetXaxis()->FindBin(low); // int maxBin = fFluxHist->GetXaxis()->FindBin(high); // // Get integral over custom range // double integral = fFluxHist->Integral(minBin, maxBin + 1, intOpt.c_str()); // return integral; // }; diff --git a/src/FitBase/Measurement1D.h b/src/FitBase/Measurement1D.h index 404ba50..dbd6471 100644 --- a/src/FitBase/Measurement1D.h +++ b/src/FitBase/Measurement1D.h @@ -1,655 +1,656 @@ // Copyright 2016 L. Pickering, P towell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #ifndef MEASUREMENT_1D_H_SEEN #define MEASUREMENT_1D_H_SEEN /*! * \addtogroup FitBase * @{ */ #include #include #include #include #include #include #include #include // ROOT includes #include #include #include #include #include #include #include #include #include #include #include #include // External data fit includes #include "FitEvent.h" -#include "FitParameters.h" + #include "FitUtils.h" #include "MeasurementBase.h" #include "PlotUtils.h" #include "StatUtils.h" #include "SignalDef.h" #include "MeasurementVariableBox.h" #include "MeasurementVariableBox1D.h" namespace NUISANCE { namespace FitBase { } } //******************************************************************** /// 1D Measurement base class. Histogram handling is done in this base layer. class Measurement1D : public MeasurementBase { //******************************************************************** public: /* Constructor/Deconstuctor */ Measurement1D(void); virtual ~Measurement1D(void); /* Setup Functions */ /// \brief Setup all configs once initialised /// /// Should be called after all configs have been setup inside fSettings container. /// Handles the processing of inputs and setting up of types. /// Replaces the old 'SetupMeasurement' function. void FinaliseSampleSettings(); /// \brief Creates the 1D data distribution given the binning provided. virtual void CreateDataHistogram(int dimx, double* binx); /// \brief Read 1D data inputs from a text file. /// /// Inputfile should have the format: \n /// low_binedge_1 bin_content_1 bin_error_1 \n /// low_binedge_2 bin_content_2 bin_error_2 \n /// .... .... .... \n /// high_bin_edge_N 0.0 0.0 virtual void SetDataFromTextFile(std::string datafile); /// \brief Read 1D data inputs from a root file. /// /// inhistfile specifies the path to the root file /// histname specifies the name of the histogram. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ';' so that: \n /// 'myhistfile.root;myhistname' \n /// will also work. virtual void SetDataFromRootFile(std::string inhistfile, std::string histname = ""); /// \brief Setup a default empty data histogram /// /// Only used for flattree creators. virtual void SetEmptyData(); /// \brief Set data bin errors to sqrt(entries) /// /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST /// /// Sets the data errors as the sqrt of the bin contents /// Should be use for counting experiments virtual void SetPoissonErrors(); /// \brief Make diagonal covariance from data /// /// \warning If no histogram passed, data must be setup first! /// Setup the covariance inputs by taking the data histogram /// errors and setting up a diagonal covariance matrix. /// /// If no data is supplied, fDataHist is used if already set. virtual void SetCovarFromDiagonal(TH1D* data = NULL); /// \brief Read the data covariance from a text file. /// /// Inputfile should have the format: \n /// covariance_11 covariance_12 covariance_13 ... \n /// covariance_21 covariance_22 covariance_23 ... \n /// ... ... ... ... \n /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCovarFromTextFile(std::string covfile, int dim = -1); virtual void SetCovarFromMultipleTextFiles(std::string covfiles, int dim = -1); /// \brief Read the data covariance from a ROOT file. /// /// - covfile specifies the full path to the file /// - histname specifies the name of the covariance object. Both TMatrixDSym and TH2D are supported. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCovarFromRootFile(std::string covfile, std::string histname=""); /// \brief Read the inverted data covariance from a text file. /// /// Inputfile should have similar format to that shown /// in SetCovarFromTextFile. /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCovarInvertFromTextFile(std::string covfile, int dim = -1); /// \brief Read the inverted data covariance from a ROOT file. /// /// Inputfile should have similar format to that shown /// in SetCovarFromRootFile. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCovarInvertFromRootFile(std::string covfile, std::string histname=""); /// \brief Read the data correlations from a text file. /// /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST /// /// Inputfile should have similar format to that shown /// in SetCovarFromTextFile. /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCorrelationFromTextFile(std::string covfile, int dim = -1); /// \brief Read the data correlations from multiple text files. /// /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST /// /// Inputfile should have similar format to that shown /// in SetCovarFromTextFile. /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of the first corrfile. virtual void SetCorrelationFromMultipleTextFiles(std::string corrfiles, int dim = -1); /// \brief Read the data correlations from a ROOT file. /// /// \warning REQUIRES DATA TO BE SET FIRST /// /// Inputfile should have similar format to that shown /// in SetCovarFromRootFile. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCorrelationFromRootFile(std::string covfile, std::string histname=""); /// \brief Read the cholesky decomposed covariance from a text file and turn it into a covariance /// /// Inputfile should have similar format to that shown /// in SetCovarFromTextFile. /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCholDecompFromTextFile(std::string covfile, int dim = -1); /// \brief Read the cholesky decomposed covariance from a ROOT file and turn it into a covariance /// /// Inputfile should have similar format to that shown /// in SetCovarFromRootFile. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCholDecompFromRootFile(std::string covfile, std::string histname=""); /// \brief Try to extract a shape-only matrix from the existing covariance virtual void SetShapeCovar(); /// \brief Scale the data by some scale factor virtual void ScaleData(double scale); /// \brief Scale the data error bars by some scale factor virtual void ScaleDataErrors(double scale); /// \brief Scale the covariaince and its invert/decomp by some scale factor. virtual void ScaleCovar(double scale); /// \brief Setup a bin masking histogram and apply masking to data /// /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST /// /// Reads in a list of bins in a text file to be masked. Format is: \n /// bin_index_1 1 \n /// bin_index_2 1 \n /// bin_index_3 1 \n /// /// If 0 is given then a bin entry will NOT be masked. So for example: \n\n /// 1 1 \n /// 2 1 \n /// 3 0 \n /// 4 1 \n\n /// Will mask only the 1st, 2nd, and 4th bins. /// /// Masking can be turned on by specifiying the MASK option when creating a sample. /// When this is passed NUISANCE will look in the following locations for the mask file: /// - FitPar::Config().GetParS(fName + ".mask") /// - "data/masks/" + fName + ".mask"; virtual void SetBinMask(std::string maskfile); /// \brief Set the current fit options from a string. /// /// This is called twice for each sample, once to set the default /// and once to set the current setting (if anything other than default given) /// /// For this to work properly it requires the default and allowed types to be /// set correctly. These should be specified as a string listing options. /// /// To split up options so that NUISANCE can automatically detect ones that /// are conflicting. Any options seperated with the '/' symbol are non conflicting /// and can be given together, whereas any seperated with the ',' symbol cannot /// be specified by the end user at the same time. /// /// Default Type Examples: /// - DIAG/FIX = Default option will be a diagonal covariance, with FIXED norm. /// - MASK/SHAPE = Default option will be a masked hist, with SHAPE always on. /// /// Allowed Type examples: /// - 'FULL/DIAG/NORM/MASK' = Any of these options can be specified. /// - 'FULL,FREE,SHAPE/MASK/NORM' = User can give either FULL, FREE, or SHAPE as on option. /// MASK and NORM can also be included as options. virtual void SetFitOptions(std::string opt); /// \brief Final constructor setup /// \warning Should be called right at the end of the constructor. /// /// Contains a series of checks to ensure the data and inputs have been setup. /// Also creates the MC histograms needed for fitting. void FinaliseMeasurement(); /* Smearing */ /// \brief Read in smearing matrix from file /// /// Set the smearing matrix from a text file given the size of the matrix virtual void SetSmearingMatrix(std::string smearfile, int truedim, int recodim); /// \brief Apply smearing to MC true to get MC reco /// /// Apply smearing matrix to fMCHist using fSmearingMatrix virtual void ApplySmearingMatrix(void); /* Reconfigure Functions */ /// \brief Create a Measurement1D box /// /// Creates a new 1D variable box containing just fXVar. /// /// This box is the bare minimum required by the JointFCN when /// running fast reconfigures during a routine. /// If for some reason a sample needs extra variables to be saved then /// it should override this function creating its own MeasurementVariableBox /// that contains the extra variables. virtual MeasurementVariableBox* CreateBox() {return new MeasurementVariableBox1D();}; /// \brief Reset all MC histograms /// /// Resets all standard histograms and those registered to auto /// process to zero. /// /// If extra histograms are not included in auto processing, then they must be reset /// by overriding this function and doing it manually if required. virtual void ResetAll(void); /// \brief Fill MC Histograms from XVar /// /// Fill standard histograms using fXVar, Weight read from the variable box. /// /// WARNING : Any extra MC histograms need to be filled by overriding this function, /// even if they have been set to auto process. virtual void FillHistograms(void); // \brief Convert event rates to final histogram /// /// Apply standard scaling procedure to standard mc histograms to convert from /// raw events to xsec prediction. /// /// If any distributions have been set to auto process /// that is done during this function call, and a differential xsec is assumed. /// If that is not the case this function must be overriden. virtual void ScaleEvents(void); /// \brief Scale MC by a factor=1/norm /// /// Apply a simple normalisation scaling if the option FREE or a norm_parameter /// has been specified in the NUISANCE routine. virtual void ApplyNormScale(double norm); /* Statistical Functions */ /// \brief Get Number of degrees of freedom /// /// Returns the number bins inside the data histogram accounting for /// any bin masking applied. virtual int GetNDOF(void); /// \brief Return Data/MC Likelihood at current state /// /// Returns the likelihood of the data given the current MC prediction. /// Diferent likelihoods definitions are used depending on the FitOptions. virtual double GetLikelihood(void); /* Fake Data */ /// \brief Set the fake data values from either a file, or MC /// /// - Setting from a file "path": \n /// When reading from a file the full path must be given to a standard /// nuisance output. The standard MC histogram should have a name that matches /// this sample for it to be read in. /// \n\n /// - Setting from "MC": \n /// If the MC option is given the current MC prediction is used as fake data. virtual void SetFakeDataValues(std::string fakeOption); /// \brief Reset fake data back to starting fake data /// /// Reset the fake data back to original fake data (Reset back to before /// ThrowCovariance was first called) virtual void ResetFakeData(void); /// \brief Reset fake data back to original data /// /// Reset the data histogram back to the true original dataset for this sample /// before any fake data was defined. virtual void ResetData(void); /// \brief Generate fake data by throwing the covariance. /// /// Can be used on fake MC data or just the original dataset. /// Call ResetFakeData or ResetData to return to values before the throw. virtual void ThrowCovariance(void); /// \brief Throw the data by its assigned errors and assign this to MC /// /// Used when creating data toys by assign the MC to this thrown data /// so that the likelihood is calculated between data and thrown data virtual void ThrowDataToy(void); /* Access Functions */ /// \brief Returns nicely formatted MC Histogram /// /// Format options can also be given in the samplesettings: /// - linecolor /// - linestyle /// - linewidth /// - fillcolor /// - fillstyle /// /// So to have a sample line colored differently in the xml cardfile put: \n /// virtual TH1D* GetMCHistogram(void); /// \brief Returns nicely formatted data Histogram /// /// Format options can also be given in the samplesettings: /// - datacolor /// - datastyle /// - datawidth /// /// So to have a sample data colored differently in the xml cardfile put: \n /// virtual TH1D* GetDataHistogram(void); /// \brief Returns a list of all MC histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. inline virtual std::vector GetMCList(void) { return std::vector(1, GetMCHistogram()); } /// \brief Returns a list of all Data histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. inline virtual std::vector GetDataList(void) { return std::vector(1, GetDataHistogram()); } /// \brief Returns a list of all Mask histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. inline virtual std::vector GetMaskList(void) { return std::vector(1, fMaskHist); }; /// \brief Returns a list of all Fine histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. inline virtual std::vector GetFineList(void) { return std::vector(1, fMCFine); }; /* Write Functions */ /// \brief Save the current state to the current TFile directory \n /// /// Data/MC are both saved by default. /// A range of other histograms can be saved by setting the /// config option 'drawopts'. /// /// Possible options: \n /// - FINE = Write Fine Histogram \n /// - WEIGHTS = Write Weighted MC Histogram (before scaling) \n /// - FLUX = Write Flux Histogram from MC Input \n /// - EVT = Write Event Histogram from MC Input \n /// - XSEC = Write XSec Histogram from MC Input \n /// - MASK = Write Mask Histogram \n /// - COV = Write Covariance Histogram \n /// - INVCOV = Write Inverted Covariance Histogram \n /// - DECMOP = Write Decomp. Covariance Histogram \n /// - RESIDUAL= Write Resudial Histograms \n /// - RATIO = Write Data/MC Ratio Histograms \n /// - SHAPE = Write MC Shape Histograms norm. to Data \n /// - CANVMC = Build MC Canvas Showing Data, MC, Shape \n /// - MODES = Write PDG Stack \n /// - CANVPDG = Build MC Canvas Showing Data, PDGStack \n /// /// So to save a range of these in parameters/config.xml set: \n /// virtual void Write(std::string drawOpt); virtual void WriteRatioPlot(); virtual void WriteShapePlot(); virtual void WriteShapeRatioPlot(); //* // OLD DEFUNCTIONS // /// OLD FUNCTION virtual void SetupMeasurement(std::string input, std::string type, FitWeight* rw, std::string fkdt); /// OLD FUNCTION virtual void SetupDefaultHist(void); /// OLD FUNCTION virtual void SetDataValues(std::string dataFile); /// OLD FUNCTION virtual void SetDataFromFile(std::string inhistfile, std::string histname); /// OLD FUNCTION virtual void SetDataFromDatabase(std::string inhistfile, std::string histname); /// OLD FUNCTION virtual void SetCovarMatrix(std::string covarFile); /// OLD FUNCTION virtual void SetCovarMatrixFromText(std::string covarFile, int dim, double scale = 1.0); /// OLD FUNCTION virtual void SetCovarMatrixFromCorrText(std::string covarFile, int dim); /// OLD FUNCTION virtual void SetCovarFromDataFile(std::string covarFile, std::string covName, bool FullUnits = false); /// OLD FUNCTION // virtual THStack GetModeStack(void); protected: // Data TH1D* fDataHist; ///< default data histogram TH1D* fDataOrig; ///< histogram to store original data before throws. TH1D* fDataTrue; ///< histogram to store true dataset std::string fPlotTitles; ///< Plot title x and y for the histograms // MC TH1D* fMCHist; ///< default MC Histogram used in the chi2 fits TH1D* fMCFine; ///< finely binned MC histogram TH1D* fMCStat; ///< histogram with unweighted events to properly calculate TH1D* fMCWeighted; ///< Weighted histogram before xsec scaling TH1I* fMaskHist; ///< Mask histogram for neglecting specific bins TMatrixD* fSmearMatrix; ///< Smearing matrix (note, this is not symmetric) TrueModeStack* fMCHist_Modes; ///< Optional True Mode Stack // Statistical TMatrixDSym* covar; ///< Inverted Covariance TMatrixDSym* fFullCovar; ///< Full Covariance TMatrixDSym* fDecomp; ///< Decomposed Covariance TMatrixDSym* fCorrel; ///< Correlation Matrix TMatrixDSym* fShapeCovar; ///< Shape-only covariance TMatrixDSym* fShapeDecomp; ///< Decomposed shape-only covariance + TMatrixDSym* fShapeInvert; ///< Inverted shape-only covariance TMatrixDSym* fCovar; ///< New FullCovar TMatrixDSym* fInvert; ///< New covar double fNormError; ///< Sample norm error double fLikelihood; ///< Likelihood value // Fake Data bool fIsFakeData; ///< Flag: is the current data fake from MC std::string fFakeDataInput; ///< Input fake data file path TFile* fFakeDataFile; ///< Input fake data file // Fit specific flags std::string fFitType; ///< Current fit type std::string fAllowedTypes; ///< Fit Types Possible std::string fDefaultTypes; ///< Starting Default Fit Types bool fIsShape; ///< Flag : Perform Shape-only fit bool fIsFree; ///< Flag : Perform normalisation free fit bool fIsDiag; ///< Flag : only include uncorrelated diagonal errors bool fIsMask; ///< Flag : Apply bin masking bool fIsRawEvents; ///< Flag : Are bin contents just event rates bool fIsEnu1D; ///< Flag : Perform Flux Unfolded Scaling bool fIsChi2SVD; ///< Flag : Use alternative Chi2 SVD Method (Do not use) bool fAddNormPen; ///< Flag : Add a normalisation penalty term to the chi2. bool fIsFix; ///< Flag : keeping norm fixed bool fIsFull; ///< Flag : using full covariaince bool fIsDifXSec; ///< Flag : creating a dif xsec bool fIsChi2; ///< Flag : using Chi2 over LL methods bool fIsSmeared; ///< Flag : Apply smearing? /// OLD STUFF TO REMOVE TH1D* fMCHist_PDG[61]; ///< REMOVE OLD MC PDG Plot // Arrays for data entries Double_t* fXBins; ///< REMOVE xBin edges Double_t* fDataValues; ///< REMOVE data bin contents Double_t* fDataErrors; ///< REMOVE data bin errors Int_t fNDataPointsX; ///< REMOVE number of data points }; /*! @} */ #endif diff --git a/src/FitBase/Measurement2D.cxx b/src/FitBase/Measurement2D.cxx index 33fdd0f..87f361f 100644 --- a/src/FitBase/Measurement2D.cxx +++ b/src/FitBase/Measurement2D.cxx @@ -1,1961 +1,1961 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "Measurement2D.h" #include "TDecompChol.h" //******************************************************************** Measurement2D::Measurement2D(void) { //******************************************************************** covar = NULL; fDecomp = NULL; fFullCovar = NULL; fMCHist = NULL; fMCFine = NULL; fDataHist = NULL; fMCHist_X = NULL; fMCHist_Y = NULL; fDataHist_X = NULL; fDataHist_Y = NULL; fMaskHist = NULL; fMapHist = NULL; fDataOrig = NULL; fDataTrue = NULL; fMCWeighted = NULL; fDefaultTypes = "FIX/FULL/CHI2"; fAllowedTypes = "FIX,FREE,SHAPE/FULL,DIAG/CHI2/NORM/ENUCORR/Q2CORR/ENU1D/FITPROJX/" "FITPROJY"; fIsFix = false; fIsShape = false; fIsFree = false; fIsDiag = false; fIsFull = false; fAddNormPen = false; fIsMask = false; fIsChi2SVD = false; fIsRawEvents = false; fIsDifXSec = false; fIsEnu = false; // XSec Scalings fScaleFactor = -1.0; fCurrentNorm = 1.0; // Histograms fDataHist = NULL; fDataTrue = NULL; fMCHist = NULL; fMCFine = NULL; fMCWeighted = NULL; fMaskHist = NULL; // Covar covar = NULL; fFullCovar = NULL; fCovar = NULL; fInvert = NULL; fDecomp = NULL; // Fake Data fFakeDataInput = ""; fFakeDataFile = NULL; // Options fDefaultTypes = "FIX/FULL/CHI2"; fAllowedTypes = "FIX,FREE,SHAPE/FULL,DIAG/CHI2/NORM/ENUCORR/Q2CORR/ENU1D/MASK"; fIsFix = false; fIsShape = false; fIsFree = false; fIsDiag = false; fIsFull = false; fAddNormPen = false; fIsMask = false; fIsChi2SVD = false; fIsRawEvents = false; fIsDifXSec = false; fIsEnu1D = false; // Inputs fInput = NULL; fRW = NULL; // Extra Histograms fMCHist_Modes = NULL; } //******************************************************************** Measurement2D::~Measurement2D(void) { //******************************************************************** if (fDataHist) delete fDataHist; if (fDataTrue) delete fDataTrue; if (fMCHist) delete fMCHist; if (fMCFine) delete fMCFine; if (fMCWeighted) delete fMCWeighted; if (fMaskHist) delete fMaskHist; if (covar) delete covar; if (fFullCovar) delete fFullCovar; if (fCovar) delete fCovar; if (fInvert) delete fInvert; if (fDecomp) delete fDecomp; } //******************************************************************** void Measurement2D::FinaliseSampleSettings() { //******************************************************************** MeasurementBase::FinaliseSampleSettings(); // Setup naming + renaming fName = fSettings.GetName(); fSettings.SetS("originalname", fName); if (fSettings.Has("rename")) { fName = fSettings.GetS("rename"); fSettings.SetS("name", fName); } // Setup all other options LOG(SAM) << "Finalising Sample Settings: " << fName << std::endl; if ((fSettings.GetS("originalname").find("Evt") != std::string::npos)) { fIsRawEvents = true; LOG(SAM) << "Found event rate measurement but using poisson likelihoods." << std::endl; } if (fSettings.GetS("originalname").find("XSec_1DEnu") != std::string::npos) { fIsEnu1D = true; LOG(SAM) << "::" << fName << "::" << std::endl; LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, " << "not flux averaged!" << std::endl; } if (fIsEnu1D && fIsRawEvents) { LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this " "really correct?!" << std::endl; LOG(SAM) << "Check experiment constructor for " << fName << " and correct this!" << std::endl; LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl; exit(-1); } if (!fRW) fRW = FitBase::GetRW(); if (!fInput) SetupInputs(fSettings.GetS("input")); // Setup options SetFitOptions(fDefaultTypes); // defaults SetFitOptions(fSettings.GetS("type")); // user specified EnuMin = GeneralUtils::StrToDbl(fSettings.GetS("enu_min")); EnuMax = GeneralUtils::StrToDbl(fSettings.GetS("enu_max")); if (fAddNormPen) { fNormError = fSettings.GetNormError(); if (fNormError <= 0.0) { ERR(WRN) << "Norm error for class " << fName << " is 0.0!" << std::endl; ERR(WRN) << "If you want to use it please add fNormError=VAL" << std::endl; throw; } } } void Measurement2D::CreateDataHistogram(int dimx, double* binx, int dimy, double* biny) { if (fDataHist) delete fDataHist; LOG(SAM) << "Creating Data Histogram dim : " << dimx << " " << dimy << std::endl; fDataHist = new TH2D( (fSettings.GetName() + "_data").c_str(), (fSettings.GetFullTitles()).c_str(), dimx - 1, binx, dimy - 1, biny ); } void Measurement2D::SetDataFromTextFile(std::string datfile) { // fDataHist = PlotUtils::GetTH2DFromTextFile(datfile,""); } void Measurement2D::SetDataFromRootFile(std::string datfile, std::string histname) { fDataHist = PlotUtils::GetTH2DFromRootFile(datfile, histname); } void Measurement2D::SetDataValuesFromTextFile(std::string datfile, TH2D* hist) { LOG(SAM) << "Setting data values from text file" << std::endl; if (!hist) hist = fDataHist; // Read TH2D From textfile TH2D* valhist = (TH2D*) hist->Clone(); valhist->Reset(); PlotUtils::Set2DHistFromText(datfile, valhist, 1.0, true); LOG(SAM) << " -> Filling values from read hist." << std::endl; for (int i = 0; i < valhist->GetNbinsX(); i++) { for (int j = 0; j < valhist->GetNbinsY(); j++) { hist->SetBinContent(i + 1, j + 1, valhist->GetBinContent(i + 1, j + 1)); } } LOG(SAM) << " --> Done" << std::endl; } void Measurement2D::SetDataErrorsFromTextFile(std::string datfile, TH2D* hist) { LOG(SAM) << "Setting data errors from text file" << std::endl; if (!hist) hist = fDataHist; // Read TH2D From textfile TH2D* valhist = (TH2D*) hist->Clone(); valhist->Reset(); PlotUtils::Set2DHistFromText(datfile, valhist, 1.0); // Fill Errors LOG(SAM) << " -> Filling errors from read hist." << std::endl; for (int i = 0; i < valhist->GetNbinsX(); i++) { for (int j = 0; j < valhist->GetNbinsY(); j++) { hist->SetBinError(i + 1, j + 1, valhist->GetBinContent(i + 1, j + 1)); } } LOG(SAM) << " --> Done" << std::endl; } void Measurement2D::SetMapValuesFromText(std::string dataFile) { TH2D* hist = fDataHist; std::vector edgex; std::vector edgey; for (int i = 0; i <= hist->GetNbinsX(); i++) edgex.push_back(hist->GetXaxis()->GetBinLowEdge(i + 1)); for (int i = 0; i <= hist->GetNbinsY(); i++) edgey.push_back(hist->GetYaxis()->GetBinLowEdge(i + 1)); fMapHist = new TH2I((fName + "_map").c_str(), (fName + fPlotTitles).c_str(), edgex.size() - 1, &edgex[0], edgey.size() - 1, &edgey[0]); LOG(SAM) << "Reading map from: " << dataFile << std::endl; PlotUtils::Set2DHistFromText(dataFile, fMapHist, 1.0); } //******************************************************************** void Measurement2D::SetPoissonErrors() { //******************************************************************** if (!fDataHist) { ERR(FTL) << "Need a data hist to setup possion errors! " << std::endl; ERR(FTL) << "Setup Data First!" << std::endl; throw; } for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) { fDataHist->SetBinError(i + 1, sqrt(fDataHist->GetBinContent(i + 1))); } } //******************************************************************** void Measurement2D::SetCovarFromDiagonal(TH2D* data) { //******************************************************************** if (!data and fDataHist) { data = fDataHist; } if (data) { LOG(SAM) << "Setting diagonal covariance for: " << data->GetName() << std::endl; fFullCovar = StatUtils::MakeDiagonalCovarMatrix(data); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } else { ERR(FTL) << "No data input provided to set diagonal covar from!" << std::endl; } // if (!fIsDiag) { // ERR(FTL) << "SetCovarMatrixFromDiag called for measurement " // << "that is not set as diagonal." << std::endl; // throw; // } } //******************************************************************** void Measurement2D::SetCovarFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) { dim = this->GetNDOF(); } - LOG(SAM) << "Reading covariance from text file: " << covfile << std::endl; + LOG(SAM) << "Reading covariance from text file: " << covfile << " " << dim << std::endl; fFullCovar = StatUtils::GetCovarFromTextFile(covfile, dim); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement2D::SetCovarFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading covariance from text file: " << covfile << ";" << histname << std::endl; fFullCovar = StatUtils::GetCovarFromRootFile(covfile, histname); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement2D::SetCovarInvertFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) { dim = this->GetNDOF(); } LOG(SAM) << "Reading inverted covariance from text file: " << covfile << std::endl; covar = StatUtils::GetCovarFromTextFile(covfile, dim); fFullCovar = StatUtils::GetInvert(covar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement2D::SetCovarInvertFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading inverted covariance from text file: " << covfile << ";" << histname << std::endl; covar = StatUtils::GetCovarFromRootFile(covfile, histname); fFullCovar = StatUtils::GetInvert(covar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement2D::SetCorrelationFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) dim = this->GetNDOF(); LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << dim << std::endl; TMatrixDSym* correlation = StatUtils::GetCovarFromTextFile(covfile, dim); if (!fDataHist) { ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n" << "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl; throw; } // Fill covar from data errors and correlations fFullCovar = new TMatrixDSym(dim); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { (*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76; } } // Fill other covars. covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete correlation; } //******************************************************************** void Measurement2D::SetCorrelationFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << histname << std::endl; TMatrixDSym* correlation = StatUtils::GetCovarFromRootFile(covfile, histname); if (!fDataHist) { ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n" << "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl; throw; } // Fill covar from data errors and correlations fFullCovar = new TMatrixDSym(fDataHist->GetNbinsX()); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { (*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76; } } // Fill other covars. covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete correlation; } //******************************************************************** void Measurement2D::SetCholDecompFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) { dim = this->GetNDOF(); } LOG(SAM) << "Reading cholesky from text file: " << covfile << " " << dim << std::endl; TMatrixD* temp = StatUtils::GetMatrixFromTextFile(covfile, dim, dim); TMatrixD* trans = (TMatrixD*)temp->Clone(); trans->T(); (*trans) *= (*temp); fFullCovar = new TMatrixDSym(dim, trans->GetMatrixArray(), ""); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete temp; delete trans; } //******************************************************************** void Measurement2D::SetCholDecompFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading cholesky decomp from root file: " << covfile << ";" << histname << std::endl; TMatrixD* temp = StatUtils::GetMatrixFromRootFile(covfile, histname); TMatrixD* trans = (TMatrixD*)temp->Clone(); trans->T(); (*trans) *= (*temp); fFullCovar = new TMatrixDSym(temp->GetNrows(), trans->GetMatrixArray(), ""); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete temp; delete trans; } //******************************************************************** void Measurement2D::ScaleData(double scale) { //******************************************************************** fDataHist->Scale(scale); } //******************************************************************** void Measurement2D::ScaleDataErrors(double scale) { //******************************************************************** for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsY(); j++) { fDataHist->SetBinError(i + 1, j + 1, fDataHist->GetBinError(i + 1, j + 1) * scale); } } } //******************************************************************** void Measurement2D::ScaleCovar(double scale) { //******************************************************************** (*fFullCovar) *= scale; (*covar) *= 1.0 / scale; (*fDecomp) *= sqrt(scale); } //******************************************************************** void Measurement2D::SetBinMask(std::string maskfile) { //******************************************************************** if (!fIsMask) return; LOG(SAM) << "Reading bin mask from file: " << maskfile << std::endl; // Create a mask histogram with dim of data int nbinsx = fDataHist->GetNbinsX(); int nbinxy = fDataHist->GetNbinsY(); fMaskHist = new TH2I((fSettings.GetName() + "_BINMASK").c_str(), (fSettings.GetName() + "_BINMASK; Bin; Mask?").c_str(), nbinsx, 0, nbinsx, nbinxy, 0, nbinxy); std::string line; std::ifstream mask(maskfile.c_str(), ifstream::in); if (!mask.is_open()) { LOG(FTL) << " Cannot find mask file." << std::endl; throw; } while (std::getline(mask >> std::ws, line, '\n')) { std::vector entries = GeneralUtils::ParseToInt(line, " "); // Skip lines with poorly formatted lines if (entries.size() < 2) { LOG(WRN) << "Measurement2D::SetBinMask(), couldn't parse line: " << line << std::endl; continue; } // The first index should be the bin number, the second should be the mask // value. int val = 0; if (entries[2] > 0) val = 1; fMaskHist->SetBinContent(entries[0], entries[1], val); } // Apply masking by setting masked data bins to zero PlotUtils::MaskBins(fDataHist, fMaskHist); return; } //******************************************************************** void Measurement2D::FinaliseMeasurement() { //******************************************************************** LOG(SAM) << "Finalising Measurement: " << fName << std::endl; if (fSettings.GetB("onlymc")) { if (fDataHist) delete fDataHist; fDataHist = new TH2D("empty_data", "empty_data", 1, 0.0, 1.0,1,0.0,1.0); } // Make sure data is setup if (!fDataHist) { ERR(FTL) << "No data has been setup inside " << fName << " constructor!" << std::endl; throw; } // Make sure covariances are setup if (!fFullCovar) { fIsDiag = true; SetCovarFromDiagonal(fDataHist); } if (!covar) { covar = StatUtils::GetInvert(fFullCovar); } if (!fDecomp) { fDecomp = StatUtils::GetDecomp(fFullCovar); } // Setup fMCHist from data fMCHist = (TH2D*)fDataHist->Clone(); fMCHist->SetNameTitle((fSettings.GetName() + "_MC").c_str(), (fSettings.GetFullTitles()).c_str()); fMCHist->Reset(); // Setup fMCFine fMCFine = new TH2D("mcfine", "mcfine", fDataHist->GetNbinsX() * 6, fMCHist->GetXaxis()->GetBinLowEdge(1), fMCHist->GetXaxis()->GetBinLowEdge(fDataHist->GetNbinsX() + 1), fDataHist->GetNbinsY() * 6, fMCHist->GetYaxis()->GetBinLowEdge(1), fMCHist->GetYaxis()->GetBinLowEdge(fDataHist->GetNbinsY() + 1)); fMCFine->SetNameTitle((fSettings.GetName() + "_MC_FINE").c_str(), (fSettings.GetFullTitles()).c_str()); fMCFine->Reset(); // Setup MC Stat fMCStat = (TH2D*)fMCHist->Clone(); fMCStat->Reset(); // Search drawopts for possible types to include by default std::string drawopts = FitPar::Config().GetParS("drawopts"); if (drawopts.find("MODES") != std::string::npos) { fMCHist_Modes = new TrueModeStack( (fSettings.GetName() + "_MODES").c_str(), ("True Channels"), fMCHist); SetAutoProcessTH1(fMCHist_Modes); } // Setup bin masks using sample name if (fIsMask) { std::string curname = fName; std::string origname = fSettings.GetS("originalname"); // Check rename.mask std::string maskloc = FitPar::Config().GetParDIR(curname + ".mask"); // Check origname.mask if (maskloc.empty()) maskloc = FitPar::Config().GetParDIR(origname + ".mask"); // Check database if (maskloc.empty()) { maskloc = FitPar::GetDataBase() + "/masks/" + origname + ".mask"; } // Setup Bin Mask SetBinMask(maskloc); } if (fScaleFactor < 0) { ERR(FTL) << "I found a negative fScaleFactor in " << __FILE__ << ":" << __LINE__ << std::endl; ERR(FTL) << "fScaleFactor = " << fScaleFactor << std::endl; ERR(FTL) << "EXITING" << std::endl; throw; } // Create and fill Weighted Histogram if (!fMCWeighted) { fMCWeighted = (TH2D*)fMCHist->Clone(); fMCWeighted->SetNameTitle((fName + "_MCWGHTS").c_str(), (fName + "_MCWGHTS" + fPlotTitles).c_str()); fMCWeighted->GetYaxis()->SetTitle("Weighted Events"); } } //******************************************************************** void Measurement2D::SetFitOptions(std::string opt) { //******************************************************************** // Do nothing if default given if (opt == "DEFAULT") return; // CHECK Conflicting Fit Options std::vector fit_option_allow = GeneralUtils::ParseToStr(fAllowedTypes, "/"); for (UInt_t i = 0; i < fit_option_allow.size(); i++) { std::vector fit_option_section = GeneralUtils::ParseToStr(fit_option_allow.at(i), ","); bool found_option = false; for (UInt_t j = 0; j < fit_option_section.size(); j++) { std::string av_opt = fit_option_section.at(j); if (!found_option and opt.find(av_opt) != std::string::npos) { found_option = true; } else if (found_option and opt.find(av_opt) != std::string::npos) { ERR(FTL) << "ERROR: Conflicting fit options provided: " << opt << std::endl << "Conflicting group = " << fit_option_section.at(i) << std::endl << "You should only supply one of these options in card file." << std::endl; throw; } } } // Check all options are allowed std::vector fit_options_input = GeneralUtils::ParseToStr(opt, "/"); for (UInt_t i = 0; i < fit_options_input.size(); i++) { if (fAllowedTypes.find(fit_options_input.at(i)) == std::string::npos) { ERR(FTL) << "ERROR: Fit Option '" << fit_options_input.at(i) << "' Provided is not allowed for this measurement." << std::endl; ERR(FTL) << "Fit Options should be provided as a '/' seperated list " "(e.g. FREE/DIAG/NORM)" << std::endl; ERR(FTL) << "Available options for " << fName << " are '" << fAllowedTypes << "'" << std::endl; throw; } } // Set TYPE fFitType = opt; // FIX,SHAPE,FREE if (opt.find("FIX") != std::string::npos) { fIsFree = fIsShape = false; fIsFix = true; } else if (opt.find("SHAPE") != std::string::npos) { fIsFree = fIsFix = false; fIsShape = true; } else if (opt.find("FREE") != std::string::npos) { fIsFix = fIsShape = false; fIsFree = true; } // DIAG,FULL (or default to full) if (opt.find("DIAG") != std::string::npos) { fIsDiag = true; fIsFull = false; } else if (opt.find("FULL") != std::string::npos) { fIsDiag = false; fIsFull = true; } // CHI2/LL (OTHERS?) if (opt.find("LOG") != std::string::npos) { fIsChi2 = false; ERR(FTL) << "No other LIKELIHOODS properly supported!" << std::endl; ERR(FTL) << "Try to use a chi2!" << std::endl; throw; } else { fIsChi2 = true; } // EXTRAS if (opt.find("RAW") != std::string::npos) fIsRawEvents = true; if (opt.find("DIF") != std::string::npos) fIsDifXSec = true; if (opt.find("ENU1D") != std::string::npos) fIsEnu1D = true; if (opt.find("NORM") != std::string::npos) fAddNormPen = true; if (opt.find("MASK") != std::string::npos) fIsMask = true; // Set TYPE fFitType = opt; // FIX,SHAPE,FREE if (opt.find("FIX") != std::string::npos) { fIsFree = fIsShape = false; fIsFix = true; } else if (opt.find("SHAPE") != std::string::npos) { fIsFree = fIsFix = false; fIsShape = true; } else if (opt.find("FREE") != std::string::npos) { fIsFix = fIsShape = false; fIsFree = true; } // DIAG,FULL (or default to full) if (opt.find("DIAG") != std::string::npos) { fIsDiag = true; fIsFull = false; } else if (opt.find("FULL") != std::string::npos) { fIsDiag = false; fIsFull = true; } // CHI2/LL (OTHERS?) if (opt.find("LOG") != std::string::npos) fIsChi2 = false; else fIsChi2 = true; // EXTRAS if (opt.find("RAW") != std::string::npos) fIsRawEvents = true; if (opt.find("DIF") != std::string::npos) fIsDifXSec = true; if (opt.find("ENU1D") != std::string::npos) fIsEnu = true; if (opt.find("NORM") != std::string::npos) fAddNormPen = true; if (opt.find("MASK") != std::string::npos) fIsMask = true; fIsProjFitX = (opt.find("FITPROJX") != std::string::npos); fIsProjFitY = (opt.find("FITPROJY") != std::string::npos); return; }; /* Reconfigure LOOP */ //******************************************************************** void Measurement2D::ResetAll() { //******************************************************************** fMCHist->Reset(); fMCFine->Reset(); fMCStat->Reset(); return; }; //******************************************************************** void Measurement2D::FillHistograms() { //******************************************************************** if (Signal) { fMCHist->Fill(fXVar, fYVar, Weight); fMCFine->Fill(fXVar, fYVar, Weight); fMCStat->Fill(fXVar, fYVar, 1.0); if (fMCHist_Modes) fMCHist_Modes->Fill(Mode, fXVar, fYVar, Weight); } return; }; //******************************************************************** void Measurement2D::ScaleEvents() { //******************************************************************** // Fill MCWeighted; // for (int i = 0; i < fMCHist->GetNbinsX(); i++) { // fMCWeighted->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1)); // fMCWeighted->SetBinError(i + 1, fMCHist->GetBinError(i + 1)); // } // Setup Stat ratios for MC and MC Fine double* statratio = new double[fMCHist->GetNbinsX()]; for (int i = 0; i < fMCHist->GetNbinsX(); i++) { if (fMCHist->GetBinContent(i + 1) != 0) { statratio[i] = fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1); } else { statratio[i] = 0.0; } } double* statratiofine = new double[fMCFine->GetNbinsX()]; for (int i = 0; i < fMCFine->GetNbinsX(); i++) { if (fMCFine->GetBinContent(i + 1) != 0) { statratiofine[i] = fMCFine->GetBinError(i + 1) / fMCFine->GetBinContent(i + 1); } else { statratiofine[i] = 0.0; } } // Scaling for raw event rates if (fIsRawEvents) { double datamcratio = fDataHist->Integral() / fMCHist->Integral(); fMCHist->Scale(datamcratio); fMCFine->Scale(datamcratio); if (fMCHist_Modes) fMCHist_Modes->Scale(datamcratio); // Scaling for XSec as function of Enu } else if (fIsEnu1D) { PlotUtils::FluxUnfoldedScaling(fMCHist, GetFluxHistogram(), GetEventHistogram(), fScaleFactor); PlotUtils::FluxUnfoldedScaling(fMCFine, GetFluxHistogram(), GetEventHistogram(), fScaleFactor); // if (fMCHist_Modes) { // PlotUtils::FluxUnfoldedScaling(fMCHist_Modes, GetFluxHistogram(), // GetEventHistogram(), fScaleFactor, // fNEvents); // } // Any other differential scaling } else { fMCHist->Scale(fScaleFactor, "width"); fMCFine->Scale(fScaleFactor, "width"); // if (fMCHist_Modes) fMCHist_Modes->Scale(fScaleFactor, "width"); } // Proper error scaling - ROOT Freaks out with xsec weights sometimes for (int i = 0; i < fMCStat->GetNbinsX(); i++) { fMCHist->SetBinError(i + 1, fMCHist->GetBinContent(i + 1) * statratio[i]); } for (int i = 0; i < fMCFine->GetNbinsX(); i++) { fMCFine->SetBinError(i + 1, fMCFine->GetBinContent(i + 1) * statratiofine[i]); } // Clean up delete statratio; delete statratiofine; return; }; //******************************************************************** void Measurement2D::ApplyNormScale(double norm) { //******************************************************************** fCurrentNorm = norm; fMCHist->Scale(1.0 / norm); fMCFine->Scale(1.0 / norm); return; }; /* Statistic Functions - Outsources to StatUtils */ //******************************************************************** int Measurement2D::GetNDOF() { //******************************************************************** - + // Just incase it has gone... if (!fDataHist) return -1; int nDOF = 0; // If datahist has no errors make sure we don't include those bins as they are // not data points for (int xBin = 0; xBin < fDataHist->GetNbinsX() + 1; ++xBin) { for (int yBin = 0; yBin < fDataHist->GetNbinsY() + 1; ++yBin) { if (fDataHist->GetBinError(xBin, yBin) != 0) ++nDOF; } } - + // Account for possible bin masking int nMasked = 0; if (fMaskHist and fIsMask) if (fMaskHist->Integral() > 0) for (int xBin = 0; xBin < fMaskHist->GetNbinsX() + 1; ++xBin) for (int yBin = 0; yBin < fMaskHist->GetNbinsY() + 1; ++yBin) if (fMaskHist->GetBinContent(xBin, yBin) > 0.5) ++nMasked; // Take away those masked DOF if (fIsMask) { nDOF -= nMasked; } - + return nDOF; } //******************************************************************** double Measurement2D::GetLikelihood() { //******************************************************************** // If this is for a ratio, there is no data histogram to compare to! if (fNoData || !fDataHist) return 0.; // Fix weird masking bug if (!fIsMask) { if (fMaskHist) { fMaskHist = NULL; } } else { if (fMaskHist) { PlotUtils::MaskBins(fMCHist, fMaskHist); } } // if (fIsProjFitX or fIsProjFitY) return GetProjectedChi2(); // Scale up the results to match each other (Not using width might be // inconsistent with Meas1D) double scaleF = fDataHist->Integral() / fMCHist->Integral(); if (fIsShape) { fMCHist->Scale(scaleF); fMCFine->Scale(scaleF); //PlotUtils::ScaleNeutModeArray((TH1**)fMCHist_PDG, scaleF); } if (!fMapHist) { fMapHist = StatUtils::GenerateMap(fDataHist); } // Get the chi2 from either covar or diagonals double chi2 = 0.0; if (fIsChi2) { if (fIsDiag) { chi2 = StatUtils::GetChi2FromDiag(fDataHist, fMCHist, fMapHist, fMaskHist); } else { chi2 = StatUtils::GetChi2FromCov(fDataHist, fMCHist, covar, fMapHist, fMaskHist); } } // Add a normal penalty term if (fAddNormPen) { chi2 += (1 - (fCurrentNorm)) * (1 - (fCurrentNorm)) / (fNormError * fNormError); LOG(REC) << "Norm penalty = " << (1 - (fCurrentNorm)) * (1 - (fCurrentNorm)) / (fNormError * fNormError) << std::endl; } // Adjust the shape back to where it was. if (fIsShape and !FitPar::Config().GetParB("saveshapescaling")) { fMCHist->Scale(1. / scaleF); fMCFine->Scale(1. / scaleF); } fLikelihood = chi2; return chi2; } /* Fake Data Functions */ //******************************************************************** void Measurement2D::SetFakeDataValues(std::string fakeOption) { //******************************************************************** // Setup original/datatrue TH2D* tempdata = (TH2D*) fDataHist->Clone(); if (!fIsFakeData) { fIsFakeData = true; // Make a copy of the original data histogram. if (!fDataOrig) fDataOrig = (TH2D*)fDataHist->Clone((fName + "_data_original").c_str()); } else { ResetFakeData(); } // Setup Inputs fFakeDataInput = fakeOption; LOG(SAM) << "Setting fake data from : " << fFakeDataInput << std::endl; // From MC if (fFakeDataInput.compare("MC") == 0) { fDataHist = (TH2D*)fMCHist->Clone((fName + "_MC").c_str()); // Fake File } else { if (!fFakeDataFile) fFakeDataFile = new TFile(fFakeDataInput.c_str(), "READ"); fDataHist = (TH2D*)fFakeDataFile->Get((fName + "_MC").c_str()); } // Setup Data Hist fDataHist->SetNameTitle((fName + "_FAKE").c_str(), (fName + fPlotTitles).c_str()); // Replace Data True if (fDataTrue) delete fDataTrue; fDataTrue = (TH2D*)fDataHist->Clone(); fDataTrue->SetNameTitle((fName + "_FAKE_TRUE").c_str(), (fName + fPlotTitles).c_str()); // Make a new covariance for fake data hist. int nbins = fDataHist->GetNbinsX() * fDataHist->GetNbinsY(); double alpha_i = 0.0; double alpha_j = 0.0; for (int i = 0; i < nbins; i++) { for (int j = 0; j < nbins; j++) { if (tempdata->GetBinContent(i + 1) && tempdata->GetBinContent(j + 1)) { alpha_i = fDataHist->GetBinContent(i + 1) / tempdata->GetBinContent(i + 1); alpha_j = fDataHist->GetBinContent(j + 1) / tempdata->GetBinContent(j + 1); } else { alpha_i = 0.0; alpha_j = 0.0; } (*fFullCovar)(i, j) = alpha_i * alpha_j * (*fFullCovar)(i, j); } } // Setup Covariances if (covar) delete covar; covar = StatUtils::GetInvert(fFullCovar); if (fDecomp) delete fDecomp; fDecomp = StatUtils::GetInvert(fFullCovar); delete tempdata; return; }; //******************************************************************** void Measurement2D::ResetFakeData() { //******************************************************************** if (fIsFakeData) { if (fDataHist) delete fDataHist; fDataHist = (TH2D*)fDataTrue->Clone((fSettings.GetName() + "_FKDAT").c_str()); } } //******************************************************************** void Measurement2D::ResetData() { //******************************************************************** if (fIsFakeData) { if (fDataHist) delete fDataHist; fDataHist = (TH2D*)fDataOrig->Clone((fSettings.GetName() + "_data").c_str()); } fIsFakeData = false; } //******************************************************************** void Measurement2D::ThrowCovariance() { //******************************************************************** // Take a fDecomposition and use it to throw the current dataset. // Requires fDataTrue also be set incase used repeatedly. if (fDataHist) delete fDataHist; fDataHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar); return; }; //******************************************************************** void Measurement2D::ThrowDataToy() { //******************************************************************** if (!fDataTrue) fDataTrue = (TH2D*) fDataHist->Clone(); if (fMCHist) delete fMCHist; fMCHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar); } /* Access Functions */ //******************************************************************** TH2D* Measurement2D::GetMCHistogram() { //******************************************************************** if (!fMCHist) return fMCHist; std::ostringstream chi2; chi2 << std::setprecision(5) << this->GetLikelihood(); int linecolor = kRed; int linestyle = 1; int linewidth = 1; int fillcolor = 0; int fillstyle = 1001; if (fSettings.Has("linecolor")) linecolor = fSettings.GetI("linecolor"); if (fSettings.Has("linestyle")) linestyle = fSettings.GetI("linestyle"); if (fSettings.Has("linewidth")) linewidth = fSettings.GetI("linewidth"); if (fSettings.Has("fillcolor")) fillcolor = fSettings.GetI("fillcolor"); if (fSettings.Has("fillstyle")) fillstyle = fSettings.GetI("fillstyle"); fMCHist->SetTitle(chi2.str().c_str()); fMCHist->SetLineColor(linecolor); fMCHist->SetLineStyle(linestyle); fMCHist->SetLineWidth(linewidth); fMCHist->SetFillColor(fillcolor); fMCHist->SetFillStyle(fillstyle); return fMCHist; }; //******************************************************************** TH2D* Measurement2D::GetDataHistogram() { //******************************************************************** if (!fDataHist) return fDataHist; int datacolor = kBlack; int datastyle = 1; int datawidth = 1; if (fSettings.Has("datacolor")) datacolor = fSettings.GetI("datacolor"); if (fSettings.Has("datastyle")) datastyle = fSettings.GetI("datastyle"); if (fSettings.Has("datawidth")) datawidth = fSettings.GetI("datawidth"); fDataHist->SetLineColor(datacolor); fDataHist->SetLineWidth(datawidth); fDataHist->SetMarkerStyle(datastyle); return fDataHist; }; /* Write Functions */ // Save all the histograms at once //******************************************************************** void Measurement2D::Write(std::string drawOpt) { //******************************************************************** // Get Draw Options drawOpt = FitPar::Config().GetParS("drawopts"); // Write Settigns if (drawOpt.find("SETTINGS") != std::string::npos) { fSettings.Set("#chi^{2}", fLikelihood); fSettings.Set("NDOF", this->GetNDOF() ); fSettings.Set("#chi^{2}/NDOF", fLikelihood / this->GetNDOF() ); fSettings.Write(); } // Write Data/MC GetDataList().at(0)->Write(); GetMCList().at(0)->Write(); // Write Fine Histogram if (drawOpt.find("FINE") != std::string::npos) GetFineList().at(0)->Write(); // Write Weighted Histogram if (drawOpt.find("WEIGHTS") != std::string::npos && fMCWeighted) fMCWeighted->Write(); // Save Flux/Evt if no event manager if (!FitPar::Config().GetParB("EventManager")) { if (drawOpt.find("FLUX") != std::string::npos && GetFluxHistogram()) GetFluxHistogram()->Write(); if (drawOpt.find("EVT") != std::string::npos && GetEventHistogram()) GetEventHistogram()->Write(); if (drawOpt.find("XSEC") != std::string::npos && GetEventHistogram()) GetEventHistogram()->Write(); } // Write Mask if (fIsMask && (drawOpt.find("MASK") != std::string::npos)) { fMaskHist->Write(); } // Write Covariances if (drawOpt.find("COV") != std::string::npos && fFullCovar) { PlotUtils::GetFullCovarPlot(fFullCovar, fSettings.GetName()); } if (drawOpt.find("INVCOV") != std::string::npos && covar) { PlotUtils::GetInvCovarPlot(covar, fSettings.GetName()); } if (drawOpt.find("DECOMP") != std::string::npos && fDecomp) { PlotUtils::GetDecompCovarPlot(fDecomp, fSettings.GetName()); } // // Likelihood residual plots // if (drawOpt.find("RESIDUAL") != std::string::npos) { // WriteResidualPlots(); // } // // RATIO // if (drawOpt.find("CANVMC") != std::string::npos) { // TCanvas* c1 = WriteMCCanvas(fDataHist, fMCHist); // c1->Write(); // delete c1; // } // // PDG // if (drawOpt.find("CANVPDG") != std::string::npos && fMCHist_Modes) { // TCanvas* c2 = WritePDGCanvas(fDataHist, fMCHist, fMCHist_Modes); // c2->Write(); // delete c2; // } // Write Extra Histograms AutoWriteExtraTH1(); WriteExtraHistograms(); /// 2D VERSION // If null pointer return if (!fMCHist and !fDataHist) { LOG(SAM) << fName << "Incomplete histogram set!" << std::endl; return; } - // FitPar::Config().out->cd(); + // Config::Get().out->cd(); // Get Draw Options drawOpt = FitPar::Config().GetParS("drawopts"); bool drawData = (drawOpt.find("DATA") != std::string::npos); bool drawNormal = (drawOpt.find("MC") != std::string::npos); bool drawEvents = (drawOpt.find("EVT") != std::string::npos); bool drawXSec = (drawOpt.find("XSEC") != std::string::npos); bool drawFine = (drawOpt.find("FINE") != std::string::npos); bool drawRatio = (drawOpt.find("RATIO") != std::string::npos); // bool drawModes = (drawOpt.find("MODES") != std::string::npos); bool drawShape = (drawOpt.find("SHAPE") != std::string::npos); bool residual = (drawOpt.find("RESIDUAL") != std::string::npos); bool drawMatrix = (drawOpt.find("MATRIX") != std::string::npos); bool drawFlux = (drawOpt.find("FLUX") != std::string::npos); bool drawMask = (drawOpt.find("MASK") != std::string::npos); bool drawMap = (drawOpt.find("MAP") != std::string::npos); bool drawProj = (drawOpt.find("PROJ") != std::string::npos); // bool drawCanvPDG = (drawOpt.find("CANVPDG") != std::string::npos); bool drawCov = (drawOpt.find("COV") != std::string::npos); bool drawSliceCanvYMC = (drawOpt.find("CANVYMC") != std::string::npos); bool drawWeighted = (drawOpt.find("WGHT") != std::string::npos); if (FitPar::Config().GetParB("EventManager")) { drawFlux = false; drawXSec = false; drawEvents = false; } if (fMaskHist) fMaskHist->Write(); // Save standard plots if (drawData) this->GetDataList().at(0)->Write(); if (drawNormal) this->GetMCList().at(0)->Write(); if (drawCov) { TH2D(*fFullCovar).Write((fName + "_COV").c_str()); } if (drawOpt.find("INVCOV") != std::string::npos) { TH2D(*covar).Write((fName + "_INVCOV").c_str()); } // Generate a simple map if (!fMapHist) fMapHist = StatUtils::GenerateMap(fDataHist); // Convert to 1D Lists TH1D* data_1D = StatUtils::MapToTH1D(fDataHist, fMapHist); TH1D* mc_1D = StatUtils::MapToTH1D(fMCHist, fMapHist); TH1I* mask_1D = StatUtils::MapToMask(fMaskHist, fMapHist); data_1D->Write(); mc_1D->Write(); if (mask_1D) { mask_1D->Write(); TMatrixDSym* calc_cov = StatUtils::ApplyInvertedMatrixMasking(covar, mask_1D); TH1D* calc_data = StatUtils::ApplyHistogramMasking(data_1D, mask_1D); TH1D* calc_mc = StatUtils::ApplyHistogramMasking(mc_1D, mask_1D); TH2D* bin_cov = new TH2D(*calc_cov); bin_cov->Write(); calc_data->Write(); calc_mc->Write(); delete mask_1D; delete calc_cov; delete calc_data; delete calc_mc; delete bin_cov; } delete data_1D; delete mc_1D; // Save only mc and data if splines if (fEventType == 4 or fEventType == 3) { return; } // Draw Extra plots if (drawFine) this->GetFineList().at(0)->Write(); if (drawFlux and GetFluxHistogram()) { GetFluxHistogram()->Write(); } if (drawEvents and GetEventHistogram()) { GetEventHistogram()->Write(); } if (fIsMask and drawMask) { fMaskHist->Write((fName + "_MSK").c_str()); //< save mask } if (drawMap) fMapHist->Write((fName + "_MAP").c_str()); //< save map // // Save neut stack // if (drawModes) { // THStack combo_fMCHist_PDG = PlotUtils::GetNeutModeStack( // (fName + "_MC_PDG").c_str(), (TH1**)fMCHist_PDG, 0); // combo_fMCHist_PDG.Write(); // } // Save Matrix plots if (drawMatrix and fFullCovar and covar and fDecomp) { TH2D cov = TH2D((*fFullCovar)); cov.SetNameTitle((fName + "_cov").c_str(), (fName + "_cov;Bins; Bins;").c_str()); cov.Write(); TH2D covinv = TH2D((*this->covar)); covinv.SetNameTitle((fName + "_covinv").c_str(), (fName + "_cov;Bins; Bins;").c_str()); covinv.Write(); TH2D covdec = TH2D((*fDecomp)); covdec.SetNameTitle((fName + "_covdec").c_str(), (fName + "_cov;Bins; Bins;").c_str()); covdec.Write(); } // Save ratio plots if required if (drawRatio) { // Needed for error bars for (int i = 0; i < fMCHist->GetNbinsX() * fMCHist->GetNbinsY(); i++) fMCHist->SetBinError(i + 1, 0.0); fDataHist->GetSumw2(); fMCHist->GetSumw2(); // Create Ratio Histograms TH2D* dataRatio = (TH2D*)fDataHist->Clone((fName + "_data_RATIO").c_str()); TH2D* mcRatio = (TH2D*)fMCHist->Clone((fName + "_MC_RATIO").c_str()); mcRatio->Divide(fMCHist); dataRatio->Divide(fMCHist); // Cancel bin errors on MC for (int i = 0; i < mcRatio->GetNbinsX() * mcRatio->GetNbinsY(); i++) { mcRatio->SetBinError( i + 1, fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1)); } mcRatio->SetMinimum(0); mcRatio->SetMaximum(2); dataRatio->SetMinimum(0); dataRatio->SetMaximum(2); mcRatio->Write(); dataRatio->Write(); delete mcRatio; delete dataRatio; } // Save Shape Plots if required if (drawShape) { // Create Shape Histogram TH2D* mcShape = (TH2D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str()); double shapeScale = 1.0; if (fIsRawEvents) { shapeScale = fDataHist->Integral() / fMCHist->Integral(); } else { shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width"); } mcShape->Scale(shapeScale); mcShape->SetLineWidth(3); mcShape->SetLineStyle(7); // dashes mcShape->Write(); // Save shape ratios if (drawRatio) { // Needed for error bars mcShape->GetSumw2(); // Create shape ratio histograms TH2D* mcShapeRatio = (TH2D*)mcShape->Clone((fName + "_MC_SHAPE_RATIO").c_str()); TH2D* dataShapeRatio = (TH2D*)fDataHist->Clone((fName + "_data_SHAPE_RATIO").c_str()); // Divide the histograms mcShapeRatio->Divide(mcShape); dataShapeRatio->Divide(mcShape); // Colour the shape ratio plots mcShapeRatio->SetLineWidth(3); mcShapeRatio->SetLineStyle(7); // dashes mcShapeRatio->Write(); dataShapeRatio->Write(); delete mcShapeRatio; delete dataShapeRatio; } delete mcShape; } // Save residual calculations of what contributed to the chi2 values. if (residual) { } if (fIsProjFitX or fIsProjFitY or drawProj) { // If not already made, make the projections if (!fMCHist_X) { PlotUtils::MatchEmptyBins(fDataHist, fMCHist); fMCHist_X = PlotUtils::GetProjectionX(fMCHist, fMaskHist); fMCHist_Y = PlotUtils::GetProjectionY(fMCHist, fMaskHist); fDataHist_X = PlotUtils::GetProjectionX(fDataHist, fMaskHist); fDataHist_Y = PlotUtils::GetProjectionY(fDataHist, fMaskHist); double chi2X = StatUtils::GetChi2FromDiag(fDataHist_X, fMCHist_X); double chi2Y = StatUtils::GetChi2FromDiag(fDataHist_Y, fMCHist_Y); fMCHist_X->SetTitle(Form("%f", chi2X)); fMCHist_Y->SetTitle(Form("%f", chi2Y)); } // Save the histograms fDataHist_X->Write(); fMCHist_X->Write(); fDataHist_Y->Write(); fMCHist_Y->Write(); } if (drawSliceCanvYMC or true) { TCanvas* c1 = new TCanvas((fName + "_MC_CANV_Y").c_str(), (fName + "_MC_CANV_Y").c_str(), 800, 600); c1->Divide(int(sqrt(fDataHist->GetNbinsY() + 1)), int(sqrt(fDataHist->GetNbinsY() + 1))); TH2D* mcShape = (TH2D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str()); double shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width"); mcShape->Scale(shapeScale); mcShape->SetLineStyle(7); c1->cd(1); TLegend* leg = new TLegend(0.6, 0.6, 0.9, 0.9); leg->AddEntry(fDataHist, (fName + " Data").c_str(), "ep"); leg->AddEntry(fMCHist, (fName + " MC").c_str(), "l"); leg->AddEntry(mcShape, (fName + " Shape").c_str(), "l"); leg->Draw("SAME"); /* // Make Y slices for (int i = 0; i < fDataHist->GetNbinY(); i++){ c1->cd(i+2); TH1D* fDataHist_SliceY = PlotUtils::GetSliceY(fDataHist, i); fDataHist_SliceY->Draw("E1"); TH1D* fMCHist_SliceY = PlotUtils::GetSliceY(fMCHist, i); fMCHist_SliceY->Draw("SAME HIST C"); TH1D* mcShape_SliceY = PlotUtils::GetSliceY(mcShape, i); mcShape_SliceY->Draw("SAME HIST C"); } */ c1->Write(); } if (drawWeighted) { fMCWeighted->Write(); } // Returning LOG(SAM) << "Written Histograms: " << fName << std::endl; return; // Returning LOG(SAM) << "Written Histograms: " << fName << std::endl; return; } /* Setup Functions */ //******************************************************************** void Measurement2D::SetupMeasurement(std::string inputfile, std::string type, FitWeight* rw, std::string fkdt) { //******************************************************************** // Check if name contains Evt, indicating that it is a raw number of events // measurements and should thus be treated as once fIsRawEvents = false; if ((fName.find("Evt") != std::string::npos) && fIsRawEvents == false) { fIsRawEvents = true; LOG(SAM) << "Found event rate measurement but fIsRawEvents == false!" << std::endl; LOG(SAM) << "Overriding this and setting fIsRawEvents == true!" << std::endl; } fIsEnu = false; if ((fName.find("XSec") != std::string::npos) && (fName.find("Enu") != std::string::npos)) { fIsEnu = true; LOG(SAM) << "::" << fName << "::" << std::endl; LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, " "not flux averaged!" << std::endl; if (FitPar::Config().GetParB("EventManager")) { ERR(FTL) << "Enu Measurements do not yet work with the Event Manager!" << std::endl; ERR(FTL) << "If you want decent flux unfolded results please run in " "series mode (-q EventManager=0)" << std::endl; sleep(2); } } if (fIsEnu && fIsRawEvents) { LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this " "really correct?!" << std::endl; LOG(SAM) << "Check experiment constructor for " << fName << " and correct this!" << std::endl; LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl; exit(-1); } // Reset everything to NULL fRW = rw; // Setting up 2D Inputs this->SetupInputs(inputfile); // Set Default Options SetFitOptions(fDefaultTypes); // Set Passed Options SetFitOptions(type); } //******************************************************************** void Measurement2D::SetupDefaultHist() { //******************************************************************** // Setup fMCHist fMCHist = (TH2D*)fDataHist->Clone(); fMCHist->SetNameTitle((fName + "_MC").c_str(), (fName + "_MC" + fPlotTitles).c_str()); // Setup fMCFine Int_t nBinsX = fMCHist->GetNbinsX(); Int_t nBinsY = fMCHist->GetNbinsY(); fMCFine = new TH2D((fName + "_MC_FINE").c_str(), (fName + "_MC_FINE" + fPlotTitles).c_str(), nBinsX * 3, fMCHist->GetXaxis()->GetBinLowEdge(1), fMCHist->GetXaxis()->GetBinLowEdge(nBinsX + 1), nBinsY * 3, fMCHist->GetYaxis()->GetBinLowEdge(1), fMCHist->GetYaxis()->GetBinLowEdge(nBinsY + 1)); // Setup MC Stat fMCStat = (TH2D*)fMCHist->Clone(); fMCStat->Reset(); // Setup the NEUT Mode Array //PlotUtils::CreateNeutModeArray(fMCHist, (TH1**)fMCHist_PDG); // Setup bin masks using sample name if (fIsMask) { std::string maskloc = FitPar::Config().GetParDIR(fName + ".mask"); if (maskloc.empty()) { maskloc = FitPar::GetDataBase() + "/masks/" + fName + ".mask"; } SetBinMask(maskloc); } return; } //******************************************************************** void Measurement2D::SetDataValues(std::string dataFile, std::string TH2Dname) { //******************************************************************** if (dataFile.find(".root") == std::string::npos) { ERR(FTL) << "Error! " << dataFile << " is not a .root file" << std::endl; ERR(FTL) << "Currently only .root file reading is supported (MiniBooNE " "CC1pi+ 2D), but implementing .txt should be dirt easy" << std::endl; ERR(FTL) << "See me at " << __FILE__ << ":" << __LINE__ << std::endl; exit(-1); } else { TFile* inFile = new TFile(dataFile.c_str(), "READ"); fDataHist = (TH2D*)(inFile->Get(TH2Dname.c_str())->Clone()); fDataHist->SetDirectory(0); fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_MC" + fPlotTitles).c_str()); delete inFile; } return; } //******************************************************************** void Measurement2D::SetDataValues(std::string dataFile, double dataNorm, std::string errorFile, double errorNorm) { //******************************************************************** // Make a counter to track the line number int yBin = 0; std::string line; std::ifstream data(dataFile.c_str(), ifstream::in); fDataHist = new TH2D((fName + "_data").c_str(), (fName + fPlotTitles).c_str(), fNDataPointsX - 1, fXBins, fNDataPointsY - 1, fYBins); if (data.is_open()) LOG(SAM) << "Reading data from: " << dataFile.c_str() << std::endl; while (std::getline(data >> std::ws, line, '\n')) { int xBin = 0; // Loop over entries and insert them into the histogram std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { fDataHist->SetBinContent(xBin + 1, yBin + 1, (*iter) * dataNorm); xBin++; } yBin++; } yBin = 0; std::ifstream error(errorFile.c_str(), ifstream::in); if (error.is_open()) LOG(SAM) << "Reading errors from: " << errorFile.c_str() << std::endl; while (std::getline(error >> std::ws, line, '\n')) { int xBin = 0; // Loop over entries and insert them into the histogram std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { fDataHist->SetBinError(xBin + 1, yBin + 1, (*iter) * errorNorm); xBin++; } yBin++; } return; }; //******************************************************************** void Measurement2D::SetDataValuesFromText(std::string dataFile, double dataNorm) { //******************************************************************** fDataHist = new TH2D((fName + "_data").c_str(), (fName + fPlotTitles).c_str(), fNDataPointsX - 1, fXBins, fNDataPointsY - 1, fYBins); LOG(SAM) << "Reading data from: " << dataFile << std::endl; PlotUtils::Set2DHistFromText(dataFile, fDataHist, dataNorm, true); return; }; //******************************************************************** void Measurement2D::SetCovarMatrix(std::string covarFile) { //******************************************************************** // Used to read a covariance matrix from a root file TFile* tempFile = new TFile(covarFile.c_str(), "READ"); // Make plots that we want TH2D* covarPlot = new TH2D(); // TH2D* decmpPlot = new TH2D(); TH2D* covarInvPlot = new TH2D(); TH2D* fFullCovarPlot = new TH2D(); // Get covariance options for fake data studies std::string covName = ""; std::string covOption = FitPar::Config().GetParS("throw_covariance"); // Which matrix to get? if (fIsShape || fIsFree) covName = "shp_"; if (fIsDiag) covName += "diag"; else covName += "full"; covarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str()); covarInvPlot = (TH2D*)tempFile->Get((covName + "covinv").c_str()); // Throw either the sub matrix or the full matrix if (!covOption.compare("SUB")) fFullCovarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str()); else if (!covOption.compare("FULL")) fFullCovarPlot = (TH2D*)tempFile->Get("fullcov"); else ERR(WRN) << " Incorrect thrown_covariance option in parameters." << std::endl; // Bin masking? int dim = int(fDataHist->GetNbinsX()); //-this->masked->Integral()); int covdim = int(fDataHist->GetNbinsX()); // Make new covars this->covar = new TMatrixDSym(dim); fFullCovar = new TMatrixDSym(dim); fDecomp = new TMatrixDSym(dim); // Full covariance values int row, column = 0; row = 0; column = 0; for (Int_t i = 0; i < covdim; i++) { // masking can be dodgy // if (this->masked->GetBinContent(i+1) > 0) continue; for (Int_t j = 0; j < covdim; j++) { // if (this->masked->GetBinContent(j+1) > 0) continue; (*this->covar)(row, column) = covarPlot->GetBinContent(i + 1, j + 1); (*fFullCovar)(row, column) = fFullCovarPlot->GetBinContent(i + 1, j + 1); column++; } column = 0; row++; } // Set bin errors on data if (!fIsDiag) { for (Int_t i = 0; i < fDataHist->GetNbinsX(); i++) { fDataHist->SetBinError( i + 1, sqrt((covarPlot->GetBinContent(i + 1, i + 1))) * 1E-38); } } TDecompSVD LU = TDecompSVD(*this->covar); this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); tempFile->Close(); delete tempFile; return; }; //******************************************************************** void Measurement2D::SetCovarMatrixFromText(std::string covarFile, int dim) { //******************************************************************** // Make a counter to track the line number int row = 0; std::string line; std::ifstream covar(covarFile.c_str(), ifstream::in); this->covar = new TMatrixDSym(dim); fFullCovar = new TMatrixDSym(dim); if (covar.is_open()) LOG(SAM) << "Reading covariance matrix from file: " << covarFile << std::endl; while (std::getline(covar >> std::ws, line, '\n')) { int column = 0; // Loop over entries and insert them into matrix // Multiply by the errors to get the covariance, rather than the correlation // matrix std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { double val = (*iter) * fDataHist->GetBinError(row + 1) * 1E38 * fDataHist->GetBinError(column + 1) * 1E38; (*this->covar)(row, column) = val; (*fFullCovar)(row, column) = val; column++; } row++; } // Robust matrix inversion method TDecompSVD LU = TDecompSVD(*this->covar); this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); return; }; //******************************************************************** void Measurement2D::SetCovarMatrixFromChol(std::string covarFile, int dim) { //******************************************************************** // Make a counter to track the line number int row = 0; std::string line; std::ifstream covarread(covarFile.c_str(), ifstream::in); TMatrixD* newcov = new TMatrixD(dim, dim); if (covarread.is_open()) LOG(SAM) << "Reading covariance matrix from file: " << covarFile << std::endl; while (std::getline(covarread >> std::ws, line, '\n')) { int column = 0; // Loop over entries and insert them into matrix // Multiply by the errors to get the covariance, rather than the correlation // matrix std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { (*newcov)(row, column) = *iter; column++; } row++; } covarread.close(); // Form full covariance TMatrixD* trans = (TMatrixD*)(newcov)->Clone(); trans->T(); (*trans) *= (*newcov); fFullCovar = new TMatrixDSym(dim, trans->GetMatrixArray(), ""); delete newcov; delete trans; // Robust matrix inversion method TDecompChol LU = TDecompChol(*this->fFullCovar); this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); return; }; // //******************************************************************** // void Measurement2D::SetMapValuesFromText(std::string dataFile) { // //******************************************************************** // fMapHist = new TH2I((fName + "_map").c_str(), (fName + fPlotTitles).c_str(), // fNDataPointsX - 1, fXBins, fNDataPointsY - 1, fYBins); // LOG(SAM) << "Reading map from: " << dataFile << std::endl; // PlotUtils::Set2DHistFromText(dataFile, fMapHist, 1.0); // return; // }; diff --git a/src/FitBase/Measurement2D.h b/src/FitBase/Measurement2D.h index a5a44dc..44b2e66 100644 --- a/src/FitBase/Measurement2D.h +++ b/src/FitBase/Measurement2D.h @@ -1,641 +1,641 @@ // 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 MEASUREMENT_2D_HXX_SEEN #define MEASUREMENT_2D_HXX_SEEN /*! * \addtogroup FitBase * @{ */ #include #include #include #include #include #include #include #include #include // ROOT includes #include #include #include #include #include #include #include #include #include // External data fit includes #include "FitEvent.h" -#include "FitParameters.h" + #include "FitUtils.h" #include "MeasurementBase.h" #include "PlotUtils.h" #include "SignalDef.h" #include "StatUtils.h" #include "MeasurementVariableBox2D.h" //******************************************************************** //! 2D Measurement base class. Histogram handling is done in this base layer. class Measurement2D : public MeasurementBase { //******************************************************************** public: /* Constructor/Deconstuctor */ //! Default Constructor Measurement2D(); //! Default Destructor virtual ~Measurement2D(); /* Setup Functions */ /// \brief Setup all configs once initialised /// /// Should be called after all configs have been setup inside fSettings container. /// Handles the processing of inputs and setting up of types. /// Replaces the old 'SetupMeasurement' function. void FinaliseSampleSettings(); /// \brief Creates the 2D data distribution given the binning provided. virtual void CreateDataHistogram(int dimx, double* binx, int dimy, double* biny); /// \brief Set Data Histogram from a list of contents in a text file /// /// Assumes the format: \n /// x_low_1 y_low_1 cont_11 err_11 \n /// x_low_1 y_low_2 cont_12 err_12 \n /// x_low_2 y_low_1 cont_21 err_21 \n /// x_low_2 y_low_2 cont_22 err_22 \n /// x_low_2 y_low_3 cont_23 err_23 \n /// x_low_3 y_low_2 cont_32 err_32 \n virtual void SetDataFromTextFile(std::string datfile); /// \brief Set Data Histogram from a TH2D in a file /// /// - datfile = Full path to data file /// - histname = Name of histogram /// /// If histname not given it assumes that datfile /// is in the format: \n /// 'file.root;histname' virtual void SetDataFromRootFile(std::string datfile, std::string histname=""); /// \brief Set data values from a 2D array in text file /// /// \warning requires DATA HISTOGRAM TO BE SET FIRST /// /// Assumes form: \n /// cont_11 cont_12 ... cont_1N \n /// cont_21 cont_22 ... cont_2N \n /// ... ... ... ... \n /// cont_N1 cont_N2 ... cont_NN \n virtual void SetDataValuesFromTextFile(std::string datfile, TH2D* hist = NULL); /// \brief Set data errors from a 2D array in text file /// /// \warning requires DATA HISTOGRAM TO BE SET FIRST /// /// Assumes form: \n /// errs_11 errs_12 ... errs_1N \n /// errs_21 errs_22 ... errs_2N \n /// ... ... ... ... \n /// errs_N1 errs_N2 ... errs_NN \n virtual void SetDataErrorsFromTextFile(std::string datfile, TH2D* hist = NULL); /// \brief Set data bin errors to sqrt(entries) /// /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST /// /// Sets the data errors as the sqrt of the bin contents /// Should be use for counting experiments virtual void SetPoissonErrors(); /// \brief Make diagonal covariance from data /// /// \warning If no histogram passed, data must be setup first! /// Setup the covariance inputs by taking the data histogram /// errors and setting up a diagonal covariance matrix. /// /// If no data is supplied, fDataHist is used if already set. virtual void SetCovarFromDiagonal(TH2D* data = NULL); /// \brief Read the data covariance from a text file. /// /// Inputfile should have the format: \n /// covariance_11 covariance_12 covariance_13 ... \n /// covariance_21 covariance_22 covariance_23 ... \n /// ... ... ... ... \n /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCovarFromTextFile(std::string covfile, int dim = -1); /// \brief Read the data covariance from a ROOT file. /// /// - covfile specifies the full path to the file /// - histname specifies the name of the covariance object. Both TMatrixDSym and TH2D are supported. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCovarFromRootFile(std::string covfile, std::string histname=""); /// \brief Read the inverted data covariance from a text file. /// /// Inputfile should have similar format to that shown /// in SetCovarFromTextFile. /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCovarInvertFromTextFile(std::string covfile, int dim = -1); /// \brief Read the inverted data covariance from a ROOT file. /// /// Inputfile should have similar format to that shown /// in SetCovarFromRootFile. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCovarInvertFromRootFile(std::string covfile, std::string histname=""); /// \brief Read the data correlations from a text file. /// /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST /// /// Inputfile should have similar format to that shown /// in SetCovarFromTextFile. /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCorrelationFromTextFile(std::string covfile, int dim = -1); /// \brief Read the data correlations from a ROOT file. /// /// \warning REQUIRES DATA TO BE SET FIRST /// /// Inputfile should have similar format to that shown /// in SetCovarFromRootFile. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCorrelationFromRootFile(std::string covfile, std::string histname=""); /// \brief Read the cholesky decomposed covariance from a text file and turn it into a covariance /// /// Inputfile should have similar format to that shown /// in SetCovarFromTextFile. /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCholDecompFromTextFile(std::string covfile, int dim = -1); /// \brief Read the cholesky decomposed covariance from a ROOT file and turn it into a covariance /// /// Inputfile should have similar format to that shown /// in SetCovarFromRootFile. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCholDecompFromRootFile(std::string covfile, std::string histname=""); /// \brief Read the map values from a text file /// /// \warning Requires DATA hist to be set beforehand. /// Format should be a 2D array of mappings. /// -1 indicates empty bins. \n /// e.g.: \n /// 1 2 3 4 5 \n /// -1 6 7 8 9 \n /// -1 -1 10 11 -1 \n virtual void SetMapValuesFromText(std::string dataFile); /// \brief Scale the data by some scale factor virtual void ScaleData(double scale); /// \brief Scale the data error bars by some scale factor virtual void ScaleDataErrors(double scale); /// \brief Scale the covariaince and its invert/decomp by some scale factor. virtual void ScaleCovar(double scale); /// \brief Setup a bin masking histogram and apply masking to data /// /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST /// /// Reads in a list of bins in a text file to be masked. Format is: \n /// bin_index_x_1 bin_index_y_1 1 \n /// bin_index_x_2 bin_index_y_2 1 \n /// bin_index_x_3 bin_index_y_3 1 \n /// /// If 0 is given then a bin entry will NOT be masked. So for example: \n\n /// 1 1 1 \n /// 2 0 1 \n /// 3 4 0 \n /// 4 0 1 \n\n /// Will mask only the (1,1), (2,0), and (4,0) bins. /// /// Masking can be turned on by specifiying the MASK option when creating a sample. /// When this is passed NUISANCE will look in the following locations for the mask file: /// - FitPar::Config().GetParS(fName + ".mask") /// - "data/masks/" + fName + ".mask"; virtual void SetBinMask(std::string maskfile); /// \brief Set the current fit options from a string. /// /// This is called twice for each sample, once to set the default /// and once to set the current setting (if anything other than default given) /// /// For this to work properly it requires the default and allowed types to be /// set correctly. These should be specified as a string listing options. /// /// To split up options so that NUISANCE can automatically detect ones that /// are conflicting. Any options seperated with the '/' symbol are non conflicting /// and can be given together, whereas any seperated with the ',' symbol cannot /// be specified by the end user at the same time. /// /// Default Type Examples: /// - DIAG/FIX = Default option will be a diagonal covariance, with FIXED norm. /// - MASK/SHAPE = Default option will be a masked hist, with SHAPE always on. /// /// Allowed Type examples: /// - 'FULL/DIAG/NORM/MASK' = Any of these options can be specified. /// - 'FULL,FREE,SHAPE/MASK/NORM' = User can give either FULL, FREE, or SHAPE as on option. /// MASK and NORM can also be included as options. virtual void SetFitOptions(std::string opt); /// \brief Final constructor setup /// \warning Should be called right at the end of the constructor. /// /// Contains a series of checks to ensure the data and inputs have been setup. /// Also creates the MC histograms needed for fitting. void FinaliseMeasurement(); /* Reconfigure */ /// \brief Create a Measurement1D box /// /// Creates a new 1D variable box containing just fXVar. /// /// This box is the bare minimum required by the JointFCN when /// running fast reconfigures during a routine. /// If for some reason a sample needs extra variables to be saved then /// it should override this function creating its own MeasurementVariableBox /// that contains the extra variables. virtual MeasurementVariableBox* CreateBox() {return new MeasurementVariableBox2D();}; /// \brief Reset all MC histograms /// /// Resets all standard histograms and those registered to auto /// process to zero. /// /// If extra histograms are not included in auto processing, then they must be reset /// by overriding this function and doing it manually if required. virtual void ResetAll(void); /// \brief Fill MC Histograms from XVar, YVar /// /// Fill standard histograms using fXVar, fYVar, Weight read from the variable box. /// /// WARNING : Any extra MC histograms need to be filled by overriding this function, /// even if they have been set to auto process. virtual void FillHistograms(void); // \brief Convert event rates to final histogram /// /// Apply standard scaling procedure to standard mc histograms to convert from /// raw events to xsec prediction. /// /// If any distributions have been set to auto process /// that is done during this function call, and a differential xsec is assumed. /// If that is not the case this function must be overriden. virtual void ScaleEvents(void); /// \brief Scale MC by a factor=1/norm /// /// Apply a simple normalisation scaling if the option FREE or a norm_parameter /// has been specified in the NUISANCE routine. virtual void ApplyNormScale(double norm); /* Statistical Functions */ /// \brief Get Number of degrees of freedom /// /// Returns the number bins inside the data histogram accounting for /// any bin masking applied. virtual int GetNDOF(); /// \brief Return Data/MC Likelihood at current state /// /// Returns the likelihood of the data given the current MC prediction. /// Diferent likelihoods definitions are used depending on the FitOptions. virtual double GetLikelihood(void); /* Fake Data */ /// \brief Set the fake data values from either a file, or MC /// /// - Setting from a file "path": \n /// When reading from a file the full path must be given to a standard /// nuisance output. The standard MC histogram should have a name that matches /// this sample for it to be read in. /// \n\n /// - Setting from "MC": \n /// If the MC option is given the current MC prediction is used as fake data. virtual void SetFakeDataValues(std::string fakeOption); /// \brief Reset fake data back to starting fake data /// /// Reset the fake data back to original fake data (Reset back to before /// ThrowCovariance was first called) virtual void ResetFakeData(void); /// \brief Reset fake data back to original data /// /// Reset the data histogram back to the true original dataset for this sample /// before any fake data was defined. virtual void ResetData(void); /// \brief Generate fake data by throwing the covariance. /// /// Can be used on fake MC data or just the original dataset. /// Call ResetFakeData or ResetData to return to values before the throw. virtual void ThrowCovariance(void); /// \brief Throw the data by its assigned errors and assign this to MC /// /// Used when creating data toys by assign the MC to this thrown data /// so that the likelihood is calculated between data and thrown data virtual void ThrowDataToy(void); /* Access Functions */ /// \brief Returns nicely formatted MC Histogram /// /// Format options can also be given in the samplesettings: /// - linecolor /// - linestyle /// - linewidth /// - fillcolor /// - fillstyle /// /// So to have a sample line colored differently in the xml cardfile put: \n /// virtual TH2D* GetMCHistogram(void); /// \brief Returns nicely formatted data Histogram /// /// Format options can also be given in the samplesettings: /// - datacolor /// - datastyle /// - datawidth /// /// So to have a sample data colored differently in the xml cardfile put: \n /// virtual TH2D* GetDataHistogram(void); /// \brief Returns a list of all MC histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. inline virtual std::vector GetMCList(void) { return std::vector(1, GetMCHistogram()); } /// \brief Returns a list of all Data histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. inline virtual std::vector GetDataList(void) { return std::vector(1, GetDataHistogram()); } /// \brief Returns a list of all Mask histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. inline virtual std::vector GetMaskList(void) { return std::vector(1, fMaskHist); }; /// \brief Returns a list of all Fine histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. inline virtual std::vector GetFineList(void) { return std::vector(1, fMCFine); }; /* Write Functions */ /// \brief Save the current state to the current TFile directory \n /// /// Data/MC are both saved by default. /// A range of other histograms can be saved by setting the /// config option 'drawopts'. /// /// Possible options: \n /// - FINE = Write Fine Histogram \n /// - WEIGHTS = Write Weighted MC Histogram (before scaling) \n /// - FLUX = Write Flux Histogram from MC Input \n /// - EVT = Write Event Histogram from MC Input \n /// - XSEC = Write XSec Histogram from MC Input \n /// - MASK = Write Mask Histogram \n /// - COV = Write Covariance Histogram \n /// - INVCOV = Write Inverted Covariance Histogram \n /// - DECMOP = Write Decomp. Covariance Histogram \n /// - RESIDUAL= Write Resudial Histograms \n /// - RATIO = Write Data/MC Ratio Histograms \n /// - SHAPE = Write MC Shape Histograms norm. to Data \n /// - CANVMC = Build MC Canvas Showing Data, MC, Shape \n /// - MODES = Write PDG Stack \n /// - CANVPDG = Build MC Canvas Showing Data, PDGStack \n /// /// So to save a range of these in parameters/config.xml set: \n /// virtual void Write(std::string drawOpt); //////// OLD FUNCTIONS //////////// //! Intial setup of common measurement variables. Parse input files, types, //! etc. virtual void SetupMeasurement(std::string input, std::string type, FitWeight* rw, std::string fkdt); //! Setup the default mc Hist given a data histogram virtual void SetupDefaultHist(); //! Set the data values and errors from two files virtual void SetDataValues(std::string dataFile, double dataNorm, std::string errorFile, double errorNorm); virtual void SetDataValues(std::string dataFile, std::string TH2Dname); //! Set the data values only from a text file virtual void SetDataValuesFromText(std::string dataFile, double norm); //! Read a covariance matrix from a file (Default name "covar" in file) virtual void SetCovarMatrix(std::string covarFile); //! Set the covariance matrix from a text file virtual void SetCovarMatrixFromText(std::string covarFile, int dim); //! Set the covariance matrix from a text file containing the cholesky //! fDecomposition virtual void SetCovarMatrixFromChol(std::string covarFile, int dim); protected: // The data histograms TH2D* fDataHist; //!< default data histogram (use in chi2 calculations) TH2D* fDataOrig; //!< histogram to store original data before throws. TH2D* fDataTrue; //!< histogram to store true dataset TH1D* fDataHist_X; //!< Projections onto X of the fDataHist TH1D* fDataHist_Y; //!< Projections onto Y of the fDataHist // The MC histograms TH2D* fMCHist; //!< MC Histogram (used in chi2 calculations) TH2D* fMCFine; //!< Finely binned MC Histogram TH2D* fMCHist_PDG[61]; //!< MC Histograms for each interaction mode TH1D* fMCHist_X; //!< Projections onto X of the fMCHist TH1D* fMCHist_Y; //!< Projections onto Y of the fMCHist TH2D* fMCWeighted; //!< Raw Event Weights TH2D* fMCStat; TH2I* fMaskHist; //!< mask histogram for the data TH2I* fMapHist; //!< map histogram used to convert 2D to 1D distributions bool fIsFakeData; //!< is current data actually fake std::string fakeDataFile; //!< MC fake data input file std::string fPlotTitles; //!< X and Y plot titles. std::string fFitType; std::string fDefaultTypes; //!< Default Fit Options std::string fAllowedTypes; //!< Any allowed Fit Options TMatrixDSym* covar; //!< inverted covariance matrix TMatrixDSym* fFullCovar; //!< covariance matrix TMatrixDSym* fDecomp; //!< fDecomposed covariance matrix TMatrixDSym* fCorrel; //!< correlation matrix double fCovDet; //!< covariance deteriminant double fNormError; //!< Normalisation on the error on the data double fLikelihood; //!< Likelihood value Double_t* fXBins; //!< X Bin Edges Double_t* fYBins; //!< Y Bin Edges Int_t fNDataPointsX; //!< Number of X data points Int_t fNDataPointsY; //!< NUmber of Y data points // Fit specific flags bool fIsShape; //!< Flag: Perform shape-only fit bool fIsFree; //!< Flag: Perform normalisation free fit bool fIsDiag; //!< Flag: Only use diagonal bin errors in stats bool fIsMask; //!< Flag: Apply bin masking bool fIsRawEvents; //!< Flag: Only event rates in histograms bool fIsEnu; //!< Needs Enu Unfolding bool fIsChi2SVD; //!< Flag: Chi2 SVD Method (DO NOT USE) bool fAddNormPen; //!< Flag: Add normalisation penalty to fi bool fIsProjFitX; //!< Flag: Use 1D projections onto X and Y to calculate the //!Chi2 Method. If flagged X will be used to set the rate. bool fIsProjFitY; //!< Flag: Use 1D projections onto X and Y to calculate the //!Chi2 Method. If flagged Y will be used to set the rate. bool fIsFix; //!< Flag: Fixed Histogram Norm bool fIsFull; //!< Flag; Use Full Covar bool fIsDifXSec; //!< Flag: Differential XSec bool fIsEnu1D; //!< Flag: Flux Unfolded XSec bool fIsChi2; //!< Flag; Use Chi2 over LL TrueModeStack* fMCHist_Modes; ///< Optional True Mode Stack TMatrixDSym* fCovar; ///< New FullCovar TMatrixDSym* fInvert; ///< New covar // Fake Data std::string fFakeDataInput; ///< Input fake data file path TFile* fFakeDataFile; ///< Input fake data file // Arrays for data entries Double_t* fDataValues; ///< REMOVE data bin contents Double_t* fDataErrors; ///< REMOVE data bin errors }; /*! @} */ #endif diff --git a/src/FitBase/MeasurementBase.h b/src/FitBase/MeasurementBase.h index 33a0ef6..00dddc7 100644 --- a/src/FitBase/MeasurementBase.h +++ b/src/FitBase/MeasurementBase.h @@ -1,362 +1,362 @@ // 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 INPUTHANDLER_H_SEEN #define INPUTHANDLER_H_SEEN /*! * \addtogroup FitBase * @{ */ // C Includes #include #include #include #include #include #include #include #include #include #include // ROOT includes #include #include #include #include #include #include #include #include #include #include // External data fit includes #include "FitEvent.h" -#include "FitParameters.h" + #include "FitUtils.h" #include "GeneralUtils.h" #include "PlotUtils.h" #include "StatUtils.h" #include "InputFactory.h" #include "FitWeight.h" #include "TMultiDimFit.h" #ifdef __GENIE_ENABLED__ #include "Conventions/Units.h" #endif #include "EventManager.h" #include "TObject.h" #include "InputHandler.h" #include "NuisConfig.h" #include "NuisKey.h" #include "SampleSettings.h" #include "StackBase.h" #include "StandardStacks.h" /// Enumerations to help with extra plot functions enum extraplotflags { kCMD_Reset = 0, kCMD_Fill, kCMD_Scale, kCMD_Norm, kCMD_Write, kCMD_Error, kCMD_extraplotflags }; enum MeasurementSpeciesClass { kSingleSpeciesMeasurement = 0, kNumuWithWrongSignMeasurement, kNueWithWrongSignMeasurement, kFourSpeciesMeasurement, }; /// InputHandler Class /// /// Inherits from Measurement base to handle whatever input is throwna t the /// fitter automatically. /// All functions here handle how files are read in, converted to custom formats /// and reconfigures are called. /// Used generally for the MC inputs. //! 2nd level experiment class that handles converting MC into a common format //! and calling reconfigure class MeasurementBase { public: /* Constructor/Destructors */ //! Default Constructor. Set everything to NULL MeasurementBase(); //! Default virtual destructor virtual ~MeasurementBase(void); virtual void InitialSetup(void) {}; /* Reconfigure Functions */ //! Function called if MC tuning dials haven't been changed and all we want to //! do is update the normalisation. virtual void Renormalise(void); //! Call reconfigure only looping over signal events to save time. virtual void ReconfigureFast(void); virtual void FillHistograms(double weight); //! Call reconfigure looping over all MC events including background virtual void Reconfigure(void); // virtual TH2D GetCovarMatrix(void) = 0; virtual double GetLikelihood(void) { return 0.0; }; virtual int GetNDOF(void) { return 0; }; virtual void ThrowCovariance(void) = 0; virtual void ThrowDataToy(void) = 0; virtual void SetFakeDataValues(std::string fkdt) = 0; //! Get the total integrated flux between this samples energy range virtual double TotalIntegratedFlux(std::string intOpt = "width", double low = -9999.9, double high = -9999.9); //! Get the predicted event rate for this sample virtual double PredictedEventRate(std::string intOpt = "width", double low = -9999.9, double high = -9999.9); virtual SampleSettings LoadSampleSettings(nuiskey samplekey); virtual SampleSettings LoadSampleSettings(std::string name, std::string input, std::string type); virtual void FinaliseSampleSettings(); virtual void FinaliseMeasurement(); virtual void ProcessExtraHistograms(int cmd, MeasurementVariableBox* vars, double weight = 1.0); virtual void FillExtraHistograms(MeasurementVariableBox* vars, double weight = 1.0); virtual void ScaleExtraHistograms(MeasurementVariableBox* vars); virtual void ResetExtraHistograms(); virtual void NormExtraHistograms(MeasurementVariableBox* vars, double norm = 1.0); virtual void WriteExtraHistograms(); virtual MeasurementVariableBox* CreateBox() {return new MeasurementVariableBox();}; int GetPassed() { int signalSize = 0; return signalSize; } int GetTotal() { return fNEvents; } /* Reconfigure LOOP */ // All these should be virtual ///! Reset Histograms (Handled at Measurement Stage) virtual void ResetAll(void) = 0; ///! Fill the event variables for this sample (Handled in each inherited /// sample) virtual void FillEventVariables(FitEvent* event) { (void)event; }; ///! Check whether this event is signle (Handled in each inherited sample) virtual bool isSignal(FitEvent* event) { (void)event; return false; }; ///! Fill the histogram for this event using fXVar and fYVar (Handled in each /// inherited sample) virtual void FillHistograms(void) {}; ///! Convert event rates to whatever distributions you need. virtual void ConvertEventRates(void); ///! Call scale events after the plots have been filled at the end of /// reconfigure. virtual void ScaleEvents(void) {}; ///! Apply the scale factor at the end of reconfigure. virtual void ApplyNormScale(double norm) { (void)norm; }; ///! Save Histograms virtual void Write(std::string drawOpt = "") = 0; virtual MeasurementVariableBox* FillVariableBox(FitEvent* event); virtual MeasurementVariableBox* GetBox(); void FillHistogramsFromBox(MeasurementVariableBox* var, double weight); /* Histogram Access Functions */ ///! Virtual function to get data histogram virtual std::vector GetDataList(void) = 0; ///! Virtual function to get MC histogram virtual std::vector GetMCList(void) = 0; virtual std::vector GetFineList(void) = 0; virtual std::vector GetMaskList(void) = 0; ///! Return flux histograms in a vector virtual std::vector GetFluxList(void); virtual std::vector GetEventRateList(void); virtual std::vector GetXSecList(void); virtual TH1D* GetEventHistogram() { return fInput->GetEventHistogram(); }; virtual TH1D* GetXSecHistogram() { return fInput->GetXSecHistogram(); }; virtual TH1D* GetFluxHistogram() { return fInput->GetFluxHistogram(); }; ///! Return input for this sample InputHandlerBase* GetInput(void); std::string GetName(void) { return fName; }; double GetScaleFactor(void) { return fScaleFactor; }; double GetXVar(void) { return fXVar; }; double GetYVar(void) { return fYVar; }; double GetZVar(void) { return fZVar; }; double GetMode(void) { return this->Mode; }; double GetEnu(void) { return this->Enu; }; void SetupInputs(std::string inputfile); int GetInputID(void); std::string GetInputFileName() { return fInputFileName; }; void SetSignal(bool sig); void SetSignal(FitEvent* evt); void SetWeight(double wght); void SetMode(int md); void SetNoData(bool isTrue = true) { fNoData = isTrue; }; inline void SetXVar(double xvar) { fXVar = xvar; }; inline void SetYVar(double yvar) { fYVar = yvar; }; inline void SetZVar(double zvar) { fZVar = zvar; }; virtual std::vector GetSubSamples() { return std::vector(1, this); } void SetAutoProcessTH1(TH1* hist, int c1 = -1, int c2 = -1, int c3 = -1, int c4 = -1, int c5 = -1); void SetAutoProcess(TH1* hist, int c1 = -1, int c2 = -1, int c3 = -1, int c4 = -1, int c5 = -1); void SetAutoProcess(TGraph* g, int c1 = -1, int c2 = -1, int c3 = -1, int c4 = -1, int c5 = -1); void SetAutoProcess(TF1* f, int c1 = -1, int c2 = -1, int c3 = -1, int c4 = -1, int c5 = -1); void SetAutoProcess(StackBase* hist, int c1 = -1, int c2 = -1, int c3 = -1, int c4 = -1, int c5 = -1); void SetAutoProcessTH1(StackBase* hist, int c1 = -1, int c2 = -1, int c3 = -1, int c4 = -1, int c5 = -1); void AutoFillExtraTH1(); void AutoResetExtraTH1(); void AutoScaleExtraTH1(); void AutoNormExtraTH1(double norm); void AutoWriteExtraTH1(); // functions that need to be added. // - Initial Check // - Check Target/Beam loop. // - Check flux shape if suggested one given. // - Return MeasurementList (returns ) protected: // Minimum and maximum energies double Enu; //!< Neutrino Energy double EnuMin; //!< Minimum incoming particle energy of events to include double EnuMax; //!< Maximum incoming particle energy of events to include BaseFitEvt* signal_event; FitEvent* cust_event; FitWeight* fRW; //!< Pointer to the rw engine InputHandlerBase* fInput; //!< Instance of the input handler std::string fName; //!< Name of the sample int fEventType; double fBeamDistance; //!< Incoming Particle flight distance (for oscillation //! analysis) double fScaleFactor; //!< fScaleFactor applied to events to convert from //! eventrate to final distribution double fCurrentNorm; //!< current normalisation factor applied if fit is "FREE" bool fMCFilled; //!< flag whether MC plots have been filled (For //! ApplyNormalisation) bool fNoData; //!< flag whether data plots do not exist (for ratios) bool fIsNoWidth; ///< Flag : Don't scale by bin width // TEMP OBJECTS TO HANDLE MERGE double fXVar, fYVar, fZVar, Mode, Weight; bool Signal; int ievt; int fNEvents; double Enu_rec, ThetaMu, CosThetaMu; InputUtils::InputType fInputType; std::string fInputFileName; TH1D* fFluxHist; TH1D* fEventHist; MeasurementSpeciesClass fMeasurementSpeciesType; SampleSettings fSettings; MeasurementVariableBox* fEventVariables; std::map > fExtraTH1s; int NSignal; // std::map fExtaStacks; bool fIsJoint; double fNPOT, fFluxIntegralOverride, fTargetVolume, fTargetMaterialDensity; double fEvtRateScaleFactor; }; // Class TypeDefs typedef std::list::const_iterator MeasListConstIter; typedef std::list::iterator MeasListIter; typedef std::vector::const_iterator MeasVectConstIter; typedef std::vector::iterator MeasVectIter; /*! @} */ #endif diff --git a/src/FitBase/SampleSettings.cxx b/src/FitBase/SampleSettings.cxx index f574209..b94bb56 100644 --- a/src/FitBase/SampleSettings.cxx +++ b/src/FitBase/SampleSettings.cxx @@ -1,231 +1,231 @@ #include "SampleSettings.h" SampleSettings::SampleSettings() { }; SampleSettings::SampleSettings(nuiskey key) { fKeyValues = key; - if (!key.Has("type")) key.AddS("type", "DEFAULT"); + if (!key.Has("type")) key.Set("type", "DEFAULT"); } std::string SampleSettings::GetName() { return GetS("name"); } void SampleSettings::SetS(std::string name, std::string val) { fKeyValues.SetS(name, val); }; bool SampleSettings::Found(std::string name, std::string substr) { std::string compstring = fKeyValues.GetS(name); return compstring.find(substr) != std::string::npos; } void SampleSettings::SetXTitle(std::string name) { SetDefault("xtitle", name); }; void SampleSettings::SetYTitle(std::string name) { SetDefault("ytitle", name); }; void SampleSettings::SetZTitle(std::string name) { SetDefault("ztitle", name); }; void SampleSettings::SetNormError(double norm) { SetDefault("norm_error", GeneralUtils::DblToStr(norm)); }; double SampleSettings::GetNormError() { return GetD("norm_error"); }; std::string SampleSettings::GetCovarInput() { return GetS("covar"); } void SampleSettings::SetAllowedTypes(std::string allowed, std::string defaulttype) { SetDefault("default_types", allowed); SetDefault("allowed_types", defaulttype); }; void SampleSettings::SetEnuRangeFromFlux(TH1D* fluxhist) { double enu_min = fluxhist->GetXaxis()->GetXmin(); double enu_max = fluxhist->GetXaxis()->GetXmax(); SetEnuRange(enu_min, enu_max); }; void SampleSettings::SetEnuRange(double min, double max) { SetDefault("enu_min", min); SetDefault("enu_max", max); }; void SampleSettings::Set(std::string name, double d) { SetDefault(name, d); } void SampleSettings::Set(std::string name, int i) { SetDefault(name, i); } void SampleSettings::Set(std::string name, std::string s) { SetDefault(name, s); } void SampleSettings::DefineAllowedTargets(std::string targ) { // fAllowedTargets = TargetUtils::ParseTargetsToIntVect(targ); }; void SampleSettings::FoundFill(std::string name, std::string substr, bool& cont, bool def) { std::string compstring = fKeyValues.GetS(name); if (compstring.find(substr) != std::string::npos) { cont = def; } else { cont = !def; } }; void SampleSettings::SetTitle(std::string val) { SetDefault("title", val); }; void SampleSettings::SetDataInput(std::string val) { SetDefault("data", val); }; std::string SampleSettings::GetMapInput() { return GetS("map"); } void SampleSettings::SetMapInput(std::string val) { SetDefault("map", val); } void SampleSettings::SetErrorInput(std::string val) { SetDefault("error", val); }; void SampleSettings::SetCovarInput(std::string val) { SetDefault("covar", val); }; void SampleSettings::SetShapeCovarInput(std::string val) { SetDefault("shapecovar", val); }; void SampleSettings::SetDefault(std::string name, std::string val) { - if (!fKeyValues.Has(name)) fKeyValues.AddS(name, val); + if (!fKeyValues.Has(name)) fKeyValues.Set(name, val); }; void SampleSettings::SetDefault(std::string name, double val ) { - if (!fKeyValues.Has(name)) fKeyValues.AddD(name, val); + if (!fKeyValues.Has(name)) fKeyValues.Set(name, val); }; void SampleSettings::SetHasExtraHistograms(bool opt) { fHasExtraHistograms = opt; }; void SampleSettings::DefineAllowedSpecies(std::string species) { fAllowedTargets = BeamUtils::ParseSpeciesToIntVect(species); }; std::string SampleSettings::Title() { return GetS("title"); } std::string SampleSettings::GetDataInput() { return GetS("data"); }; std::string SampleSettings::GetErrorInput() { return GetS("error"); }; std::string SampleSettings::PlotTitles() { return ";" + GetS("xtitle") + ";" + GetS("ytitle"); }; std::string SampleSettings::GetFullTitles() { return Title() + PlotTitles(); } int SampleSettings::GetI(std::string name) { return fKeyValues.GetI(name); } bool SampleSettings::GetB(std::string name){ return fKeyValues.GetB(name); } double SampleSettings::GetD(std::string name) { return fKeyValues.GetD(name); } std::string SampleSettings::GetS(std::string name) { return fKeyValues.GetS(name); } void SampleSettings::SetSuggestedFlux(std::string str) { SetS("suggested_flux", str); } void SampleSettings::SetDescription(std::string str) { SetS("description", str); } void SampleSettings::Write(std::string name) { if (name.empty()) name = this->GetS("name") + "_settings"; // Make a new canvas TCanvas* c1 = new TCanvas( name.c_str(), name.c_str(), 800, 600 ); c1->cd(); // Make new TPaveText TPaveText pttitle = TPaveText(0.05, 0.85, 0.95, 0.95); pttitle.AddText( name.c_str() ); pttitle.SetTextAlign(11); pttitle.SetTextSize(15); pttitle.Draw(); TPaveText pt = TPaveText(0.05, 0.05, 0.95, 0.80); std::vector keys = fKeyValues.GetAllKeys(); for (int i = 0; i < keys.size(); i++) { std::string keyval = fKeyValues.GetS(keys[i]); std::vector lines = GeneralUtils::ParseToStr(keyval, "\n"); if (lines.size() == 1) { pt.AddText( ("#bullet #bf{" + keys[i] + "} : " + fKeyValues.GetS(keys[i])).c_str() ); } else { pt.AddText( ("#bullet #bf{" + keys[i] + "} : ").c_str() ); for (int j = 0; j < lines.size(); j++) { pt.AddText((" |--> " + lines[j]).c_str() ); } } } pt.SetTextAlign(11); pt.SetTextSize(14); pt.Draw("SAME"); c1->Write(); delete c1; } void SampleSettings::SetOnlyMC(bool state) { SetDefault("onlymc", state); } diff --git a/src/Utils/StackBase.cxx b/src/FitBase/StackBase.cxx similarity index 100% rename from src/Utils/StackBase.cxx rename to src/FitBase/StackBase.cxx diff --git a/src/Utils/StackBase.h b/src/FitBase/StackBase.h similarity index 99% rename from src/Utils/StackBase.h rename to src/FitBase/StackBase.h index 826edb1..398afa6 100644 --- a/src/Utils/StackBase.h +++ b/src/FitBase/StackBase.h @@ -1,126 +1,126 @@ #ifndef STACK_BASE_H #define STACK_BASE_H #include "MeasurementVariableBox.h" #include "FitLogger.h" #include "GeneralUtils.h" #include "TH1.h" #include "TH1D.h" #include "TH2D.h" #include "THStack.h" #include "TH2.h" #include "TH3.h" -#include "FitParameters.h" + #include "PlotUtils.h" class StackBase { public: StackBase() {}; ~StackBase() {}; virtual void AddMode(std::string name, std::string title, int linecolor = 1, int linewidth = 1, int fillstyle = 1001); virtual void AddMode(int index, std::string name, std::string title, int linecolor = 1, int linewidth = 1, int fillstyle = 1001); virtual bool IncludeInStack(TH1* hist); virtual bool IncludeInStack(int index); virtual void SetupStack(TH1* hist); virtual void Scale(double sf, std::string opt = ""); virtual void FluxUnfold(TH1D* flux, TH1D* events, double scalefactor); virtual void Reset(); virtual void FillStack(int index, double x, double y = 1.0, double z = 1.0, double weight = 1.0); virtual void Write(); virtual void Add(StackBase* hist, double scale); virtual void Add(TH1* hist, double scale); virtual void AddNewHist(std::string name, TH1* hist); virtual void AddToCategory(std::string name, TH1* hist); virtual void AddToCategory(int index, TH1* hist); virtual void Divide(TH1* hist); virtual void Multiply(TH1* hist); virtual TH1* GetHist(int entry); virtual TH1* GetHist(std::string label); virtual THStack GetStack(); std::string GetType(){return fType;}; std::string fName; std::string fTitle; std::string fXTitle; std::string fYTitle; std::string fZTitle; std::string fType; TH1* fTemplate; int fNDim; // Maps incase we want to be selective std::vector< std::vector > fAllStyles; std::vector fAllTitles; std::vector fAllLabels; std::vector fAllHists; }; /* class NuSpeciesStack : public StackBase { public: SetupStack(TH1* hist) { AddMode("numu", "numu", kBlue, 2, 3004); AddMode("numubar", "numubar", kRed, 2, 3004 ); AddMode("nue", "nue", kGreen, 2, 3004 ); StackBase::SetupStack(hist); }; void NuSpeciesStack::FillStack(int species, double x, double y = 1.0, double z = 1.0, double weight = 1.0) { Stackbase::FillStack(ConvertSpeciesToIndex(species), x, y, z, weight); } int ConvertSpeciesToIndex(int species) { switch (species) { case 14: return 0; case -14: return 1; case 11: return 2; default: return -1; } }; }; class TargetStack : public StackBase { public: SetupStack(TH1* hist) { AddMode("C", "C", kBlue, 2, 3004); AddMode("H", "H", kRed, 2, 3004 ); AddMode("O", "O", kGreen, 2, 3004 ); StackBase::SetupStack(hist); }; void NuSpeciesStack::FillStack(int species, double x, double y = 1.0, double z = 1.0, double weight = 1.0) { Stackbase::FillStack(ConvertTargetToIndex(species), x, y, z, weight); } int ConvertTargetToIndex(int target) { switch (species) { case 1000010010: return 0; case 1000: return 1; case 1000: return 2; default: return -1; } }; } */ #endif diff --git a/src/Utils/StandardStacks.cxx b/src/FitBase/StandardStacks.cxx similarity index 100% rename from src/Utils/StandardStacks.cxx rename to src/FitBase/StandardStacks.cxx diff --git a/src/Utils/StandardStacks.h b/src/FitBase/StandardStacks.h similarity index 100% rename from src/Utils/StandardStacks.h rename to src/FitBase/StandardStacks.h diff --git a/src/InputHandler/FitEvent.h b/src/InputHandler/FitEvent.h index dc20304..07653b3 100644 --- a/src/InputHandler/FitEvent.h +++ b/src/InputHandler/FitEvent.h @@ -1,640 +1,640 @@ // 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 FITEVENT2_H_SEEN #define FITEVENT2_H_SEEN /*! * \addtogroup InputHandler * @{ */ #include #include #include #include "FitParticle.h" #include "TLorentzVector.h" #include "TSpline.h" -#include "FitParameters.h" + #include "BaseFitEvt.h" #include "FitLogger.h" #include "TArrayD.h" #include "TTree.h" #include "TChain.h" #include "PhysConst.h" /// Common container for event particles class FitEvent : public BaseFitEvt { public: FitEvent(); ~FitEvent() {}; void FreeFitParticles(); void ClearFitParticles(); void ResetEvent(void); void ResetParticleList(void); void HardReset(); void OrderStack(); void SetBranchAddress(TChain* tn); void AddBranchesToTree(TTree* tn); void Print(); void PrintChris(); void DeallocateParticleStack(); void AllocateParticleStack(int stacksize); void ExpandParticleStack(int stacksize); void AddGeneratorInfo(GeneratorInfoBase* gen); // ---- HELPER/ACCESS FUNCTIONS ---- // /// Return True Interaction ID inline int GetMode (void) const { return fMode; }; /// Return Target Atomic Number inline int GetTargetA (void) const { return fTargetA; }; /// Return Target Nuclear Charge inline int GetTargetZ (void) const { return fTargetZ; }; /// Get Event Total Cross-section inline int GetTotCrs (void) const { return fTotCrs; }; /// Is Event Charged Current? inline bool IsCC() const { return (abs(fMode) <= 30); }; /// Is Event Neutral Current? inline bool IsNC() const { return (abs(fMode) > 30); }; /// Return Particle 4-momentum for given index in particle stack TLorentzVector GetParticleP4 (int index) const; /// Return Particle 3-momentum for given index in particle stack TVector3 GetParticleP3 (int index) const; /// Return Particle absolute momentum for given index in particle stack double GetParticleMom (int index) const; /// Return Particle absolute momentum-squared for given index in particle stack double GetParticleMom2 (int index) const; /// Return Particle energy for given index in particle stack double GetParticleE (int index) const; /// Return Particle State for given index in particle stack int GetParticleState (int index) const; /// Return Particle PDG for given index in particle stack int GetParticlePDG (int index) const; /// Allows the removal of KE up to total KE. inline void RemoveKE(int index, double KE){ FitParticle *fp = GetParticle(index); double mass = fp->M(); double oKE = fp->KE(); double nE = mass + (oKE - KE); if(nE < mass){ // Can't take more KE than it has nE = mass; } double n3Mom = sqrt(nE*nE - mass*mass); TVector3 np3 = fp->P3().Unit()*n3Mom; fParticleMom[index][0] = np3[0]; fParticleMom[index][1] = np3[1]; fParticleMom[index][2] = np3[2]; fParticleMom[index][3] = nE; } /// Allows the removal of KE up to total KE. inline void GiveKE(int index, double KE){ RemoveKE(index,-KE); } /// Return Particle for given index in particle stack FitParticle* GetParticle(int const index); /// Get Total Number of Particles in stack inline uint NParticles (void) const { return fNParticles; }; /// Check if event contains a particle given a pdg and state. /// If no state is passed all states are considered. bool HasParticle (int const pdg = 0, int const state = -1) const ; template inline bool HasParticle(int const (&pdgs)[N], int const state = -1) const { for (size_t i = 0; i < N; i++) { if (HasParticle( pdgs[i], state )) { return false; } } return false; } /// Get total number of particles given a pdg and state. /// If no state is passed all states are considered. int NumParticle (int const pdg = 0, int const state = -1) const; template inline int NumParticle(int const (&pdgs)[N], int const state = -1) const { int ncount = 0; for (size_t i = 0; i < N; i++) { ncount += NumParticle( pdgs[i], state ); } return ncount; } /// Return a vector of particle indices that can be used with 'GetParticle' /// functions given a particle pdg and state. /// If no state is passed all states are considered. std::vector GetAllParticleIndices (int const pdg = -1, int const state = -1) const; template inline std::vector GetAllParticleIndices(int const (&pdgs)[N], const int state = -1) const { std::vector plist; for (size_t i = 0; i < N; i++) { std::vector plisttemp = GetAllParticleIndices(pdgs[i], state); plist.insert( plist.end(), plisttemp.begin(), plisttemp.end() ); } return plist; } /// Return a vector of FitParticles given a particle pdg and state. /// This is memory intensive and slow than GetAllParticleIndices, /// but is slightly easier to use. std::vector GetAllParticle (int const pdg = -1, int const state = -1); template inline std::vector GetAllParticle(int const (&pdgs)[N], int const state = -1) { std::vector plist; for (size_t i = 0; i < N; i++) { std::vector plisttemp = GetAllParticle(pdgs[i], state); plist.insert( plist.end(), plisttemp.begin(), plisttemp.end() ); } return plist; } inline std::vector GetAllNuElectronIndices (void) { return GetAllParticleIndices(12); }; inline std::vector GetAllNuMuonIndices (void) { return GetAllParticleIndices(14); }; inline std::vector GetAllNuTauIndices (void) { return GetAllParticleIndices(16); }; inline std::vector GetAllElectronIndices (void) { return GetAllParticleIndices(11); }; inline std::vector GetAllMuonIndices (void) { return GetAllParticleIndices(13); }; inline std::vector GetAllTauIndices (void) { return GetAllParticleIndices(15); }; inline std::vector GetAllProtonIndices (void) { return GetAllParticleIndices(2212); }; inline std::vector GetAllNeutronIndices (void) { return GetAllParticleIndices(2112); }; inline std::vector GetAllPiZeroIndices (void) { return GetAllParticleIndices(111); }; inline std::vector GetAllPiPlusIndices (void) { return GetAllParticleIndices(211); }; inline std::vector GetAllPiMinusIndices (void) { return GetAllParticleIndices(-211); }; inline std::vector GetAllPhotonIndices (void) { return GetAllParticleIndices(22); }; inline std::vector GetAllNuElectron (void) { return GetAllParticle(12); }; inline std::vector GetAllNuMuon (void) { return GetAllParticle(14); }; inline std::vector GetAllNuTau (void) { return GetAllParticle(16); }; inline std::vector GetAllElectron (void) { return GetAllParticle(11); }; inline std::vector GetAllMuon (void) { return GetAllParticle(13); }; inline std::vector GetAllTau (void) { return GetAllParticle(15); }; inline std::vector GetAllProton (void) { return GetAllParticle(2212); }; inline std::vector GetAllNeutron (void) { return GetAllParticle(2112); }; inline std::vector GetAllPiZero (void) { return GetAllParticle(111); }; inline std::vector GetAllPiPlus (void) { return GetAllParticle(211); }; inline std::vector GetAllPiMinus (void) { return GetAllParticle(-211); }; inline std::vector GetAllPhoton (void) { return GetAllParticle(22); }; // --- Highest Momentum Search Functions --- // /// Returns the Index of the highest momentum particle given a pdg and state. /// If no state is given all states are considered, but that will just return the /// momentum of the beam in most cases so is not advised. int GetHMParticleIndex (int const pdg = 0, int const state = -1) const; template inline int GetHMParticleIndex (int const (&pdgs)[N], int const state = -1) const { double mom = -999.9; int rtnindex = -1; for (size_t i = 0; i < N; ++i) { // Use ParticleMom as doesn't require Particle Mem alloc int pindex = GetHMParticleIndex(pdgs[i], state); if (pindex != -1){ double momnew = GetParticleMom2(pindex); if (momnew > mom) { rtnindex = pindex; mom = momnew; } } } return rtnindex; }; /// Returns the highest momentum particle given a pdg and state. /// If no state is given all states are considered, but that will just return the /// momentum of the beam in most cases so is not advised. inline FitParticle* GetHMParticle(int const pdg = 0, int const state = -1) { return GetParticle( GetHMParticleIndex(pdg, state) ); } template inline FitParticle* GetHMParticle(int const (&pdgs)[N], int const state) { return GetParticle(GetHMParticleIndex(pdgs, state)); }; // ---- Initial State Helpers --- // /// Checks the event has a particle of a given pdg in the initial state. inline bool HasISParticle(int const pdg) const { return HasParticle(pdg, kInitialState); }; template inline bool HasISParticle(int const (&pdgs)[N]) const { return HasParticle(pdgs, kInitialState); }; /// Returns the number of particles with a given pdg in the initial state. inline int NumISParticle(int const pdg = 0) const { return NumParticle(pdg, kInitialState); }; template inline int NumISParticle(int const (&pdgs)[N]) const { return NumParticle(pdgs, kInitialState); }; /// Returns a list of indices for all particles with a given pdg /// in the initial state. These can be used with the 'GetParticle' functions. inline std::vector GetAllISParticleIndices(int const pdg = -1) const { return GetAllParticleIndices(pdg, kInitialState); }; template inline std::vector GetAllISParticleIndices(int const (&pdgs)[N]) const { return GetAllParticleIndices(pdgs, kInitialState); }; /// Returns a list of particles with a given pdg in the initial state. /// This function is more memory intensive and slower than the Indices function. inline std::vector GetAllISParticle(int const pdg = -1) { return GetAllParticle(pdg, kInitialState); }; template inline std::vector GetAllISParticle(int const (&pdgs)[N]) { return GetAllParticle(pdgs, kInitialState); }; /// Returns the highest momentum particle with a given pdg in the initial state. inline FitParticle* GetHMISParticle(int const pdg) { return GetHMParticle(pdg, kInitialState); }; template inline FitParticle* GetHMISParticle(int const (&pdgs)[N]) { return GetHMParticle(pdgs, kInitialState); }; /// Returns the highest momentum particle index with a given pdg in the initial state. inline int GetHMISParticleIndex(int const pdg) const { return GetHMParticleIndex(pdg, kInitialState); }; template inline int GetHMISParticleIndex(int const (&pdgs)[N]) const { return GetHMParticleIndex(pdgs, kInitialState); }; inline bool HasISNuElectron (void) const { return HasISParticle(12); }; inline bool HasISNuMuon (void) const { return HasISParticle(14); }; inline bool HasISNuTau (void) const { return HasISParticle(16); }; inline bool HasISElectron (void) const { return HasISParticle(11); }; inline bool HasISMuon (void) const { return HasISParticle(13); }; inline bool HasISTau (void) const { return HasISParticle(15); }; inline bool HasISProton (void) const { return HasISParticle(2212); }; inline bool HasISNeutron (void) const { return HasISParticle(2112); }; inline bool HasISPiZero (void) const { return HasISParticle(111); }; inline bool HasISPiPlus (void) const { return HasISParticle(211); }; inline bool HasISPiMinus (void) const { return HasISParticle(-211); }; inline bool HasISPhoton (void) const { return HasISParticle(22); }; inline bool HasISLeptons (void) const { return HasISParticle(PhysConst::pdg_leptons); }; inline bool HasISPions (void) const { return HasISParticle(PhysConst::pdg_pions); }; inline bool HasISChargePions (void) const { return HasISParticle(PhysConst::pdg_charged_pions); }; inline int NumISNuElectron (void) const { return NumISParticle(12); }; inline int NumISNuMuon (void) const { return NumISParticle(14); }; inline int NumISNuTau (void) const { return NumISParticle(16); }; inline int NumISElectron (void) const { return NumISParticle(11); }; inline int NumISMuon (void) const { return NumISParticle(13); }; inline int NumISTau (void) const { return NumISParticle(15); }; inline int NumISProton (void) const { return NumISParticle(2212); }; inline int NumISNeutron (void) const { return NumISParticle(2112); }; inline int NumISPiZero (void) const { return NumISParticle(111); }; inline int NumISPiPlus (void) const { return NumISParticle(211); }; inline int NumISPiMinus (void) const { return NumISParticle(-211); }; inline int NumISPhoton (void) const { return NumISParticle(22); }; inline int NumISLeptons (void) const { return NumISParticle(PhysConst::pdg_leptons); }; inline int NumISPions (void) const { return NumISParticle(PhysConst::pdg_pions); }; inline int NumISChargePions (void) const { return NumISParticle(PhysConst::pdg_charged_pions); }; inline std::vector GetAllISNuElectronIndices (void) const { return GetAllISParticleIndices(12); }; inline std::vector GetAllISNuMuonIndices (void) const { return GetAllISParticleIndices(14); }; inline std::vector GetAllISNuTauIndices (void) const { return GetAllISParticleIndices(16); }; inline std::vector GetAllISElectronIndices (void) const { return GetAllISParticleIndices(11); }; inline std::vector GetAllISMuonIndices (void) const { return GetAllISParticleIndices(13); }; inline std::vector GetAllISTauIndices (void) const { return GetAllISParticleIndices(15); }; inline std::vector GetAllISProtonIndices (void) const { return GetAllISParticleIndices(2212); }; inline std::vector GetAllISNeutronIndices (void) const { return GetAllISParticleIndices(2112); }; inline std::vector GetAllISPiZeroIndices (void) const { return GetAllISParticleIndices(111); }; inline std::vector GetAllISPiPlusIndices (void) const { return GetAllISParticleIndices(211); }; inline std::vector GetAllISPiMinusIndices (void) const { return GetAllISParticleIndices(-211); }; inline std::vector GetAllISPhotonIndices (void) const { return GetAllISParticleIndices(22); }; inline std::vector GetAllISLeptonsIndices (void) const { return GetAllISParticleIndices(PhysConst::pdg_leptons); }; inline std::vector GetAllISPionsIndices (void) const { return GetAllISParticleIndices(PhysConst::pdg_pions); }; inline std::vector GetAllISChargePionsIndices(void) const { return GetAllISParticleIndices(PhysConst::pdg_charged_pions); }; inline std::vector GetAllISNuElectron (void) { return GetAllISParticle(12); }; inline std::vector GetAllISNuMuon (void) { return GetAllISParticle(14); }; inline std::vector GetAllISNuTau (void) { return GetAllISParticle(16); }; inline std::vector GetAllISElectron (void) { return GetAllISParticle(11); }; inline std::vector GetAllISMuon (void) { return GetAllISParticle(13); }; inline std::vector GetAllISTau (void) { return GetAllISParticle(15); }; inline std::vector GetAllISProton (void) { return GetAllISParticle(2212); }; inline std::vector GetAllISNeutron (void) { return GetAllISParticle(2112); }; inline std::vector GetAllISPiZero (void) { return GetAllISParticle(111); }; inline std::vector GetAllISPiPlus (void) { return GetAllISParticle(211); }; inline std::vector GetAllISPiMinus (void) { return GetAllISParticle(-211); }; inline std::vector GetAllISPhoton (void) { return GetAllISParticle(22); }; inline std::vector GetAllISLeptons (void) { return GetAllISParticle(PhysConst::pdg_leptons); }; inline std::vector GetAllISPions (void) { return GetAllISParticle(PhysConst::pdg_pions); }; inline std::vector GetAllISChargePions(void) { return GetAllISParticle(PhysConst::pdg_charged_pions); }; inline FitParticle* GetHMISNuElectron (void) { return GetHMISParticle(12); }; inline FitParticle* GetHMISNuMuon (void) { return GetHMISParticle(14); }; inline FitParticle* GetHMISNuTau (void) { return GetHMISParticle(16); }; inline FitParticle* GetHMISElectron (void) { return GetHMISParticle(11); }; inline FitParticle* GetHMISMuon (void) { return GetHMISParticle(13); }; inline FitParticle* GetHMISTau (void) { return GetHMISParticle(15); }; inline FitParticle* GetHMISAnyLeptons (void) { return GetHMISParticle(PhysConst::pdg_all_leptons); }; inline FitParticle* GetHMISProton (void) { return GetHMISParticle(2212); }; inline FitParticle* GetHMISNeutron (void) { return GetHMISParticle(2112); }; inline FitParticle* GetHMISPiZero (void) { return GetHMISParticle(111); }; inline FitParticle* GetHMISPiPlus (void) { return GetHMISParticle(211); }; inline FitParticle* GetHMISPiMinus (void) { return GetHMISParticle(-211); }; inline FitParticle* GetHMISPhoton (void) { return GetHMISParticle(22); }; inline FitParticle* GetHMISLepton (void) { return GetHMISParticle(PhysConst::pdg_leptons); }; inline FitParticle* GetHMISPions (void) { return GetHMISParticle(PhysConst::pdg_pions); }; inline FitParticle* GetHMISChargePions(void) { return GetHMISParticle(PhysConst::pdg_charged_pions); }; inline int GetHMISNuElectronIndex (void) { return GetHMISParticleIndex(12); }; inline int GetHMISNuMuonIndex (void) { return GetHMISParticleIndex(14); }; inline int GetHMISNuTauIndex (void) { return GetHMISParticleIndex(16); }; inline int GetHMISElectronIndex (void) { return GetHMISParticleIndex(11); }; inline int GetHMISMuonIndex (void) { return GetHMISParticleIndex(13); }; inline int GetHMISTauIndex (void) { return GetHMISParticleIndex(15); }; inline int GetHMISProtonIndex (void) { return GetHMISParticleIndex(2212); }; inline int GetHMISNeutronIndex (void) { return GetHMISParticleIndex(2112); }; inline int GetHMISPiZeroIndex (void) { return GetHMISParticleIndex(111); }; inline int GetHMISPiPlusIndex (void) { return GetHMISParticleIndex(211); }; inline int GetHMISPiMinusIndex (void) { return GetHMISParticleIndex(-211); }; inline int GetHMISPhotonIndex (void) { return GetHMISParticleIndex(22); }; inline int GetHMISLeptonsIndex (void) { return GetHMISParticleIndex(PhysConst::pdg_leptons); }; inline int GetHMISPionsIndex (void) { return GetHMISParticleIndex(PhysConst::pdg_pions); }; inline int GetHMISChargePionsIndex(void) { return GetHMISParticleIndex(PhysConst::pdg_charged_pions); }; // ---- Final State Helpers --- // inline bool HasFSParticle(int const pdg) const { return HasParticle(pdg, kFinalState); }; template inline bool HasFSParticle(int const (&pdgs)[N]) const { return HasParticle(pdgs, kFinalState); }; inline int NumFSParticle(int const pdg = 0) const { return NumParticle(pdg, kFinalState); }; template inline int NumFSParticle(int const (&pdgs)[N]) const { return NumParticle(pdgs, kFinalState); }; inline std::vector GetAllFSParticleIndices(int const pdg = -1) const { return GetAllParticleIndices(pdg, kFinalState); }; template inline std::vector GetAllFSParticleIndices(int const (&pdgs)[N]) const { return GetAllParticleIndices(pdgs, kFinalState); }; inline std::vector GetAllFSParticle(int const pdg = -1) { return GetAllParticle(pdg, kFinalState); }; template inline std::vector GetAllFSParticle(int const (&pdgs)[N]) { return GetAllParticle(pdgs, kFinalState); }; inline FitParticle* GetHMFSParticle(int const pdg) { return GetHMParticle(pdg, kFinalState); }; template inline FitParticle* GetHMFSParticle(int const (&pdgs)[N]) { return GetHMParticle(pdgs, kFinalState); }; inline int GetHMFSParticleIndex(int const pdg) const { return GetHMParticleIndex(pdg, kFinalState); }; template inline int GetHMFSParticleIndex(int const (&pdgs)[N]) const { return GetHMParticleIndex(pdgs, kFinalState); }; inline bool HasFSNuElectron (void) const { return HasFSParticle(12); }; inline bool HasFSNuMuon (void) const { return HasFSParticle(14); }; inline bool HasFSNuTau (void) const { return HasFSParticle(16); }; inline bool HasFSElectron (void) const { return HasFSParticle(11); }; inline bool HasFSMuon (void) const { return HasFSParticle(13); }; inline bool HasFSTau (void) const { return HasFSParticle(15); }; inline bool HasFSProton (void) const { return HasFSParticle(2212); }; inline bool HasFSNeutron (void) const { return HasFSParticle(2112); }; inline bool HasFSPiZero (void) const { return HasFSParticle(111); }; inline bool HasFSPiPlus (void) const { return HasFSParticle(211); }; inline bool HasFSPiMinus (void) const { return HasFSParticle(-211); }; inline bool HasFSPhoton (void) const { return HasFSParticle(22); }; inline bool HasFSLeptons (void) const { return HasFSParticle(PhysConst::pdg_leptons); }; inline bool HasFSPions (void) const { return HasFSParticle(PhysConst::pdg_pions); }; inline bool HasFSChargePions (void) const { return HasFSParticle(PhysConst::pdg_charged_pions); }; inline int NumFSNuElectron (void) const { return NumFSParticle(12); }; inline int NumFSNuMuon (void) const { return NumFSParticle(14); }; inline int NumFSNuTau (void) const { return NumFSParticle(16); }; inline int NumFSElectron (void) const { return NumFSParticle(11); }; inline int NumFSMuon (void) const { return NumFSParticle(13); }; inline int NumFSTau (void) const { return NumFSParticle(15); }; inline int NumFSProton (void) const { return NumFSParticle(2212); }; inline int NumFSNeutron (void) const { return NumFSParticle(2112); }; inline int NumFSPiZero (void) const { return NumFSParticle(111); }; inline int NumFSPiPlus (void) const { return NumFSParticle(211); }; inline int NumFSPiMinus (void) const { return NumFSParticle(-211); }; inline int NumFSPhoton (void) const { return NumFSParticle(22); }; int NumFSLeptons (void) const; // { return NumFSParticle(PhysConst::pdg_leptons); }; inline int NumFSPions (void) const { return NumFSParticle(PhysConst::pdg_pions); }; inline int NumFSChargePions (void) const { return NumFSParticle(PhysConst::pdg_charged_pions); }; inline std::vector GetAllFSNuElectronIndices (void) const { return GetAllFSParticleIndices(12); }; inline std::vector GetAllFSNuMuonIndices (void) const { return GetAllFSParticleIndices(14); }; inline std::vector GetAllFSNuTauIndices (void) const { return GetAllFSParticleIndices(16); }; inline std::vector GetAllFSElectronIndices (void) const { return GetAllFSParticleIndices(11); }; inline std::vector GetAllFSMuonIndices (void) const { return GetAllFSParticleIndices(13); }; inline std::vector GetAllFSTauIndices (void) const { return GetAllFSParticleIndices(15); }; inline std::vector GetAllFSProtonIndices (void) const { return GetAllFSParticleIndices(2212); }; inline std::vector GetAllFSNeutronIndices (void) const { return GetAllFSParticleIndices(2112); }; inline std::vector GetAllFSPiZeroIndices (void) const { return GetAllFSParticleIndices(111); }; inline std::vector GetAllFSPiPlusIndices (void) const { return GetAllFSParticleIndices(211); }; inline std::vector GetAllFSPiMinusIndices (void) const { return GetAllFSParticleIndices(-211); }; inline std::vector GetAllFSPhotonIndices (void) const { return GetAllFSParticleIndices(22); }; inline std::vector GetAllFSLeptonsIndices (void) const { return GetAllFSParticleIndices(PhysConst::pdg_leptons); }; inline std::vector GetAllFSPionsIndices (void) const { return GetAllFSParticleIndices(PhysConst::pdg_pions); }; inline std::vector GetAllFSChargePionsIndices(void) const { return GetAllFSParticleIndices(PhysConst::pdg_charged_pions); }; inline std::vector GetAllFSNuElectron (void) { return GetAllFSParticle(12); }; inline std::vector GetAllFSNuMuon (void) { return GetAllFSParticle(14); }; inline std::vector GetAllFSNuTau (void) { return GetAllFSParticle(16); }; inline std::vector GetAllFSElectron (void) { return GetAllFSParticle(11); }; inline std::vector GetAllFSMuon (void) { return GetAllFSParticle(13); }; inline std::vector GetAllFSTau (void) { return GetAllFSParticle(15); }; inline std::vector GetAllFSProton (void) { return GetAllFSParticle(2212); }; inline std::vector GetAllFSNeutron (void) { return GetAllFSParticle(2112); }; inline std::vector GetAllFSPiZero (void) { return GetAllFSParticle(111); }; inline std::vector GetAllFSPiPlus (void) { return GetAllFSParticle(211); }; inline std::vector GetAllFSPiMinus (void) { return GetAllFSParticle(-211); }; inline std::vector GetAllFSPhoton (void) { return GetAllFSParticle(22); }; inline std::vector GetAllFSLeptons (void) { return GetAllFSParticle(PhysConst::pdg_leptons); }; inline std::vector GetAllFSPions (void) { return GetAllFSParticle(PhysConst::pdg_pions); }; inline std::vector GetAllFSChargePions (void) { return GetAllFSParticle(PhysConst::pdg_charged_pions); }; inline FitParticle* GetHMFSNuElectron (void) { return GetHMFSParticle(12); }; inline FitParticle* GetHMFSNuMuon (void) { return GetHMFSParticle(14); }; inline FitParticle* GetHMFSNuTau (void) { return GetHMFSParticle(16); }; inline FitParticle* GetHMFSElectron (void) { return GetHMFSParticle(11); }; inline FitParticle* GetHMFSMuon (void) { return GetHMFSParticle(13); }; inline FitParticle* GetHMFSTau (void) { return GetHMFSParticle(15); }; inline FitParticle* GetHMFSAnyLeptons (void) { return GetHMFSParticle(PhysConst::pdg_all_leptons); }; inline FitParticle* GetHMFSProton (void) { return GetHMFSParticle(2212); }; inline FitParticle* GetHMFSNeutron (void) { return GetHMFSParticle(2112); }; inline FitParticle* GetHMFSPiZero (void) { return GetHMFSParticle(111); }; inline FitParticle* GetHMFSPiPlus (void) { return GetHMFSParticle(211); }; inline FitParticle* GetHMFSPiMinus (void) { return GetHMFSParticle(-211); }; inline FitParticle* GetHMFSPhoton (void) { return GetHMFSParticle(22); }; inline FitParticle* GetHMFSLeptons (void) { return GetHMFSParticle(PhysConst::pdg_leptons); }; inline FitParticle* GetHMFSAnyLepton (void) { return GetHMFSParticle(PhysConst::pdg_all_leptons); }; inline FitParticle* GetHMFSPions (void) { return GetHMFSParticle(PhysConst::pdg_pions); }; inline FitParticle* GetHMFSChargePions(void) { return GetHMFSParticle(PhysConst::pdg_charged_pions); }; inline int GetHMFSNuElectronIndex (void) const { return GetHMFSParticleIndex(12); }; inline int GetHMFSNuMuonIndex (void) const { return GetHMFSParticleIndex(14); }; inline int GetHMFSNuTauIndex (void) const { return GetHMFSParticleIndex(16); }; inline int GetHMFSElectronIndex (void) const { return GetHMFSParticleIndex(11); }; inline int GetHMFSMuonIndex (void) const { return GetHMFSParticleIndex(13); }; inline int GetHMFSTauIndex (void) const { return GetHMFSParticleIndex(15); }; inline int GetHMFSProtonIndex (void) const { return GetHMFSParticleIndex(2212); }; inline int GetHMFSNeutronIndex (void) const { return GetHMFSParticleIndex(2112); }; inline int GetHMFSPiZeroIndex (void) const { return GetHMFSParticleIndex(111); }; inline int GetHMFSPiPlusIndex (void) const { return GetHMFSParticleIndex(211); }; inline int GetHMFSPiMinusIndex (void) const { return GetHMFSParticleIndex(-211); }; inline int GetHMFSPhotonIndex (void) const { return GetHMFSParticleIndex(22); }; inline int GetHMFSLeptonsIndex (void) const { return GetHMFSParticleIndex(PhysConst::pdg_leptons); }; inline int GetHMFSAnyLeptonIndex (void) const { return GetHMFSParticleIndex(PhysConst::pdg_all_leptons); }; inline int GetHMFSPionsIndex (void) const { return GetHMFSParticleIndex(PhysConst::pdg_pions); }; inline int GetHMFSChargePionsIndex(void) const { return GetHMFSParticleIndex(PhysConst::pdg_charged_pions); }; // ---- NEUTRINO INCOMING Related Functions int GetBeamNeutrinoIndex (void) const; inline TLorentzVector GetBeamNeutrinoP4 (void) const { return GetParticleP4(GetBeamNeutrinoIndex()); }; inline TVector3 GetBeamNeutrinoP3 (void) const { return GetParticleP3(GetBeamNeutrinoIndex()); }; inline double GetBeamNeutrinoMom (void) const { return GetParticleMom(GetBeamNeutrinoIndex()); }; inline double GetBeamNeutrinoMom2 (void) const { return GetParticleMom2(GetBeamNeutrinoIndex()); }; inline double GetBeamNeutrinoE (void) const { return GetParticleE(GetBeamNeutrinoIndex()); }; inline double Enu (void) const { return GetBeamNeutrinoE(); }; inline int GetBeamNeutrinoPDG (void) const { return GetParticlePDG(GetBeamNeutrinoIndex()); }; inline int PDGnu (void) const { return GetBeamNeutrinoPDG(); }; inline int GetNeutrinoInPos (void) const { return GetBeamNeutrinoIndex(); }; inline FitParticle* GetBeamNeutrino (void) { return GetParticle(GetBeamNeutrinoIndex()); }; inline FitParticle* GetNeutrinoIn (void) { return GetParticle(GetBeamNeutrinoIndex()); }; // ---- Electron INCOMING Related Functions int GetBeamElectronIndex (void) const; inline TLorentzVector GetBeamElectronP4 (void) const { return GetParticleP4(GetBeamElectronIndex()); }; inline TVector3 GetBeamElectronP3 (void) const { return GetParticleP3(GetBeamElectronIndex()); }; inline double GetBeamElectronMom (void) const { return GetParticleMom(GetBeamElectronIndex()); }; inline double GetBeamElectronMom2 (void) const { return GetParticleMom2(GetBeamElectronIndex()); }; inline double GetBeamElectronE (void) const { return GetParticleE(GetBeamElectronIndex()); }; inline FitParticle* GetBeamElectron (void) { return GetParticle(GetBeamElectronIndex()); }; // ---- Pion INCOMING Functions int GetBeamPionIndex (void) const; inline TLorentzVector GetBeamPionP4 (void) const { return GetParticleP4(GetBeamPionIndex()); }; inline TVector3 GetBeamPionP3 (void) const { return GetParticleP3(GetBeamPionIndex()); }; inline double GetBeamPionMom (void) const { return GetParticleMom(GetBeamPionIndex()); }; inline double GetBeamPionMom2 (void) const { return GetParticleMom2(GetBeamPionIndex()); }; inline double GetBeamPionE (void) const { return GetParticleE(GetBeamPionIndex()); }; inline FitParticle* GetBeamPion (void) { return GetParticle(GetBeamPionIndex()); }; /// Legacy Functions inline FitParticle* PartInfo(uint i) { return GetParticle(i); }; inline UInt_t Npart (void) const { return NPart(); }; inline UInt_t NPart (void) const { return fNParticles; }; // Other Functions int NumFSMesons(); inline int GetBeamPartPos(void) const { return 0; }; FitParticle* GetBeamPart(void); int GetLeptonOutPos(void) const; FitParticle* GetLeptonOut(void); // Event Information double weight; // need for silly reason int Mode; // Public access needed int fMode; UInt_t fEventNo; double fTotCrs; int fTargetA; int fTargetZ; int fTargetH; bool fBound; int fDistance; int fTargetPDG; // Reduced Particle Stack UInt_t kMaxParticles; int fNParticles; double** fParticleMom; UInt_t* fParticleState; int* fParticlePDG; FitParticle** fParticleList; double** fOrigParticleMom; UInt_t* fOrigParticleState; int* fOrigParticlePDG; double* fNEUT_ParticleStatusCode; double* fNEUT_ParticleAliveCode; GeneratorInfoBase* fGenInfo; // Config Options for this class bool kRemoveFSIParticles; bool kRemoveUndefParticles; }; /*! @} */ #endif diff --git a/src/InputHandler/InputUtils.cxx b/src/InputHandler/InputUtils.cxx index 8f7acdf..cb6047d 100644 --- a/src/InputHandler/InputUtils.cxx +++ b/src/InputHandler/InputUtils.cxx @@ -1,173 +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 . *******************************************************************************/ -#include "FitParameters.h" + #include "GeneralUtils.h" #include "InputHandler.h" #include "InputUtils.h" namespace InputUtils { std::vector ParseInputFileList(std::string const &inpFile) { std::vector inputs = GeneralUtils::ParseToStr(inpFile, ","); if (inputs.front()[0] == '(') { inputs.front() = inputs.front().substr(1); } if (inputs.back()[inputs.back().size() - 1] == ')') { inputs.back() = inputs.back().substr(0, inputs.back().size() - 1); } return inputs; } InputType ParseInputType(std::string const &inp) { // The hard-coded list of supported input generators const static std::string filetypes[] = { "NEUT", "NUWRO", "GENIE", "GiBUU", "NUANCE", "EVSPLN", "EMPTY", "FEVENT", "JOINT", "SIGMAQ0HIST", "HISTO"}; size_t nInputTypes = GeneralUtils::GetArraySize(filetypes); for (size_t i = 0; i < nInputTypes; i++) { if (inp == filetypes[i]) { return InputType(i); } } return kInvalid_Input; } bool IsJointInput(std::string const &inputs) { bool isJoint = (inputs[0] == '('); if (isJoint && (inputs[inputs.length() - 1] != ')')) { ERR(FTL) << "Inputs specifier: \"" << inputs << "\" looks like a composite input specifier -- " "(filea.root,fileb.root), however, it did not end in a \')\', " "it ended in a \'" << inputs[inputs.length() - 1] << "\'" << std::endl; throw; } return isJoint; } std::string ExpandInputDirectories(std::string const &inputs) { // Parse the "environement" flags in the fitter config // Can specify NEUT_DIR = "" and others in parameters/fitter.config.dat const static std::string filedir[] = {"NEUT_DIR", "NUWRO_DIR", "GENIE_DIR", "NUANCE_DIR", "EVSPLN_DIR", "GIBUU_DIR"}; size_t nfiledir = GeneralUtils::GetArraySize(filedir); std::string expandedInputs = inputs; for (size_t i = 0; i < nfiledir; i++) { std::string tempdir = "@" + filedir[i]; bool didRpl; do { size_t torpl = expandedInputs.find(tempdir); if (torpl != std::string::npos) { std::string event_folder = FitPar::Config().GetParS(filedir[i]); expandedInputs.replace(torpl, tempdir.size(), event_folder); didRpl = true; } else { didRpl = false; } } while (didRpl); } bool didRpl; do { size_t torpl = expandedInputs.find("//"); if (torpl != std::string::npos) { expandedInputs.replace(torpl, 2, "/"); didRpl = true; } else { didRpl = false; } } while (didRpl); return expandedInputs; } InputType GuessInputTypeFromFile(TFile *inpF) { const std::string NEUT_TreeName = "neuttree"; const std::string NuWro_TreeName = "treeout"; const std::string GENIE_TreeName = "gtree"; const std::string GiBUU_TreeName = "giRooTracker"; if (!inpF) { return kInvalid_Input; } TTree *NEUT_Input = dynamic_cast(inpF->Get(NEUT_TreeName.c_str())); if (NEUT_Input) { return kNEUT_Input; } TTree *NUWRO_Input = dynamic_cast(inpF->Get(NuWro_TreeName.c_str())); if (NUWRO_Input) { return kNUWRO_Input; } TTree *GENIE_Input = dynamic_cast(inpF->Get(GENIE_TreeName.c_str())); if (GENIE_Input) { return kGENIE_Input; } TTree *GiBUU_Input = dynamic_cast(inpF->Get(GiBUU_TreeName.c_str())); if (GiBUU_Input) { return kGiBUU_Input; } return kInvalid_Input; } std::string PrependGuessedInputTypeToName(std::string const &inpFName) { //If it already has a name. if(inpFName.find(":") != std::string::npos){ return inpFName; } TFile *inpF = TFile::Open(inpFName.c_str(), "READ"); if (!inpF || !inpF->IsOpen()) { THROW("Couldn't open \"" << inpFName << "\" for reading."); } InputType iType = GuessInputTypeFromFile(inpF); if (iType == kInvalid_Input) { THROW("Couldn't determine input type from file: " << inpFName << "."); } inpF->Close(); delete inpF; switch (iType) { case kNEUT_Input: { return "NEUT:" + inpFName; } case kNUWRO_Input: { return "NUWRO:" + inpFName; } case kGENIE_Input: { return "GENIE:" + inpFName; } case kGiBUU_Input: { return "GiBUU:" + inpFName; } default: { ERR(FTL) << "Input type from file: " << inpFName << " was invalid." << std::endl; throw; } } } } diff --git a/src/Routines/CMakeLists.txt b/src/Logger/CMakeLists.txt similarity index 79% copy from src/Routines/CMakeLists.txt copy to src/Logger/CMakeLists.txt index 2c5cf1c..dee1fc1 100644 --- a/src/Routines/CMakeLists.txt +++ b/src/Logger/CMakeLists.txt @@ -1,66 +1,54 @@ # 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 . ################################################################################ -set(IMPLFILES -ComparisonRoutines.cxx -SystematicRoutines.cxx -SplineRoutines.cxx -) - -if(USE_MINIMIZER) - set(IMPLFILES ${IMPLFILES};MinimizerRoutines.cxx) -endif() - set(HEADERFILES -ComparisonRoutines.h -SystematicRoutines.h -SplineRoutines.h +FitLogger.h +Initialiser.h ) -if(USE_MINIMIZER) - set(HEADERFILES ${HEADERFILES};MinimizerRoutines.h) -endif() +set(IMPLFILES +PythiaQuiet.f +FitLogger.cxx +Initialiser.cxx +) -set(LIBNAME Routines) +set(LIBNAME Logger) if(CMAKE_BUILD_TYPE MATCHES DEBUG) add_library(${LIBNAME} STATIC ${IMPLFILES}) else(CMAKE_BUILD_TYPE MATCHES RELEASE) add_library(${LIBNAME} SHARED ${IMPLFILES}) endif() -include_directories(${EXP_INCLUDE_DIRECTORIES}) - include_directories(${MINIMUM_INCLUDE_DIRECTORIES}) -include_directories(${CMAKE_SOURCE_DIR}/src/FCN) -include_directories(${CMAKE_SOURCE_DIR}/src/MCStudies) - set_target_properties(${LIBNAME} PROPERTIES VERSION "${NUISANCE_VERSION_MAJOR}.${NUISANCE_VERSION_MINOR}.${NUISANCE_VERSION_REVISION}") + #set_target_properties(${LIBNAME} PROPERTIES LINK_FLAGS ${ROOT_LD_FLAGS}) if(DEFINED PROJECTWIDE_EXTRA_DEPENDENCIES) add_dependencies(${LIBNAME} ${PROJECTWIDE_EXTRA_DEPENDENCIES}) endif() install(TARGETS ${LIBNAME} DESTINATION lib) #Can uncomment this to install the headers... but is it really neccessary? #install(FILES ${HEADERFILES} DESTINATION include) set(MODULETargets ${MODULETargets} ${LIBNAME} PARENT_SCOPE) + diff --git a/src/Utils/FitLogger.cxx b/src/Logger/FitLogger.cxx similarity index 99% rename from src/Utils/FitLogger.cxx rename to src/Logger/FitLogger.cxx index a5d364f..f675869 100644 --- a/src/Utils/FitLogger.cxx +++ b/src/Logger/FitLogger.cxx @@ -1,350 +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 "FitLogger.h" #include #include namespace Logger { // Logger Variables int log_verb = 4; bool use_colors = true; -bool showtrace = false; + +bool showtrace = true; + std::ostream* __LOG_outstream(&std::cout); std::ofstream __LOG_nullstream; // Error Variables int err_verb = 0; std::ostream* __ERR_outstream(&std::cerr); // Extra Variables bool external_verb = false; bool super_rainbow_mode = true; //!< For when fitting gets boring. unsigned int super_rainbow_mode_colour = 0; std::streambuf* default_cout = std::cout.rdbuf(); std::streambuf* default_cerr = std::cerr.rdbuf(); std::ofstream redirect_stream("/dev/null"); int silentfd = open("/dev/null", O_WRONLY); int savedstdoutfd = dup(fileno(stdout)); int savedstderrfd = dup(fileno(stderr)); int nloggercalls = 0; int timelastlog = 0; } // -------- Logging Functions --------- // bool LOGGING(int level) { // std::cout << "LOGGING : " << __FILENAME__ << " " << __FUNCTION__ << // std::endl; return (Logger::log_verb >= (uint)__GETLOG_LEVEL(level, __FILENAME__, __FUNCTION__)); }; int __GETLOG_LEVEL(int level, const char* filename, const char* funct) { #ifdef __DEBUG__ int logfile = FitPar::Config().GetParI("logging." + std::string(filename)); if (logfile >= DEB and logfile <= EVT) { level = logfile; } int logfunc = FitPar::Config().GetParI("logging." + std::string(funct)); if (logfunc >= DEB and logfunc <= EVT) { level = logfunc; } #endif return level; }; std::ostream& __OUTLOG(int level, const char* filename, const char* funct, int line) { if (Logger::log_verb < (unsigned int)level && Logger::log_verb != (unsigned int)DEB) { return (Logger::__LOG_nullstream); } else { if (Logger::use_colors) { switch (level) { case FIT: std::cout << BOLDGREEN; break; case MIN: std::cout << BOLDBLUE; break; case SAM: std::cout << MAGENTA; break; case REC: std::cout << BLUE; break; case SIG: std::cout << GREEN; break; case DEB: std::cout << CYAN; break; default: break; } } switch (level) { case FIT: std::cout << "[LOG Fitter]"; break; case MIN: std::cout << "[LOG Minmzr]"; break; case SAM: std::cout << "[LOG Sample]"; break; case REC: std::cout << "[LOG Reconf]"; break; case SIG: std::cout << "[LOG Signal]"; break; case EVT: std::cout << "[LOG Event ]"; break; case DEB: std::cout << "[LOG DEBUG ]"; break; default: std::cout << "[LOG INFO ]"; break; } // Apply indent if (true) { switch (level) { case FIT: std::cout << ": "; break; case MIN: std::cout << ":- "; break; case SAM: std::cout << ":-- "; break; case REC: std::cout << ":--- "; break; case SIG: std::cout << ":---- "; break; case EVT: std::cout << ":----- "; break; case DEB: std::cout << ":------ "; break; default: std::cout << " "; break; } } if (Logger::use_colors) std::cout << RESET; if (Logger::showtrace) { std::cout << " : " << filename << "::" << funct << "[l. " << line << "] : "; } return *(Logger::__LOG_outstream); } } void SETVERBOSITY(int level) { Logger::log_verb = level; } void SETVERBOSITY(std::string verb) { if (!verb.compare("DEB")) Logger::log_verb = -1; else if (!verb.compare("QUIET")) Logger::log_verb = 0; else if (!verb.compare("FIT")) Logger::log_verb = 1; else if (!verb.compare("MIN")) Logger::log_verb = 2; else if (!verb.compare("SAM")) Logger::log_verb = 3; else if (!verb.compare("REC")) Logger::log_verb = 4; else if (!verb.compare("SIG")) Logger::log_verb = 5; else if (!verb.compare("EVT")) Logger::log_verb = 6; else Logger::log_verb = std::atoi(verb.c_str()); } /// Set Trace Option void SETTRACE(bool val) { Logger::showtrace = val; } // ------ ERROR FUNCTIONS ---------- // std::ostream& __OUTERR(int level, const char* filename, const char* funct, int line) { if (Logger::use_colors) std::cerr << RED; switch (level) { case FTL: std::cerr << "[ERR FATAL ]: "; break; case WRN: std::cerr << "[ERR WARN ]: "; break; } if (Logger::use_colors) std::cerr << RESET; // Allows enable error debugging trace if (true or Logger::showtrace) { std::cout << filename << "::" << funct << "[l. " << line << "] : "; } return *(Logger::__ERR_outstream); } // ----------- External Logging ----------- // void SETEXTERNALVERBOSITY(int level) { Logger::external_verb = (level > 0); } void StopTalking() { // Check verbosity set correctly if (!Logger::external_verb) return; // Only redirect if we're not debugging if (Logger::log_verb == (unsigned int)DEB) return; std::cout.rdbuf(Logger::redirect_stream.rdbuf()); std::cerr.rdbuf(Logger::redirect_stream.rdbuf()); shhnuisancepythiaitokay_(); fflush(stdout); fflush(stderr); dup2(Logger::silentfd, fileno(stdout)); dup2(Logger::silentfd, fileno(stderr)); } void StartTalking() { // Check verbosity set correctly if (!Logger::external_verb) return; std::cout.rdbuf(Logger::default_cout); std::cerr.rdbuf(Logger::default_cerr); canihaznuisancepythia_(); fflush(stdout); fflush(stderr); dup2(Logger::savedstdoutfd, fileno(stdout)); dup2(Logger::savedstderrfd, fileno(stderr)); } //****************************************** void LOG_VERB(std::string verb) { //****************************************** if (!verb.compare("DEB")) Logger::log_verb = -1; else if (!verb.compare("QUIET")) Logger::log_verb = 0; else if (!verb.compare("FIT")) Logger::log_verb = 1; else if (!verb.compare("MIN")) Logger::log_verb = 2; else if (!verb.compare("SAM")) Logger::log_verb = 3; else if (!verb.compare("REC")) Logger::log_verb = 4; else if (!verb.compare("SIG")) Logger::log_verb = 5; else if (!verb.compare("EVT")) Logger::log_verb = 6; // else Logger::log_verb = GeneralUtils::StrToInt(verb); std::cout << "Set logging verbosity to : " << Logger::log_verb << std::endl; return; } //****************************************** void ERR_VERB(std::string verb) { //****************************************** std::cout << "Setting ERROR VERB" << std::endl; if (!verb.compare("ERRQUIET")) Logger::err_verb = 0; else if (!verb.compare("FTL")) Logger::err_verb = 1; else if (!verb.compare("WRN")) Logger::err_verb = 2; // else Logger::err_verb = GeneralUtils::StrToInt(verb); std::cout << "Set error verbosity to : " << Logger::err_verb << std::endl; return; } //****************************************** bool LOG_LEVEL(int level) { //****************************************** if (Logger::log_verb == (unsigned int)DEB) { return true; } if (Logger::log_verb < (unsigned int)level) { return false; } return true; } void SET_TRACE(bool val) { Logger::showtrace = val; } //****************************************** std::ostream& _LOG(int level, const char* filename, const char* func, int line) //****************************************** { return __OUTLOG(level, filename, func, line); } //****************************************** std::ostream& _ERR(int level, const char* filename, const char* func, int line) //****************************************** { if (Logger::use_colors) std::cerr << RED; if (Logger::showtrace) { std::cout << filename << "::" << func << "[l. " << line << "] : "; } switch (level) { case FTL: std::cerr << "[ERR FATAL ]: "; break; case WRN: std::cerr << "[ERR WARN ] : "; break; } if (Logger::use_colors) std::cerr << RESET; return *Logger::__ERR_outstream; } diff --git a/src/Utils/FitLogger.h b/src/Logger/FitLogger.h similarity index 97% rename from src/Utils/FitLogger.h rename to src/Logger/FitLogger.h index d8b26e9..ce46f6c 100644 --- a/src/Utils/FitLogger.h +++ b/src/Logger/FitLogger.h @@ -1,218 +1,221 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #ifndef FITLOGGER_HPP #define FITLOGGER_HPP /*! * \addtogroup FitBase * @{ */ #include #include #include #include -#include "FitParameters.h" -#include "Initialiser.h" + #include "TRandom3.h" +#include "Initialiser.h" + +#include "NuisConfig.h" + #define RESET "\033[0m" #define BLACK "\033[30m" /* Black */ #define RED "\033[31m" /* Red */ #define GREEN "\033[32m" /* Green */ #define YELLOW "\033[33m" /* Yellow */ #define BLUE "\033[34m" /* Blue */ #define MAGENTA "\033[35m" /* Magenta */ #define CYAN "\033[36m" /* Cyan */ #define WHITE "\033[37m" /* White */ #define BOLDBLACK "\033[1m\033[30m" /* Bold Black */ #define BOLDRED "\033[1m\033[31m" /* Bold Red */ #define BOLDGREEN "\033[1m\033[32m" /* Bold Green */ #define BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */ #define BOLDBLUE "\033[1m\033[34m" /* Bold Blue */ #define BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */ #define BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */ #define BOLDWHITE "\033[1m\033[37m" /* Bold White */ namespace Logger { extern int log_verb; //!< Current VERBOSITY extern int err_verb; //!< Current ERROR VERBOSITY extern bool external_verb; extern bool use_colors; //!< Use BASH Terminal Colors Flag extern bool super_rainbow_mode; //!< For when fitting gets boring. extern unsigned int super_rainbow_mode_colour; extern bool showtrace; // Quick Tracing for debugging extern int nloggercalls; extern int timelastlog; extern std::streambuf* default_cout; //!< Where the STDOUT stream is currently directed extern std::streambuf* default_cerr; //!< Where the STDERR stream is currently directed extern std::ofstream redirect_stream; //!< Where should unwanted messages be thrown } /// Returns full path to file currently in #define __FILENAME__ \ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) // ------ LOGGER FUNCTIONS ------------ // namespace Logger { /// NULL Output Stream extern std::ofstream __LOG_nullstream; /// Logging Stream extern std::ostream* __LOG_outstream; } /// Fitter VERBOSITY Enumerations /// These go through the different depths of the fitter. /// /// 0 QUIET - Little output. /// 1 FIT - Top Level Minimizer Status /// 2 MIN - Output from the FCN Minimizer Functions /// 3 SAM - Output from each of the samples during setup etc /// 4 REC - Output during each reconfigure. Percentage progress etc. /// 5 SIG - Output during every signal event that is found. /// 6 EVT - Output during every event. /// -1 DEB - Will print only debugging info wherever a LOG(DEB) statement was /// made enum __LOG_levels { DEB = -1, QUIET, FIT, MIN, SAM, REC, SIG, EVT }; /// Returns log level for a given file/function int __GETLOG_LEVEL(int level, const char* filename, const char* funct); /// Actually runs the logger std::ostream& __OUTLOG(int level, const char* filename, const char* funct, int line); /// Global Logging Definitions #define QLOG(level, stream) \ { \ if (Logger::log_verb >= \ __GETLOG_LEVEL(level, __FILENAME__, __FUNCTION__)) { \ __OUTLOG(level, __FILENAME__, __FUNCTION__, __LINE__) << stream \ << std::endl; \ } \ }; #define BREAK(level) \ { \ \ if (Logger::log_verb >= \ __GETLOG_LEVEL(level, __FILENAME__, __FUNCTION__)) { \ __OUTLOG(level, __FILENAME__, __FUNCTION__, __LINE__) << std::endl; \ } \ }; /// Return whether logging level is valid bool LOGGING(int level); /// Set Global Verbosity void SETVERBOSITY(int level); /// Set Global Verbosity from String void SETVERBOSITY(std::string verb); /// Set Trace Option void SETTRACE(bool val); // ----------- ERROR FUNCTIONS ---------- // /// Error Stream extern std::ostream* __ERR_outstream; /// Fitter ERROR VERBOSITY Enumerations /// /// 0 QUIET - No Error Output /// 1 FTL - Show errors only if fatal /// 2 WRN - Show Warning messages enum __ERR_levels { ERRQUIET = 0, FTL, WRN }; /// Actually runs the error messager std::ostream& __OUTERR(int level, const char* filename, const char* funct, int line); /// Error Logging Function #define ERROR(level, stream) \ { \ __OUTERR(level, __FILENAME__, __FUNCTION__, __LINE__) << stream \ << std::endl; \ }; // ----------- ERROR HANDLING ------------- // /// Exit the program with given error message stream #define THROW(stream) \ { \ __OUTERR(FTL, __FILENAME__, __FUNCTION__, __LINE__) << stream \ << std::endl; \ __OUTERR(FTL, __FILENAME__, __FUNCTION__, __LINE__) \ << "Attempting to save output file." << std::endl; \ - if (FitPar::Config().out && FitPar::Config().out->IsOpen()) { \ - FitPar::Config().out->Write(); \ - FitPar::Config().out->Close(); \ + if (Config::Get().out && Config::Get().out->IsOpen()) { \ + Config::Get().out->Write(); \ + Config::Get().out->Close(); \ __OUTERR(FTL, __FILENAME__, __FUNCTION__, __LINE__) << "Done." \ << std::endl; \ } else { \ __OUTERR(FTL, __FILENAME__, __FUNCTION__, __LINE__) \ << "No output file set." << std::endl; \ } \ __OUTERR(FTL, __FILENAME__, __FUNCTION__, __LINE__) << "Exiting!" \ << std::endl; \ std::abort(); \ } // ----------- External Logging ----------- // void SETEXTERNALVERBOSITY(int level); void StopTalking(); void StartTalking(); extern "C" { void shhnuisancepythiaitokay_(void); void canihaznuisancepythia_(void); } // ---------- LEGACY FUNCTIONS -------------- // bool LOG_LEVEL(int level); //! Set LOG VERBOSITY from a string void LOG_VERB(std::string verb); inline void LOG_VERB(int verb) { Logger::log_verb = verb; }; void SET_TRACE(bool val); //! Set ERROR VERBOSITY from a string void ERR_VERB(std::string verb); inline void ERR_VERB(int verb) { Logger::err_verb = verb; }; /// Logging Function. Use as a string stream. e.g. LOG(SAM) << "This sample is /// dope." << std::endl; std::ostream& _LOG(int level, const char* filename, const char* funct, int line); #define LOG(level) _LOG(level, __FILENAME__, __FUNCTION__, __LINE__) //! Error Function. Use as a string stream. e.g. ERR(FTL) << "The fit is //! completely buggered." << std::endl; std::ostream& _ERR(int level, const char* filename, const char* funct, int line); #define ERR(level) _ERR(level, __FILENAME__, __FUNCTION__, __LINE__) /*! @} */ #endif diff --git a/src/Utils/Initialiser.cxx b/src/Logger/Initialiser.cxx similarity index 100% rename from src/Utils/Initialiser.cxx rename to src/Logger/Initialiser.cxx diff --git a/src/Utils/Initialiser.h b/src/Logger/Initialiser.h similarity index 100% rename from src/Utils/Initialiser.h rename to src/Logger/Initialiser.h diff --git a/src/Utils/PythiaQuiet.f b/src/Logger/PythiaQuiet.f similarity index 100% rename from src/Utils/PythiaQuiet.f rename to src/Logger/PythiaQuiet.f diff --git a/src/MCStudies/ElectronFlux_FlatTree.cxx b/src/MCStudies/ElectronFlux_FlatTree.cxx index 5ccd5ea..e355f0e 100644 --- a/src/MCStudies/ElectronFlux_FlatTree.cxx +++ b/src/MCStudies/ElectronFlux_FlatTree.cxx @@ -1,559 +1,559 @@ // 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 "ElectronFlux_FlatTree.h" //******************************************************************** /// @brief Class to perform MC Studies on a custom measurement ElectronFlux_FlatTree::ElectronFlux_FlatTree(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 << std::endl; if (fScaleFactor <= 0.0) { ERR(WRN) << "SCALE FACTOR TOO LOW " << std::endl; sleep(20); } // Setup our TTrees this->AddEventVariablesToTree(); this->AddSignalFlagsToTree(); } void ElectronFlux_FlatTree::AddEventVariablesToTree() { // Setup the TTree to save everything if (!eventVariables) { - FitPar::Config().out->cd(); + 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"); eventVariables->Branch("MLep", &MLep, "MLep/F"); eventVariables->Branch("ELep", &ELep, "ELep/F"); 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 ElectronFlux_FlatTree::AddSignalFlagsToTree() { if (!eventVariables) { - FitPar::Config().out->cd(); + 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 ElectronFlux_FlatTree::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; PDGnu = 0; PDGLep = 0; Enu_true = Enu_QE = Q2_true = Q2_QE = TLep = TPr = TNe = TPiP = TPiN = TPi0 = -999.9; Nprotons = 0; PPr = EPr = MPr = CosPr = -999.9; Nneutrons = 0; PNe = ENe = MNe = CosNe = -999.9; Npiplus = 0; PPiP = EPiP = MPiP = CosPiP = -999.9; Npineg = 0; PPiN = EPiN = MPiN = CosPiN = -999.9; Npi0 = 0; PPi0 = EPi0 = MPi0 = CosPi0 = -999.9; // All of the angles Clarence added CosPmuPpip = CosPmuPpim = CosPmuPpi0 = CosPmuPprot = CosPmuPneut = CosPpipPprot = CosPpipPneut = CosPpipPpim = CosPpipPpi0 = CosPpimPprot = CosPpimPneut = CosPpimPpi0 = CosPi0Pprot = CosPi0Pneut = CosPprotPneut = -999.9; 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; (*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 (PDGpart == 11){ 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 ElectronFlux_FlatTree::Write(std::string drawOpt) { //******************************************************************** // First save the TTree eventVariables->Write(); // Save Flux and Event Histograms too GetInput()->GetFluxHistogram()->Write(); GetInput()->GetEventHistogram()->Write(); return; } //******************************************************************** void ElectronFlux_FlatTree::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 ElectronFlux_FlatTree::isSignal(FitEvent *event) { //******************************************************************** (void)event; return true; }; //******************************************************************** void ElectronFlux_FlatTree::ScaleEvents() { //******************************************************************** // Saving everything to a TTree so no scaling required return; } //******************************************************************** void ElectronFlux_FlatTree::ApplyNormScale(float norm) { //******************************************************************** // Saving everything to a TTree so no scaling required this->fCurrentNorm = norm; return; } //******************************************************************** void ElectronFlux_FlatTree::FillHistograms() { //******************************************************************** // No Histograms need filling........ return; } //******************************************************************** void ElectronFlux_FlatTree::ResetAll() { //******************************************************************** eventVariables->Reset(); return; } //******************************************************************** float ElectronFlux_FlatTree::GetChi2() { //******************************************************************** // No Likelihood to test, purely MC return 0.0; } diff --git a/src/MCStudies/GenericFlux_Tester.cxx b/src/MCStudies/GenericFlux_Tester.cxx index a98932e..e3383b5 100644 --- a/src/MCStudies/GenericFlux_Tester.cxx +++ b/src/MCStudies/GenericFlux_Tester.cxx @@ -1,559 +1,559 @@ // 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 << 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) { - FitPar::Config().out->cd(); + 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"); eventVariables->Branch("MLep", &MLep, "MLep/F"); eventVariables->Branch("ELep", &ELep, "ELep/F"); 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) { - FitPar::Config().out->cd(); + 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; PDGnu = 0; PDGLep = 0; Enu_true = Enu_QE = Q2_true = Q2_QE = TLep = TPr = TNe = TPiP = TPiN = TPi0 = -999.9; Nprotons = 0; PPr = EPr = MPr = CosPr = -999.9; Nneutrons = 0; PNe = ENe = MNe = CosNe = -999.9; Npiplus = 0; PPiP = EPiP = MPiP = CosPiP = -999.9; Npineg = 0; PPiN = EPiN = MPiN = CosPiN = -999.9; Npi0 = 0; PPi0 = EPi0 = MPi0 = CosPi0 = -999.9; // All of the angles Clarence added CosPmuPpip = CosPmuPpim = CosPmuPpi0 = CosPmuPprot = CosPmuPneut = CosPpipPprot = CosPpipPneut = CosPpipPpim = CosPpipPpi0 = CosPpimPprot = CosPpimPneut = CosPpimPpi0 = CosPi0Pprot = CosPi0Pneut = CosPprotPneut = -999.9; 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; (*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_Vectors.cxx b/src/MCStudies/GenericFlux_Vectors.cxx index e27e1e4..eb75ee7 100644 --- a/src/MCStudies/GenericFlux_Vectors.cxx +++ b/src/MCStudies/GenericFlux_Vectors.cxx @@ -1,237 +1,237 @@ // 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_Vectors.h" GenericFlux_Vectors::GenericFlux_Vectors(std::string name, std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile) { // Measurement Details fName = name; eventVariables = NULL; // Define our energy range for flux calcs EnuMin = 0.; EnuMax = 100.; // Arbritrarily high energy limit // Set default fitter flags fIsDiag = true; fIsShape = false; fIsRawEvents = false; // This function will sort out the input files automatically and parse all the // inputs,flags,etc. // There may be complex cases where you have to do this by hand, but usually // this will do. Measurement1D::SetupMeasurement(inputfile, type, rw, fakeDataFile); eventVariables = NULL; // Setup fDataHist as a placeholder this->fDataHist = new TH1D(("empty_data"), ("empty-data"), 1, 0, 1); this->SetupDefaultHist(); fFullCovar = StatUtils::MakeDiagonalCovarMatrix(fDataHist); covar = StatUtils::GetInvert(fFullCovar); // 1. The generator is organised in SetupMeasurement so it gives the // cross-section in "per nucleon" units. // So some extra scaling for a specific measurement may be required. For // Example to get a "per neutron" measurement on carbon // which we do here, we have to multiple by the number of nucleons 12 and // divide by the number of neutrons 6. this->fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38 / (fNEvents + 0.)) / this->TotalIntegratedFlux(); LOG(SAM) << " Generic Flux Scaling Factor = " << fScaleFactor << std::endl; if (fScaleFactor <= 0.0) { ERR(WRN) << "SCALE FACTOR TOO LOW " << std::endl; } // Setup our TTrees this->AddEventVariablesToTree(); } void GenericFlux_Vectors::AddEventVariablesToTree() { // Setup the TTree to save everything if (!eventVariables) { - FitPar::Config().out->cd(); + Config::Get().out->cd(); eventVariables = new TTree((this->fName + "_VARS").c_str(), (this->fName + "_VARS").c_str()); } LOG(SAM) << "Adding Event Variables" << std::endl; eventVariables->Branch("Mode", &Mode, "Mode/I" ); eventVariables->Branch("cc", &cc, "cc/B" ); eventVariables->Branch("PDGnu", &PDGnu, "PDGnu/I" ); eventVariables->Branch("tgt", &tgt, "tgt/I" ); eventVariables->Branch("PDGLep", &PDGLep, "PDGLep/I"); eventVariables->Branch("ELep", &ELep, "ELep/F" ); eventVariables->Branch("CosLep", &CosLep, "CosLep/F"); // Basic interaction kinematics eventVariables->Branch("Q2", &Q2, "Q2/F"); eventVariables->Branch("q0", &q0, "q0/F"); eventVariables->Branch("q3", &q3, "q3/F"); eventVariables->Branch("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("W", &W, "W/F"); eventVariables->Branch("x", &x, "x/F"); eventVariables->Branch("y", &y, "y/F"); // Save outgoing particle vectors eventVariables->Branch("nfsp", &nfsp, "nfsp/I"); eventVariables->Branch("px", px, "px[nfsp]/F"); eventVariables->Branch("py", py, "py[nfsp]/F"); eventVariables->Branch("pz", pz, "pz[nfsp]/F"); eventVariables->Branch("E", E, "E[nfsp]/F"); eventVariables->Branch("pdg", pdg, "pdg[nfsp]/I"); // Event Scaling Information eventVariables->Branch("Weight", &Weight, "Weight/F"); eventVariables->Branch("InputWeight", &InputWeight, "InputWeight/F"); eventVariables->Branch("RWWeight", &RWWeight, "RWWeight/F"); eventVariables->Branch("fScaleFactor", &fScaleFactor, "fScaleFactor/F"); return; } void GenericFlux_Vectors::FillEventVariables(FitEvent *event) { // Reset all Function used to extract any variables of interest to the event PDGnu = tgt = PDGLep = 0; Enu = ELep = CosLep = Q2 = q0 = q3 = Enu_QE = Q2_QE = W_nuc_rest = W = x = y = -999.9; nfsp = 0; for (int i = 0; i < kMAX; ++i){ px[i] = py[i] = pz[i] = E[i] = -999; pdg[i] = 0; - } + } Weight = InputWeight = RWWeight = 0; partList.clear(); // Now fill the information Mode = event->Mode; cc = (abs(event->Mode) < 30); // Get the incoming neutrino and outgoing lepton FitParticle *nu = event->GetNeutrinoIn(); FitParticle *lep = event->GetHMFSAnyLepton(); - + PDGnu = nu->fPID; Enu = nu->fP.E()/1E3; tgt = event->fTargetPDG; PDGLep = lep->fPID; ELep = lep->fP.E()/1E3; CosLep = cos(nu->fP.Vect().Angle(lep->fP.Vect())); // Basic interaction kinematics Q2 = -1*(nu->fP - lep->fP).Mag2()/1E6; q0 = (nu->fP - lep->fP).E()/1E3; q3 = (nu->fP - lep->fP).Vect().Mag()/1E3; - // Get W_true with assumption of initial state nucleon at rest + // Get W_true with assumption of initial state nucleon at rest float m_n = (float)PhysConst::mass_proton; W_nuc_rest = sqrt(-Q2 + 2 * m_n * q0 + m_n * m_n); W = sqrt(-Q2 + 2 * m_n * q0 + m_n * m_n); x = Q2/(2 * m_n * q0); y = 1 - ELep/Enu; // These assume C12 binding from MINERvA... not ideal Q2_QE = FitUtils::Q2QErec(lep->fP, CosLep, 34., true); Enu_QE = FitUtils::EnuQErec(lep->fP, CosLep, 34., true); // Loop over the particles and store all the final state particles in a vector for (UInt_t i = 0; i < event->Npart(); ++i) { bool part_alive = event->PartInfo(i)->fIsAlive and event->PartInfo(i)->Status() == kFinalState; if (!part_alive) continue; partList .push_back(event->PartInfo(i)); } // Save outgoing particle vectors nfsp = (int)partList.size(); for (int i = 0; i < nfsp; ++i){ px[i] = partList[i]->fP.X()/1E3; py[i] = partList[i]->fP.Y()/1E3; pz[i] = partList[i]->fP.Z()/1E3; E[i] = partList[i]->fP.E()/1E3; pdg[i] = partList[i]->fPID; } // Fill event weights Weight = event->RWWeight * event->InputWeight; RWWeight = event->RWWeight; InputWeight = event->InputWeight; // Fill the eventVariables Tree eventVariables->Fill(); return; }; void GenericFlux_Vectors::Write(std::string drawOpt) { // First save the TTree eventVariables->Write(); // Save Flux and Event Histograms too GetInput()->GetFluxHistogram()->Write(); GetInput()->GetEventHistogram()->Write(); return; } // Override functions which aren't really necessary bool GenericFlux_Vectors::isSignal(FitEvent *event) { (void)event; return true; }; void GenericFlux_Vectors::ScaleEvents() { return; } void GenericFlux_Vectors::ApplyNormScale(float norm) { this->fCurrentNorm = norm; return; } void GenericFlux_Vectors::FillHistograms() { return; } void GenericFlux_Vectors::ResetAll() { eventVariables->Reset(); return; } float GenericFlux_Vectors::GetChi2() { return 0.0; } diff --git a/src/MCStudies/MCStudy_CCQEHistograms.cxx b/src/MCStudies/MCStudy_CCQEHistograms.cxx index bde660b..9a997f0 100644 --- a/src/MCStudies/MCStudy_CCQEHistograms.cxx +++ b/src/MCStudies/MCStudy_CCQEHistograms.cxx @@ -1,225 +1,230 @@ // 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 "MCStudy_CCQEHistograms.h" #include "T2K_SignalDef.h" #include "MINERvA_SignalDef.h" //******************************************************************** /// @brief Class to perform MC Studies on a custom measurement MCStudy_CCQEHistograms::MCStudy_CCQEHistograms(std::string name, std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile) { //******************************************************************** // Measurement Details fName = name; fEventTree = 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; // 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); fEventTree = NULL; // Setup fDataHist as a placeholder this->fDataHist = new TH1D(("approximate_data"), ("kaon_data"), 5, 1.0, 6.0); - + 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 = (this->fEventHist->Integral("width") * 1E-38 / (fNEvents + 0.)) / this->TotalIntegratedFlux(); - - + + hist_Enu = new TH1D("MCStudy_CCQE_Enu","MCStudy_CCQE_Enu",30,0.0,2.0); hist_TLep = new TH1D("MCStudy_CCQE_TLep","MCStudy_CCQE_TLep",30,0.0,4.0); hist_CosLep = new TH1D("MCStudy_CCQE_CosLep","MCStudy_CCQE_CosLep",30,-1.0,1.0); - hist_Q2 = new TH1D("MCStudy_CCQE_Q2","MCStudy_CCQE_Q2",30,0.0,2.0); - hist_Q2QE = new TH1D("MCStudy_CCQE_Q2QE","MCStudy_CCQE_Q2QE",30,0.0,2.0); + hist_Q2 = new TH1D("MCStudy_CCQE_Q2;Q^{2} (GeV^{2});d#sigma/dQ^{2} (cm^{2}/nucleon/GeV^{2})","MCStudy_CCQE_Q2",30,0.0,3.0); + hist_Q2QE = new TH1D("MCStudy_CCQE_Q2QE","MCStudy_CCQE_Q2QE",30,0.0,3.0); hist_EQE = new TH1D("MCStudy_CCQE_EQE","MCStudy_CCQE_EQE",30,0.0,5.0); hist_q0 = new TH1D("MCStudy_CCQE_q0","MCStudy_CCQE_q0",30,0.0,2.0); hist_q3 = new TH1D("MCStudy_CCQE_q3","MCStudy_CCQE_q3",30,0.0,2.0); hist_TLepCosLep = new TH2D("MCStudy_CCQE_TLepCosLep","MCStudy_CCQE_TLepCosLep",15,0.0,5.0,15,-1.0,1.0); hist_Total = new TH1D("MCStudy_CCQE_TotalXSec","MXStudy_CCQE_TotalXSec",1,0.0,1.0); + hist_q0q3 = new TH2D("MCStudy_CCQE_q0q3","MCStudy_CCQE_q0q3;q_{3} (GeV); q_{0} (GeV); d#sigma/dq_{0}dq_{3} (cm^{2}/nucleon/GeV^{2})",40,0.0,2.0,40,0.0,2.0); + return; } //******************************************************************** void MCStudy_CCQEHistograms::FillEventVariables(FitEvent *event) { //******************************************************************** // std::cout << "Event fBound = " << event->fBound << " " << event->Mode << std::endl; - if (event->fBound > 0) return; +// if (event->fBound > 0) return; if (abs(event->Mode) != 1) return; - std::cout << "Event fBound = " << event->fBound << " " << event->Mode << "-> Signal " << std::endl; + // std::cout << "Event fBound = " << event->fBound << " " << event->Mode << "-> Signal " << std::endl; FitParticle* muon = NULL; FitParticle* nu = event->GetNeutrinoIn(); bool IsNuMu = event->PDGnu() > 0; - + if (IsNuMu) muon = event->GetHMFSParticle(13); else muon = event->GetHMFSParticle(-13); // Reset Variables Enu = -999.9; TLep = -999.9; CosLep = -999.9; Q2 = -999.9; Q2QE = -999.9; EQE = -999.9; q0 = -999.9; q3 = -999.9; // Fill Variables if (muon){ Enu = event->Enu() / 1.E3; TLep = (muon->fP.E() - muon->fP.Mag()) / 1.E3; - CosLep = cos(muon->fP.Vect().Angle( nu->fP.Vect() )); + CosLep = cos(muon->fP.Vect().Angle( nu->fP.Vect() )); Q2 = fabs((muon->fP - nu->fP).Mag2() / 1.E6); Q2QE = FitUtils::Q2QErec(muon->fP, CosLep, 34., IsNuMu); EQE = FitUtils::EnuQErec(muon->fP, CosLep, 34., IsNuMu); - + q0 = fabs((muon->fP - nu->fP).E()) / 1.E3; q3 = fabs((muon->fP - nu->fP).Vect().Mag()) / 1.E3; LocalRWWeight = event->RWWeight; LocalInputWeight = event->InputWeight; - + } // Fill Tree if (abs(Mode) == 1 and Signal){ hist_Enu->Fill(Enu,event->Weight); hist_TLep->Fill(TLep,event->Weight); hist_CosLep->Fill(CosLep,event->Weight); hist_Q2->Fill(Q2,event->Weight); hist_Q2QE->Fill(Q2QE,event->Weight); hist_EQE->Fill(EQE,event->Weight); hist_q0->Fill(q0,event->Weight); hist_q3->Fill(q3,event->Weight); hist_TLepCosLep->Fill(TLep,CosLep,event->Weight); - + hist_q0q3->Fill(q3,q0,event->Weight); hist_Total->Fill(0.5,event->Weight); - + fXVar = Q2; } return; }; //******************************************************************** void MCStudy_CCQEHistograms::Write(std::string drawOpt) { //******************************************************************** // Measurement1D::Write(drawOpt); LOG(FIT) << "Writing MCStudy_CCQEHistograms " << std::endl; - // FitPar::Config().out->cd(); + // Config::Get().out->cd(); hist_Enu->Write(); hist_TLep->Write(); hist_CosLep->Write(); hist_Q2->Write(); hist_Q2QE->Write(); hist_EQE->Write(); hist_q0->Write(); hist_q3->Write(); hist_TLepCosLep->Write(); + hist_q0q3->Write(); hist_Total->Write(); return; } -//******************************************************************** +//******************************************************************** void MCStudy_CCQEHistograms::ResetAll(){ - //******************************************************************** + //******************************************************************** hist_Enu->Reset(); hist_TLep->Reset(); hist_CosLep->Reset(); hist_Q2->Reset(); hist_Q2QE->Reset(); hist_EQE->Reset(); hist_q0->Reset(); hist_q3->Reset(); + hist_q0q3->Reset(); hist_TLepCosLep->Reset(); hist_Total->Reset(); return; } -//******************************************************************** +//******************************************************************** void MCStudy_CCQEHistograms::ScaleEvents(){ -//******************************************************************** +//******************************************************************** hist_Enu->Scale(fScaleFactor,"width"); hist_TLep->Scale(fScaleFactor,"width"); hist_CosLep->Scale(fScaleFactor,"width"); hist_Q2->Scale(fScaleFactor,"width"); hist_Q2QE->Scale(fScaleFactor,"width"); hist_EQE->Scale(fScaleFactor,"width"); hist_q0->Scale(fScaleFactor,"width"); hist_q3->Scale(fScaleFactor,"width"); + hist_q0q3->Scale(fScaleFactor,"width"); hist_TLepCosLep->Scale(fScaleFactor,"width"); hist_Total->Scale(fScaleFactor,"width"); return; } //******************************************************************** /// Select only events with final state Muons bool MCStudy_CCQEHistograms::isSignal(FitEvent *event) { //******************************************************************** if (abs(event->Mode) != 1) return false; - if (event->fBound > 0) return false; + //if (event->fBound > 0) return false; // if (!event->HasFSMuon()) return false; - + // Do we want any other signal? return true; }; diff --git a/src/MCStudies/MCStudy_CCQEHistograms.h b/src/MCStudies/MCStudy_CCQEHistograms.h index 455a9f2..4799ef3 100644 --- a/src/MCStudies/MCStudy_CCQEHistograms.h +++ b/src/MCStudies/MCStudy_CCQEHistograms.h @@ -1,75 +1,76 @@ // 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 MCStudy_CCQEHistograms_H_SEEN #define MCStudy_CCQEHistograms_H_SEEN #include "Measurement1D.h" //******************************************************************** class MCStudy_CCQEHistograms : public Measurement1D { //******************************************************************** public: MCStudy_CCQEHistograms(std::string name, std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile); virtual ~MCStudy_CCQEHistograms() {}; //! Grab info from event void FillEventVariables(FitEvent *event); void ScaleEvents(); void ResetAll(); //! Define this samples signal bool isSignal(FitEvent *nvect); //! Write Files void Write(std::string drawOpt); private: double fEventScaleFactor; TTree* fEventTree; TH1D* hist_Enu; float Enu; TH1D* hist_TLep; float TLep ; TH1D* hist_CosLep; float CosLep; TH1D* hist_Q2; float Q2 ; TH1D* hist_Q2QE; float Q2QE ; TH1D* hist_EQE; float EQE ; TH1D* hist_q0; float q0 ; TH1D* hist_q3; float q3 ; + TH2D* hist_q0q3; TH1D* hist_Total; TH2D* hist_TLepCosLep; double LocalRWWeight; double LocalInputWeight; }; #endif diff --git a/src/MCStudies/MCStudy_KaonPreSelection.cxx b/src/MCStudies/MCStudy_KaonPreSelection.cxx index adee159..8a0a53c 100644 --- a/src/MCStudies/MCStudy_KaonPreSelection.cxx +++ b/src/MCStudies/MCStudy_KaonPreSelection.cxx @@ -1,234 +1,234 @@ // 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 "MCStudy_KaonPreSelection.h" #include "T2K_SignalDef.h" #include "MINERvA_SignalDef.h" //******************************************************************** /// @brief Class to perform MC Studies on a custom measurement MCStudy_KaonPreSelection::MCStudy_KaonPreSelection(std::string name, std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile) { //******************************************************************** // Measurement Details fName = name; fEventTree = 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; // 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); fEventTree = NULL; // Setup fDataHist as a placeholder this->fDataHist = new TH1D(("approximate_data"), ("kaon_data"), 5, 1.0, 6.0); // Approximate data points for now fDataHist->SetBinContent(1,0.225E-39); fDataHist->SetBinContent(2,0.215E-39); fDataHist->SetBinContent(3,0.175E-39); fDataHist->SetBinContent(4,0.230E-39); fDataHist->SetBinContent(5,0.210E-39); 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(); // Create a new TTree and add Nuisance Events Branches - FitPar::Config().out->cd(); + Config::Get().out->cd(); fEventTree = new TTree("nuisance_events","nuisance_events"); GetInput()->GetNuisanceEvent(0)->AddBranchesToTree(fEventTree); fEventTree->Branch("nlep",&nlep, "nlep/I"); fEventTree->Branch("nkplus",&nkplus, "nkplus/I"); //fEventTree->Branch("nkaon",&nkaon, "nkaon/I"); fEventTree->Branch("kplus_mom", &kplusmom, "kplus_mom/D"); // fEventTree->Branch("kaon_mom", &kaonmom, "kaon_mom/D"); // Add Event Scaling Information // This scale factor is used to get the predicted event rate for this sample given // the input flux. Use this when merging different output event ttrees fEventTree->Branch("EventScaleFactor", &fEventScaleFactor, "EventScaleFactor/D"); fEventScaleFactor = GetEventHistogram()->Integral("width") * 1E-38 / (fNEvents + 0.); // NOTES: // To get normalised predictions weight event event by 'EventScaleFactor' to get the // predicted event rate for that sample given the flux used. Then to get cross-sections // divide by the integrated flux from all samples. // e.g. To get the numu+numubar prediction, add the event rate predictions from both // samples together, then divide by the integral of the 'nuisance_flux' histograms in each // sample. // Every particle in the nuisance event is saved into the TTree. The list of particle // status codes are given in src/FitBase/FitParticle.h. The neutrino is usually the first // particle in the list. // If selecting final state kaons, select only kaons with state=2. /* enum particle_state{ kUndefinedState = 5, kInitialState = 0, kFSIState = 1, kFinalState = 2, kNuclearInitial = 3, kNuclearRemnant = 4 }; */ // The structure of the particle lists are a dimensional array for each particle mom, then a 1D array // for the PDG and state. Mode gives the true NEUT interaction channel code. /* tn->Branch("Mode", &fMode, "Mode/I"); tn->Branch("EventNo", &fEventNo, "EventNo/i"); tn->Branch("TotCrs", &fTotCrs, "TotCrs/D"); tn->Branch("TargetA", &fTargetA, "TargetA/I"); tn->Branch("TargetH", &fTargetH, "TargetH/I"); tn->Branch("Bound", &fBound, "Bound/O"); tn->Branch("InputWeight", &InputWeight, "InputWeight/D"); tn->Branch("NParticles", &fNParticles, "NParticles/I"); tn->Branch("ParticleState", fParticleState, "ParticleState[NParticles]/i"); tn->Branch("ParticlePDG", fParticlePDG, "ParticlePDG[NParticles]/I"); tn->Branch("ParticleMom", fParticleMom, "ParticleMom[NParticles][4]/D"); */ // Logging Flag fKaonLogging = FitPar::Config().GetParB("KaonLogging"); return; } //******************************************************************** void MCStudy_KaonPreSelection::FillEventVariables(FitEvent *event) { //******************************************************************** - + // Reset kplusmom = -999.9; // Save Some Extra Information nkplus = event->NumFSParticle(PhysConst::pdg_kplus); // Nmuons nlep = event->NumFSParticle(13) + event->NumFSParticle(-13); // Leading K+ Mom if (event->GetHMFSParticle(PhysConst::pdg_kplus)){ kplusmom = FitUtils::T(event->GetHMFSParticle(PhysConst::pdg_kplus)->fP)*1000.0; } // Fill XVar fXVar = kplusmom / 1.E3; // Fill If Signal if (isSignal(event)){ fEventTree->Fill(); if (fKaonLogging){ int nstrangemesons = event->NumParticle(321); int nstrangefsmesons = event->NumFSParticle(321); - + if (nstrangemesons > 0){ std::cout << "New Event ----------------------------" << std::endl; std::cout << "N S Mesons vs NFS S Mesons : " << nstrangemesons << " : " << nstrangefsmesons << std::endl; event->PrintChris(); event->fNeutVect->Dump(); } } } return; }; //******************************************************************** void MCStudy_KaonPreSelection::Write(std::string drawOpt) { //******************************************************************** // Save the event ttree fEventTree->Write(); // Save Flux and Event Histograms too GetInput()->GetFluxHistogram()->Write("nuisance_fluxhist"); GetInput()->GetEventHistogram()->Write("nuisance_eventhist"); return; } //******************************************************************** /// Select only events with final state Kaons bool MCStudy_KaonPreSelection::isSignal(FitEvent *event) { //******************************************************************** // Update to include all events return true; // Apply a Kaon Pre-selection // Search for Strange Mesons (included full list from MC PDG) /* PhystConst::pdg_strangemesons = {130,310,311,321, 9000311,9000321, 10311,10321,100311,100321, 9010311,9010321,9020311,9020321, 313,323, 10313,10323, 20313,20323, 100313,100323, 9000313,9000323, 30313,30323, 315,325, 9000315,9000325, 10315,10325, 20315,20325, 9010315,9010325,9020315,9020325, 317,327, 9010317,9010327}; PhysConst::pdg_antistrangemesons = {above * -1.0}; */ int nstrangemesons = event->NumParticle(PhysConst::pdg_strangemesons); nstrangemesons += event->NumParticle(PhysConst::pdg_antistrangemesons); if (nstrangemesons < 1) return false; // Do we want any other signal? return true; }; diff --git a/src/MCStudies/MCStudy_MuonValidation.cxx b/src/MCStudies/MCStudy_MuonValidation.cxx index 2b85815..6ad9a9b 100644 --- a/src/MCStudies/MCStudy_MuonValidation.cxx +++ b/src/MCStudies/MCStudy_MuonValidation.cxx @@ -1,167 +1,167 @@ // 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 "MCStudy_MuonValidation.h" #include "T2K_SignalDef.h" #include "MINERvA_SignalDef.h" //******************************************************************** /// @brief Class to perform MC Studies on a custom measurement MCStudy_MuonValidation::MCStudy_MuonValidation(std::string name, std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile) { //******************************************************************** // Measurement Details fName = name; fEventTree = 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; // 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); fEventTree = NULL; // Setup fDataHist as a placeholder this->fDataHist = new TH1D(("approximate_data"), ("kaon_data"), 5, 1.0, 6.0); 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(); // Create a new TTree and add Nuisance Events Branches - FitPar::Config().out->cd(); + Config::Get().out->cd(); fEventTree = new TTree((fName + "_EVENTS").c_str(),(fName + "_EVENTS").c_str()); fEventTree->Branch("ScaleFactor", &fScaleFactor, "ScaleFactor/D"); fEventTree->Branch("InputWeight", &LocalInputWeight, "InputWeight/D"); fEventTree->Branch("RWWeight", &LocalRWWeight, "RWWeight/D"); fEventTree->Branch("Mode", &Mode, "Mode/I"); fEventTree->Branch("Enu",&Enu,"Enu/F"); fEventTree->Branch("TLep",&TLep,"TLep/F"); fEventTree->Branch("CosLep",&CosLep,"CosLep/F"); fEventTree->Branch("Q2",&Q2,"Q2/F"); fEventTree->Branch("Q2QE",&Q2QE,"Q2QE/F"); fEventTree->Branch("EQE",&EQE,"EQE/F"); fEventTree->Branch("q0",&q0,"q0/F"); fEventTree->Branch("q3",&q3,"q3/F"); // the input flux. Use this when merging different output event ttrees fEventTree->Branch("EventScaleFactor", &fEventScaleFactor, "EventScaleFactor/D"); fEventScaleFactor = GetEventHistogram()->Integral("width") * 1E-38 / (fNEvents + 0.); return; } //******************************************************************** void MCStudy_MuonValidation::FillEventVariables(FitEvent *event) { //******************************************************************** FitParticle* muon = NULL; FitParticle* nu = event->GetNeutrinoIn(); bool IsNuMu = event->PDGnu() > 0; if (IsNuMu) muon = event->GetHMFSParticle(13); else muon = event->GetHMFSParticle(-13); // Reset Variables Enu = -999.9; TLep = -999.9; CosLep = -999.9; Q2 = -999.9; Q2QE = -999.9; EQE = -999.9; q0 = -999.9; q3 = -999.9; // Fill Variables if (muon){ Enu = event->Enu() / 1.E3; TLep = (muon->fP.E() - muon->fP.Mag()) / 1.E3; CosLep = cos(muon->fP.Vect().Angle( nu->fP.Vect() )); Q2 = fabs((muon->fP - nu->fP).Mag2() / 1.E6); Q2QE = FitUtils::Q2QErec(muon->fP, CosLep, 34., IsNuMu); EQE = FitUtils::EnuQErec(muon->fP, CosLep, 34., IsNuMu); q0 = fabs((muon->fP - nu->fP).E()) / 1.E3; q3 = fabs((muon->fP - nu->fP).Vect().Mag()) / 1.E3; LocalRWWeight = event->RWWeight; LocalInputWeight = event->InputWeight; } // Fill Tree if (isSignal(event)){ fEventTree->Fill(); } return; }; //******************************************************************** void MCStudy_MuonValidation::Write(std::string drawOpt) { //******************************************************************** // Save the event ttree fEventTree->Write(); // Save Flux and Event Histograms too GetInput()->GetFluxHistogram()->Write((fName + "_FLUX").c_str()); GetInput()->GetEventHistogram()->Write((fName + "_EVT").c_str()); return; } //******************************************************************** /// Select only events with final state Muons bool MCStudy_MuonValidation::isSignal(FitEvent *event) { //******************************************************************** if (!event->HasFSMuon()) return false; // Do we want any other signal? return true; }; diff --git a/src/MCStudies/MCStudy_NCpi0PreSelection.cxx b/src/MCStudies/MCStudy_NCpi0PreSelection.cxx index 424d5d1..9d5d3ed 100644 --- a/src/MCStudies/MCStudy_NCpi0PreSelection.cxx +++ b/src/MCStudies/MCStudy_NCpi0PreSelection.cxx @@ -1,215 +1,215 @@ // 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 "MCStudy_NCpi0PreSelection.h" #include "T2K_SignalDef.h" #include "MINERvA_SignalDef.h" //******************************************************************** /// @brief Class to perform MC Studies on a custom measurement MCStudy_NCpi0PreSelection::MCStudy_NCpi0PreSelection(std::string name, std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile) { //******************************************************************** // Measurement Details fName = name; fEventTree = 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; // 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); fEventTree = NULL; // Setup fDataHist as a placeholder this->fDataHist = new TH1D(("approximate_data"), ("kaon_data"), 5, 1.0, 6.0); // Approximate data points for now fDataHist->SetBinContent(1,0.225E-39); fDataHist->SetBinContent(2,0.215E-39); fDataHist->SetBinContent(3,0.175E-39); fDataHist->SetBinContent(4,0.230E-39); fDataHist->SetBinContent(5,0.210E-39); 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(); // Create a new TTree and add Nuisance Events Branches - FitPar::Config().out->cd(); + Config::Get().out->cd(); fEventTree = new TTree("nuisance_events","nuisance_events"); GetInput()->GetEventPointer()->AddBranchesToTree(fEventTree); fEventTree->Branch("nlep",&nlep, "nlep/I"); fEventTree->Branch("nkplus",&nkplus, "nkplus/I"); //fEventTree->Branch("nkaon",&nkaon, "nkaon/I"); fEventTree->Branch("kplus_mom", &kplusmom, "kplus_mom/D"); // fEventTree->Branch("kaon_mom", &kaonmom, "kaon_mom/D"); // Add Event Scaling Information // This scale factor is used to get the predicted event rate for this sample given // the input flux. Use this when merging different output event ttrees fEventTree->Branch("EventScaleFactor", &fEventScaleFactor, "EventScaleFactor/D"); fEventScaleFactor = GetEventHistogram()->Integral("width") * 1E-38 / (fNEvents + 0.); // NOTES: // To get normalised predictions weight event event by 'EventScaleFactor' to get the // predicted event rate for that sample given the flux used. Then to get cross-sections // divide by the integrated flux from all samples. // e.g. To get the numu+numubar prediction, add the event rate predictions from both // samples together, then divide by the integral of the 'nuisance_flux' histograms in each // sample. // Every particle in the nuisance event is saved into the TTree. The list of particle // status codes are given in src/FitBase/FitParticle.h. The neutrino is usually the first // particle in the list. // If selecting final state kaons, select only kaons with state=2. /* enum particle_state{ kUndefinedState = 5, kInitialState = 0, kFSIState = 1, kFinalState = 2, kNuclearInitial = 3, kNuclearRemnant = 4 }; */ // The structure of the particle lists are a dimensional array for each particle mom, then a 1D array // for the PDG and state. Mode gives the true NEUT interaction channel code. /* tn->Branch("Mode", &fMode, "Mode/I"); tn->Branch("EventNo", &fEventNo, "EventNo/i"); tn->Branch("TotCrs", &fTotCrs, "TotCrs/D"); tn->Branch("TargetA", &fTargetA, "TargetA/I"); tn->Branch("TargetH", &fTargetH, "TargetH/I"); tn->Branch("Bound", &fBound, "Bound/O"); tn->Branch("InputWeight", &InputWeight, "InputWeight/D"); tn->Branch("NParticles", &fNParticles, "NParticles/I"); tn->Branch("ParticleState", fParticleState, "ParticleState[NParticles]/i"); tn->Branch("ParticlePDG", fParticlePDG, "ParticlePDG[NParticles]/I"); tn->Branch("ParticleMom", fParticleMom, "ParticleMom[NParticles][4]/D"); */ // Logging Flag fNCpi0Logging = FitPar::Config().GetParB("NCpi0Logging"); return; } //******************************************************************** void MCStudy_NCpi0PreSelection::FillEventVariables(FitEvent *event) { //******************************************************************** - + // Reset kplusmom = -999.9; // Save Some Extra Information nkplus = event->NumFSParticle(PhysConst::pdg_kplus); // Nmuons nlep = event->NumFSParticle(13) + event->NumFSParticle(-13); // Leading K+ Mom if (event->GetHMFSParticle(PhysConst::pdg_kplus)){ kplusmom = FitUtils::T(event->GetHMFSParticle(PhysConst::pdg_kplus)->fP)*1000.0; } // Fill XVar fXVar = kplusmom / 1.E3; // Fill If Signal if (isSignal(event)){ fEventTree->Fill(); if (fNCpi0Logging){ int nstrangemesons = event->NumParticle(321); int nstrangefsmesons = event->NumFSParticle(321); - + if (nstrangemesons > 0){ std::cout << "New Event ----------------------------" << std::endl; std::cout << "N S Mesons vs NFS S Mesons : " << nstrangemesons << " : " << nstrangefsmesons << std::endl; event->PrintChris(); event->fNeutVect->Dump(); } } } return; }; //******************************************************************** void MCStudy_NCpi0PreSelection::Write(std::string drawOpt) { //******************************************************************** // Save the event ttree fEventTree->Write(); // Save Flux and Event Histograms too GetInput()->GetFluxHistogram()->Write("nuisance_fluxhist"); GetInput()->GetEventHistogram()->Write("nuisance_eventhist"); return; } //******************************************************************** /// Select only events with final state NCpi0s bool MCStudy_NCpi0PreSelection::isSignal(FitEvent *event) { //******************************************************************** // Apply a NCpi0 Pre-selection // Search for Strange Mesons (included full list from MC PDG) int npi0 = event->NumParticle(111); if (npi0 <= 0) return false; - int nlep = (event->NumFSParticle(11) + event->NumFSParticle(13) + event->NumFSParticle(15) + + int nlep = (event->NumFSParticle(11) + event->NumFSParticle(13) + event->NumFSParticle(15) + event->NumFSParticle(-11) + event->NumFSParticle(-13) + event->NumFSParticle(-15)); if (nlep > 0) return false; // Do we want any other signal? return true; }; diff --git a/src/MCStudies/Smear_SVDUnfold_Propagation_Osc.cxx b/src/MCStudies/Smear_SVDUnfold_Propagation_Osc.cxx index 67896da..7b6df60 100644 --- a/src/MCStudies/Smear_SVDUnfold_Propagation_Osc.cxx +++ b/src/MCStudies/Smear_SVDUnfold_Propagation_Osc.cxx @@ -1,823 +1,823 @@ // 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 "Smear_SVDUnfold_Propagation_Osc.h" #include "SmearceptanceUtils.h" #include "OscWeightEngine.h" #include "HistogramInputHandler.h" void Smear_SVDUnfold_Propagation_Osc::AddNDInputs(nuiskey &samplekey) { NDSample nds; // Plot Setup ------------------------------------------------------- // Check that we have the relevant near detector histograms specified. if (!NDSamples.size()) { // If this is the first ND sample, take from the // sample input InputHandlerBase *InputBase = GetInput(); if (InputBase->GetType() != kHISTO) { THROW( "Smear_SVDUnfold_Propagation_Osc expects a Histogram input that " "contains the ND observed spectrum."); } HistoInputHandler *HInput = dynamic_cast(InputBase); if (!HInput) { THROW( "Smear_SVDUnfold_Propagation_Osc expects a Histogram input that " "contains the ND observed spectrum."); } if (HInput->NHistograms() != 2) { THROW( "Input expected to contain 2 histograms. " "HISTO:input.root[NDObs_TH1D,NDSmear_TH2D]"); } nds.NDDataHist = dynamic_cast(HInput->GetHistogram(0)); nds.NDToSpectrumSmearingMatrix = dynamic_cast(HInput->GetHistogram(1)); if (!nds.NDDataHist) { THROW("Expected a valid TH1D input for the ND observed spectrum."); } if (!nds.NDToSpectrumSmearingMatrix) { THROW("Expected a valid TH2D input for the ND observed smearing."); } } else { std::vector NDObsInputs = PlotUtils::GetTH1sFromRootFile(samplekey.GetS("ObsInput")); if (NDObsInputs.size() < 2) { THROW( "Near detector sample must contain the observed ERec spectrum and " "the " "ND ETrue/ERec smearing matrix. e.g. " "ObsInput=\"input.root[NDObs_species,NDSmearing_species]\""); } nds.NDDataHist = dynamic_cast(NDObsInputs[0]); if (!nds.NDDataHist) { ERROR(FTL, "First histogram from ObsInput attribute was not a TH1D containing " "the near detector observed ERec spectrum (" << samplekey.GetS("ObsInput") << ")."); THROW( "Near detector sample must contain the observed ERec spectrum and " "the " "ND ETrue/ERec smearing matrix. e.g. " "ObsInput=\"input.root[FDObs_species,FDSmearing_species]\""); } nds.NDToSpectrumSmearingMatrix = dynamic_cast(NDObsInputs[1]); if (!nds.NDToSpectrumSmearingMatrix) { ERROR( FTL, "Second histogram from ObsInput attribute was not a TH2D containing " "the near detector ETrue/ERec smearing matrix (" << samplekey.GetS("ObsInput") << ")."); THROW( "Near detector sample must contain the observed ERec spectrum and " "the " "ND ETrue/ERec smearing matrix. e.g. " "ObsInput=\"input.root[FDObs_species,FDSmearing_species]\""); } } nds.NDDataHist->Scale(ScalePOT); if (UseRateErrors) { for (Int_t bi_it = 1; bi_it < nds.NDDataHist->GetXaxis()->GetNbins() + 1; ++bi_it) { nds.NDDataHist->SetBinError(bi_it, sqrt(nds.NDDataHist->GetBinContent(bi_it))); } } nds.TruncateStart = 0; if (samplekey.Has("TruncateStart")) { nds.TruncateStart = samplekey.GetI("TruncateStart"); } nds.TruncateUpTo = 0; if (samplekey.Has("TruncateUpTo")) { nds.TruncateUpTo = samplekey.GetI("TruncateUpTo"); QLOG(SAM, "\tAllowed to truncate unfolding matrix by up to " << nds.TruncateUpTo << " singular values to limit negative ENu spectra."); } nds.NuPDG = 14; if (samplekey.Has("NuPDG")) { nds.NuPDG = samplekey.GetI("NuPDG"); } NDSamples.push_back(nds); } void Smear_SVDUnfold_Propagation_Osc::SetupNDInputs() { for (size_t nd_it = 0; nd_it < NDSamples.size(); ++nd_it) { NDSample &nds = NDSamples[nd_it]; TMatrixD NDToSpectrumResponseMatrix_l = SmearceptanceUtils::GetMatrix( SmearceptanceUtils::SVDGetInverse(nds.NDToSpectrumSmearingMatrix)); nds.NDToSpectrumResponseMatrix.ResizeTo(NDToSpectrumResponseMatrix_l); nds.NDToSpectrumResponseMatrix = NDToSpectrumResponseMatrix_l; if (nds.TruncateStart != 0) { TMatrixD NDToSpectrumResponseMatrix_l = SmearceptanceUtils::GetMatrix(SmearceptanceUtils::SVDGetInverse( nds.NDToSpectrumSmearingMatrix, nds.TruncateStart)); nds.NDToSpectrumResponseMatrix.ResizeTo(NDToSpectrumResponseMatrix_l); nds.NDToSpectrumResponseMatrix = NDToSpectrumResponseMatrix_l; } if (nds.TruncateStart >= nds.TruncateUpTo) { nds.TruncateUpTo = nds.TruncateStart + 1; } UnfoldToNDETrueSpectrum(nd_it); } } void Smear_SVDUnfold_Propagation_Osc::ReadExtraConfig(nuiskey &samplekey) { UseRateErrors = false; if (samplekey.Has("SetErrorsFromRate")) { UseRateErrors = samplekey.GetI("SetErrorsFromRate"); } NDetectorInfo.first = 0xdeadbeef; if (samplekey.Has("DetectorVolume") && samplekey.Has("DetectorDensity")) { NDetectorInfo.first = samplekey.GetD("DetectorVolume"); NDetectorInfo.second = samplekey.GetD("DetectorDensity"); double TargetMass_kg = NDetectorInfo.first * NDetectorInfo.second; QLOG(SAM, "\tND sample detector mass : "); QLOG(SAM, "\t\tTarget volume : " << NDetectorInfo.first); QLOG(SAM, "\t\tTarget density : " << NDetectorInfo.second); QLOG(SAM, "\t\tTarget mass : " << TargetMass_kg << " kg"); } ScalePOT = 1; if (samplekey.Has("ScalePOT")) { ScalePOT = samplekey.GetD("ScalePOT"); } } void Smear_SVDUnfold_Propagation_Osc::AddFDTarget(nuiskey &nk) { FDSample fds; fds.FitRegion_Min = 0xdeadbeef; if (nk.Has("FitRegion_Min")) { fds.FitRegion_Min = nk.GetD("FitRegion_Min"); } if ((FitRegion_Min == 0xdeadbeef) || FitRegion_Min > fds.FitRegion_Min) { FitRegion_Min = fds.FitRegion_Min; } fds.FitRegion_Max = 0xdeadbeef; if (nk.Has("FitRegion_Max")) { fds.FitRegion_Max = nk.GetD("FitRegion_Max"); } if ((FitRegion_Max == 0xdeadbeef) || FitRegion_Max < fds.FitRegion_Max) { FitRegion_Max = fds.FitRegion_Max; } fds.OscillateToPDG = 0; if (nk.Has("OscillateToPDG")) { fds.OscillateToPDG = nk.GetD("OscillateToPDG"); } std::vector FDNDRatioElements = nk.GetListOfChildNodes("FDNDRatio"); for (size_t fdnd_it = 0; fdnd_it < FDNDRatioElements.size(); ++fdnd_it) { nuiskey &fnr = FDNDRatioElements[fdnd_it]; if (fnr.Has("FromPDG") && fnr.Has("DivergenceFactor")) { fds.FDNDRatios[fnr.GetI("FromPDG")] = fnr.GetD("DivergenceFactor"); QLOG(SAM, "FDND DivergenceFactor for far detector sample index: " << FDSamples.size() << " for PDG: " << fnr.GetI("FromPDG") << " -> " << fds.OscillateToPDG << " = " << fnr.GetD("DivergenceFactor")); } else { THROW( "Far detector sample contained FDNDRatio element, but couldn't find " "both FromPDG and Factor attributes."); } } fds.FDNDMassRatio = 1; if (NDetectorInfo.first != 0xdeadbeef) { if ((!nk.Has("DetectorVolume")) || (!nk.Has("DetectorDensity"))) { THROW( "Near detector sample has specified volume but FD doesn't. This is " "needed to scale the predicted event rate by the mass ratio."); } fds.DetectorInfo.first = nk.GetD("DetectorVolume"); fds.DetectorInfo.second = nk.GetD("DetectorDensity"); double TargetMass_kg = fds.DetectorInfo.first * fds.DetectorInfo.second; fds.FDNDMassRatio = TargetMass_kg / (NDetectorInfo.first * NDetectorInfo.second); QLOG(SAM, "\tFD[" << FDSamples.size() << "] Event rate prediction : "); QLOG(SAM, "\t\tTarget volume : " << fds.DetectorInfo.first); QLOG(SAM, "\t\tTarget density : " << fds.DetectorInfo.second); QLOG(SAM, "\t\tFD/ND mass : " << fds.FDNDMassRatio); } if (!nk.Has("ObsInput")) { THROW("Far detector sample must specify at least ObsInput."); } std::vector FDObsInputs = PlotUtils::GetTH1sFromRootFile(nk.GetS("ObsInput")); if (FDObsInputs.size() < 2) { THROW( "Far detector sample must contain the observed ERec spectrum and the " "FD ETrue/ERec smearing matrix. " "ObsInput=\"input.root[FDObs_species,FDSmearing_species]\""); } fds.FDDataHist = NULL; for (size_t hist_it = 0; hist_it < FDObsInputs.size() - 1; ++hist_it) { if (!dynamic_cast(FDObsInputs[hist_it])) { ERROR(FTL, "Input spectrum index " << hist_it << " from ObsInput attribute was not a TH1D containing " "a far detector observed ERec spectrum (" << nk.GetS("ObsInput") << ")."); THROW( "Far detector sample must contain the observed ERec spectrum and the " "FD ETrue/ERec smearing matrix. " "ObsInput=\"input.root[FDObs_species,(FDObs_species2),FDSmearing_" "species]\""); } FDObsInputs[hist_it]->Scale(ScalePOT); if (!fds.FDDataHist) { fds.FDDataHist = dynamic_cast(FDObsInputs[hist_it]); } else { fds.FDDataHist->Add(dynamic_cast(FDObsInputs[hist_it])); } QLOG(SAM, "Added " << (FDObsInputs.size() - 1) << " far detector component spectra to form Observed " "spectra for sample index " << FDSamples.size() << "."); } fds.SpectrumToFDSmearingMatrix_TH2 = dynamic_cast(FDObsInputs.back()); if (!fds.SpectrumToFDSmearingMatrix_TH2) { ERROR(FTL, "last histogram from ObsInput attribute was not a TH2D containing " "the far detector ETrue/ERec smearing matrix (" << nk.GetS("ObsInput") << ")."); THROW( "Far detector sample must contain the observed ERec spectrum and the " "FD ETrue/ERec smearing matrix. " "ObsInput=\"input.root[FDObs_species,FDSmearing_species]\""); } TMatrixD SpectrumToFDSmearingMatrix_l = SmearceptanceUtils::GetMatrix(fds.SpectrumToFDSmearingMatrix_TH2); fds.SpectrumToFDSmearingMatrix.ResizeTo(SpectrumToFDSmearingMatrix_l); fds.SpectrumToFDSmearingMatrix = SpectrumToFDSmearingMatrix_l; FDSamples.push_back(fds); } void Smear_SVDUnfold_Propagation_Osc::FinaliseFDSamples() { std::stringstream ss(""); for (size_t fds_it = 0; fds_it < FDSamples.size(); ++fds_it) { FDSample &fds = FDSamples[fds_it]; // Set up FD histograms. // ============================== for (size_t nd_it = 0; nd_it < NDSamples.size(); ++nd_it) { NDSample &nds = NDSamples[nd_it]; TH1D *sampleHist = static_cast(nds.ND_Unfolded_Spectrum_Hist->Clone()); sampleHist->Reset(); ss.str(""); ss << "FD_Propagated_Spectrum_Hist_" << fds_it << "_NDSample_" << nd_it; sampleHist->SetName(ss.str().c_str()); fds.FD_Propagated_Spectrum_Hist_NDSamples.push_back(sampleHist); } fds.FD_Propagated_Spectrum_Hist = static_cast( fds.FD_Propagated_Spectrum_Hist_NDSamples[0]->Clone()); fds.FD_Propagated_Spectrum_Hist->Reset(); ss.str(""); ss << "FD_Propagated_Spectrum_Hist_" << fds_it; fds.FD_Propagated_Spectrum_Hist->SetName(ss.str().c_str()); for (size_t nd_it = 0; nd_it < NDSamples.size(); ++nd_it) { NDSample &nds = NDSamples[nd_it]; TH1D *sampleHist = static_cast(fds.FD_Propagated_Spectrum_Hist->Clone()); sampleHist->Reset(); ss.str(""); ss << "NDFD_Corrected_Spectrum_Hist_" << fds_it << "_NDSample_" << nd_it; sampleHist->SetName(ss.str().c_str()); fds.NDFD_Corrected_Spectrum_Hist_NDSamples.push_back(sampleHist); } fds.NDFD_Corrected_Spectrum_Hist = static_cast(fds.FD_Propagated_Spectrum_Hist->Clone()); fds.NDFD_Corrected_Spectrum_Hist->Reset(); ss.str(""); ss << "NDFD_Corrected_Spectrum_Hist_" << fds_it; fds.NDFD_Corrected_Spectrum_Hist->SetName(ss.str().c_str()); fds.FD_Smeared_Spectrum_Hist = new TH1D(*fds.SpectrumToFDSmearingMatrix_TH2->ProjectionX()); fds.FD_Smeared_Spectrum_Hist->SetDirectory(NULL); fds.FD_Smeared_Spectrum_Hist->Reset(); ss.str(""); ss << "FD_Smeared_Spectrum_Hist_" << fds_it; fds.FD_Smeared_Spectrum_Hist->SetName(ss.str().c_str()); for (size_t nd_it = 0; nd_it < NDSamples.size(); ++nd_it) { NDSample &nds = NDSamples[nd_it]; if (!fds.FDNDRatios.count(nds.NuPDG)) { ERROR(WRN, "Have an ND sample that provides PDG:" << nds.NuPDG << " neutrinos but far detector sample index " << fds_it << " doesn't have an NDFD ratio for this sample. " "Setting to 0 (contribution from sample ignored.)"); fds.FDNDRatios[nds.NuPDG] = 0; } } } } Int_t Smear_SVDUnfold_Propagation_Osc::GetFDSampleNAnalysisBins(size_t fds_it) { if (fds_it >= FDSamples.size()) { THROW("Requested FD sample index " << fds_it << " but only initialised " << FDSamples.size()); } FDSample &fds = FDSamples[fds_it]; Int_t NAnalysisBins = 0; for (Int_t bi_it = 1; bi_it < fds.FDDataHist->GetXaxis()->GetNbins() + 1; ++bi_it) { if ((fds.FitRegion_Min != 0xdeadbeef) && (fds.FDDataHist->GetXaxis()->GetBinUpEdge(bi_it) <= fds.FitRegion_Min)) { continue; } if ((fds.FitRegion_Max != 0xdeadbeef) && (fds.FDDataHist->GetXaxis()->GetBinLowEdge(bi_it) > fds.FitRegion_Max)) { continue; } NAnalysisBins++; } return NAnalysisBins; } void Smear_SVDUnfold_Propagation_Osc::SetupChi2Hists() { fDataHist = new TH1D("SmearSVDUnfold", "", NFDAnalysisBins, 0, NFDAnalysisBins); fDataHist->SetNameTitle((fSettings.GetName() + "_data").c_str(), (fSettings.GetFullTitles()).c_str()); Int_t CurrAnalysisBin = 1; for (size_t fds_it = 0; fds_it < FDSamples.size(); ++fds_it) { FDSample &fds = FDSamples[fds_it]; for (Int_t bi_it = 1; bi_it < fds.FDDataHist->GetXaxis()->GetNbins() + 1; ++bi_it) { if ((fds.FitRegion_Min != 0xdeadbeef) && (fds.FDDataHist->GetXaxis()->GetBinUpEdge(bi_it) <= fds.FitRegion_Min)) { continue; } if ((fds.FitRegion_Max != 0xdeadbeef) && (fds.FDDataHist->GetXaxis()->GetBinLowEdge(bi_it) > fds.FitRegion_Max)) { continue; } fDataHist->SetBinContent(CurrAnalysisBin, fds.FDDataHist->GetBinContent(bi_it)); if (UseRateErrors) { fDataHist->SetBinError(CurrAnalysisBin, sqrt(fds.FDDataHist->GetBinContent(bi_it))); } else { fDataHist->SetBinError(CurrAnalysisBin, fds.FDDataHist->GetBinError(bi_it)); } CurrAnalysisBin++; } } fMCHist = static_cast(fDataHist->Clone()); fMCHist->SetNameTitle((fSettings.GetName() + "_MC").c_str(), (fSettings.GetFullTitles()).c_str()); fMCHist->Reset(); } void Smear_SVDUnfold_Propagation_Osc::UpdateChi2Hists() { Int_t CurrAnalysisBin = 1; for (size_t fds_it = 0; fds_it < FDSamples.size(); ++fds_it) { FDSample &fds = FDSamples[fds_it]; for (Int_t bi_it = 1; bi_it < fds.FD_Smeared_Spectrum_Hist->GetXaxis()->GetNbins() + 1; ++bi_it) { if ((fds.FitRegion_Min != 0xdeadbeef) && (fds.FD_Smeared_Spectrum_Hist->GetXaxis()->GetBinUpEdge(bi_it) <= fds.FitRegion_Min)) { continue; } if ((fds.FitRegion_Max != 0xdeadbeef) && (fds.FD_Smeared_Spectrum_Hist->GetXaxis()->GetBinLowEdge(bi_it) > fds.FitRegion_Max)) { continue; } fMCHist->SetBinContent( CurrAnalysisBin, fds.FD_Smeared_Spectrum_Hist->GetBinContent(bi_it)); fMCHist->SetBinError(CurrAnalysisBin, fds.FD_Smeared_Spectrum_Hist->GetBinError(bi_it)); CurrAnalysisBin++; } } } //******************************************************************** Smear_SVDUnfold_Propagation_Osc::Smear_SVDUnfold_Propagation_Osc( nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "Simple measurement class for doing fake data oscillation studies.\n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetTitle("Osc Studies"); fSettings.SetDescription(descrip); fSettings.SetXTitle("XXX"); fSettings.SetYTitle("Number of events"); fSettings.SetEnuRange(0.0, 50); fSettings.SetAllowedTypes("EVT/SHAPE/DIAG", "EVT/SHAPE/DIAG"); fSettings.DefineAllowedTargets("*"); fSettings.DefineAllowedSpecies("numu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = GetEventHistogram()->Integral("width") / (fNEvents + 0.); fMCHist = NULL; fDataHist = NULL; ReadExtraConfig(samplekey); AddNDInputs(samplekey); std::vector NDTargets = samplekey.GetListOfChildNodes("NDObs"); for (size_t nd_it = 0; nd_it < NDTargets.size(); ++nd_it) { AddNDInputs(NDTargets[nd_it]); } std::vector FDTargets = samplekey.GetListOfChildNodes("FDObs"); NFDAnalysisBins = 0; if (!FDTargets.size()) { // If no child elements, assume that everything is // contained on the sample element AddFDTarget(samplekey); } else { for (size_t fd_it = 0; fd_it < FDTargets.size(); ++fd_it) { AddFDTarget(FDTargets[fd_it]); NFDAnalysisBins += GetFDSampleNAnalysisBins(fd_it); } } SetupNDInputs(); FinaliseFDSamples(); QLOG(SAM, "Set up " << FDSamples.size() << " samples for oscillation analysis with " << NFDAnalysisBins << " analysis bins."); SetupChi2Hists(); SetCovarFromDiagonal(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void Smear_SVDUnfold_Propagation_Osc::FillEventVariables(FitEvent *event){}; bool Smear_SVDUnfold_Propagation_Osc::isSignal(FitEvent *event) { return false; } void Smear_SVDUnfold_Propagation_Osc::UnfoldToNDETrueSpectrum(size_t nd_it) { if (nd_it >= NDSamples.size()) { THROW("Attempting to unfold ND sample index " << nd_it << " but only have " << NDSamples.size() << " ND samples."); } NDSample &nds = NDSamples[nd_it]; nds.ND_Unfolded_Spectrum_Hist = new TH1D(*nds.NDToSpectrumSmearingMatrix->ProjectionY()); nds.ND_Unfolded_Spectrum_Hist->SetDirectory(NULL); nds.ND_Unfolded_Spectrum_Hist->Clear(); std::stringstream ss(""); ss << "ND_Unfolded_Spectrum_Hist_" << nd_it; nds.ND_Unfolded_Spectrum_Hist->SetName(ss.str().c_str()); bool HasNegValue = false; int truncations = nds.TruncateStart; do { if (truncations >= nds.TruncateUpTo) { THROW("Unfolded enu spectrum had negative values even after " << truncations << " SVD singular value truncations."); } // Unfold ND ERec -> Enu spectrum // ------------------------------ SmearceptanceUtils::PushTH1ThroughMatrixWithErrors( nds.NDDataHist, nds.ND_Unfolded_Spectrum_Hist, nds.NDToSpectrumResponseMatrix, 1000, false); HasNegValue = false; for (Int_t bi_it = 1; bi_it < nds.ND_Unfolded_Spectrum_Hist->GetXaxis()->GetNbins() + 1; ++bi_it) { if ((FitRegion_Min != 0xdeadbeef) && (nds.ND_Unfolded_Spectrum_Hist->GetXaxis()->GetBinUpEdge(bi_it) <= FitRegion_Min)) { continue; } if ((FitRegion_Max != 0xdeadbeef) && (nds.ND_Unfolded_Spectrum_Hist->GetXaxis()->GetBinLowEdge(bi_it) > FitRegion_Max)) { continue; } if (nds.ND_Unfolded_Spectrum_Hist->GetBinContent(bi_it) < 0) { HasNegValue = true; break; } } if (HasNegValue) { TMatrixD NDToSpectrumResponseMatrix_l = SmearceptanceUtils::GetMatrix(SmearceptanceUtils::SVDGetInverse( nds.NDToSpectrumSmearingMatrix, truncations)); nds.NDToSpectrumResponseMatrix.ResizeTo(NDToSpectrumResponseMatrix_l); nds.NDToSpectrumResponseMatrix = NDToSpectrumResponseMatrix_l; } truncations++; } while (HasNegValue); } void Smear_SVDUnfold_Propagation_Osc::PropagateFDSample(size_t fds_it) { if (fds_it >= FDSamples.size()) { THROW("Requested FD sample index " << fds_it << " but only initialised " << FDSamples.size()); } FDSample &fds = FDSamples[fds_it]; // Apply Oscillations // ------------------------------ FitWeight *fw = FitBase::GetRW(); OscWeightEngine *oscWE = dynamic_cast(fw->GetRWEngine(kOSCILLATION)); if (!oscWE) { THROW( "Couldn't load oscillation weight engine for sample: " "Smear_SVDUnfold_Propagation_Osc."); } for (Int_t bi_it = 1; bi_it < fds.NDFD_Corrected_Spectrum_Hist->GetXaxis()->GetNbins() + 1; ++bi_it) { double content_osc = 0; double error_osc = 0; double content_fdnd = 0; double error_fdnd = 0; // Oscillate each ND sample to FD neutrino for (size_t nd_it = 0; nd_it < NDSamples.size(); ++nd_it) { NDSample &nds = NDSamples[nd_it]; double oscWeight = oscWE->CalcWeight( nds.ND_Unfolded_Spectrum_Hist->GetXaxis()->GetBinCenter(bi_it), nds.NuPDG, fds.OscillateToPDG); double sample_content_osc = nds.ND_Unfolded_Spectrum_Hist->GetBinContent(bi_it) * oscWeight; double sample_error_osc = nds.ND_Unfolded_Spectrum_Hist->GetBinError(bi_it) * oscWeight; fds.FD_Propagated_Spectrum_Hist_NDSamples[nd_it]->SetBinContent( bi_it, sample_content_osc); fds.FD_Propagated_Spectrum_Hist_NDSamples[nd_it]->SetBinError( bi_it, sample_error_osc); double sample_content_fdnd = sample_content_osc * fds.FDNDRatios[nds.NuPDG] * fds.FDNDMassRatio; double sample_error_fdnd = sample_error_osc * fds.FDNDRatios[nds.NuPDG] * fds.FDNDMassRatio; fds.NDFD_Corrected_Spectrum_Hist_NDSamples[nd_it]->SetBinContent( bi_it, sample_content_fdnd); fds.NDFD_Corrected_Spectrum_Hist_NDSamples[nd_it]->SetBinError( bi_it, sample_error_fdnd); content_osc += sample_content_osc; error_osc += sample_error_osc * sample_error_osc; content_fdnd += sample_content_fdnd; error_fdnd += sample_error_fdnd * sample_error_fdnd; } fds.FD_Propagated_Spectrum_Hist->SetBinContent(bi_it, content_osc); fds.FD_Propagated_Spectrum_Hist->SetBinError(bi_it, sqrt(error_osc)); fds.NDFD_Corrected_Spectrum_Hist->SetBinContent(bi_it, content_fdnd); fds.NDFD_Corrected_Spectrum_Hist->SetBinError(bi_it, sqrt(error_fdnd)); } // Forward fold Spectrum -> ERec FD // ------------------------------ SmearceptanceUtils::PushTH1ThroughMatrixWithErrors( fds.NDFD_Corrected_Spectrum_Hist, fds.FD_Smeared_Spectrum_Hist, fds.SpectrumToFDSmearingMatrix, 1000, true); } void Smear_SVDUnfold_Propagation_Osc::ConvertEventRates(void) { for (size_t fds_it = 0; fds_it < FDSamples.size(); ++fds_it) { PropagateFDSample(fds_it); } UpdateChi2Hists(); } void Smear_SVDUnfold_Propagation_Osc::Write(std::string drawOpt) { TDirectory *ogDir = gDirectory; ConvertEventRates(); FitWeight *fw = FitBase::GetRW(); OscWeightEngine *oscWE = dynamic_cast(fw->GetRWEngine(kOSCILLATION)); if (!oscWE) { THROW( "Couldn't load oscillation weight engine for sample: " "Smear_SVDUnfold_Propagation_Osc."); } oscWE->Print(); // Write ND samples //---------------- for (size_t nd_it = 0; nd_it < NDSamples.size(); ++nd_it) { NDSample &nds = NDSamples[nd_it]; std::stringstream ss(""); ss << "Smear_SVDUnfold_Propagation_Osc_NDSample_" << nd_it; if (ogDir) { ogDir->mkdir(ss.str().c_str()); ogDir->cd(ss.str().c_str()); } else { - FitPar::Config().out->mkdir(ss.str().c_str()); - FitPar::Config().out->cd(ss.str().c_str()); + Config::Get().out->mkdir(ss.str().c_str()); + Config::Get().out->cd(ss.str().c_str()); } nds.NDToSpectrumSmearingMatrix->Write("SmearingMatrix_ND", TObject::kOverwrite); nds.NDDataHist->Write("Obs_ND", TObject::kOverwrite); nds.ND_Unfolded_Spectrum_Hist->Write( nds.ND_Unfolded_Spectrum_Hist->GetName(), TObject::kOverwrite); if (ogDir) { ogDir->cd(); } else { - FitPar::Config().out->cd(); + Config::Get().out->cd(); } } // Write FD samples //---------------- for (size_t fds_it = 0; fds_it < FDSamples.size(); ++fds_it) { FDSample &fds = FDSamples[fds_it]; std::stringstream ss(""); ss << "Smear_SVDUnfold_Propagation_Osc_FDSample_" << fds_it; if (ogDir) { ogDir->mkdir(ss.str().c_str()); ogDir->cd(ss.str().c_str()); } else { - FitPar::Config().out->mkdir(ss.str().c_str()); - FitPar::Config().out->cd(ss.str().c_str()); + Config::Get().out->mkdir(ss.str().c_str()); + Config::Get().out->cd(ss.str().c_str()); } // Calc oscillation probability // ------------------------------ FitWeight *fw = FitBase::GetRW(); OscWeightEngine *oscWE = dynamic_cast(fw->GetRWEngine(kOSCILLATION)); if (!oscWE) { THROW( "Couldn't load oscillation weight engine for sample: " "Smear_SVDUnfold_Propagation_Osc."); } for (size_t nd_it = 0; nd_it < NDSamples.size(); ++nd_it) { NDSample &nds = NDSamples[nd_it]; ss.str(""); ss << "NDSample_" << nd_it << "_contribution"; fds.FD_Propagated_Spectrum_Hist_NDSamples[nd_it]->Write( ss.str().c_str(), TObject::kOverwrite); ss.str(""); ss << "NDSample_" << nd_it << "_FDNDCorrected_contribution"; fds.NDFD_Corrected_Spectrum_Hist_NDSamples[nd_it]->Write( ss.str().c_str(), TObject::kOverwrite); ss.str(""); ss << "NDSample_" << nd_it << "_OscillationProb"; TGraph POsc; POsc.Set(1E4 - 1); double min = nds.ND_Unfolded_Spectrum_Hist->GetXaxis()->GetBinLowEdge(1); double step = (nds.ND_Unfolded_Spectrum_Hist->GetXaxis()->GetBinUpEdge( nds.ND_Unfolded_Spectrum_Hist->GetXaxis()->GetNbins()) - nds.ND_Unfolded_Spectrum_Hist->GetXaxis()->GetBinLowEdge(1)) / double(1E4); for (size_t i = 1; i < 1E4; ++i) { double enu = min + i * step; double ow = oscWE->CalcWeight(enu, nds.NuPDG, fds.OscillateToPDG); if (ow != ow) { std::cout << "Bad osc weight for ENu: " << enu << std::endl; } POsc.SetPoint(i - 1, enu, ow); } POsc.Write(ss.str().c_str(), TObject::kOverwrite); } fds.FDDataHist->Write("Obs_FD", TObject::kOverwrite); fds.FD_Propagated_Spectrum_Hist->Write( fds.FD_Propagated_Spectrum_Hist->GetName(), TObject::kOverwrite); fds.NDFD_Corrected_Spectrum_Hist->Write( fds.NDFD_Corrected_Spectrum_Hist->GetName(), TObject::kOverwrite); fds.SpectrumToFDSmearingMatrix_TH2->Write("SmearingMatrix_FD", TObject::kOverwrite); fds.FD_Smeared_Spectrum_Hist->Write(fds.FD_Smeared_Spectrum_Hist->GetName(), TObject::kOverwrite); if (ogDir) { ogDir->cd(); } else { - FitPar::Config().out->cd(); + Config::Get().out->cd(); } } fMCHist->Write("Pred_FD", TObject::kOverwrite); fDataHist->Write("Obs_FD", TObject::kOverwrite); Measurement1D::Write(drawOpt); } diff --git a/src/MCStudies/Smearceptance_Tester.cxx b/src/MCStudies/Smearceptance_Tester.cxx index 67677e2..17f3de7 100644 --- a/src/MCStudies/Smearceptance_Tester.cxx +++ b/src/MCStudies/Smearceptance_Tester.cxx @@ -1,785 +1,788 @@ // 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::Get().GetConfigNode("NPOT")) { - samplekey.SetS("NPOT", Config::Get().ConfS("NPOT")); + if (Config::HasPar("NPOT")) { + samplekey.SetS("NPOT", Config::GetParS("NPOT")); } - if (Config::Get().GetConfigNode("FluxIntegralOverride")) { + if (Config::HasPar("FluxIntegralOverride")) { samplekey.SetS("FluxIntegralOverride", - Config::Get().ConfS("FluxIntegralOverride")); + Config::GetParS("FluxIntegralOverride")); } - if (Config::Get().GetConfigNode("TargetVolume")) { - samplekey.SetS("TargetVolume", Config::Get().ConfS("TargetVolume")); + if (Config::HasPar("TargetVolume")) { + samplekey.SetS("TargetVolume", Config::GetParS("TargetVolume")); } - if (Config::Get().GetConfigNode("TargetMaterialDensity")) { + if (Config::HasPar("TargetMaterialDensity")) { samplekey.SetS("TargetMaterialDensity", - Config::Get().ConfS("TargetMaterialDensity")); + Config::GetParS("TargetMaterialDensity")); } OutputSummaryTree = true; - if (Config::Get().GetConfigNode("smear.OutputSummaryTree")) { - OutputSummaryTree = Config::Get().ConfI("smear.OutputSummaryTree"); + 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 = fName.substr(firstUS + 1); + 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; - LOG(SAM) << "Smearceptance Flux Scaling Factor = " << fScaleFactor - << std::endl; + QLOG(SAM, "Smearceptance Flux Scaling Factor = " << fScaleFactor); if (fScaleFactor <= 0.0) { - ERR(WRN) << "SCALE FACTOR TOO LOW " << std::endl; + 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::Get().GetConfigNode("smear.reconstructed.binning")) { + if (Config::HasPar("smear.reconstructed.binning")) { std::vector args = GeneralUtils::ParseToStr( - Config::Get().ConfS("smear.reconstructed.binning"), ","); + 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::Get().GetConfigNode("smear.true.binning")) { - std::vector args = GeneralUtils::ParseToStr( - Config::Get().ConfS("smear.true.binning"), ","); + 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::Get().GetConfigNode("smear.true.binning")) { - SVDTruncation = Config::Get().ConfI("smear.SVD.truncation"); + 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) { - FitPar::Config().out->cd(); + 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_mu_true", &HMFS_mu_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_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_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("HMFS_mu_rec", &HMFS_mu_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_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_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_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("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("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("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("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); } 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); } 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 ProtonPDG[] = {2212}; static int const NeutronPDG[] = {2112}; static int const GammaPDG[] = {22}; static int const CLeptonPDGs[] = {11, 13, 15}; static int const ExplicitPDGs[] = {211, -211, 111, 2212, 2112, 22, 11, 13, 15, 12, 14, 16}; RecoInfo *ri = smearceptor->Smearcept(event); HMFS_mu_true = TLorentzVector(0, 0, 0, 0); HMFS_mu_rec = TLorentzVector(0, 0, 0, 0); FitParticle *fsMu = event->GetHMFSMuon(); if (fsMu) { HMFS_mu_true = fsMu->P4(); HMFS_mu_rec = GetHMFSRecParticles(*ri, 13); } 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, 211); } 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, -211); } 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_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, 2212); } 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_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; 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(); 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_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_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; 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); 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); 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; flagCC0Pi_true = (Ncpi_true + Npi0_true) == 0; flagCC1Pi_true = (Ncpi_true + Npi0_true) == 1; flagCCINC_rec = FSCLep_seen && PDGFSLep_true & 1; flagCC0Pi_rec = ((Ncpi_seen + Npi0_seen) == 0) && flagCCINC_rec; flagCC1Pi_rec = ((Ncpi_seen + Npi0_seen) == 1) && flagCCINC_rec; 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 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); } 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/CMakeLists.txt b/src/MINERvA/CMakeLists.txt index d8a5008..6e89fe5 100644 --- a/src/MINERvA/CMakeLists.txt +++ b/src/MINERvA/CMakeLists.txt @@ -1,167 +1,174 @@ # 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 . ################################################################################ set(IMPLFILES MINERvA_CCQE_XSec_1DQ2_antinu.cxx MINERvA_CCQE_XSec_1DQ2_joint.cxx MINERvA_CCQE_XSec_1DQ2_nu.cxx MINERvA_CC0pi_XSec_1DEe_nue.cxx MINERvA_CC0pi_XSec_1DQ2_nue.cxx MINERvA_CC0pi_XSec_1DQ2_nu_proton.cxx MINERvA_CC0pi_XSec_1DThetae_nue.cxx MINERvA_CC1pi0_XSec_1DEnu_antinu.cxx MINERvA_CC1pi0_XSec_1DQ2_antinu.cxx MINERvA_CC1pi0_XSec_1Dpmu_antinu.cxx MINERvA_CC1pi0_XSec_1Dppi0_antinu.cxx MINERvA_CC1pi0_XSec_1DTpi0_antinu.cxx MINERvA_CC1pi0_XSec_1Dth_antinu.cxx MINERvA_CC1pi0_XSec_1Dthmu_antinu.cxx MINERvA_CC1pi0_XSec_1D_nu.cxx MINERvA_CC1pip_XSec_1DTpi_20deg_nu.cxx MINERvA_CC1pip_XSec_1DTpi_nu.cxx MINERvA_CC1pip_XSec_1Dth_20deg_nu.cxx MINERvA_CC1pip_XSec_1Dth_nu.cxx MINERvA_CC1pip_XSec_1D_2017Update.cxx MINERvA_CCNpip_XSec_1DEnu_nu.cxx MINERvA_CCNpip_XSec_1DQ2_nu.cxx MINERvA_CCNpip_XSec_1DTpi_nu.cxx MINERvA_CCNpip_XSec_1Dpmu_nu.cxx MINERvA_CCNpip_XSec_1Dth_nu.cxx MINERvA_CCNpip_XSec_1Dthmu_nu.cxx MINERvA_CCinc_XSec_2DEavq3_nu.cxx MINERvA_CCinc_XSec_1Dx_ratio.cxx MINERvA_CCinc_XSec_1DEnu_ratio.cxx MINERvA_CCinc_XSec_1Dx_nu.cxx MINERvA_CCinc_XSec_1DEnu_nu.cxx MINERvA_CCDIS_XSec_1Dx_ratio.cxx MINERvA_CCDIS_XSec_1DEnu_ratio.cxx MINERvA_CCDIS_XSec_1Dx_nu.cxx MINERvA_CCDIS_XSec_1DEnu_nu.cxx MINERvA_CC0pi_XSec_1DQ2_Tgt_nu.cxx MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu.cxx MINERvA_CC0pi_XSec_2Dptpx_nu.cxx MINERvA_CC0pi_XSec_2Dptpx_antinu.cxx MINERvA_CCCOHPI_XSec_1DEnu_nu.cxx MINERvA_CCCOHPI_XSec_1DEpi_nu.cxx MINERvA_CCCOHPI_XSec_1Dth_nu.cxx MINERvA_CCCOHPI_XSec_1DQ2_nu.cxx MINERvA_CCCOHPI_XSec_1DEnu_antinu.cxx MINERvA_CCCOHPI_XSec_1DEpi_antinu.cxx MINERvA_CCCOHPI_XSec_1Dth_antinu.cxx MINERvA_CCCOHPI_XSec_1DQ2_antinu.cxx +MINERvA_CCCOHPI_XSec_joint.cxx + MINERvAUtils.cxx MINERvA_SignalDef.cxx ) set(HEADERFILES MINERvA_CCQE_XSec_1DQ2_antinu.h MINERvA_CCQE_XSec_1DQ2_joint.h MINERvA_CCQE_XSec_1DQ2_nu.h MINERvA_CC0pi_XSec_1DEe_nue.h MINERvA_CC0pi_XSec_1DQ2_nue.h MINERvA_CC0pi_XSec_1DQ2_nu_proton.h MINERvA_CC0pi_XSec_1DThetae_nue.h MINERvA_CC1pi0_XSec_1DEnu_antinu.h MINERvA_CC1pi0_XSec_1DQ2_antinu.h MINERvA_CC1pi0_XSec_1Dpmu_antinu.h MINERvA_CC1pi0_XSec_1Dppi0_antinu.h MINERvA_CC1pi0_XSec_1DTpi0_antinu.h MINERvA_CC1pi0_XSec_1Dth_antinu.h MINERvA_CC1pi0_XSec_1Dthmu_antinu.h MINERvA_CC1pip_XSec_1DTpi_20deg_nu.h MINERvA_CC1pip_XSec_1DTpi_nu.h MINERvA_CC1pip_XSec_1Dth_20deg_nu.h MINERvA_CC1pip_XSec_1Dth_nu.h MINERvA_CCNpip_XSec_1DEnu_nu.h MINERvA_CCNpip_XSec_1DQ2_nu.h MINERvA_CCNpip_XSec_1DTpi_nu.h MINERvA_CCNpip_XSec_1Dpmu_nu.h MINERvA_CCNpip_XSec_1Dth_nu.h MINERvA_CCNpip_XSec_1Dthmu_nu.h MINERvA_CCinc_XSec_2DEavq3_nu.h MINERvA_CCinc_XSec_1Dx_ratio.h MINERvA_CCinc_XSec_1DEnu_ratio.h MINERvA_CCinc_XSec_1Dx_nu.h MINERvA_CCinc_XSec_1DEnu_nu.h MINERvA_CCDIS_XSec_1Dx_ratio.h MINERvA_CCDIS_XSec_1DEnu_ratio.h MINERvA_CCDIS_XSec_1Dx_nu.h MINERvA_CCDIS_XSec_1DEnu_nu.h MINERvA_CC0pi_XSec_1DQ2_Tgt_nu.h MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu.h MINERvA_CC0pi_XSec_2Dptpx_nu.h MINERvA_CC0pi_XSec_2Dptpx_antinu.h MINERvA_CC1pip_XSec_1D_2017Update.h MINERvA_CCCOHPI_XSec_1DEnu_nu.h MINERvA_CCCOHPI_XSec_1DEpi_nu.h MINERvA_CCCOHPI_XSec_1Dth_nu.h +MINERvA_CCCOHPI_XSec_1DQ2_nu.h + MINERvA_CCCOHPI_XSec_1DEnu_antinu.h MINERvA_CCCOHPI_XSec_1DEpi_antinu.h MINERvA_CCCOHPI_XSec_1Dth_antinu.h +MINERvA_CCCOHPI_XSec_1DQ2_antinu.h + +MINERvA_CCCOHPI_XSec_joint.h MINERvAUtils.h MINERvA_SignalDef.h MINERvAVariableBoxes.h ) set(LIBNAME expMINERvA) if(CMAKE_BUILD_TYPE MATCHES DEBUG) add_library(${LIBNAME} STATIC ${IMPLFILES}) else(CMAKE_BUILD_TYPE MATCHES RELEASE) add_library(${LIBNAME} SHARED ${IMPLFILES}) endif() include_directories(${MINIMUM_INCLUDE_DIRECTORIES}) set_target_properties(${LIBNAME} PROPERTIES VERSION "${NUISANCE_VERSION_MAJOR}.${NUISANCE_VERSION_MINOR}.${NUISANCE_VERSION_REVISION}") #set_target_properties(${LIBNAME} PROPERTIES LINK_FLAGS ${ROOT_LD_FLAGS}) if(DEFINED PROJECTWIDE_EXTRA_DEPENDENCIES) add_dependencies(${LIBNAME} ${PROJECTWIDE_EXTRA_DEPENDENCIES}) endif() install(TARGETS ${LIBNAME} DESTINATION lib) #Can uncomment this to install the headers... but is it really neccessary? #install(FILES ${HEADERFILES} DESTINATION include) set(MODULETargets ${MODULETargets} ${LIBNAME} PARENT_SCOPE) diff --git a/src/MINERvA/MINERvAUtils.cxx b/src/MINERvA/MINERvAUtils.cxx index 1770ea3..c9d20e2 100644 --- a/src/MINERvA/MINERvAUtils.cxx +++ b/src/MINERvA/MINERvAUtils.cxx @@ -1,312 +1,312 @@ // 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 "MINERvAUtils.h" -#include "FitParameters.h" + #include "FitUtils.h" namespace MINERvAPar{ double MINERvADensity = FitPar::Config().GetParD("MINERvADensity"); double MINERvARecoDist = FitPar::Config().GetParD("MINERvARecoDist"); double PenetratingMuonE = FitPar::Config().GetParD("PenetratingMuonEnergy"); double NumRangeSteps = FitPar::Config().GetParI("NumRangeSteps"); } double MINERvAUtils::StoppedEfficiency(TH2D *effHist, FitParticle *nu, FitParticle *muon){ double eff = 0.; if (!effHist) return eff; eff = effHist->GetBinContent(effHist->FindBin(FitUtils::p(muon), FitUtils::th(nu, muon)/TMath::Pi()*180.)); return eff; } double MINERvAUtils::PenetratedEfficiency(FitParticle *nu, FitParticle *muon){ double eff = 0.; if (FitUtils::th(nu, muon)/TMath::Pi()*180. > 50) eff = 0.; if (FitUtils::p(muon) < 1.4) eff = 0.; return eff; } double MINERvAUtils::BetheBlochCH(double E, double mass){ double beta2 = 1 - mass*mass/E/E; double gamma = 1./sqrt(1-beta2); double mass_ratio = PhysConst::mass_electron*1000./mass; // Argh, have to remember to convert to MeV or you'll hate yourself! double I2 = 68.7e-6*68.7e-6; // mean excitation potential I double w_max = 2*PhysConst::mass_electron*1000.*beta2*gamma*gamma; w_max /= 1 + 2*gamma*mass_ratio + mass_ratio*mass_ratio; // Values taken from the PDG for K = 0.307075 MeV mol-1 cm2, mean ionization energy I = 68.7 eV (Polystyrene) // = 0.53768 (pdg.lbl.gov/AtomicNuclearProperties) double log_term = log(2*PhysConst::mass_electron*1000.*beta2*gamma*gamma*w_max/I2); double dedx = 0.307075*0.53768/beta2*(0.5*log_term - beta2); return dedx; } // This function returns an estimate of the range of the particle in scintillator. // It uses crude integration and Bethe-Bloch to approximate the range. double MINERvAUtils::RangeInScintillator(FitParticle* particle, int nsteps){ // The particle energy double E = particle->fP.E(); double M = particle->fP.M(); double Ek = E - M; double step_size = Ek/float(nsteps+1); double range = 0; // Add an offset to make the integral a touch more accurate Ek -= step_size/2.; for (int i = 0; i < nsteps; ++i){ double dEdx = MINERvAUtils::BetheBlochCH(Ek+M, M); Ek -= step_size; // dEdx is -ve range -= step_size/dEdx; } // Account for density of polystyrene range /= MINERvAPar::MINERvADensity; // Range estimate is in cm return fabs(range); } double MINERvAUtils::GetEDepositOutsideRangeInScintillator(FitParticle* particle, double rangelimit){ // The particle energy double E = particle->fP.E(); double M = particle->fP.M(); double Ek = E - M; int nsteps = MINERvAPar::NumRangeSteps; double step_size = Ek/float(nsteps+1); double range = 0; double Ekinside = 0.0; double Ekstart = Ek; // Add an offset to make the integral a touch more accurate Ek -= step_size/2.; for (int i = 0; i < nsteps; ++i){ double dEdx = MINERvAUtils::BetheBlochCH(Ek+M, M); Ek -= step_size; // dEdx is -ve range -= step_size/dEdx; if (fabs(range) / MINERvAPar::MINERvADensity < rangelimit){ Ekinside = Ek; } } // Range estimate is in cm return Ekstart - Ekinside; } double MINERvAUtils::GetEDepositInsideRangeInScintillator(FitParticle* particle, double rangelimit){ // The particle energy double E = particle->fP.E(); double M = particle->fP.M(); double Ek = E - M; return Ek - GetEDepositOutsideRangeInScintillator(particle, rangelimit); } // Function to calculate the distance the particle travels in scintillator bool MINERvAUtils::PassesDistanceCut(FitParticle* beam, FitParticle* particle){ double dist = MINERvAUtils::RangeInScintillator(particle, MINERvAPar::NumRangeSteps); double zdist = dist*cos(FitUtils::th(beam, particle)); if (abs(zdist) < MINERvAPar::MINERvARecoDist) return false; return true; } // Function to return the MainTrk int MINERvAUtils::GetMainTrack(FitEvent *event, TH2D *effHist, FitParticle*& mainTrk, double& weight, bool penetrated){ FitParticle *nu = event->GetNeutrinoIn(); double highestMom = 0; int index = 0; mainTrk = NULL; // Loop over particles for (uint j = 2; j < event->Npart(); ++j){ // Final state only! if (!(event->PartInfo(j))->fIsAlive) continue; if (event->PartInfo(j)->fNEUTStatusCode != 0) continue; int PID = event->PartInfo(j)->fPID; // Only consider pions, muons for now if (abs(PID) != 211 && abs(PID) != 13) continue; // Ignore if higher momentum tracks available if (FitUtils::p(event->PartInfo(j)) < highestMom) continue; // Okay, now this is highest momentum highestMom = FitUtils::p(event->PartInfo(j)); weight *= MINERvAUtils::StoppedEfficiency(effHist, nu, event->PartInfo(j)); index = j; mainTrk = event->PartInfo(j); } // end loop over particle stack return index; } void MINERvAUtils::GetOtherTrackInfo(FitEvent *event, int mainIndex, int& nProtons, int& nPiMus, int& nVertex, FitParticle*& secondTrk){ // Reset everything nPiMus = 0; nProtons = 0; nVertex = 0; secondTrk = NULL; double highestMom = 0.; // Loop over particles for (uint j = 2; j < event->Npart(); ++j){ // Don't re-count the main track if (j == (uint)mainIndex) continue; // Final state only! if (!(event->PartInfo(j))->fIsAlive) continue; if (event->PartInfo(j)->fNEUTStatusCode != 0) continue; int PID = event->PartInfo(j)->fPID; // Only consider pions, muons, protons if (abs(PID) != 211 && PID != 2212 && abs(PID) != 13) continue; // Must be reconstructed as a track in SciBooNE if (MINERvAUtils::PassesDistanceCut(event->PartInfo(0), event->PartInfo(j))){ // Keep track of the second highest momentum track if (FitUtils::p(event->PartInfo(j)) > highestMom){ highestMom = FitUtils::p(event->PartInfo(j)); secondTrk = event->PartInfo(j); } if (PID == 2212) nProtons += 1; else nPiMus += 1; } else nVertex += 1; } // end loop over particle stack return; } // NOTE: need to adapt this to allow for penetrating events... // Simpler, but gives the same results as in Hirade-san's thesis double MINERvAUtils::CalcThetaPr(FitEvent *event, FitParticle *main, FitParticle *second, bool penetrated){ FitParticle *nu = event->GetNeutrinoIn(); if (!main || !nu || !second) return -999; // Construct the vector p_pr = (-p_mux, -p_muy, Enurec - pmucosthetamu) // where p_mux, p_muy are the projections of the candidate muon momentum onto the x and y dimension respectively double pmu = main->fP.Vect().Mag(); double pmu_x = main->fP.Vect().X(); double pmu_y = main->fP.Vect().Y(); if (penetrated){ pmu = 1400.; double ratio = 1.4/main->fP.Vect().Mag(); TVector3 mod_mu = main->fP.Vect()*ratio; pmu_x = mod_mu.X(); pmu_y = mod_mu.Y(); } double Enuqe = FitUtils::EnuQErec(pmu/1000.,cos(FitUtils::th(nu, main)), 27., true)*1000.; double p_pr_z = Enuqe - pmu*cos(FitUtils::th(nu, main)); TVector3 p_pr = TVector3(-pmu_x, -pmu_y, p_pr_z); double thetapr = p_pr.Angle(second->fP.Vect())/TMath::Pi()*180.; return thetapr; } double MINERvAUtils::CalcThetaPi(FitEvent *event, FitParticle *second){ FitParticle *nu = event->GetNeutrinoIn(); if (!second || !nu) return -999; double thetapi = FitUtils::th(nu, second)/TMath::Pi()*180.; return thetapi; } /// Functions to deal with the SB mode stacks MINERvAUtils::ModeStack::ModeStack(std::string name, std::string title, TH1* hist) { fName = name; fTitle = title; AddMode(0, "Other", "Other", kGreen+2, 2, 3244); AddMode(1, "CCDIS", "#nu_{#mu} CC DIS", kRed, 2, 3304); AddMode(2, "CCRES", "#nu_{#mu} CC Resonant", kGray+2, 2, 1001); AddMode(3, "CCQE", "#nu_{#mu} CC QE", kMagenta, 2, 1001); AddMode(4, "CC2P2H", "#nu_{#mu} CC 2p2h", kAzure+1, 2, 1001); StackBase::SetupStack(hist); }; int MINERvAUtils::ModeStack::ConvertModeToIndex(int mode){ switch (abs(mode)){ case 1: return 3; case 2: return 4; case 11: case 12: case 13: return 2; case 26: return 1; default: return 0; } }; void MINERvAUtils::ModeStack::Fill(int mode, double x, double y, double z, double weight) { StackBase::FillStack(MINERvAUtils::ModeStack::ConvertModeToIndex(mode), x, y, z, weight); }; void MINERvAUtils::ModeStack::Fill(FitEvent* evt, double x, double y, double z, double weight) { StackBase::FillStack(MINERvAUtils::ModeStack::ConvertModeToIndex(evt->Mode), x, y, z, weight); }; void MINERvAUtils::ModeStack::Fill(BaseFitEvt* evt, double x, double y, double z, double weight) { StackBase::FillStack(MINERvAUtils::ModeStack::ConvertModeToIndex(evt->Mode), x, y, z, weight); }; diff --git a/src/MINERvA/MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu.cxx b/src/MINERvA/MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu.cxx index 3494bc7..d524079 100644 --- a/src/MINERvA/MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu.cxx +++ b/src/MINERvA/MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu.cxx @@ -1,138 +1,138 @@ // 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_CC0pi_XSec_1DQ2_TgtRatio_nu.h" //******************************************************************** MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu::MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu sample. \n" \ "Target: Target;CH (2 INPUTS)\n" \ "Flux: MINERvA Forward Horn Current Numu \n" \ "Signal: Any event with 1 muon, 1 proton p>450, no pions"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("Q^{2}_{QE} (GeV^{2})"); fSettings.SetYTitle(" d#sigma/dQ^{2}_{QE} (cm^{2}/GeV^{2}/nucleon)"); fSettings.SetAllowedTypes("FIX/DIAG,FULL/MASK", "FIX/FULL"); fSettings.SetEnuRange(0.0, 100.0); // CCQELike plot information fSettings.SetTitle("MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu"); fIsRatio = true; nBins = 5; target = ""; if (fSettings.Found("name", "TgtRatioFe")) target = "Fe"; else if (fSettings.Found("name", "TgtRatioPb")) target = "Pb"; else if (fSettings.Found("name", "TgtRatioC")) target = "C"; else { ERR(FTL) << "target " << target << " was not found!" << std::endl; exit(-1); } std::string basedir = FitPar::GetDataBase() + "/MINERvA/CC0pi/"; fSettings.SetDataInput( basedir + "Q2_TgtRatio_" + target + "_data.txt"); fSettings.SetCovarInput( basedir + "Q2_TgtRatio_" + target + "_covar.txt"); FinaliseSampleSettings(); // Get parsed input files if (fSubInFiles.size() != 2) ERR(FTL) << "MINERvA CC0pi ratio requires input files in format: NUMERATOR;DENOMINATOR" << std::endl; std::string inFileNUM = fSubInFiles.at(0); std::string inFileDEN = fSubInFiles.at(1); // Scaling Setup --------------------------------------------------- // Ratio of sub classes so non needed // Plot Setup ------------------------------------------------------- SetDataFromTextFile( fSettings.GetDataInput() ); SetCorrelationFromTextFile(fSettings.GetCovarInput()); // Setup Experiments ------------------------------------------------------- std::string type = samplekey.GetS("type"); - nuiskey samplekey_num = Config::CreateKey("sample"); - samplekey_num.AddS("name", "MINERvA_CC0pi_XSec_1DQ2_Tgt" + target + "_nu"); - samplekey_num.AddS("input", inFileNUM); - samplekey_num.AddS("type", type); - - nuiskey samplekey_den = Config::CreateKey("sample"); - samplekey_den.AddS("name", "MINERvA_CC0pi_XSec_1DQ2_TgtCH_nu"); - samplekey_den.AddS("input", inFileDEN); - samplekey_den.AddS("type", type); + nuiskey samplekey_num = nuiskey("sample"); + samplekey_num.Set("name", "MINERvA_CC0pi_XSec_1DQ2_Tgt" + target + "_nu"); + samplekey_num.Set("input", inFileNUM); + samplekey_num.Set("type", type); + + nuiskey samplekey_den = nuiskey("sample"); + samplekey_den.Set("name", "MINERvA_CC0pi_XSec_1DQ2_TgtCH_nu"); + samplekey_den.Set("input", inFileDEN); + samplekey_den.Set("type", type); NUM = new MINERvA_CC0pi_XSec_1DQ2_Tgt_nu(samplekey_num); DEN = new MINERvA_CC0pi_XSec_1DQ2_Tgt_nu(samplekey_den); NUM ->SetNoData(); DEN ->SetNoData(); // Add to chain for processing this->fSubChain.clear(); this->fSubChain.push_back(NUM); this->fSubChain.push_back(DEN); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; //******************************************************************** void MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu::MakePlots() { //******************************************************************** UInt_t sample = 0; for (std::vector::const_iterator expIter = this->fSubChain.begin(); expIter != this->fSubChain.end(); expIter++) { MeasurementBase* exp = static_cast(*expIter); if (sample == 0) this->NUM = static_cast(exp); else if (sample == 1) this->DEN = static_cast(exp); else break; sample++; } // Now make the ratio histogram TH1D* NUM_MC = (TH1D*)this->NUM->GetMCList().at(0)->Clone(); TH1D* DEN_MC = (TH1D*)this->DEN->GetMCList().at(0)->Clone(); for (int i = 0; i < nBins; ++i) { double binVal = 0; double binErr = 0; if (DEN_MC->GetBinContent(i + 1) && NUM_MC->GetBinContent(i + 1)) { binVal = NUM_MC->GetBinContent(i + 1) / DEN_MC->GetBinContent(i + 1); double fractErrNUM = NUM_MC->GetBinError(i + 1) / NUM_MC->GetBinContent(i + 1); double fractErrDEN = DEN_MC->GetBinError(i + 1) / DEN_MC->GetBinContent(i + 1); binErr = binVal * sqrt(fractErrNUM * fractErrNUM + fractErrDEN * fractErrDEN); } this->fMCHist->SetBinContent(i + 1, binVal); this->fMCHist->SetBinError(i + 1, binErr); } return; } diff --git a/src/MINERvA/MINERvA_CC0pi_XSec_2Dptpx_nu.cxx b/src/MINERvA/MINERvA_CC0pi_XSec_2Dptpx_nu.cxx index 0d88e2c..ac88a09 100755 --- a/src/MINERvA/MINERvA_CC0pi_XSec_2Dptpx_nu.cxx +++ b/src/MINERvA/MINERvA_CC0pi_XSec_2Dptpx_nu.cxx @@ -1,110 +1,110 @@ //Adrian Orea //I used the file MINERvA_CCinc_XSec_2DEavq3_nu.cxx as a template //Also, I am fully aware of the naming typo (should be ptpz), but Everything is already named the same way so... //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 . *******************************************************************************/ /* Author : Adrian Orea */ #include "MINERvA_SignalDef.h" #include "MINERvA_CC0pi_XSec_2Dptpx_nu.h" //******************************************************************** MINERvA_CC0pi_XSec_2Dptpx_nu::MINERvA_CC0pi_XSec_2Dptpx_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MINERvA_CC0pi_XSec_2Dptpx_nu sample. \n" \ "Target: CH \n" \ "Flux: MINERvA Medium Energy FHC numu \n" \ "Signal: CC-0pi \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); - fSettings.SetXTitle("p_{z} (GeV)"); - fSettings.SetYTitle("p_{t} (GeV)"); + fSettings.SetYTitle("p_{z} (GeV)"); + fSettings.SetZTitle("p_{t} (GeV)"); fSettings.SetZTitle("d^{2}#sigma/dP_{t}dP_{z} (cm^{2}/GeV^{2}/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/MASK", "FIX/FULL"); fSettings.SetEnuRange(0.0, 100.0); fSettings.DefineAllowedTargets("C,H"); // CCQELike plot information fSettings.SetTitle("MINERvA_CC0pi_XSec_2Dptpx_nu"); - fSettings.SetDataInput( FitPar::GetDataBase() + "MINERvA/CC0pi/CCQE_Neutrino_CV_Result.txt" ); - fSettings.SetCovarInput( FitPar::GetDataBase() + "MINERvA/CC0pi/covar_2D.txt" ); - fSettings.SetMapInput( FitPar::GetDataBase() + "MINERvA/CC0pi/map_2D.txt" ); + fSettings.SetDataInput( FitPar::GetDataBase() + "MINERvA/CC0pi_ptpz_nu/data2D.txt"); + fSettings.SetCovarInput( FitPar::GetDataBase() + "MINERvA/CC0pi_ptpz_nu/covar.txt"); + fSettings.SetMapInput( FitPar::GetDataBase() + "MINERvA/CC0pi_ptpz_nu/map2D.txt" ); fSettings.DefineAllowedSpecies("numu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon - fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-37 / (fNEvents + 0.)) / this->TotalIntegratedFlux(); + // fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-37 / (fNEvents + 0.)) / this->TotalIntegratedFlux(); + fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38 / (fNEvents + 0.)) / this->TotalIntegratedFlux(); // Plot Setup ------------------------------------------------------- Double_t P_t[14] = {0,0.075,0.15,0.25,0.325,0.4,0.475,0.55,0.7,0.85,1.0,1.25,1.5,2.5}; Double_t P_z[13] = {1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,6.0,8.0,10.0,15.0,20.0}; - CreateDataHistogram(13, P_z, 14, P_t); + CreateDataHistogram(14, P_t, 13, P_z); + SetDataValuesFromTextFile( fSettings.GetDataInput() ); - ScaleData(1E-41); + // fDataHist->Scale(1.0, "width"); SetMapValuesFromText( fSettings.GetMapInput() ); - - SetCholDecompFromTextFile( fSettings.GetCovarInput() ); - ScaleCovar(1E-16); - + SetCovarFromTextFile( fSettings.GetCovarInput(), FitPar::Config().GetParI("CC0piNBINS") ); + StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, fMapHist, 1E-38); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; //******************************************************************** void MINERvA_CC0pi_XSec_2Dptpx_nu::FillEventVariables(FitEvent *event) { //******************************************************************** // Checking to see if there is a Muon if (event->NumFSParticle(13) == 0) return; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; //I Added this part Double_t px = Pmu.X()/1000; Double_t py = Pmu.Y()/1000; Double_t pz = Pmu.Z()/1000; Double_t pt = sqrt(px*px+py*py); -// Set Hist Variables - fYVar = pt; - fXVar = pz; + // Set Hist Variables + fYVar = pz; + fXVar = pt; return; }; //******************************************************************** bool MINERvA_CC0pi_XSec_2Dptpx_nu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCC0pi_MINERvAPTPZ(event, 14, EnuMin, EnuMax); }; diff --git a/src/MINERvA/MINERvA_CC1pi0_XSec_1D_nu.cxx b/src/MINERvA/MINERvA_CC1pi0_XSec_1D_nu.cxx new file mode 100644 index 0000000..594a2c9 --- /dev/null +++ b/src/MINERvA/MINERvA_CC1pi0_XSec_1D_nu.cxx @@ -0,0 +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)"; + 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_CC1pi0_XSec_1D_nu.h b/src/MINERvA/MINERvA_CC1pi0_XSec_1D_nu.h new file mode 100644 index 0000000..5247d84 --- /dev/null +++ b/src/MINERvA/MINERvA_CC1pi0_XSec_1D_nu.h @@ -0,0 +1,74 @@ +// 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 MINERVA_CC1PI0_XSEC_1D_NU_H_SEEN +#define MINERVA_CC1PI0_XSEC_1D_NU_H_SEEN + +#include "Measurement1D.h" + +// Implementation of 2017 MINERvA numu CC1pi0 +// arxiv:1708.03723v1 hep-ex +// c.wret14@imperial.ac.uk + +class MINERvA_CC1pi0_XSec_1D_nu : public Measurement1D { +public: + MINERvA_CC1pi0_XSec_1D_nu(nuiskey samplekey); + virtual ~MINERvA_CC1pi0_XSec_1D_nu() {}; + + void SetupDataSettings(); + void FillEventVariables(FitEvent *event); + bool isSignal(FitEvent *event); + + private: + int fDist; + + double WexpCut; + double ProtonCut; + + // The enums for the different distributions + // P.S. the order __IS__ important: after Wexp we require a proton and impose other cuts + enum DataDistribution { + // Pion kinetic energy + kTpi, + // Pion-neutrino angle + kth, + // Muon momentum + kpmu, + // Muon-neutrino angle + kthmu, + // True Q2 + kQ2, + // True Enu + kEnu, + // And the interesting distributions ^_^ + // Wexperimental + kWexp, + // p, pi0 invariant mass with Wexp < 1.8 + kPPi0Mass, + // p, pi0 invariant mass with Wexp < 1.4 + kPPi0MassDelta, + // Cos theta Adler angle + kCosAdler, + // Phi Adler angle + kPhiAdler + } CC1pi0_DataDistributions; + +}; + +#endif diff --git a/src/Reweight/CMakeLists.txt b/src/Reweight/CMakeLists.txt index 685133c..55b9fef 100644 --- a/src/Reweight/CMakeLists.txt +++ b/src/Reweight/CMakeLists.txt @@ -1,81 +1,83 @@ # 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 . ################################################################################ set(IMPLFILES GlobalDialList.cxx FitWeight.cxx WeightEngineBase.cxx NEUTWeightEngine.cxx NuWroWeightEngine.cxx GENIEWeightEngine.cxx WeightUtils.cxx SampleNormEngine.cxx LikelihoodWeightEngine.cxx SplineWeightEngine.cxx NUISANCESyst.cxx T2KWeightEngine.cxx NUISANCEWeightEngine.cxx NUISANCEWeightCalcs.cxx NIWGWeightEngine.cxx OscWeightEngine.cxx MINERvAWeightCalcs.cxx +weightRPA.h ) set(HEADERFILES GlobalDialList.h FitWeight.h WeightEngineBase.h NEUTWeightEngine.h NuWroWeightEngine.h GENIEWeightEngine.h WeightUtils.h SampleNormEngine.h LikelihoodWeightEngine.h SplineWeightEngine.h NUISANCESyst.h T2KWeightEngine.h NUISANCEWeightEngine.h NUISANCEWeightCalcs.h NIWGWeightEngine.h OscWeightEngine.h MINERvAWeightCalcs.h +weightRPA.h ) set(LIBNAME Reweight) if(CMAKE_BUILD_TYPE MATCHES DEBUG) add_library(${LIBNAME} STATIC ${IMPLFILES}) else(CMAKE_BUILD_TYPE MATCHES RELEASE) add_library(${LIBNAME} SHARED ${IMPLFILES}) endif() include_directories(${MINIMUM_INCLUDE_DIRECTORIES}) set_target_properties(${LIBNAME} PROPERTIES VERSION "${ExtFit_VERSION_MAJOR}.${ExtFit_VERSION_MINOR}.${ExtFit_VERSION_REVISION}") #set_target_properties(${LIBNAME} PROPERTIES LINK_FLAGS ${ROOT_LD_FLAGS}) if(DEFINED PROJECTWIDE_EXTRA_DEPENDENCIES) add_dependencies(${LIBNAME} ${PROJECTWIDE_EXTRA_DEPENDENCIES}) endif() install(TARGETS ${LIBNAME} DESTINATION lib) #Can uncomment this to install the headers... but is it really neccessary? install(FILES ${HEADERFILES} DESTINATION include) set(MODULETargets ${MODULETargets} ${LIBNAME} PARENT_SCOPE) diff --git a/src/Reweight/GENIEWeightEngine.cxx b/src/Reweight/GENIEWeightEngine.cxx index 4b4ceb1..8e0aab6 100644 --- a/src/Reweight/GENIEWeightEngine.cxx +++ b/src/Reweight/GENIEWeightEngine.cxx @@ -1,231 +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"); 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); - if (xsec_coh) - fGenieRW->AdoptWghtCalc("xsec_coh", new genie::rew::GReWeightNuXSecCOH); + 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 (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/MINERvAWeightCalcs.cxx b/src/Reweight/MINERvAWeightCalcs.cxx index ebd453a..00953a4 100644 --- a/src/Reweight/MINERvAWeightCalcs.cxx +++ b/src/Reweight/MINERvAWeightCalcs.cxx @@ -1,469 +1,554 @@ #ifdef __MINERVA_RW_ENABLED__ #ifdef __GENIE_ENABLED__ #include "MINERvAWeightCalcs.h" #include "BaseFitEvt.h" namespace nuisance { namespace reweight { //******************************************************* MINERvAReWeight_QE::MINERvAReWeight_QE() { //******************************************************* fTwk_NormCCQE = 0.0; fDef_NormCCQE = 1.0; fCur_NormCCQE = fDef_NormCCQE; } MINERvAReWeight_QE::~MINERvAReWeight_QE(){}; double MINERvAReWeight_QE::CalcWeight(BaseFitEvt* evt) { // Check GENIE if (evt->fType != kGENIE) return 1.0; // Extract the GENIE Record GHepRecord* ghep = static_cast(evt->genie_event->event); const Interaction* interaction = ghep->Summary(); const InitialState& init_state = interaction->InitState(); const ProcessInfo& proc_info = interaction->ProcInfo(); const Target& tgt = init_state.Tgt(); // If the event is not QE this Calc doesn't handle it if (!proc_info.IsQuasiElastic()) return 1.0; // WEIGHT CALCULATIONS ------------- double w = 1.0; // CCQE Dial if (!proc_info.IsWeakCC()) w *= fCur_NormCCQE; // Return Combined Weight return w; } void MINERvAReWeight_QE::SetDialValue(std::string name, double val) { SetDialValue(Reweight::ConvDial(name, kCUSTOM), val); } void MINERvAReWeight_QE::SetDialValue(int rwenum, double val) { // Check Handled int curenum = rwenum % 1000; if (!IsHandled(curenum)) return; // Set Values if (curenum == kMINERvARW_NormCCQE) { fTwk_NormCCQE = val; fCur_NormCCQE = fDef_NormCCQE + fTwk_NormCCQE; } // Define Tweaked fTweaked = ((fTwk_NormCCQE != 0.0)); } bool MINERvAReWeight_QE::IsHandled(int rwenum) { int curenum = rwenum % 1000; switch (curenum) { case kMINERvARW_NormCCQE: return true; default: return false; } } //******************************************************* MINERvAReWeight_MEC::MINERvAReWeight_MEC() { //******************************************************* fTwk_NormCCMEC = 0.0; fDef_NormCCMEC = 1.0; fCur_NormCCMEC = fDef_NormCCMEC; } MINERvAReWeight_MEC::~MINERvAReWeight_MEC(){}; double MINERvAReWeight_MEC::CalcWeight(BaseFitEvt* evt) { // Check GENIE if (evt->fType != kGENIE) return 1.0; // Extract the GENIE Record GHepRecord* ghep = static_cast(evt->genie_event->event); const Interaction* interaction = ghep->Summary(); const InitialState& init_state = interaction->InitState(); const ProcessInfo& proc_info = interaction->ProcInfo(); const Target& tgt = init_state.Tgt(); // If the event is not MEC this Calc doesn't handle it if (!proc_info.IsMEC()) return 1.0; // WEIGHT CALCULATIONS ------------- double w = 1.0; // CCMEC Dial if (!proc_info.IsWeakCC()) w *= fCur_NormCCMEC; // Return Combined Weight return w; } void MINERvAReWeight_MEC::SetDialValue(std::string name, double val) { SetDialValue(Reweight::ConvDial(name, kCUSTOM), val); } void MINERvAReWeight_MEC::SetDialValue(int rwenum, double val) { // Check Handled int curenum = rwenum % 1000; if (!IsHandled(curenum)) return; // Set Values if (curenum == kMINERvARW_NormCCMEC) { fTwk_NormCCMEC = val; fCur_NormCCMEC = fDef_NormCCMEC + fTwk_NormCCMEC; } // Define Tweaked fTweaked = ((fTwk_NormCCMEC != 0.0)); } bool MINERvAReWeight_MEC::IsHandled(int rwenum) { int curenum = rwenum % 1000; switch (curenum) { case kMINERvARW_NormCCMEC: return true; default: return false; } } //******************************************************* MINERvAReWeight_RES::MINERvAReWeight_RES() { //******************************************************* fTwk_NormCCRES = 0.0; fDef_NormCCRES = 1.0; fCur_NormCCRES = fDef_NormCCRES; } MINERvAReWeight_RES::~MINERvAReWeight_RES(){}; double MINERvAReWeight_RES::CalcWeight(BaseFitEvt* evt) { // std::cout << "Caculating RES" << std::endl; // Check GENIE if (evt->fType != kGENIE) return 1.0; // Extract the GENIE Record GHepRecord* ghep = static_cast(evt->genie_event->event); const Interaction* interaction = ghep->Summary(); const InitialState& init_state = interaction->InitState(); const ProcessInfo& proc_info = interaction->ProcInfo(); const Target& tgt = init_state.Tgt(); // If the event is not RES this Calc doesn't handle it if (!proc_info.IsResonant()) return 1.0; // WEIGHT CALCULATIONS ------------- double w = 1.0; // CCRES Dial if (proc_info.IsWeakCC()) w *= fCur_NormCCRES; // Return Combined Weight return w; } void MINERvAReWeight_RES::SetDialValue(std::string name, double val) { SetDialValue(Reweight::ConvDial(name, kCUSTOM), val); } void MINERvAReWeight_RES::SetDialValue(int rwenum, double val) { // Check Handled int curenum = rwenum % 1000; if (!IsHandled(curenum)) return; // Set Values if (curenum == kMINERvARW_NormCCRES) { fTwk_NormCCRES = val; fCur_NormCCRES = fDef_NormCCRES + fTwk_NormCCRES; } // Define Tweaked fTweaked = ((fTwk_NormCCRES != 0.0)); } bool MINERvAReWeight_RES::IsHandled(int rwenum) { int curenum = rwenum % 1000; switch (curenum) { case kMINERvARW_NormCCRES: return true; default: return false; } } //******************************************************* RikRPA::RikRPA() { //******************************************************* // - Syst : kMINERvA_RikRPA_ApplyRPA // - Type : Binary // - Limits : 0.0 (false) -> 1.0 (true) // - Default : 0.0 fApplyDial_RPACorrection = false; // - Syst : kMINERvA_RikRPA_LowQ2 // - Type : Absolute // - Limits : 1.0 -> 1.0 // - Default : 0.0 // - Frac Error : 100% fDefDial_RPALowQ2 = 0.0; fCurDial_RPALowQ2 = fDefDial_RPALowQ2; fErrDial_RPALowQ2 = 0.0; // - Syst : kMINERvA_RikRPA_HighQ2 // - Type : Absolute // - Limits : 1.0 -> 1.0 // - Default : 0.0 // - Frac Error : 100% fDefDial_RPAHighQ2 = 0.0; fCurDial_RPAHighQ2 = fDefDial_RPAHighQ2; fErrDial_RPAHighQ2 = 1.0; - fEventWeights = new double[5]; + + + // - Syst : kMINERvA_RikRESRPA_ApplyRPA + // - Type : Binary + // - Limits : 0.0 (false) -> 1.0 (true) + // - Default : 0.0 + fApplyDial_RESRPACorrection = false; + + // - Syst : kMINERvA_RikRESRPA_LowQ2 + // - Type : Absolute + // - Limits : 1.0 -> 1.0 + // - Default : 0.0 + // - Frac Error : 100% + fDefDial_RESRPALowQ2 = 0.0; + fCurDial_RESRPALowQ2 = fDefDial_RESRPALowQ2; + fErrDial_RESRPALowQ2 = 0.0; + // - Syst : kMINERvA_RikRESRPA_HighQ2 + // - Type : Absolute + // - Limits : 1.0 -> 1.0 + // - Default : 0.0 + // - Frac Error : 100% + fDefDial_RESRPAHighQ2 = 0.0; + fCurDial_RESRPAHighQ2 = fDefDial_RESRPAHighQ2; + fErrDial_RESRPAHighQ2 = 1.0; + + + // Setup Calculators + fEventWeights = new double[5]; for (size_t i = 0; i < kMaxCalculators; i++) { - // fRPACalculators[i] = NULL; + fRPACalculators[i] = NULL; } fTweaked = false; } RikRPA::~RikRPA() { - delete fEventWeights; + // delete fEventWeights; - for (size_t i = 0; i < kMaxCalculators; i++) { - // if (fRPACalculators[i]) delete fRPACalculators[i]; - // fRPACalculators[i] = NULL; - } + // for (size_t i = 0; i < kMaxCalculators; i++) { + // if (fRPACalculators[i]) delete fRPACalculators[i]; + // fRPACalculators[i] = NULL; + // } } double RikRPA::CalcWeight(BaseFitEvt* evt) { // LOG(FIT) << "Calculating RikRPA" << std::endl; // Return 1.0 if not tweaked if (!fTweaked) return 1.0; double w = 1.0; // Extract the GENIE Record GHepRecord* ghep = static_cast(evt->genie_event->event); const Interaction* interaction = ghep->Summary(); const InitialState& init_state = interaction->InitState(); const ProcessInfo& proc_info = interaction->ProcInfo(); // const Kinematics & kine = interaction->Kine(); // const XclsTag & xcls = interaction->ExclTag(); const Target& tgt = init_state.Tgt(); // If not QE return 1.0 // LOG(FIT) << "RikRPA : Event QE = " << proc_info.IsQuasiElastic() << // std::endl; if (!tgt.IsNucleus()) return 1.0; - if (!proc_info.IsQuasiElastic()) return 1.0; + if (!proc_info.IsQuasiElastic() && !proc_info.IsResonant()) return 1.0; // Extract Beam and Target PDG GHepParticle* neutrino = ghep->Probe(); int bpdg = neutrino->Pdg(); GHepParticle* target = ghep->Particle(1); assert(target); int tpdg = target->Pdg(); // Find the enum we need int calcenum = GetRPACalcEnum(bpdg, tpdg); if (calcenum == -1) return 1.0; // Check we have the RPA Calc setup for this enum // if not, set it up at that point - // if (!fRPACalculators[calcenum]) SetupRPACalculator(calcenum); - // weightRPA* rpacalc = fRPACalculators[calcenum]; - // if (!rpacalc) { - // THROW("Failed to grab the RPA Calculator : " << calcenum); - // } + if (!fRPACalculators[calcenum]) SetupRPACalculator(calcenum); + weightRPA* rpacalc = fRPACalculators[calcenum]; + if (!rpacalc) { + THROW("Failed to grab the RPA Calculator : " << calcenum); + } // Extract Q0-Q3 GHepParticle* fsl = ghep->FinalStatePrimaryLepton(); const TLorentzVector& k1 = *(neutrino->P4()); const TLorentzVector& k2 = *(fsl->P4()); double q0 = fabs((k1 - k2).E()); double q3 = fabs((k1 - k2).Vect().Mag()); + double Q2 = fabs((k1 - k2).Mag2()); - // Now use q0-q3 and RPA Calculator to fill fWeights - // LOG(FIT) << "Getting Weights = " << q0 << " " << q3 << std::endl; - // rpacalc->getWeight(q0, q3, fEventWeights); + // Quasielastic + if (proc_info.IsQuasiElastic()){ - // Apply Interpolation (for the time being simple linear) + // Now use q0-q3 and RPA Calculator to fill fWeights + rpacalc->getWeight(q0, q3, fEventWeights); - // Syst Application : kMINERvA_RikRPA_ApplyRPA - if (fApplyDial_RPACorrection) { - w *= fEventWeights[0]; // CV - } + if (fApplyDial_RPACorrection) { + w *= fEventWeights[0]; // CV + } - LOG(FIT) << " fCurDial_RPALowQ2 = " << fCurDial_RPALowQ2 - << " fCurDial_RPAHighQ2 = " << fCurDial_RPAHighQ2 << " Weights " - << fEventWeights[0] << " " << fEventWeights[1] << " " - << fEventWeights[2] << " " << fEventWeights[3] << " " - << fEventWeights[4] << std::endl; - - // Syst Application : kMINERvA_RikRPA_LowQ2 - if (fabs(fCurDial_RPALowQ2) > 0.0) { - double interpw = fEventWeights[0]; - - if (fCurDial_RPALowQ2 > 0.0) { - interpw = fEventWeights[0] - (fEventWeights[0] - fEventWeights[1]) * - fCurDial_RPALowQ2; // WLow+ } else if - } else if (fCurDial_RPALowQ2 < 0.0) { - interpw = fEventWeights[0] - (fEventWeights[2] - fEventWeights[0]) * - fCurDial_RPALowQ2; // WLow- + // Syst Application : kMINERvA_RikRPA_LowQ2 + if (fabs(fCurDial_RPALowQ2) > 0.0) { + double interpw = fEventWeights[0]; + + if (fCurDial_RPALowQ2 > 0.0 && Q2 < 2.0) { + interpw = fEventWeights[0] - (fEventWeights[0] - fEventWeights[1]) * + fCurDial_RPALowQ2; // WLow+ } else if + } else if (fCurDial_RPALowQ2 < 0.0 && Q2 < 2.0) { + interpw = fEventWeights[0] - (fEventWeights[2] - fEventWeights[0]) * + fCurDial_RPALowQ2; // WLow- + } + w *= interpw / fEventWeights[0]; // Div by CV again + } + + // Syst Application : kMINERvA_RikRPA_HighQ2 + if (fabs(fCurDial_RPAHighQ2) > 0.0) { + double interpw = fEventWeights[0]; + + if (fCurDial_RPAHighQ2 > 0.0) { + interpw = fEventWeights[0] - (fEventWeights[0] - fEventWeights[3]) * + fCurDial_RPAHighQ2; // WHigh+ + + } else if (fCurDial_RPAHighQ2 < 0.0) { + interpw = fEventWeights[0] - (fEventWeights[4] - fEventWeights[0]) * + fCurDial_RPAHighQ2; // WHigh- + } + w *= interpw / fEventWeights[0]; // Div by CV again } - w *= interpw / fEventWeights[0]; // Div by CV again } - // Syst Application : kMINERvA_RikRPA_HighQ2 - if (fabs(fCurDial_RPAHighQ2) > 0.0) { - double interpw = fEventWeights[0]; - if (fCurDial_RPAHighQ2 > 0.0) { - interpw = fEventWeights[0] - (fEventWeights[0] - fEventWeights[3]) * - fCurDial_RPAHighQ2; // WHigh+ } else - if (fCurDial_RPAHighQ2 < 0.0) { + // Resonant Events + if (proc_info.IsResonant()){ + + // Now use Q2 and RESRPA Calculator to fill fWeights + double CV = rpacalc->getWeight(Q2); + + if (fApplyDial_RESRPACorrection) { + w *= CV; //fEventWeights[0]; // CVa + } + + /* + // Syst Application : kMINERvA_RikRESRPA_LowQ2 + if (fabs(fCurDial_RESRPAHighQ2) > 0.0) { + double interpw = fEventWeights[0]; + + if (fCurDial_RESRPAHighQ2 > 0.0) { + interpw = fEventWeights[0] - (fEventWeights[0] - fEventWeights[3]) * + fCurDial_RESRPAHighQ2; // WHigh+ + + } else if (fCurDial_RESRPAHighQ2 < 0.0) { + interpw = fEventWeights[0] - (fEventWeights[4] - fEventWeights[0]) * + fCurDial_RESRPAHighQ2; // WHigh- + } + w *= interpw / fEventWeights[0]; // Div by CV again + } + + // Syst Application : kMINERvA_RikRESRPA_HighQ2 + if (fabs(fCurDial_RESRPAHighQ2) > 0.0) { + double interpw = fEventWeights[0]; + + if (fCurDial_RESRPAHighQ2 > 0.0) { + interpw = fEventWeights[0] - (fEventWeights[0] - fEventWeights[3]) * + fCurDial_RESRPAHighQ2; // WHigh+ + + } else if (fCurDial_RESRPAHighQ2 < 0.0) { interpw = fEventWeights[0] - (fEventWeights[4] - fEventWeights[0]) * - fCurDial_RPAHighQ2; // WHigh- + fCurDial_RESRPAHighQ2; // WHigh- } w *= interpw / fEventWeights[0]; // Div by CV again } + */ } // LOG(FIT) << "RPA Weight = " << w << std::endl; return w; } // namespace reweight void RikRPA::SetDialValue(std::string name, double val) { SetDialValue(Reweight::ConvDial(name, kCUSTOM), val); } void RikRPA::SetDialValue(int rwenum, double val) { int curenum = rwenum % 1000; // Check Handled if (!IsHandled(curenum)) return; - if (curenum == kMINERvARW_RikRPA_ApplyRPA) - fApplyDial_RPACorrection = (val > 0.5); - if (curenum == kMINERvARW_RikRPA_LowQ2) fCurDial_RPALowQ2 = val; - if (curenum == kMINERvARW_RikRPA_HighQ2) fCurDial_RPAHighQ2 = val; + if (curenum == kMINERvARW_RikRPA_ApplyRPA) fApplyDial_RPACorrection = (val > 0.5); + if (curenum == kMINERvARW_RikRPA_LowQ2) fCurDial_RPALowQ2 = val; + if (curenum == kMINERvARW_RikRPA_HighQ2) fCurDial_RPAHighQ2 = val; + if (curenum == kMINERvARW_RikRESRPA_ApplyRPA) fApplyDial_RESRPACorrection = (val > 0.5); + if (curenum == kMINERvARW_RikRESRPA_LowQ2) fCurDial_RESRPALowQ2 = val; + if (curenum == kMINERvARW_RikRESRPA_HighQ2) fCurDial_RESRPAHighQ2 = val; + // Assign flag to say stuff has changed fTweaked = (fApplyDial_RPACorrection || fabs(fCurDial_RPAHighQ2 - fDefDial_RPAHighQ2) > 0.0 || - fabs(fCurDial_RPALowQ2 - fDefDial_RPALowQ2) > 0.0); + fabs(fCurDial_RPALowQ2 - fDefDial_RPALowQ2) > 0.0 || + fApplyDial_RESRPACorrection || + fabs(fCurDial_RESRPAHighQ2 - fDefDial_RESRPAHighQ2) > 0.0 || + fabs(fCurDial_RESRPALowQ2 - fDefDial_RESRPALowQ2) > 0.0); + } bool RikRPA::IsHandled(int rwenum) { int curenum = rwenum % 1000; switch (curenum) { - case kMINERvARW_RikRPA_ApplyRPA: - return true; - case kMINERvARW_RikRPA_LowQ2: - return true; - case kMINERvARW_RikRPA_HighQ2: - return true; - default: - return false; + case kMINERvARW_RikRESRPA_ApplyRPA: + return true; + case kMINERvARW_RikRESRPA_LowQ2: + return true; + case kMINERvARW_RikRESRPA_HighQ2: + return true; + case kMINERvARW_RikRPA_ApplyRPA: + return true; + case kMINERvARW_RikRPA_LowQ2: + return true; + case kMINERvARW_RikRPA_HighQ2: + return true; + default: + return false; } } void RikRPA::SetupRPACalculator(int calcenum) { std::string rwdir = FitPar::GetDataBase() + "/reweight/MINERvA/RikRPA/"; std::string fidir = ""; switch (calcenum) { case kNuMuC12: fidir = "outNievesRPAratio-nu12C-20GeV-20170202.root"; break; case kNuMuO16: fidir = "outNievesRPAratio-nu16O-20GeV-20170202.root"; break; case kNuMuAr40: fidir = "outNievesRPAratio-nu40Ar-20GeV-20170202.root"; break; case kNuMuCa40: fidir = "outNievesRPAratio-nu40Ca-20GeV-20170202.root"; break; case kNuMuFe56: fidir = "outNievesRPAratio-nu56Fe-20GeV-20170202.root"; break; case kNuMuBarC12: fidir = "outNievesRPAratio-anu12C-20GeV-20170202.root"; break; case kNuMuBarO16: fidir = "outNievesRPAratio-anu16O-20GeV-20170202.root"; break; case kNuMuBarAr40: fidir = "outNievesRPAratio-anu40Ar-20GeV-20170202.root"; break; case kNuMuBarCa40: fidir = "outNievesRPAratio-anu40Ca-20GeV-20170202.root"; break; case kNuMuBarFe56: fidir = "outNievesRPAratio-anu56Fe-20GeV-20170202.root"; break; } LOG(FIT) << "Loading RPA CALC : " << fidir << std::endl; TDirectory* olddir = gDirectory; - // fRPACalculators[calcenum] = new weightRPA(rwdir + "/" + fidir); + std::cout << "***********************************************" << std::endl; + std::cout << "Loading a new weightRPA calculator" << std::endl; + std::cout << "Authors: Rik Gran, Heidi Schellman" << std::endl; + std::cout << "Citation: arXiv:1705.02932 [hep-ex]" << std::endl; + std::cout << "***********************************************" << std::endl; + + fRPACalculators[calcenum] = new weightRPA(rwdir + "/" + fidir); olddir->cd(); return; } int RikRPA::GetRPACalcEnum(int bpdg, int tpdg) { if (bpdg == 14 && tpdg == 1000060120) return kNuMuC12; else if (bpdg == 14 && tpdg == 1000080160) return kNuMuO16; else if (bpdg == 14 && tpdg == 1000180400) return kNuMuAr40; else if (bpdg == 14 && tpdg == 1000200400) return kNuMuCa40; else if (bpdg == 14 && tpdg == 1000280560) return kNuMuFe56; else if (bpdg == -14 && tpdg == 1000060120) return kNuMuBarC12; else if (bpdg == -14 && tpdg == 1000080160) return kNuMuBarO16; else if (bpdg == -14 && tpdg == 1000180400) return kNuMuBarAr40; else if (bpdg == -14 && tpdg == 1000200400) return kNuMuBarCa40; else if (bpdg == -14 && tpdg == 1000280560) return kNuMuBarFe56; else { ERROR(WRN, "Unknown beam and target combination for RPA Calcs! " << bpdg << " " << tpdg); } return -1; } } // namespace reweight } // namespace nuisance #endif #endif diff --git a/src/Reweight/MINERvAWeightCalcs.h b/src/Reweight/MINERvAWeightCalcs.h index d3ec9a1..629b6ec 100644 --- a/src/Reweight/MINERvAWeightCalcs.h +++ b/src/Reweight/MINERvAWeightCalcs.h @@ -1,136 +1,148 @@ #ifndef MINERVA_WEIGHT_CALCS #define MINERVA_WEIGHT_CALCS #include #ifdef __MINERVA_RW_ENABLED__ #ifdef __GENIE_ENABLED__ #include "Conventions/Units.h" #include "EVGCore/EventRecord.h" #include "FitEvent.h" -#include "FitParameters.h" + #include "GHEP/GHepParticle.h" #include "GHEP/GHepRecord.h" #include "GHEP/GHepUtils.h" #include "GeneralUtils.h" #include "NUISANCESyst.h" #include "NUISANCEWeightCalcs.h" #include "Ntuple/NtpMCEventRecord.h" #include "PDG/PDGUtils.h" #include "WeightUtils.h" -// #include "weightRPA.h" +#include "weightRPA.h" using namespace genie; class BaseFitEvt; namespace nuisance { namespace reweight { // MEC Dials class MINERvAReWeight_QE : public NUISANCEWeightCalc { public: MINERvAReWeight_QE(); virtual ~MINERvAReWeight_QE(); double CalcWeight(BaseFitEvt* evt); void SetDialValue(std::string name, double val); void SetDialValue(int rwenum, double val); bool IsHandled(int rwenum); double fTwk_NormCCQE; double fCur_NormCCQE; double fDef_NormCCQE; bool fTweaked; }; // MEC Dials class MINERvAReWeight_MEC : public NUISANCEWeightCalc { public: MINERvAReWeight_MEC(); virtual ~MINERvAReWeight_MEC(); double CalcWeight(BaseFitEvt* evt); void SetDialValue(std::string name, double val); void SetDialValue(int rwenum, double val); bool IsHandled(int rwenum); double fTwk_NormCCMEC; double fCur_NormCCMEC; double fDef_NormCCMEC; bool fTweaked; }; // RES Dials class MINERvAReWeight_RES : public NUISANCEWeightCalc { public: MINERvAReWeight_RES(); virtual ~MINERvAReWeight_RES(); double CalcWeight(BaseFitEvt* evt); void SetDialValue(std::string name, double val); void SetDialValue(int rwenum, double val); bool IsHandled(int rwenum); double fTwk_NormCCRES; double fCur_NormCCRES; double fDef_NormCCRES; bool fTweaked; }; /// RPA Weight Calculator that applies RPA systematics /// to GENIE events. GENIE EVENTS ONLY! class RikRPA : public NUISANCEWeightCalc { public: RikRPA(); ~RikRPA(); double CalcWeight(BaseFitEvt* evt); void SetDialValue(std::string name, double val); void SetDialValue(int rwenum, double val); bool IsHandled(int rwenum); void SetupRPACalculator(int calcenum); int GetRPACalcEnum(int bpdg, int tpdg); bool fApplyDial_RPACorrection; double fTwkDial_RPALowQ2; double fDefDial_RPALowQ2; double fCurDial_RPALowQ2; double fErrDial_RPALowQ2; double fTwkDial_RPAHighQ2; double fDefDial_RPAHighQ2; double fCurDial_RPAHighQ2; double fErrDial_RPAHighQ2; + + bool fApplyDial_RESRPACorrection; + + double fTwkDial_RESRPALowQ2; + double fDefDial_RESRPALowQ2; + double fCurDial_RESRPALowQ2; + double fErrDial_RESRPALowQ2; + + double fTwkDial_RESRPAHighQ2; + double fDefDial_RESRPAHighQ2; + double fCurDial_RESRPAHighQ2; + double fErrDial_RESRPAHighQ2; double* fEventWeights; bool fTweaked; const static int kMaxCalculators = 10; enum rpacalcenums { kNuMuC12, kNuMuO16, kNuMuAr40, kNuMuCa40, kNuMuFe56, kNuMuBarC12, kNuMuBarO16, kNuMuBarAr40, kNuMuBarCa40, kNuMuBarFe56 }; - // weightRPA* fRPACalculators[kMaxCalculators]; + weightRPA* fRPACalculators[kMaxCalculators]; }; }; // namespace reweight }; // namespace nuisance #endif // __GENIE_ENABLED__ #endif //__MINERVA_RW_ENABLED__ #endif diff --git a/src/Reweight/NUISANCESyst.h b/src/Reweight/NUISANCESyst.h index 3fec5a7..dfc84e2 100644 --- a/src/Reweight/NUISANCESyst.h +++ b/src/Reweight/NUISANCESyst.h @@ -1,58 +1,62 @@ #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_RikRPA_LowQ2, + kMINERvARW_RikRPA_HighQ2, + + kMINERvARW_RikRESRPA_ApplyRPA, + kMINERvARW_RikRESRPA_LowQ2, + kMINERvARW_RikRESRPA_HighQ2, kNUISANCEDial_LAST }; int ConvertNUISANCEDial(std::string type); std::string ConvNUISANCEDial(int type); }; #endif diff --git a/src/Reweight/NUISANCEWeightCalcs.h b/src/Reweight/NUISANCEWeightCalcs.h index 95fa64b..3814d67 100644 --- a/src/Reweight/NUISANCEWeightCalcs.h +++ b/src/Reweight/NUISANCEWeightCalcs.h @@ -1,100 +1,100 @@ #ifndef NUISANCE_WEIGHT_CALCS #define NUISANCE_WEIGHT_CALCS #include "FitEvent.h" #include "GeneralUtils.h" #include "BaseFitEvt.h" #include "WeightUtils.h" #include "NUISANCESyst.h" -#include "FitParameters.h" + using namespace Reweight; 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 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/WeightUtils.h b/src/Reweight/WeightUtils.h index c2e35ef..52cf634 100644 --- a/src/Reweight/WeightUtils.h +++ b/src/Reweight/WeightUtils.h @@ -1,144 +1,144 @@ #ifndef WEIGHTUTILS_H #define WEIGHTUTILS_H #include "FitEvent.h" #include "FitLogger.h" -#include "FitParameters.h" + #include "TF1.h" #ifdef __T2KREW_ENABLED__ #include "T2KGenieReWeight.h" #include "T2KNIWGReWeight.h" #include "T2KNIWGUtils.h" #include "T2KNeutReWeight.h" #include "T2KNeutUtils.h" #include "T2KReWeight.h" using namespace t2krew; #endif #ifdef __NIWG_ENABLED__ #include "NIWGReWeight.h" #include "NIWGReWeight1piAngle.h" #include "NIWGReWeight2010a.h" #include "NIWGReWeight2012a.h" #include "NIWGReWeight2014a.h" #include "NIWGReWeightDeltaMass.h" #include "NIWGReWeightEffectiveRPA.h" #include "NIWGReWeightHadronMultSwitch.h" #include "NIWGReWeightMEC.h" #include "NIWGReWeightPiMult.h" #include "NIWGReWeightProtonFSIbug.h" #include "NIWGReWeightRPA.h" #include "NIWGReWeightSpectralFunc.h" #include "NIWGReWeightSplineEnu.h" #include "NIWGSyst.h" #include "NIWGSystUncertainty.h" #endif #ifdef __NEUT_ENABLED__ #include "NReWeight.h" #include "NReWeightCasc.h" #include "NReWeightNuXSecCCQE.h" #include "NReWeightNuXSecCCRES.h" #include "NReWeightNuXSecCOH.h" #include "NReWeightNuXSecDIS.h" #include "NReWeightNuXSecNC.h" #include "NReWeightNuXSecNCEL.h" #include "NReWeightNuXSecNCRES.h" #include "NReWeightNuXSecRES.h" #include "NReWeightNuclPiless.h" #include "NSyst.h" #include "NSystUncertainty.h" #include "neutpart.h" #include "neutvect.h" #endif #ifdef __NUWRO_ENABLED__ #include "event1.h" #endif #ifdef __NUWRO_REWEIGHT_ENABLED__ #include "NuwroReWeight.h" #include "NuwroReWeight_FlagNorm.h" #include "NuwroReWeight_QEL.h" #include "NuwroReWeight_SPP.h" #include "NuwroSyst.h" #include "NuwroSystUncertainty.h" #endif #ifdef __GENIE_ENABLED__ #include "EVGCore/EventRecord.h" #include "EVGCore/EventRecord.h" #include "GHEP/GHepRecord.h" #include "GSyst.h" #include "GSystUncertainty.h" #include "Ntuple/NtpMCEventRecord.h" #include "ReWeight/GReWeight.h" #include "ReWeight/GReWeightAGKY.h" #include "ReWeight/GReWeightDISNuclMod.h" #include "ReWeight/GReWeightFGM.h" #include "ReWeight/GReWeightFZone.h" #include "ReWeight/GReWeightINuke.h" #include "ReWeight/GReWeightNonResonanceBkg.h" #include "ReWeight/GReWeightNuXSecCCQE.h" #include "ReWeight/GReWeightNuXSecCCQEvec.h" #include "ReWeight/GReWeightNuXSecCCRES.h" #include "ReWeight/GReWeightNuXSecCOH.h" #include "ReWeight/GReWeightNuXSecDIS.h" #include "ReWeight/GReWeightNuXSecNC.h" #include "ReWeight/GReWeightNuXSecNCEL.h" #include "ReWeight/GReWeightNuXSecNCRES.h" #include "ReWeight/GReWeightResonanceDecay.h" using namespace genie; using namespace genie::rew; #endif #include "GlobalDialList.h" #include "NUISANCESyst.h" enum extra_reweight_types { kOSCILLATION = kLast_generator_event_type }; namespace FitBase { TF1 GetRWConvFunction(std::string type, std::string name); std::string GetRWUnits(std::string type, std::string name); double RWSigmaToFrac(std::string type, std::string name, double val); double RWSigmaToAbs(std::string type, std::string name, double val); double RWAbsToSigma(std::string type, std::string name, double val); double RWFracToSigma(std::string type, std::string name, double val); int ConvDialType(std::string type); std::string ConvDialType(int type); int GetDialEnum(std::string type, std::string name); int GetDialEnum(int type, std::string name); static std::map gNormEnums; static std::map gLikeWeightEnums; static std::map gSplineParameterEnums; } namespace Reweight { int ConvDial(std::string name, std::string type, bool exceptions = false); int ConvDial(std::string name, int type, bool exceptions = false); std::string ConvDial(int nuisenum); int ConvDialType(std::string type); std::string ConvDialType(int type); int NEUTEnumFromName(std::string name); int NIWGEnumFromName(std::string name); int NUWROEnumFromName(std::string name); int T2KEnumFromName(std::string name); int GENIEEnumFromName(std::string name); int CustomEnumFromName(std::string name); int NUISANCEEnumFromName(std::string name, int type); int OscillationEnumFromName(std::string name); static const int kNoDialFound = -1; static const int kNoTypeFound = -2; static const int kGeneratorNotBuilt = -3; } #endif diff --git a/src/Reweight/weightRPA.h b/src/Reweight/weightRPA.h new file mode 100644 index 0000000..6f969fd --- /dev/null +++ b/src/Reweight/weightRPA.h @@ -0,0 +1,414 @@ +#ifndef weightRPA_h +#define weightRPA_h + +#include //ifstream +#include //cout + +#include +#include +#include +#include +#include "math.h" +#include "assert.h" +//For Compatibility with ROOT compiler +//uncomment the following: +//#define ROOT + +/*! + * Code example to extract the RPA effect central weight + * and its uncertainties from the prepared files. + * Heidi Schellman (Oregon State) and Rik Gran (Minnesota Duluth) + * for use in MINERvA experiment analysis + * must compile with the ROOT libraries + * g++ `root-config --glibs --cflags` -O3 weightRPAtest.cxx -o weightRPA + + + * The underlying model is from the IFIC Valencia group + * see (public) minerva docdb:12688 for the full physics discussion + + */ + + +// NOTE UNITS ARE GEV in the calculation +// make sure you convert MeV to GeV before calling these functions + + +// Class for getting RPA paramaters inputs from a given file +// Includes methods that return all five RPA weights at once +// (is the most cpu efficient way to get them) +// Or return just the central value +// (skipping the uncertainties code completely if only cv wanted) +// Or return each CV and uncertainty one at a time +// (is the least cpu efficient, repeats some calculations 5 times) + +class weightRPA { +public: + //Constructor: Read in params from a filename + weightRPA(const TString f) { read(f); } //Read in params from file + + TString filename; + TFile* fRPAratio; + TH2D *hRPArelratio; + TH2D *hRPAnonrelratio; + TH1D *hQ2relratio; + TH1D *hQ2nonrelratio; + TArrayD *TADrpapolyrel; + Double_t *rpapolyrel ; + TArrayD *TADrpapolynonrel; + Double_t *rpapolynonrel; + static const int CENTRAL=0; + static const int LOWQ2 = 1; + static const int HIGHQ2 = 2; + + // true to take from histogram, false use parameterization + static const bool Q2histORparam = true; + + // MINERvA holds kinematics in MeV, but all these functions require GeV + // So make sure you pass them in GeV. + inline double getWeight(const double mc_q0, const double mc_q3, double * weights); //in GeV + inline double getWeight(const double mc_q0, const double mc_q3); //in GeV + inline double getWeight(const double mc_q0, const double mc_q3, int type, int sign); //in GeV + inline double getWeight(const double Q2); //in GeV^2 + inline double getWeightLowQ2(const double mc_q0, const double mc_q3, const int sign); + inline double getWeightHighQ2(const double mc_q0, const double mc_q3, const int sign); + inline double getWeightQ2(const double mc_Q2, const bool relORnonrel=true); + //Initializer + inline void read(const TString f); + + // q0 and q3 in GeV, type = 1 for low Q2, 2 for high Q2, 0 for central + //double getWeightInternal(const double mc_q0, const double mc_q3,int type, int sign); + + private: + inline double getWeightInternal(const double mc_Q2); + + inline double getWeightInternal(const double mc_q0, const double mc_q3, const int type, const int sign); + inline double getWeightInternal(const double mc_q0, const double mc_q3, double *weights=0); + inline double getWeightQ2parameterization(const double mc_Q2, const bool relORnonrel); + inline double getWeightQ2fromhistogram(const double mc_Q2, const bool relORnonrel); + + +}; + +void weightRPA::read(const TString f) +//Read in the params doubles from a file +//argument: valid filename +{ + fRPAratio = TFile::Open(f,"READONLY"); + if (fRPAratio){ + hRPArelratio = (TH2D*)fRPAratio->Get("hrelratio"); + hRPAnonrelratio = (TH2D*)fRPAratio->Get("hnonrelratio"); + hQ2relratio = (TH1D*)fRPAratio->Get("hQ2relratio"); + hQ2nonrelratio = (TH1D*)fRPAratio->Get("hQ2nonrelratio"); + TADrpapolyrel = (TArrayD*)fRPAratio->Get("rpapolyrel"); + rpapolyrel = TADrpapolyrel->GetArray(); + TADrpapolynonrel = (TArrayD*)fRPAratio->Get("rpapolynonrel"); + rpapolynonrel = TADrpapolynonrel->GetArray(); + hRPArelratio->Print(); + std::cout << "have read in ratios from file " << f <= gevlimit) q0bin = rpamevlimit - 1; + if(mc_q3 >= gevlimit) q3bin = rpamevlimit - 1; + + // Nieves does not calculate anything below binding energy. + // I don't know what GENIE does, but lets be soft about this. + // Two things lurking here at once. + // One, we are taking out a 10 MeV offset between GENIE and Valencia. + // Second, we are protecting against being asked for a weight that is too low in q0. + // It actually shouldn't happen for real GENIE events, + // but this protection does something that doesn't suck, just in case. + // you would see the artifact in a plot for sure, but better than writing 1.0. + Int_t q0offsetValenciaGENIE = 10; + if(mc_q0 < 0.018) q0bin = 18+q0offsetValenciaGENIE; + Double_t thisrwtemp = hRPArelratio->GetBinContent(q3bin,q0bin-q0offsetValenciaGENIE); + + // now trap bogus entries. Not sure why they happen, but set to 1.0 not 0.0 + if(thisrwtemp <= 0.001)thisrwtemp = 1.0; + + // events in genie but not in valencia should get a weight + // related to a similar q0 from the bulk distribution. + if(mc_q0 < 0.15 && thisrwtemp > 0.9){ + thisrwtemp = hRPArelratio->GetBinContent(q3bin+150, q0bin-q0offsetValenciaGENIE); + } + + + + //Double_t *mypoly; + //mypoly = rpapoly; + + if(Q2gev >= 9.0){ + thisrwtemp = 1.0; + } + else if(Q2gev > 3.0) { + // hiding option, use the Q2 parameterization everywhere + // } else if(Q2gev > 3.0 || rwRPAQ2) { + // turn rwRPAQ2 all the way on to override the 2D histogram + // illustrates the old-style Q2 suppression many folks still use. + + thisrwtemp = getWeightQ2(Q2gev,true); + + // double powerQ2 = 1.0; + //thisrwtemp = 0.0; + //for(int ii=0; ii<10; ii++){ + // thisrwtemp += rpapoly[ii]*powerQ2; + // powerQ2 *= Q2gev; + //} + //std::cout << "test temp " << thisrwtemp << " " << rpamypoly[2] << std::endl; + } + + if(!(thisrwtemp >= 0.001 && thisrwtemp <= 2.0))thisrwtemp = 1.0; + + // hiding option, turn off the enhancement. + //if(rwoffSRC && thisrwtemp > 1.0)thisrwtemp = 1.0; + + if (0 == weights) return thisrwtemp; + // if this was called without passing an array, + // the user didn't want us to calculate the +/- 1-sigma bounds + // so the above line returned before even trying. + + weights[0] = thisrwtemp; + + //if (type == 0) return thisrwtemp; + + //if (type == 1) { + // Construct the error bands on the low Q2 suppression. + // Double_t thisrwSupP1 = 1.0; + // Double_t thisrwSupM1 = 1.0; + + if( thisrwtemp < 1.0){ + // make the suppression stronger or weaker to muon capture uncertainty + // rwRPAonesig is either +1 or -1, which is 0.25 (25%). + // possible to be re-written to produce 2 and 3 sigma. + + weights[1] = thisrwtemp + 1.0 * (0.25)*(1.0 - thisrwtemp); + weights[2] = thisrwtemp - 1.0 * (0.25)*(1.0 - thisrwtemp); + + + + } + else{ + weights[1] = thisrwtemp; + weights[2] = thisrwtemp; + } + + //std::cout << "check " << thisrwtemp << " " << weights[1] << " " << weights[2] << std::endl; + + + + + // Construct the rest of the error bands on the low Q2 suppression. + // this involves getting the weight from the non-relativistic ratio + + //if (type == 2){ + + Double_t thisrwEnhP1 = 1.0; + Double_t thisrwEnhM1 = 1.0; + + // make enhancement stronger or weaker to Federico Sanchez uncertainty + // this does NOT mean two sigma, its overloading the option. + Double_t thisrwextreme = hRPAnonrelratio->GetBinContent(q3bin,q0bin-q0offsetValenciaGENIE); + // now trap bogus entries. Not sure why they happen, but set to 1.0 not 0.0 + if(thisrwextreme <= 0.001)thisrwextreme = 1.0; + + if(mc_q0 < 0.15 && thisrwextreme > 0.9){ + thisrwextreme = hRPAnonrelratio->GetBinContent(q3bin+150, q0bin-q0offsetValenciaGENIE); + } + + //std::cout << "ext " << thisrwextreme << " " << thisrwtemp << std::endl; + + // get the same for the Q2 dependent thing, + // but from the nonrelativistic polynomial + + if(Q2gev >= 9.0){ + thisrwextreme = 1.0; + } + else if(Q2gev > 3.0 ) { + thisrwextreme = getWeightQ2(Q2gev,false); + //double powerQ2 = 1.0; + //thisrwextreme = 0.0; + //for(int ii=0; ii<10; ii++){ + // thisrwextreme += rpapolynonrel[ii]*powerQ2; + // powerQ2 *= Q2gev; + //} + //std::cout << "test extreme " << thisrwextreme << " " << mypolynonrel[2] << std::endl; + } + + if(!(thisrwextreme >= 0.001 && thisrwextreme <= 2.0))thisrwextreme = 1.0; + + //std::cout << "test extreme " << Q2gev << " " << thisrwextreme << " " << thisrwtemp << std::endl; + + Double_t RelToNonRel = 0.6; + + // based on some distance between central value and extreme + thisrwEnhP1 = thisrwtemp + RelToNonRel * (thisrwextreme-thisrwtemp); + Double_t thisrwEnhP1max = thisrwextreme; + + if(Q2gev < 0.9)thisrwEnhP1 += 1.5*(0.9 - Q2gev)*(thisrwEnhP1max - thisrwEnhP1); + // sanity check, don't let the upper error bound go above the nonrel limit. + if(thisrwEnhP1 > thisrwEnhP1max)thisrwEnhP1 = thisrwEnhP1max; + // don't let positive error bound be closer than 3% above the central value + // will happen at very high Q2 and very close to Q2 = 0 + if(thisrwEnhP1 < thisrwtemp + 0.03)thisrwEnhP1 = thisrwtemp + 0.03; + + thisrwEnhM1 = thisrwtemp - RelToNonRel * (thisrwextreme-thisrwtemp); + // don't let negative error bound be closer than 3% below the central value + if(thisrwEnhM1 > thisrwtemp - 0.03)thisrwEnhM1 = thisrwtemp - 0.03; + // even still, don't let the lower error bound go below 1.0 at high-ish Q2 + if(Q2gev > 1.0 && thisrwEnhM1 < 1.0)thisrwEnhM1 = 1.0; + + // whew. so now return the main weight + // and return the array of all five weights in some array + // thisrwtemp, thisrwSupP1, thisrwSupM1, thisrwEnhP1, thisrwEnhM1 + + //if (sign == 1) return thisrwEnhP1; + //if (sign == -1) return thisrwEnhM1; + + weights[3] = thisrwEnhP1; + weights[4] = thisrwEnhM1; + + // still return the central value + return thisrwtemp; + +} + + +double weightRPA::getWeight(const double mc_q0, const double mc_q3){ + + return getWeightInternal(mc_q0, mc_q3); + +} + +double weightRPA::getWeight(const double mc_q0, const double mc_q3, double *weights){ + + return getWeightInternal(mc_q0, mc_q3, weights); + +} + +double weightRPA::getWeight(const double mc_q0, const double mc_q3, int type, int sign){ + + return getWeightInternal(mc_q0, mc_q3, type, sign); + +} + +double weightRPA::getWeight(const double mc_Q2){ + + return getWeightQ2(mc_Q2); + +} + +double weightRPA::getWeightInternal(const double mc_q0, const double mc_q3, int type, int sign){ + + double weights[5] = {1., 1., 1., 1., 1.}; + double cv = getWeightInternal(mc_q0, mc_q3, weights); + + if(type==0)return cv; + else if(type==weightRPA::LOWQ2 && sign == 1)return weights[1]; + else if(type==weightRPA::LOWQ2 && sign == -1)return weights[2]; + else if(type==weightRPA::HIGHQ2 && sign == 1)return weights[3]; + else if(type==weightRPA::HIGHQ2 && sign == -1)return weights[4]; + //else { + // // should never happen? Bork ? + // return cv; //? + //} + + return cv; +} + +double weightRPA::getWeightQ2(const double mc_Q2, const bool relORnonrel){ + + if(mc_Q2 < 0.0)return 1.0; // this is Q2 actually, not sure hw + if(mc_Q2 > 9.0)return 1.0; + + // this function needs to know two options. + // does user want rel (cv) or nonrel + // does user want to use the histogram or parameterization + + if(Q2histORparam)return getWeightQ2fromhistogram(mc_Q2, relORnonrel); + else return getWeightQ2parameterization(mc_Q2, relORnonrel); + +} + +double weightRPA::getWeightQ2parameterization(const double mc_Q2, const bool relORnonrel){ + + if(mc_Q2 < 0.0)return 1.0; + if(mc_Q2 > 9.0)return 1.0; + + // this one returns just the polynomial Q2 version + // for special tests. Poor answer for baseline MINERvA QE events. + // No uncertainty assigned to this usecase at this time. + //double gevmev = 0.001; // minerva sends in MeV. + double Q2gev = mc_Q2; + double powerQ2 = 1.0; + double thisrwtemp = 0.0; + thisrwtemp = 0.0; + for(int ii=0; ii<10; ii++){ + if(relORnonrel)thisrwtemp += rpapolyrel[ii]*powerQ2; + else thisrwtemp += rpapolynonrel[ii]*powerQ2; + powerQ2 *= Q2gev; + } + return thisrwtemp; + + +} + +double weightRPA::getWeightQ2fromhistogram(const double mc_Q2, const bool relORnonrel){ + + if(mc_Q2 < 0.0)return 1.0; + if(mc_Q2 > 9.0) return 1.0; + + if(relORnonrel)return hQ2relratio->GetBinContent( hQ2relratio->FindBin(mc_Q2) ); + else return hQ2nonrelratio->GetBinContent( hQ2nonrelratio->FindBin(mc_Q2) ); + + // interpolation might be overkill for such a finely binned histogram, 0.01% + // but the extra cpu cycles maybe small. + // save it here for some future use. + //if(relORnonrel)return hQ2relratio->Interpolate(mc_Q2); + //else return hQ2nonrelratio->Interpolate(mc_Q2); + +} + + +double weightRPA::getWeightLowQ2(const double mc_q0, const double mc_q3, int sign){ + return getWeightInternal(mc_q0,mc_q3,weightRPA::LOWQ2,sign); +} + +double weightRPA::getWeightHighQ2(const double mc_q0, const double mc_q3, int sign){ + return getWeightInternal(mc_q0,mc_q3,weightRPA::HIGHQ2,sign); +} + + +#endif + + + diff --git a/src/Routines/ComparisonRoutines.cxx b/src/Routines/BayesianRoutines.cxx similarity index 53% copy from src/Routines/ComparisonRoutines.cxx copy to src/Routines/BayesianRoutines.cxx index c5463c0..5d1b69c 100755 --- a/src/Routines/ComparisonRoutines.cxx +++ b/src/Routines/BayesianRoutines.cxx @@ -1,537 +1,521 @@ // 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 "BayesianRoutines.h" -/* - Constructor/Destructor -*/ -//************************ -void ComparisonRoutines::Init() { -//************************ +void BayesianRoutines::Init() { + + fInputFile = ""; + fInputRootFile = NULL; fOutputFile = ""; fOutputRootFile = NULL; - fStrategy = "Compare"; - + fStrategy = "BayesianThrows"; fRoutines.clear(); + fRoutines.push_back("BayesianThrows"); fCardFile = ""; fFakeDataInput = ""; - fSampleFCN = NULL; + fSampleFCN = NULL; - fAllowedRoutines = ("Compare"); - -}; + fAllowedRoutines = ("f"); -//************************************* -ComparisonRoutines::~ComparisonRoutines() { -//************************************* }; +BayesianRoutines::~BayesianRoutines() { +}; - -/* - Input Functions -*/ -//************************************* -ComparisonRoutines::ComparisonRoutines(int argc, char* argv[]) { -//************************************* +BayesianRoutines::BayesianRoutines(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; - + fNThrows = 250; + fStartThrows = 0; + fThrowString = ""; // 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, "-t", fNThrows, 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.AddS("cardfile", fCardFile); - if (!fOutputFile.empty()) fCompKey.AddS("outputfile", fOutputFile); - if (!fStrategy.empty()) fCompKey.AddS("strategy", fStrategy); + 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.LoadConfig( fCompKey.GetS("cardfile"), ""); - - // Add CMD XML Structs - for (size_t i = 0; i < xmlcmds.size(); i++) { - configuration.AddXMLLine(xmlcmds[i]); - } + 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")){ + if (maxevents.compare("-1")) { configuration.OverrideConfig("MAXEVENTS=" + maxevents); } // Finish configuration XML - configuration.FinaliseConfig(fCompKey.GetS("outputfile") + ".xml"); + configuration.FinaliseSettings(fCompKey.GetS("outputfile") + ".xml"); // Add Error Verbo Lines - verbocount += Config::Get().GetParI("VERBOSITY"); - errorcount += Config::Get().GetParI("ERROR"); - bool trace = Config::Get().GetParB("TRACE"); + verbocount += Config::GetParI("VERBOSITY"); + errorcount += Config::GetParI("ERROR"); std::cout << "[ NUISANCE ]: Setting VERBOSITY=" << verbocount << std::endl; std::cout << "[ NUISANCE ]: Setting ERROR=" << errorcount << std::endl; SETVERBOSITY(verbocount); - SETTRACE(trace); - - // Comparison Setup ======================================== // Proper Setup - fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE"); - SetupComparisonsFromXML(); + if (fStrategy.find("ErrorBands") != std::string::npos || + fStrategy.find("MergeErrors") != std::string::npos) { + fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE"); + } + + // fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE"); + SetupSystematicsFromXML(); SetupRWEngine(); SetupFCN(); return; }; -//************************************* -void ComparisonRoutines::SetupComparisonsFromXML() { -//************************************* +void BayesianRoutines::SetupSystematicsFromXML() { - LOG(FIT) << "Setting up nuiscomp" << std::endl; + 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; - ERR(FTL) << "type='PARAMETER_TYPE'" << std::endl; throw; } else if (!key.Has("name")) { ERR(FTL) << "No name given for parameter " << i << std::endl; - ERR(FTL) << "name='SAMPLE_NAME'" << std::endl; throw; } else if (!key.Has("nominal")) { ERR(FTL) << "No nominal given for parameter " << i << std::endl; - ERR(FTL) << "nominal='NOMINAL_VALUE'" << 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 if state not given - if (!key.Has("state")){ - key.SetS("state","FIX"); + + // Override if state not given + if (!key.Has("state")) { + key.SetS("state", "FIX"); } std::string parstate = key.GetS("state"); - // Check for incomplete limtis - int limdef = ((int)key.Has("low") + - (int)key.Has("high") + - (int)key.Has("step")); - - if (limdef > 0 and limdef < 3){ - ERR(FTL) << "Incomplete limit set given for parameter : " << parname << std::endl; - ERR(FTL) << "Requires: low='LOWER_LIMIT' high='UPPER_LIMIT' step='STEP_SIZE' " << std::endl; - throw; - } - // 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; } - // Convert if required + // 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; - fStateVals[parname] = parstate; + + 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; + } else { + ERR(WRN) << "NO SAMPLES LOADED" << 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 " << i << ". : " - << samplename << " (" << sampletype << ") [Norm=" << samplenorm<<"]"<< std::endl - << " -> input='" << samplefile << "'" << std::endl; + 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()) { + 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; 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("nominal")) { + } 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("nominal"); + double parnom = key.GetD("nom"); // Push into vectors fFakeVals[parname] = parnom; } } +/* + Setup Functions +*/ //************************************* -void ComparisonRoutines::SetupRWEngine() { +void BayesianRoutines::SetupRWEngine() { //************************************* - LOG(FIT) << "Setting up FitWeight Engine" << std::endl; for (UInt_t i = 0; i < fParams.size(); i++) { std::string name = fParams[i]; - FitBase::GetRW()->IncludeDial(name, fTypeVals.at(name)); + FitBase::GetRW() -> IncludeDial(name, fTypeVals.at(name) ); } + UpdateRWEngine(fStartVals); return; } //************************************* -void ComparisonRoutines::SetupFCN() { - //************************************* +void BayesianRoutines::SetupFCN() { +//************************************* - LOG(FIT) << "Building the SampleFCN" << std::endl; + LOG(FIT) << "Making the jointFCN" << std::endl; if (fSampleFCN) delete fSampleFCN; - FitPar::Config().out = fOutputRootFile; - fOutputRootFile->cd(); fSampleFCN = new JointFCN(fOutputRootFile); - SetFakeData(); - - return; -} - -//************************************* -void ComparisonRoutines::SetFakeData() { -//************************************* - - if (fFakeDataInput.empty()) return; - - if (fFakeDataInput.compare("MC") == 0) { - LOG(FIT) << "Setting fake data from MC starting prediction." << std::endl; - UpdateRWEngine(fFakeVals); - - FitBase::GetRW()->Reconfigure(); - fSampleFCN->ReconfigureAllEvents(); - fSampleFCN->SetFakeData("MC"); - - UpdateRWEngine(fCurVals); - LOG(FIT) << "Set all data to fake MC predictions." << std::endl; - } else { - LOG(FIT) << "Setting fake data from: " << fFakeDataInput << std::endl; - fSampleFCN->SetFakeData(fFakeDataInput); - } + fInputThrows = fSampleFCN->GetPullList(); return; } /* Fitting Functions */ //************************************* -void ComparisonRoutines::UpdateRWEngine( - std::map& updateVals) { - //************************************* +void BayesianRoutines::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 ComparisonRoutines::Run() { +void BayesianRoutines::ThrowParameters() { //************************************* - LOG(FIT) << "Running ComparisonRoutines : " << fStrategy << std::endl; - - if (FitPar::Config().GetParB("save_nominal")) { - SaveNominal(); + // Set fThrownVals to all values in currentVals + for (UInt_t i = 0; i < fParams.size(); i++) { + std::string name = fParams.at(i); + fThrownVals[name] = fCurVals[name]; } - // Parse given routines - fRoutines = GeneralUtils::ParseToStr(fStrategy, ","); - if (fRoutines.empty()) { - ERR(FTL) << "Trying to run ComparisonRoutines with no routines given!" << std::endl; - throw; - } + for (PullListConstIter iter = fInputThrows.begin(); + iter != fInputThrows.end(); iter++) { + ParamPull* pull = *iter; - for (UInt_t i = 0; i < fRoutines.size(); i++) { - std::string routine = fRoutines.at(i); + pull->ThrowCovariance(); + TH1D dialhist = pull->GetDataHist(); - LOG(FIT) << "Routine: " << routine << std::endl; - if (!routine.compare("Compare")) { - UpdateRWEngine(fCurVals); - GenerateComparison(); - PrintState(); - SaveCurrentState(); + for (int i = 0; i < dialhist.GetNbinsX(); i++) { + std::string name = std::string(dialhist.GetXaxis()->GetBinLabel(i + 1)); + if (fCurVals.find(name) != fCurVals.end()) { + fThrownVals[name] = dialhist.GetBinContent(i + 1); + } } + + // Reset throw incase pulls are calculated. + pull->ResetToy(); + } + // Now update Parameters + UpdateRWEngine(fThrownVals); + // Update Pulls + for (PullListConstIter iter = fInputThrows.begin(); + iter != fInputThrows.end(); iter++) { + ParamPull* pull = *iter; + pull->Reconfigure(); + } return; -} +}; //************************************* -void ComparisonRoutines::GenerateComparison() { - //************************************* - LOG(FIT) << "Generating Comparison." << std::endl; - // Main Event Loop from event Manager - fSampleFCN->ReconfigureAllEvents(); - return; - -} - +void BayesianRoutines::Run() { //************************************* -void ComparisonRoutines::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 = 0.0; - - 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::cout << "Running routines " << std::endl; + fRoutines = GeneralUtils::ParseToStr(fStrategy, ","); - std::ostringstream curparstring; + for (UInt_t i = 0; i < fRoutines.size(); i++) { - 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; + std::string routine = fRoutines.at(i); + LOG(FIT) << "Running Routine: " << routine << std::endl; - LOG(FIT) << curparstring.str() << std::endl; + if (!routine.compare("BayesianThrows")) GenerateThrows(); + else THROW("UNKNOWN ROUTINE " << routine); } - 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; + return; } -/* - Write Functions -*/ //************************************* -void ComparisonRoutines::SaveCurrentState(std::string subdir) { +void BayesianRoutines::GenerateThrows() { //************************************* - LOG(FIT) << "Saving current full FCN predictions" << std::endl; + // Create a new output file + TFile* outfile = new TFile((fOutputFile + ".throws.root").c_str(), "RECREATE"); + outfile->cd(); + + int nthrows = fNThrows; + + // Setting Seed + // Matteo Mazzanti's Fix + struct timeval mytime; + gettimeofday(&mytime, NULL); + Double_t seed = time(NULL) + int(getpid()) + (mytime.tv_sec * 1000.) + (mytime.tv_usec / 1000.); + gRandom->SetSeed(seed); + LOG(FIT) << "Using Seed : " << seed << std::endl; + LOG(FIT) << "nthrows = " << nthrows << std::endl; + + // Run the Initial Reconfigure + LOG(FIT) << "Making nominal prediction " << std::endl; + TDirectory* nominal = (TDirectory*) outfile->mkdir("nominal"); + nominal->cd(); + UpdateRWEngine(fStartVals); + fSampleFCN->ReconfigureUsingManager(); + fSampleFCN->Write(); - // Setup DIRS - TDirectory* curdir = gDirectory; - if (!subdir.empty()) { - TDirectory* newdir = (TDirectory*)gDirectory->mkdir(subdir.c_str()); - newdir->cd(); + // Create an iteration tree inside SampleFCN + fSampleFCN->CreateIterationTree("error_iterations", FitBase::GetRW()); + + // Create a new iteration TTree + TTree* LIKETREE = new TTree("likelihood", "likelihood"); + std::vector likenames = fSampleFCN->GetAllNames(); + std::vector likevals = fSampleFCN->GetAllLikelihoods(); + std::vector likendof = fSampleFCN->GetAllNDOF(); + double* LIKEVALS = new double[likevals.size()]; + int* LIKENDOF = new int[likendof.size()]; + + for (size_t i = 0; i < likendof.size(); i++) { + LIKETREE->Branch( (likenames[i] + "_likelihood" ).c_str(), &LIKEVALS[i], + (likenames[i] + "_likelihood/D").c_str() ); + LIKETREE->Branch( (likenames[i] + "_ndof" ).c_str(), &LIKENDOF[i], + (likenames[i] + "_ndof/I").c_str() ); + LIKENDOF[i] = likendof[i]; } - fSampleFCN->Write(); + likenames .clear(); + likevals .clear(); + likendof .clear(); - // Change back to current DIR - curdir->cd(); + double* PARAMVALS = new double[fParams.size()]; + for (size_t i = 0; i < fParams.size(); i++){ + LIKETREE->Branch( fParams[i].c_str(), &PARAMVALS[i], (fParams[i] + "/D").c_str() ); + } - return; -} + // Run Throws and save + for (Int_t i = 0; i < nthrows; i++) { -//************************************* -void ComparisonRoutines::SaveNominal() { - //************************************* + // Skip the start throw + if (i == 0) continue; + LOG(FIT) << "Throw " << i << " ================================" << std::endl; - fOutputRootFile->cd(); + // Throw Parameters + ThrowParameters(); + FitBase::GetRW()->Print(); - LOG(FIT) << "Saving Nominal Predictions (be cautious with this)" << std::endl; - FitBase::GetRW()->Reconfigure(); - GenerateComparison(); - SaveCurrentState("nominal"); -}; + // Get Parameter Values + for (size_t i = 0; i < fParams.size(); i++){ + PARAMVALS[i] = fThrownVals[fParams[i]]; + } + + // Run Sample Prediction + fSampleFCN->ReconfigureFastUsingManager(); + // Get vector of likelihoods/ndof + std::vector likevals = fSampleFCN->GetAllLikelihoods(); + for (size_t i = 0; i < likevals.size(); i++) { + LIKEVALS[i] = likevals[i]; + } + + // Save to TTree + LIKETREE->Fill(); + + // Save the FCN + // if (fSavePredictions){ SaveSamplePredictions(); } + LOG(FIT) << "END OF THROW ================================" << std::endl; + } + + // Finish up + outfile->cd(); + LIKETREE->Write(); + outfile->Close(); + delete LIKEVALS; + delete LIKENDOF; + delete PARAMVALS; +} diff --git a/src/Routines/SplineRoutines.h b/src/Routines/BayesianRoutines.h similarity index 60% copy from src/Routines/SplineRoutines.h copy to src/Routines/BayesianRoutines.h index a56f692..777e716 100755 --- a/src/Routines/SplineRoutines.h +++ b/src/Routines/BayesianRoutines.h @@ -1,197 +1,183 @@ // 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 SPLINE_ROUTINES_H -#define SPLINE_ROUTINES_H +#ifndef BAYESIAN_ROUTINES_H +#define BAYESIAN_ROUTINES_H /*! * \addtogroup Minimizer * @{ */ #include "TH1.h" #include "TF1.h" #include "TMatrixD.h" #include "TVectorD.h" #include "TSystem.h" #include "TFile.h" #include "TProfile.h" - +#include #include #include #include #include #include #include "FitEvent.h" #include "JointFCN.h" -#include "FitParameters.h" -#include "FitLogger.h" -#include "BaseFitEvt.h" -#include "NuisConfig.h" -#include "NuisKey.h" -#include "SplineReader.h" -#include "SplineWriter.h" -#include "SplineMerger.h" + #include "ParserUtils.h" -#include "OpenMPWrapper.h" + enum minstate { kErrorStatus = -1, kGoodStatus, kFitError, kNoChange, kFitFinished, kFitUnfinished, kStateChange, }; //************************************* //! Collects all possible fit routines into a single class to avoid repeated code -class SplineRoutines{ +class BayesianRoutines{ //************************************* public: /* Constructor/Destructor */ //! Constructor reads in arguments given at the command line for the fit here. - SplineRoutines(int argc, char* argv[]); + BayesianRoutines(int argc, char* argv[]); //! Default destructor - ~SplineRoutines(); + ~BayesianRoutines(); //! Reset everything to default/NULL void Init(); /* Input Functions */ //! Splits the arguments ready for initial setup void ParseArgs(int argc, char* argv[]); - + + //! Sorts out configuration and verbosity right at the very start. + //! Calls readCard to set everything else up. + void InitialSetup(); + /* Setup Functions */ - - //! Setup the configuration given the arguments passed at the commandline and card file - void SetupConfig(); + void SetupSystematicsFromXML(); //! Setups up our custom RW engine with all the parameters passed in the card file void SetupRWEngine(); - void Run(); - void SaveEvents(); - void TestEvents(); - void GenerateEventSplines(); - void GenerateEventWeights(); - void GenerateEventWeightChunks(int procchunk = -1); - void BuildEventSplines(int procchunk = -1); - void MergeEventSplinesChunks(); - /* - Testing Functions - */ - - /// Scan parameter space in 1D at finer resolution than points. Compare Raw/Spline on an event by event basis. - void TestSplines_1DEventScan(); - - /// Scan parameter space in 1D at finer resolution than points. Compare likelihoods for all testsamples. - void TestSplines_1DLikelihoodScan(); - - /// Randomly throw in parameter space. For each throw, calc average weight difference. - void TestSplines_NDEventThrow(); - - /// Randomly thow in parameter space. For each throw, calc likelihood difference for each sample. - void TestSplines_NDLikelihoodThrow(); - - - /// Generate a set of spline vs weight canvases and save to file - void SaveSplinePlots(); + //! Setups up the jointFCN. + void SetupFCN(); /* Fitting Functions */ + //! Main function to actually start iterating over the different required fit routines + void Run(); + //! Given a new map change the values that the RW engine is currently set to void UpdateRWEngine(std::map& updateVals); - /* - MISC Functions - */ - - //! Get previous fit status from a file - Int_t GetStatus(); + //! Given a single routine (see tutorial for options) run that fit routine now. + int RunFitRoutine(std::string routine); - void MergeSplines(); + //! Throw the current covariance of dial values we have, and fill the thrownVals and thrownNorms maps. + //! If uniformly is true parameters will be thrown uniformly between their upper and lower limits. + void ThrowParameters(); + //! Run Throws + void GenerateThrows(); + protected: //! Our Custom ReWeight Object FitWeight* rw; - FitWeight* fRW; - + std::string fOutputFile; std::string fInputFile; TFile* fInputRootFile; TFile* fOutputRootFile; - + + //! Flag for whether the fit should be continued if an output file is already found. + bool fitContinue; + + //! Minimizer Object for handling roots different minimizer methods JointFCN* fSampleFCN; - std::list fSamples; - + + int nfreepars; + std::string fCardFile; std::string fStrategy; std::vector fRoutines; std::string fAllowedRoutines; + std::string fFakeDataInput; + // Input Dial Vals //! Vector of dial names std::vector fParams; std::map fStateVals; std::map fStartVals; std::map fCurVals; std::map fErrorVals; std::map fMinVals; std::map fMaxVals; std::map fStepVals; std::map fTypeVals; std::map fFixVals; std::map fStartFixVals; - std::vector fGenericInputNames; - std::map fGenericInputFiles; - std::map fGenericOutputFiles; - std::map fGenericOutputTypes; - std::map fGenericInputs; + //! Vector of fake parameter names + std::map fFakeVals; + + //! Map of thrown parameter names and values (After ThrowCovariance) + std::map fThrownVals; + + + std::list fInputThrows; //!< Pointers to pull terms + std::vector fInputDials; //!< Vector of Input Histograms + std::vector fInputCovar; //!< Vector of Input Covariances + + nuiskey fCompKey; + std::vector fThrowList; + std::string fThrowString; + + int fNThrows; + int fStartThrows; - std::vector fSplineNames; - std::map fSplineTypes; - std::map fSplinePoints; - nuiskey fCompKey; - - }; /*! @} */ #endif diff --git a/src/Routines/CMakeLists.txt b/src/Routines/CMakeLists.txt index 2c5cf1c..a87e4a0 100644 --- a/src/Routines/CMakeLists.txt +++ b/src/Routines/CMakeLists.txt @@ -1,66 +1,68 @@ # 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 . ################################################################################ set(IMPLFILES ComparisonRoutines.cxx SystematicRoutines.cxx SplineRoutines.cxx +BayesianRoutines.cxx ) if(USE_MINIMIZER) set(IMPLFILES ${IMPLFILES};MinimizerRoutines.cxx) endif() set(HEADERFILES ComparisonRoutines.h SystematicRoutines.h +BayesianRoutines.h SplineRoutines.h ) if(USE_MINIMIZER) set(HEADERFILES ${HEADERFILES};MinimizerRoutines.h) endif() set(LIBNAME Routines) if(CMAKE_BUILD_TYPE MATCHES DEBUG) add_library(${LIBNAME} STATIC ${IMPLFILES}) else(CMAKE_BUILD_TYPE MATCHES RELEASE) add_library(${LIBNAME} SHARED ${IMPLFILES}) endif() include_directories(${EXP_INCLUDE_DIRECTORIES}) include_directories(${MINIMUM_INCLUDE_DIRECTORIES}) include_directories(${CMAKE_SOURCE_DIR}/src/FCN) include_directories(${CMAKE_SOURCE_DIR}/src/MCStudies) set_target_properties(${LIBNAME} PROPERTIES VERSION "${NUISANCE_VERSION_MAJOR}.${NUISANCE_VERSION_MINOR}.${NUISANCE_VERSION_REVISION}") #set_target_properties(${LIBNAME} PROPERTIES LINK_FLAGS ${ROOT_LD_FLAGS}) if(DEFINED PROJECTWIDE_EXTRA_DEPENDENCIES) add_dependencies(${LIBNAME} ${PROJECTWIDE_EXTRA_DEPENDENCIES}) endif() install(TARGETS ${LIBNAME} DESTINATION lib) #Can uncomment this to install the headers... but is it really neccessary? #install(FILES ${HEADERFILES} DESTINATION include) set(MODULETargets ${MODULETargets} ${LIBNAME} PARENT_SCOPE) diff --git a/src/Routines/ComparisonRoutines.cxx b/src/Routines/ComparisonRoutines.cxx index c5463c0..1f4f7bb 100755 --- a/src/Routines/ComparisonRoutines.cxx +++ b/src/Routines/ComparisonRoutines.cxx @@ -1,537 +1,532 @@ // 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" /* Constructor/Destructor */ //************************ void ComparisonRoutines::Init() { //************************ fOutputFile = ""; fOutputRootFile = NULL; fStrategy = "Compare"; fRoutines.clear(); fCardFile = ""; fFakeDataInput = ""; fSampleFCN = NULL; fAllowedRoutines = ("Compare"); - + }; //************************************* ComparisonRoutines::~ComparisonRoutines() { //************************************* }; /* Input Functions */ //************************************* ComparisonRoutines::ComparisonRoutines(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.AddS("cardfile", fCardFile); - if (!fOutputFile.empty()) fCompKey.AddS("outputfile", fOutputFile); - if (!fStrategy.empty()) fCompKey.AddS("strategy", fStrategy); + 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.LoadConfig( fCompKey.GetS("cardfile"), ""); - - // Add CMD XML Structs - for (size_t i = 0; i < xmlcmds.size(); i++) { - configuration.AddXMLLine(xmlcmds[i]); - } + 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.FinaliseConfig(fCompKey.GetS("outputfile") + ".xml"); + configuration.FinaliseSettings(fCompKey.GetS("outputfile") + ".xml"); // Add Error Verbo Lines - verbocount += Config::Get().GetParI("VERBOSITY"); - errorcount += Config::Get().GetParI("ERROR"); - bool trace = Config::Get().GetParB("TRACE"); + verbocount += Config::GetParI("VERBOSITY"); + errorcount += Config::GetParI("ERROR"); + bool trace = Config::GetParB("TRACE"); std::cout << "[ NUISANCE ]: Setting VERBOSITY=" << verbocount << std::endl; std::cout << "[ NUISANCE ]: Setting ERROR=" << errorcount << std::endl; SETVERBOSITY(verbocount); SETTRACE(trace); // Comparison Setup ======================================== // Proper Setup fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE"); SetupComparisonsFromXML(); SetupRWEngine(); SetupFCN(); return; }; //************************************* void ComparisonRoutines::SetupComparisonsFromXML() { //************************************* LOG(FIT) << "Setting up nuiscomp" << 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; ERR(FTL) << "type='PARAMETER_TYPE'" << std::endl; throw; } else if (!key.Has("name")) { ERR(FTL) << "No name given for parameter " << i << std::endl; ERR(FTL) << "name='SAMPLE_NAME'" << std::endl; throw; } else if (!key.Has("nominal")) { ERR(FTL) << "No nominal given for parameter " << i << std::endl; ERR(FTL) << "nominal='NOMINAL_VALUE'" << 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 if state not given if (!key.Has("state")){ key.SetS("state","FIX"); } std::string parstate = key.GetS("state"); // Check for incomplete limtis int limdef = ((int)key.Has("low") + (int)key.Has("high") + (int)key.Has("step")); if (limdef > 0 and limdef < 3){ ERR(FTL) << "Incomplete limit set given for parameter : " << parname << std::endl; ERR(FTL) << "Requires: low='LOWER_LIMIT' high='UPPER_LIMIT' step='STEP_SIZE' " << std::endl; throw; } // 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; } // Convert if required 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);; fCurVals[parname] = parnom; fStateVals[parname] = parstate; } // 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 " << i << ". : " << samplename << " (" << sampletype << ") [Norm=" << samplenorm<<"]"<< std::endl << " -> input='" << samplefile << "'" << 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; fCurVals[normname] = samplenorm; } // 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("nominal")) { ERR(FTL) << "No nominal given for fakeparameter " << i << std::endl; throw; } // Get Inputs std::string parname = key.GetS("name"); double parnom = key.GetD("nominal"); // Push into vectors fFakeVals[parname] = parnom; } } //************************************* void ComparisonRoutines::SetupRWEngine() { //************************************* LOG(FIT) << "Setting up FitWeight Engine" << std::endl; for (UInt_t i = 0; i < fParams.size(); i++) { std::string name = fParams[i]; FitBase::GetRW()->IncludeDial(name, fTypeVals.at(name)); } return; } //************************************* void ComparisonRoutines::SetupFCN() { //************************************* LOG(FIT) << "Building the SampleFCN" << std::endl; if (fSampleFCN) delete fSampleFCN; - FitPar::Config().out = fOutputRootFile; + Config::Get().out = fOutputRootFile; fOutputRootFile->cd(); fSampleFCN = new JointFCN(fOutputRootFile); SetFakeData(); return; } //************************************* void ComparisonRoutines::SetFakeData() { //************************************* if (fFakeDataInput.empty()) return; if (fFakeDataInput.compare("MC") == 0) { LOG(FIT) << "Setting fake data from MC starting prediction." << std::endl; UpdateRWEngine(fFakeVals); FitBase::GetRW()->Reconfigure(); fSampleFCN->ReconfigureAllEvents(); fSampleFCN->SetFakeData("MC"); UpdateRWEngine(fCurVals); LOG(FIT) << "Set all data to fake MC predictions." << std::endl; } else { LOG(FIT) << "Setting fake data from: " << fFakeDataInput << std::endl; fSampleFCN->SetFakeData(fFakeDataInput); } return; } /* Fitting Functions */ //************************************* void ComparisonRoutines::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 ComparisonRoutines::Run() { //************************************* LOG(FIT) << "Running ComparisonRoutines : " << 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 ComparisonRoutines with no routines given!" << std::endl; throw; } for (UInt_t i = 0; i < fRoutines.size(); i++) { std::string routine = fRoutines.at(i); LOG(FIT) << "Routine: " << routine << std::endl; if (!routine.compare("Compare")) { UpdateRWEngine(fCurVals); GenerateComparison(); PrintState(); SaveCurrentState(); } } return; } //************************************* void ComparisonRoutines::GenerateComparison() { //************************************* LOG(FIT) << "Generating Comparison." << std::endl; // Main Event Loop from event Manager fSampleFCN->ReconfigureAllEvents(); return; } //************************************* void ComparisonRoutines::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 = 0.0; 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; } /* Write Functions */ //************************************* void ComparisonRoutines::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(); } fSampleFCN->Write(); // Change back to current DIR curdir->cd(); return; } //************************************* void ComparisonRoutines::SaveNominal() { //************************************* fOutputRootFile->cd(); LOG(FIT) << "Saving Nominal Predictions (be cautious with this)" << std::endl; FitBase::GetRW()->Reconfigure(); GenerateComparison(); SaveCurrentState("nominal"); }; diff --git a/src/Routines/ComparisonRoutines.h b/src/Routines/ComparisonRoutines.h index 701481c..1d967ac 100755 --- a/src/Routines/ComparisonRoutines.h +++ b/src/Routines/ComparisonRoutines.h @@ -1,168 +1,168 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #ifndef COMPARISON_ROUTINES_H #define COMPARISON_ROUTINES_H /*! \addtogroup Routines @{ */ #include "TH1.h" #include "TF1.h" #include "TMatrixD.h" #include "TVectorD.h" #include "TSystem.h" #include "TFile.h" #include "TProfile.h" #include #include #include #include #include #include "FitEvent.h" #include "JointFCN.h" -#include "FitParameters.h" + #include "GeneralUtils.h" #include "NuisConfig.h" #include "NuisKey.h" #include "FitLogger.h" #include "ParserUtils.h" enum minstate { kErrorStatus = -1, kGoodStatus, kFitError, kNoChange, kFitFinished, kFitUnfinished, kStateChange, }; //************************************* /// Collects all possible fit routines into a single class to avoid repeated code class ComparisonRoutines { //************************************* public: /* Constructor/Destructor */ /// Constructor reads in arguments given at the command line for the fit here. ComparisonRoutines(int argc, char* argv[]); /// Default destructor ~ComparisonRoutines(); /// Reset everything to default/NULL void Init(); /* Input Functions */ /// Queries configuration keys to setup Parameters/Samples/FakeParameters void SetupComparisonsFromXML(); /* Setup Functions */ /// Setups up our custom RW engine with all the parameters passed in the card file void SetupRWEngine(); /// Setups up the jointFCN. void SetupFCN(); /// Set the current data histograms in each sample to the fake data. void SetFakeData(); /* Fitting Functions */ /// Main function to actually start iterating over the different required fit routines void Run(); /// Creates a comparison from FCN void GenerateComparison(); /// Given a new map change the values that the RW engine is currently set to void UpdateRWEngine(std::map& updateVals); /// Print current value void PrintState(); /* Write Functions */ /// Save the sample plots for current MC /// dir if not empty forces plots to be saved in a subdirectory of outputfile void SaveCurrentState(std::string subdir=""); /// Save starting predictions into a seperate folder void SaveNominal(); /* MISC Functions */ /// Get previous fit status from a file Int_t GetStatus(); protected: //! Our Custom ReWeight Object FitWeight* rw; std::string fOutputFile; ///< Output file name // std::string fInputFile; ///< Input file name // TFile* fInputRootFile; ///< TFile* fOutputRootFile; ///< Output ROOT TFile JointFCN* fSampleFCN; ///< Joint Samples Container that handles reconfigures. std::string fCardFile; ///< Input card/XML file. std::string fStrategy; ///< Comparison routine selection. std::vector fRoutines; ///< Split vector of comparison routine selection. std::string fAllowedRoutines; ///< Hard coded list of allowed routines. /// Fake data flag. Can be 'MC' to use 'fake_parameter' /// or 'path_to_file.root' to use previous NUISANCE MC predictions. std::string fFakeDataInput; // Input Dial Vals std::vector fParams; ///< Vector of dial names. std::map fStateVals; ///< Map of dial states std::map fCurVals; ///< Map of dial values std::map fTypeVals; ///< Map of dial type enums. // Fake Dial Vals std::map fFakeVals; ///< Map of fake data settings. // Configuration nuiskey fCompKey; ///< Configuration Key for this Comparison Instance }; /*! @} */ #endif diff --git a/src/Routines/MinimizerRoutines.cxx b/src/Routines/MinimizerRoutines.cxx index e5ad2a5..ee3e995 100755 --- a/src/Routines/MinimizerRoutines.cxx +++ b/src/Routines/MinimizerRoutines.cxx @@ -1,1511 +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.AddS("cardfile", fCardFile); - if (!fOutputFile.empty()) fCompKey.AddS("outputfile", fOutputFile); - if (!fStrategy.empty()) fCompKey.AddS("strategy", fStrategy); + 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.LoadConfig(fCompKey.GetS("cardfile"), ""); - - // Add CMD XML Structs - for (size_t i = 0; i < xmlcmds.size(); i++) { - configuration.AddXMLLine(xmlcmds[i]); - } + 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.FinaliseConfig(fCompKey.GetS("outputfile") + ".xml"); + configuration.FinaliseSettings(fCompKey.GetS("outputfile") + ".xml"); // Add Error Verbo Lines - verbocount += Config::Get().GetParI("VERBOSITY"); - errorcount += Config::Get().GetParI("ERROR"); + 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")); 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")); 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 verbosity = FitPar::Config().GetParI("VERBOSITY"); std::string trueroutine = routine; std::string substring = "LowStat"; trueroutine.erase(trueroutine.find(substring), substring.length()); // Set MAX EVENTS=1000 - FitPar::Config().SetParI("input.maxevents", lowstatsevents); - FitPar::Config().SetParI("VERBOSITY", 3); + Config::SetPar("input.maxevents", lowstatsevents); + Config::SetPar("VERBOSITY", 3); SetupFCN(); RunFitRoutine(trueroutine); - FitPar::Config().SetParI("input.maxevents", maxevents); + Config::SetPar("input.maxevents", maxevents); SetupFCN(); - FitPar::Config().SetParI("VERBOSITY", verbosity); + 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::Get().GetParI("VERBOSITY"); + 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/Routines/MinimizerRoutines.h b/src/Routines/MinimizerRoutines.h index 310ca60..0733601 100755 --- a/src/Routines/MinimizerRoutines.h +++ b/src/Routines/MinimizerRoutines.h @@ -1,270 +1,270 @@ // 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 MINIMIZER_ROUTINES_H #define MINIMIZER_ROUTINES_H /*! * \addtogroup Minimizer * @{ */ #include "TH1.h" #include "TF1.h" #include "TMatrixD.h" #include "TVectorD.h" #include "Minuit2/FCNBase.h" #include "TFitterMinuit.h" #include "TSystem.h" #include "TFile.h" #include "TProfile.h" #include #include #include #include #include #include "FitEvent.h" #include "JointFCN.h" #include "MinimizerFCN.h" -#include "FitParameters.h" + #include "Math/Minimizer.h" #include "Math/Factory.h" #include "Math/Functor.h" #include "FitLogger.h" #include "ParserUtils.h" enum minstate { kErrorStatus = -1, kGoodStatus, kFitError, kNoChange, kFitFinished, kFitUnfinished, kStateChange, }; //************************************* //! Collects all possible fit routines into a single class to avoid repeated code class MinimizerRoutines{ //************************************* public: /* Constructor/Destructor */ //! Constructor reads in arguments given at the command line for the fit here. MinimizerRoutines(int argc, char* argv[]); //! Default destructor ~MinimizerRoutines(); //! Reset everything to default/NULL void Init(); /* Input Functions */ //! Splits the arguments ready for initial setup void ParseArgs(int argc, char* argv[]); //! Sorts out configuration and verbosity right at the very start. //! Calls readCard to set everything else up. void InitialSetup(); //! Loops through each line of the card file and passes it to other read functions void ReadCard(std::string cardfile); //! Check for parameter string in the line and assign the correct type. //! Fills maps for each of the parameters int ReadParameters(std::string parstring); //! Reads in fake parameters and assigns them (Requires the parameter to be included as a normal parameter as well) int ReadFakeDataPars(std::string parstring); //! Read in the samples so we can set up the free normalisation dials if required int ReadSamples(std::string sampleString); void SetupMinimizerFromXML(); /* Setup Functions */ //! Setup the configuration given the arguments passed at the commandline and card file void SetupConfig(); //! Setups up our custom RW engine with all the parameters passed in the card file void SetupRWEngine(); //! Setups up the jointFCN. void SetupFCN(); //! Sets up the minimizerObj for ROOT. there are cases where this is called repeatedly, e.g. If you are using a brute force scan before using Migrad. void SetupFitter(std::string routine); //! Set the current data histograms in each sample to the fake data. void SetFakeData(); //! Setup the covariances with the correct dimensions. At the start this is either uncorrelated or merged given all the input covariances. //! At the end of the fit this produces the blank covariances which can then be filled by the minimizerObj with best fit covariances. void SetupCovariance(); /* Fitting Functions */ //! Main function to actually start iterating over the different required fit routines void Run(); //! Given a new map change the values that the RW engine is currently set to void UpdateRWEngine(std::map& updateVals); //! Given a single routine (see tutorial for options) run that fit routine now. int RunFitRoutine(std::string routine); //! Get the current state of minimizerObj and fill it into currentVals and currentNorms void GetMinimizerState(); //! Print current value void PrintState(); //! Performs a fit routine where the input.maxevents is set to a much lower value to try and move closer to the best fit minimum. void LowStatRoutine(std::string routine); //! Perform a chi2 scan in 1D around the current point void Create1DScans(); //! Perform a chi2 scan in 2D around the current point void Chi2Scan2D(); //! Currently a placeholder NEEDS UPDATING void CreateContours(); //! If any currentVals are close to the limits set them to the limit and fix them int FixAtLimit(); //! Throw the current covariance of dial values we have, and fill the thrownVals and thrownNorms maps. //! If uniformly is true parameters will be thrown uniformly between their upper and lower limits. void ThrowCovariance(bool uniformly); //! Given the covariance we currently have generate error bands by throwing the covariance. //! The FitPar config "error_uniform" defines whether to throw using the covariance or uniformly. //! The FitPar config "error_throws" defines how many throws are needed. //! Currently only supports TH1D plots. void GenerateErrorBands(); /* Write Functions */ //! Write plots and TTrees listing the minimizerObj result of the fit to file void SaveMinimizerState(); //! Save the sample plots for current MC //! dir if not empty forces plots to be saved in a subdirectory of outputfile void SaveCurrentState(std::string subdir=""); //! Save starting predictions into a seperate folder void SaveNominal(); //! Save predictions before the fit is ran into a seperate folder void SavePrefit(); void SaveResults(); /* MISC Functions */ //! Get previous fit status from a file Int_t GetStatus(); /// Makes a histogram of likelihoods when throwing the data according to its statistics void ThrowDataToys(); protected: //! Our Custom ReWeight Object FitWeight* rw; std::string fOutputFile; std::string fInputFile; TFile* fInputRootFile; TFile* fOutputRootFile; //! Flag for whether the fit should be continued if an output file is already found. bool fitContinue; //! Minimizer Object for handling roots different minimizer methods ROOT::Math::Minimizer* fMinimizer; JointFCN* fSampleFCN; MinimizerFCN* fMinimizerFCN; ROOT::Math::Functor* fCallFunctor; int nfreepars; std::string fCardFile; std::string fStrategy; std::vector fRoutines; std::string fAllowedRoutines; std::string fFakeDataInput; // Input Dial Vals //! Vector of dial names std::vector fParams; std::map fStateVals; std::map fStartVals; std::map fCurVals; std::map fErrorVals; std::map fMinVals; std::map fMaxVals; std::map fStepVals; std::map fTypeVals; std::map fFixVals; std::map fStartFixVals; //! Vector of fake parameter names std::map fFakeVals; //! Map of thrown parameter names and values (After ThrowCovariance) std::map fThrownVals; TH2D* fCorrel; TH2D* fDecomp; TH2D* fCovar; TH2D* fCorFree; TH2D* fDecFree; TH2D* fCovFree; nuiskey fCompKey; }; /*! @} */ #endif diff --git a/src/Routines/Simple_MH_Sampler.h b/src/Routines/Simple_MH_Sampler.h index 48d43fa..527be29 100644 --- a/src/Routines/Simple_MH_Sampler.h +++ b/src/Routines/Simple_MH_Sampler.h @@ -1,334 +1,334 @@ #include "Math/Minimizer.h" #include "FitLogger.h" using ROOT::Math::Minimizer; class Simple_MH_Sampler : public Minimizer { TRandom3 RNJesus; size_t step_i; int moved; size_t thin; size_t thin_ctr; size_t discard; struct Param { Param() : IsFixed(false), name(""), Val(0xdeadbeef), StepWidth(0xdeadbeef), LowLim(0xdeadbeef), UpLim(0xdeadbeef) {} Param(bool i, std::string n, double v, double s, double l, double u) : IsFixed(i), name(n), Val(v), StepWidth(s), LowLim(l), UpLim(u) {} bool IsFixed; std::string name; double Val, StepWidth, LowLim, UpLim; }; std::vector start_params; double curr_value; std::vector curr_params; double propose_value; std::vector propose_params; double min_value; std::vector min_params; TGraph trace; void RestartParams() { curr_params.resize(start_params.size()); for (size_t p_it = 0; p_it < start_params.size(); ++p_it) { curr_params[p_it] = start_params[p_it].Val; } min_params = curr_params; propose_params = curr_params; } TTree *StepTree; void Write(); ROOT::Math::IMultiGenFunction const *FCN; public: Simple_MH_Sampler() : Minimizer(), RNJesus(), trace() { - thin = Config::Get().ConfI("MCMC.thin"); + thin = Config::GetParI("MCMC.thin"); thin_ctr = 0; - discard = Config::Get().ConfI("MCMC.BurnInSteps"); + discard = Config::GetParI("MCMC.BurnInSteps"); } void SetFunction(ROOT::Math::IMultiGenFunction const &func) { FCN = &func; } bool SetVariable(unsigned int ivar, std::string const &name, double val, double step) { if (start_params.size() <= ivar) { start_params.resize(ivar + 1); } start_params[ivar] = Param(false, name, val, step, 0xdeadbeef, 0xdeadbeef); RestartParams(); return true; } bool SetLowerLimitedVariable(unsigned int ivar, std::string const &name, double val, double step, double lower) { SetVariable(ivar, name, val, step); start_params[ivar].LowLim = lower; return true; } bool SetUpperLimitedVariable(unsigned int ivar, std::string const &name, double val, double step, double upper) { SetVariable(ivar, name, val, step); start_params[ivar].UpLim = upper; return true; } bool SetLimitedVariable(unsigned int ivar, std::string const &name, double val, double step, double lower, double upper) { SetLowerLimitedVariable(ivar, name, val, step, lower); start_params[ivar].UpLim = upper; return true; } bool SetFixedVariable(unsigned int ivar, std::string const &name, double val) { SetVariable(ivar, name, val, 0xdeadbeef); start_params[ivar].IsFixed = true; return true; } bool SetVariableValue(unsigned int ivar, double value) { if (start_params.size() <= ivar) { ERROR(WRN, "Tried to set uninitialised variable."); return false; } start_params[ivar].Val = value; return true; } bool SetVariableStepSize(unsigned int ivar, double value) { if (start_params.size() <= ivar) { ERROR(WRN, "Tried to set uninitialised variable."); return false; } start_params[ivar].StepWidth = value; return true; } bool SetVariableLowerLimit(unsigned int ivar, double lower) { if (start_params.size() <= ivar) { ERROR(WRN, "Tried to set uninitialised variable."); return false; } start_params[ivar].LowLim = lower; return true; } bool SetVariableUpperLimit(unsigned int ivar, double upper) { if (start_params.size() <= ivar) { ERROR(WRN, "Tried to set uninitialised variable."); return false; } start_params[ivar].UpLim = upper; return true; } bool SetVariableLimits(unsigned int ivar, double lower, double upper) { SetVariableLowerLimit(ivar, lower); SetVariableUpperLimit(ivar, upper); return true; } bool FixVariable(unsigned int ivar) { if (start_params.size() <= ivar) { ERROR(WRN, "Tried to fix uninitialised variable."); return false; } start_params[ivar].IsFixed = true; return true; } bool ReleaseVariable(unsigned int ivar) { if (start_params.size() <= ivar) { ERROR(WRN, "Tried to fix uninitialised variable."); return false; } start_params[ivar].IsFixed = false; return true; } bool IsFixedVariable(unsigned int ivar) { if (start_params.size() <= ivar) { ERROR(WRN, "Tried to fix uninitialised variable."); return false; } return start_params[ivar].IsFixed; } double MinValue() const { return min_value; } const double *X() const { return min_params.data(); } const double *Errors() const { return min_params.data(); } unsigned int NDim() const { return start_params.size(); } unsigned int NFree() const { unsigned int NFree = 0; for (size_t p_it = 0; p_it < start_params.size(); ++p_it) { NFree += !start_params[p_it].IsFixed; } return NFree; } void AddBranches() { TFile *ogf = gFile; - if (FitPar::Config().out && FitPar::Config().out->IsOpen()) { - FitPar::Config().out->cd(); + if (Config::Get().out && Config::Get().out->IsOpen()) { + Config::Get().out->cd(); } StepTree = new TTree("MCMChain", ""); StepTree->Branch("Step", &step_i, "Step/I"); StepTree->Branch("Value", &curr_value, "Value/D"); StepTree->Branch("Moved", &moved, "Moved/I"); std::stringstream ss(""); for (size_t p_it = 0; p_it < curr_params.size(); ++p_it) { ss.str(""); ss << "param_" << p_it; StepTree->Branch(ss.str().c_str(), &curr_params[p_it], (ss.str() + "/D").c_str()); } if (ogf && ogf->IsOpen()) { ogf->cd(); } } void Fill() { StepTree->Fill(); } void Propose() { for (size_t p_it = 0; p_it < start_params.size(); ++p_it) { double propose_param = curr_params[p_it]; if (!start_params[p_it].IsFixed) { size_t attempts = 0; do { if (attempts > 1000) { THROW("After 1000 attempts, failed to throw Gaus(" << start_params[p_it].Val << ", " << start_params[p_it].StepWidth << ") inside limits: [ " << start_params[p_it].LowLim << " -- " << start_params[p_it].UpLim << " ]"); } double thr = RNJesus.Gaus(curr_params[p_it], start_params[p_it].StepWidth); if ((start_params[p_it].LowLim != 0xdeadbeef) && (thr < start_params[p_it].LowLim)) { attempts++; continue; } if ((start_params[p_it].UpLim != 0xdeadbeef) && (thr > start_params[p_it].UpLim)) { attempts++; continue; } propose_param = thr; break; } while (true); } propose_params[p_it] = propose_param; } } void Evaluate() { propose_value = exp(-(*FCN)(propose_params.data()) / 10000.0); if (propose_value < min_value) { min_params = propose_params; } } void PrintResults() { QLOG(FIT, "Simple_MH_Sampler State: "); for (size_t p_it = 0; p_it < start_params.size(); ++p_it) { QLOG(FIT, "\t[" << p_it << "]: " << (start_params[p_it].IsFixed ? " FIX" : "FREE") << " " << curr_params[p_it]); } QLOG(FIT, "Curr LHood: " << curr_value << ", Min LHood: " << min_value); } void Step() { moved = false; if (propose_value != propose_value) { curr_params = propose_params; curr_value = propose_value; PrintResults(); THROW("Proposed a NAN value."); } std::cout << "[" << step_i << "] proposed: " << propose_value << " | current: " << curr_value << std::endl; double a = propose_value / curr_value; std::cout << "\ta = " << a << std::endl; if (a >= 1.0) { moved = true; std::cout << "\tMoved." << std::endl; } else { double b = RNJesus.Uniform(1); if (b < a) { moved = true; std::cout << "\tMoved (" << b << ")" << std::endl; } else { std::cout << "\tStayed. (" << b << ")" << std::endl; } } if (moved) { curr_params = propose_params; curr_value = propose_value; } } bool Minimize() { if (!start_params.size()) { ERROR(FTL, "No Parameters passed to Simple_MH_Sampler."); return false; } RestartParams(); AddBranches(); size_t NSteps = Options().MaxIterations(); trace.Set(NSteps); QLOG(FIT, "Running chain for " << NSteps << " steps."); step_i = 0; while (step_i < NSteps) { Propose(); Evaluate(); Step(); trace.SetPoint(step_i, step_i, curr_value); if (step_i >= discard) { thin_ctr++; if (thin_ctr == thin) { Fill(); thin_ctr = 0; } } step_i++; } StepTree->Write(); trace.Write("MCMCTrace"); return true; }; }; diff --git a/src/Routines/SplineRoutines.cxx b/src/Routines/SplineRoutines.cxx index 8a24297..9369da2 100755 --- a/src/Routines/SplineRoutines.cxx +++ b/src/Routines/SplineRoutines.cxx @@ -1,2593 +1,2588 @@ // 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 "SplineRoutines.h" void SplineRoutines::Init() { fStrategy = "SaveEvents"; fRoutines.clear(); fCardFile = ""; fSampleFCN = NULL; fRW = NULL; fAllowedRoutines = ("SaveEvents,TestEvents,SaveSplineEvents"); }; SplineRoutines::~SplineRoutines() { }; SplineRoutines::SplineRoutines(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, "-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.AddS("cardfile", fCardFile); - fCompKey.AddS("outputfile", fOutputFile); - if (!fStrategy.empty()) fCompKey.AddS("strategy", fStrategy); + if (!fCardFile.empty()) fCompKey.Set("cardfile", fCardFile); + fCompKey.Set("outputfile", fOutputFile); + if (!fStrategy.empty()) fCompKey.Set("strategy", fStrategy); // Load XML Cardfile - configuration.LoadConfig( fCompKey.GetS("cardfile"), ""); - - // Add CMD XML Structs - for (size_t i = 0; i < xmlcmds.size(); i++) { - configuration.AddXMLLine(xmlcmds[i]); - } + 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")) { std::cout << "[ NUISANCE ] : Overriding " << "MAXEVENTS=" + maxevents << std::endl; configuration.OverrideConfig("MAXEVENTS=" + maxevents); } // Finish configuration XML - configuration.FinaliseConfig(fCompKey.GetS("outputfile") + ".xml"); + configuration.FinaliseSettings(fCompKey.GetS("outputfile") + ".xml"); // Add Error Verbo Lines - verbocount += Config::Get().GetParI("VERBOSITY"); - errorcount += Config::Get().GetParI("ERROR"); + 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); // Starting Setup // --------------------------- SetupRWEngine(); return; }; /* Setup Functions */ //************************************* void SplineRoutines::SetupRWEngine() { //************************************* fRW = new FitWeight("splineweight"); // std::vector splinekeys = Config::QueryKeys("spline"); std::vector parameterkeys = Config::QueryKeys("parameter"); // Add Parameters for (size_t i = 0; i < parameterkeys.size(); i++) { nuiskey key = parameterkeys[i]; std::string parname = key.GetS("name"); std::string partype = key.GetS("type"); double nom = key.GetD("nominal"); fRW->IncludeDial( key.GetS("name"), FitBase::ConvDialType(key.GetS("type")), nom); fRW->SetDialValue( key.GetS("name"), key.GetD("nominal") ); } fRW->Reconfigure(); return; } /* Fitting Functions */ //************************************* void SplineRoutines::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; fRW->SetDialValue(name, updateVals.at(name)); } fRW->Reconfigure(); return; } //************************************* void SplineRoutines::Run() { //************************************* std::cout << "Running " << std::endl; // Parse given routines fRoutines = GeneralUtils::ParseToStr(fStrategy, ","); if (fRoutines.empty()) { ERR(FTL) << "Trying to run ComparisonRoutines with no routines given!" << std::endl; throw; } for (size_t i = 0; i < fRoutines.size(); i++) { LOG(FIT) << "Running Routine: " << fRoutines[i] << std::endl; std::string rout = fRoutines[i]; if (!rout.compare("SaveEvents")) SaveEvents(); else if (!rout.compare("TestEvents")) TestEvents(); else if (!rout.compare("GenerateEventSplines")) { GenerateEventWeights(); BuildEventSplines(); } else if (!rout.compare("GenerateEventWeights")) { GenerateEventWeights(); } else if (!rout.compare("GenerateEventWeightChunks")){ GenerateEventWeightChunks(FitPar::Config().GetParI("spline_procchunk")); } else if (!rout.compare("BuildEventSplines")) { BuildEventSplines(); } else if (!rout.compare("TestSplines_1DEventScan")) TestSplines_1DEventScan(); else if (!rout.compare("TestSplines_NDEventThrow")) TestSplines_NDEventThrow(); else if (!rout.compare("SaveSplinePlots")) SaveSplinePlots(); else if (!rout.compare("TestSplines_1DLikelihoodScan")) TestSplines_1DLikelihoodScan(); else if (!rout.compare("TestSplines_NDLikelihoodThrow")) TestSplines_NDLikelihoodThrow(); else if (!rout.compare("BuildEventSplinesChunks")) { int chunk = FitPar::Config().GetParI("spline_procchunk"); BuildEventSplines(chunk); } else if (!rout.compare("MergeEventSplinesChunks")) { MergeEventSplinesChunks(); } } } //************************************* void SplineRoutines::SaveEvents() { //************************************* if (fRW) delete fRW; SetupRWEngine(); fRW->Reconfigure(); fRW->Print(); // Generate a set of nominal events // Method, Loop over inputs, create input handler, then create a ttree std::vector eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } // Make new outputfile TFile* outputfile = new TFile(outputfilename.c_str(), "RECREATE"); outputfile->cd(); // Make a new input handler std::vector file_descriptor = GeneralUtils::ParseToStr(inputfilename, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfilename << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inptype = InputUtils::ParseInputType(file_descriptor[0]); InputHandlerBase* input = InputUtils::CreateInputHandler("eventsaver", inptype, file_descriptor[1]); // Get info from inputhandler int nevents = input->GetNEvents(); int countwidth = (nevents / 10); FitEvent* nuisevent = input->FirstNuisanceEvent(); // Setup a TTree to save the event outputfile->cd(); TTree* eventtree = new TTree("nuisance_events", "nuisance_events"); nuisevent->AddBranchesToTree(eventtree); // Loop over all events and fill the TTree int icount = 0; // int countwidth = nevents / 5; while (nuisevent) { // Get Event Weight nuisevent->RWWeight = fRW->CalcWeight(nuisevent); // if (nuisevent->RWWeight != 1.0){ // std::cout << "Weight = " << nuisevent->RWWeight << std::endl; // } // Save everything eventtree->Fill(); // Logging if (icount % countwidth == 0) { LOG(REC) << "Saved " << icount << "/" << nevents << " nuisance events. [M, W] = [" << nuisevent->Mode << ", " << nuisevent->RWWeight << "]" << std::endl; } // iterate nuisevent = input->NextNuisanceEvent(); icount++; } // Save flux and close file outputfile->cd(); eventtree->Write(); input->GetFluxHistogram()->Write("nuisance_fluxhist"); input->GetEventHistogram()->Write("nuisance_eventhist"); // Close Output outputfile->Close(); // Delete Inputs delete input; } // remove Keys eventkeys.clear(); // Finished LOG(FIT) << "Finished processing all nuisance events." << std::endl; } //************************************* void SplineRoutines::TestEvents() { //************************************* LOG(FIT) << "Testing events." << std::endl; // Create a new file for the test samples if (!fOutputRootFile) { fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE"); } // Loop over all tests int count = 0; std::vector testkeys = Config::QueryKeys("sampletest"); for (std::vector::iterator iter = testkeys.begin(); iter != testkeys.end(); iter++) { nuiskey key = (*iter); // 0. Create new measurement list std::list samplelist; // 1. Build Sample From Events std::string samplename = key.GetS("name"); std::string eventsid = key.GetS("inputid"); nuiskey eventskey = Config::QueryLastKey("events", "id=" + eventsid); std::string rawfile = eventskey.GetS("input"); LOG(FIT) << "Creating sample " << samplename << std::endl; MeasurementBase* rawsample = SampleUtils::CreateSample(samplename, rawfile, "", "", FitBase::GetRW()); // 2. Build Sample From Nuisance Events std::string eventsfile = eventskey.GetS("output"); LOG(FIT) << "Creating Fit Eevnt Sample " << samplename << " " << eventsfile << std::endl; MeasurementBase* nuissample = SampleUtils::CreateSample(samplename, "FEVENT:" + eventsfile, "", "", FitBase::GetRW()); // 3. Make some folders to save stuff TDirectory* sampledir = (TDirectory*) fOutputRootFile->mkdir(Form((samplename + "_test_%d").c_str(), count)); TDirectory* rawdir = (TDirectory*) sampledir->mkdir("raw"); TDirectory* nuisancedir = (TDirectory*) sampledir->mkdir("nuisance"); TDirectory* difdir = (TDirectory*) sampledir->mkdir("difference"); // 4. Reconfigure both rawdir->cd(); rawsample->Reconfigure(); rawsample->Write(); nuisancedir->cd(); nuissample->Reconfigure(); nuissample->Write(); // 4. Compare Raw to Nuisance Events // Loop over all keyse TIter next(rawdir->GetListOfKeys()); TKey *dirkey; while ((dirkey = (TKey*)next())) { // If not a 1D/2D histogram skip TClass *cl = gROOT->GetClass(dirkey->GetClassName()); if (!cl->InheritsFrom("TH1D") and !cl->InheritsFrom("TH2D")) continue; // Get TH1* from both dir TH1 *rawplot = (TH1*)rawdir->Get(dirkey->GetName()); TH1 *nuisanceplot = (TH1*)nuisancedir->Get(dirkey->GetName()); // Take Difference nuisanceplot->Add(rawplot, -1.0); // Save to dif folder difdir->cd(); nuisanceplot->Write(); } // 5. Tidy Up samplelist.clear(); // Iterator count++; } } void SplineRoutines::GenerateEventWeightChunks(int procchunk) { if (fRW) delete fRW; SetupRWEngine(); // Setup the spline reader SplineWriter* splwrite = new SplineWriter(fRW); std::vector splinekeys = Config::QueryKeys("spline"); // Add splines to splinewriter for (std::vector::iterator iter = splinekeys.begin(); iter != splinekeys.end(); iter++) { nuiskey splkey = (*iter); // Add Spline Info To Reader splwrite->AddSpline(splkey); } splwrite->SetupSplineSet(); // Event Loop // Loop over all events and calculate weights for each parameter set. // Generate a set of nominal events // Method, Loop over inputs, create input handler, then create a ttree std::vector eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } outputfilename += ".weights.root"; // Make new outputfile TFile* outputfile = new TFile(outputfilename.c_str(), "RECREATE"); outputfile->cd(); // Make a new input handler std::vector file_descriptor = GeneralUtils::ParseToStr(inputfilename, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfilename << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inptype = InputUtils::ParseInputType(file_descriptor[0]); InputHandlerBase* input = InputUtils::CreateInputHandler("eventsaver", inptype, file_descriptor[1]); // Get info from inputhandler int nevents = input->GetNEvents(); // int countwidth = (nevents / 1000); FitEvent* nuisevent = input->FirstNuisanceEvent(); // Setup a TTree to save the event outputfile->cd(); TTree* eventtree = new TTree("nuisance_events", "nuisance_events"); // Add a flag that allows just splines to be saved. nuisevent->AddBranchesToTree(eventtree); // Save the spline reader splwrite->Write("spline_reader"); // Setup the spline TTree TTree* weighttree = new TTree("weight_tree", "weight_tree"); splwrite->AddWeightsToTree(weighttree); // Make container for all weights int nweights = splwrite->GetNWeights(); // int npar = splwrite->GetNPars(); // double* weightcont = new double[nweights]; int lasttime = time(NULL); // Load N Chunks of the Weights into Memory // Split into N processing chunks int nchunks = FitPar::Config().GetParI("spline_chunks"); if (nchunks <= 0) nchunks = 1; if (nchunks >= nevents / 2) nchunks = nevents / 2; std::cout << "Starting NChunks " << nchunks << std::endl; for (int ichunk = 0; ichunk < nchunks; ichunk++) { // Skip to only do one processing chunk if (procchunk != -1 and procchunk != ichunk) continue; LOG(FIT) << "On Processing Chunk " << ichunk << std::endl; int neventsinchunk = nevents / nchunks; int loweventinchunk = neventsinchunk * ichunk; // int higheventinchunk = neventsinchunk * (ichunk + 1); double** allweightcont = new double*[neventsinchunk]; for (int k = 0; k < neventsinchunk; k++){ allweightcont[k] = new double[nweights]; } // Start Set Processing Here. for (int iset = 0; iset < nweights; iset++) { splwrite->ReconfigureSet(iset); // Could reorder this to save the weightconts in order instead of reconfiguring per event. // Loop over all events and fill the TTree for (int i = 0; i < neventsinchunk; i++){ nuisevent = input->GetNuisanceEvent(i+loweventinchunk); double w = splwrite->GetWeightForThisSet(nuisevent); if (iset == 0){ allweightcont[i][0] = w; } else { allweightcont[i][iset] = w/allweightcont[i][0]; } // Save everything if (iset == 0) { eventtree->Fill(); } } std::ostringstream timestring; int timeelapsed = time(NULL) - lasttime; if (timeelapsed) { lasttime = time(NULL); int setsleft = (nweights-iset-1) + (nweights * (nchunks - ichunk - 1)); float proj = (float(setsleft) *timeelapsed) / 60 / 60; timestring << setsleft << " sets remaining. Last one took " << timeelapsed << ". " << proj << " hours remaining."; } LOG(REC) << "Processed Set " << iset << "/" << nweights <<" in chunk " << ichunk << "/" << nchunks << " " << timestring.str() << std::endl; } // Fill weights for this chunk into the TTree for (int k = 0; k < neventsinchunk; k++){ splwrite->SetWeights(allweightcont[k]); weighttree->Fill(); } } // at end of the chunk, when all sets have been done // loop over the container and fill weights to ttree outputfile->cd(); eventtree->Write(); weighttree->Write(); input->GetFluxHistogram()->Write("nuisance_fluxhist"); input->GetEventHistogram()->Write("nuisance_eventhist"); splwrite->Write("spline_reader"); outputfile->Close(); // Close Output outputfile->Close(); // Delete Inputs delete input; } // remove Keys eventkeys.clear(); } //************************************* void SplineRoutines::GenerateEventWeights() { //************************************* if (fRW) delete fRW; SetupRWEngine(); // Setup the spline reader SplineWriter* splwrite = new SplineWriter(fRW); std::vector splinekeys = Config::QueryKeys("spline"); // Add splines to splinewriter for (std::vector::iterator iter = splinekeys.begin(); iter != splinekeys.end(); iter++) { nuiskey splkey = (*iter); // Add Spline Info To Reader splwrite->AddSpline(splkey); } splwrite->SetupSplineSet(); // Event Loop // Loop over all events and calculate weights for each parameter set. // Generate a set of nominal events // Method, Loop over inputs, create input handler, then create a ttree std::vector eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } outputfilename += ".weights.root"; // Make new outputfile TFile* outputfile = new TFile(outputfilename.c_str(), "RECREATE"); outputfile->cd(); // Make a new input handler std::vector file_descriptor = GeneralUtils::ParseToStr(inputfilename, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfilename << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inptype = InputUtils::ParseInputType(file_descriptor[0]); InputHandlerBase* input = InputUtils::CreateInputHandler("eventsaver", inptype, file_descriptor[1]); // Get info from inputhandler int nevents = input->GetNEvents(); int countwidth = (nevents / 1000); FitEvent* nuisevent = input->FirstNuisanceEvent(); // Setup a TTree to save the event outputfile->cd(); TTree* eventtree = new TTree("nuisance_events", "nuisance_events"); // Add a flag that allows just splines to be saved. nuisevent->AddBranchesToTree(eventtree); // Save the spline reader splwrite->Write("spline_reader"); // Setup the spline TTree TTree* weighttree = new TTree("weight_tree", "weight_tree"); splwrite->AddWeightsToTree(weighttree); // Make container for all weights int nweights = splwrite->GetNWeights(); // int npar = splwrite->GetNPars(); double* weightcont = new double[nweights]; int lasttime = time(NULL); // Could reorder this to save the weightconts in order instead of reconfiguring per event. // Loop over all events and fill the TTree while (nuisevent) { // Calculate the weights for each parameter set splwrite->GetWeightsForEvent(nuisevent, weightcont); // Save everything eventtree->Fill(); weighttree->Fill(); // Logging if (i % countwidth == 0) { std::ostringstream timestring; int timeelapsed = time(NULL) - lasttime; if (i != 0 and timeelapsed) { lasttime = time(NULL); int eventsleft = nevents - i; float speed = float(countwidth) / float(timeelapsed); float proj = (float(eventsleft) / float(speed)) / 60 / 60; timestring << proj << " hours remaining."; } LOG(REC) << "Saved " << i << "/" << nevents << " nuisance spline weights. " << timestring.str() << std::endl; } // Iterate i++; nuisevent = input->NextNuisanceEvent(); } // at end of the chunk, when all sets have been done // loop over the container and fill weights to ttree outputfile->cd(); eventtree->Write(); weighttree->Write(); input->GetFluxHistogram()->Write("nuisance_fluxhist"); input->GetEventHistogram()->Write("nuisance_eventhist"); splwrite->Write("spline_reader"); outputfile->Close(); // Close Output outputfile->Close(); // Delete Inputs delete input; } // remove Keys eventkeys.clear(); } //************************************* void SplineRoutines::GenerateEventSplines() { //************************************* if (fRW) delete fRW; SetupRWEngine(); // Setup the spline reader SplineWriter* splwrite = new SplineWriter(fRW); std::vector splinekeys = Config::QueryKeys("spline"); // Add splines to splinewriter for (std::vector::iterator iter = splinekeys.begin(); iter != splinekeys.end(); iter++) { nuiskey splkey = (*iter); // Add Spline Info To Reader splwrite->AddSpline(splkey); } splwrite->SetupSplineSet(); // Make an ugly list for N cores int ncores = FitPar::Config().GetParI("NCORES");//omp_get_max_threads(); std::vector splwriterlist; for (int i = 0; i < ncores; i++) { SplineWriter* tmpwriter = new SplineWriter(fRW); for (std::vector::iterator iter = splinekeys.begin(); iter != splinekeys.end(); iter++) { nuiskey splkey = (*iter); // Add Spline Info To Reader tmpwriter->AddSpline(splkey); } tmpwriter->SetupSplineSet(); splwriterlist.push_back(tmpwriter); } // Event Loop // Loop over all events and calculate weights for each parameter set. // Generate a set of nominal events // Method, Loop over inputs, create input handler, then create a ttree std::vector eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } // Make new outputfile TFile* outputfile = new TFile(outputfilename.c_str(), "RECREATE"); outputfile->cd(); // Make a new input handler std::vector file_descriptor = GeneralUtils::ParseToStr(inputfilename, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfilename << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inptype = InputUtils::ParseInputType(file_descriptor[0]); InputHandlerBase* input = InputUtils::CreateInputHandler("eventsaver", inptype, file_descriptor[1]); // Get info from inputhandler int nevents = input->GetNEvents(); int countwidth = (nevents / 1000); FitEvent* nuisevent = input->FirstNuisanceEvent(); // Setup a TTree to save the event outputfile->cd(); TTree* eventtree = new TTree("nuisance_events", "nuisance_events"); // Add a flag that allows just splines to be saved. nuisevent->AddBranchesToTree(eventtree); // Save the spline reader splwrite->Write("spline_reader"); // Setup the spline TTree TTree* weighttree = new TTree("weight_tree", "weight_tree"); splwrite->AddWeightsToTree(weighttree); // Make container for all weights int nweights = splwrite->GetNWeights(); double** weightcont = new double*[nevents]; for (int k = 0; k < nevents; k++) { weightcont[k] = new double[nweights]; } int npar = splwrite->GetNPars(); int lasttime = time(NULL); // Could reorder this to save the weightconts in order instead of reconfiguring per event. // Loop over all events and fill the TTree while (nuisevent) { // std::cout << "Fitting event " << i << std::endl; // Calculate the weights for each parameter set // splwrite->FitSplinesForEvent(nuisevent); splwrite->GetWeightsForEvent(nuisevent, weightcont[i]); bool hasresponse = false; for (int j = 0; j < nweights; j++) { if (weightcont[i][j] != 1.0) { // std::cout << "Non Zero Weight at " << i << " " << j << std::endl; hasresponse = true; } else { // std::cout << "Empty Weight at " << i << " " << j << std::endl; } } if (!hasresponse) { // std::cout << "Deleting flat response " << nuisevent->Mode << std::endl; delete weightcont[i]; weightcont[i] = NULL; } // Save everything eventtree->Fill(); weighttree->Fill(); // splinetree->Fill(); // nuisevent->Print(); // std::cout << "Done with event " << i << std::endl; // Push weight sets into a the array // sleep(4); // Logging if (i % countwidth == 0) { std::ostringstream timestring; int timeelapsed = time(NULL) - lasttime; if (i != 0 and timeelapsed) { lasttime = time(NULL); int eventsleft = nevents - i; float speed = float(countwidth) / float(timeelapsed); float proj = (float(eventsleft) / float(speed)) / 60 / 60; timestring << proj << " hours remaining."; } LOG(REC) << "Saved " << i << "/" << nevents << " nuisance spline weights. " << timestring.str() << std::endl; } // Iterate i++; nuisevent = input->NextNuisanceEvent(); } outputfile->cd(); eventtree->Write(); weighttree->Write(); input->GetFluxHistogram()->Write("nuisance_fluxhist"); input->GetEventHistogram()->Write("nuisance_eventhist"); outputfile->Close(); outputfile = new TFile(outputfilename.c_str(), "UPDATE"); outputfile->cd(); weighttree = (TTree*) outputfile->Get("weight_tree"); // splwrite->ReadWeightsFromTree(weighttree); // Divide weights container into Ncores. // Parrallelise this loop checking for what core we are on. // for (int i = 0; i < nevents; i++){ // splwriterlist[int(i / (nevents/4))]->FitSplinesForEvent(coeff); // } // // Now loop over weights tree // for (int i = 0; i < weighttree->GetEntries(); i++) { // weighttree->GetEntry(i); // splwrite->FitSplinesForEvent(); // splinetree->Fill(); // if (i % countwidth == 0) { // std::ostringstream timestring; // int timeelapsed = time(NULL) - lasttime; // if (i != 0 and timeelapsed) { // lasttime = time(NULL); // int eventsleft = nevents - i; // float speed = float(countwidth) / float(timeelapsed); // float proj = (float(eventsleft) / float(speed)) / 60 / 60; // timestring << proj << " hours remaining."; // } // LOG(REC) << "Built " << i << "/" << nevents << " nuisance spline events. " << timestring.str() << std::endl; // } // } // Get Splines float** allcoeff = new float*[nevents]; for (int k = 0; k < nevents; k++) { allcoeff[k] = new float[npar]; } // #pragma omp parallel for num_threads(ncores) for (int i = 0; i < nevents; i++) { //#pragma omp atomic // printf("Using Thread %d to build event %d \n", int(omp_get_thread_num()), (int)i ); // std::cout<< " -> Writer = " << splwriterlist[ i / (nevents/ncores) ] << std::endl; // #pragma omp atomic if (weightcont[i]) { splwriterlist[ int(omp_get_thread_num()) ]->FitSplinesForEvent(weightcont[i], allcoeff[i]); } else { for (int j = 0; j < npar; j++) { allcoeff[i][j] = float(0.0); } } // splwrite->FitSplinesForEvent(weightcont[i], allcoeff[i]); if (i % 500 == 0) { if (LOG_LEVEL(REC)) { printf("Using Thread %d to build event %d \n", int(omp_get_thread_num()), (int)i ); } } /* std::ostringstream timestring; int timeelapsed = time(NULL) - lasttime; if (i != 0 and timeelapsed) { lasttime = time(NULL); int eventsleft = nevents - i; float speed = float(countwidth) / float(timeelapsed); float proj = (float(eventsleft) / float(speed)) / 60 / 60; timestring << proj << " hours remaining."; timestring << " Using Writer at " << i / (nevents/ncores) << " = " << splwriterlist[ i / (nevents/ncores) ] << std::endl; } LOG(REC) << "Built " << i << "/" << nevents << " nuisance spline events. " << timestring.str() << std::endl; } */ } // Save Splines into TTree float* coeff = new float[npar]; outputfile->cd(); TTree* splinetree = new TTree("spline_tree", "spline_tree"); splinetree->Branch("SplineCoeff", coeff, Form("SplineCoeff[%d]/F", npar)); std::cout << "Saving to the allcoeff" << std::endl; for (int k = 0; k < nevents; k++) { for (int l = 0; l < npar; l++) { coeff[l] = allcoeff[k][l]; } std::cout << "Coeff 0, 1, 2 = " << coeff[0] << " " << coeff[1] << " " << coeff[2] << std::endl; splinetree->Fill(); } // Save flux and close file outputfile->cd(); splinetree->Write(); // Delete the container. for (int k = 0; k < nevents; k++) { delete weightcont[k]; } delete weightcont; delete coeff; // Close Output outputfile->Close(); // Delete Inputs delete input; } // remove Keys eventkeys.clear(); } //************************************* void SplineRoutines::BuildEventSplines(int procchunk) { //************************************* if (fRW) delete fRW; SetupRWEngine(); // Setup the spline reader SplineWriter* splwrite = new SplineWriter(fRW); std::vector splinekeys = Config::QueryKeys("spline"); // Add splines to splinewriter for (std::vector::iterator iter = splinekeys.begin(); iter != splinekeys.end(); iter++) { nuiskey splkey = (*iter); // Add Spline Info To Reader splwrite->AddSpline(splkey); } splwrite->SetupSplineSet(); // Make an ugly list for N cores int ncores = FitPar::Config().GetParI("spline_cores");//omp_get_max_threads(); if (ncores > omp_get_max_threads()) ncores = omp_get_max_threads(); if (ncores <= 0) ncores = 1; std::vector splwriterlist; for (int i = 0; i < ncores; i++) { SplineWriter* tmpwriter = new SplineWriter(fRW); for (std::vector::iterator iter = splinekeys.begin(); iter != splinekeys.end(); iter++) { nuiskey splkey = (*iter); // Add Spline Info To Reader tmpwriter->AddSpline(splkey); } tmpwriter->SetupSplineSet(); splwriterlist.push_back(tmpwriter); } // Event Loop // Loop over all events and calculate weights for each parameter set. // Generate a set of nominal events // Method, Loop over inputs, create input handler, then create a ttree std::vector eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } // Make new outputfile TFile* outputfile; if (procchunk == -1) outputfile = new TFile(outputfilename.c_str(), "RECREATE"); else outputfile = new TFile((outputfilename + std::string(Form(".coeffchunk_%d.root", procchunk))).c_str(), "RECREATE"); outputfile->cd(); // Get Weights File TFile* weightsfile = new TFile((outputfilename + ".weights.root").c_str(), "READ"); TTree* weighttree = (TTree*) weightsfile->Get("weight_tree"); // Get SPLWRite Info //splwrite->ReadWeightsFromTree(weighttree); int nevents = weighttree->GetEntries(); // int countwidth = (nevents / 1000); int nweights = splwrite->GetNWeights(); int npar = splwrite->GetNPars(); // Access Weights double* eventweights = new double[nweights]; weighttree->SetBranchAddress("SplineWeights", eventweights); // Make counter // int lasttime = time(NULL); // Setup Splines To Be Saved into TTree outputfile->cd(); TTree* splinetree = new TTree("spline_tree", "spline_tree"); float* coeff = new float[npar]; splinetree->Branch("SplineCoeff", coeff, Form("SplineCoeff[%d]/F", npar)); // Load N Chunks of the Weights into Memory // Split into N processing chunks int nchunks = FitPar::Config().GetParI("spline_chunks"); if (nchunks <= 0) nchunks = 1; if (nchunks >= nevents / 2) nchunks = nevents / 2; std::cout << "Starting NChunks " << nchunks << std::endl; sleep(1); for (int ichunk = 0; ichunk < nchunks; ichunk++) { // Skip to only do one processing chunk if (procchunk != -1 and procchunk != ichunk) continue; LOG(FIT) << "On Processing Chunk " << ichunk << std::endl; int neventsinchunk = nevents / nchunks; int loweventinchunk = neventsinchunk * ichunk; // int higheventinchunk = neventsinchunk * (ichunk + 1); // Build Chunk Containers for Event Weights double** weightcont = new double*[nevents]; float** allcoeff = new float*[nevents]; // Load Chunks into Containers for (int k = 0; k < neventsinchunk; k++) { weighttree->GetEntry(loweventinchunk + k); weightcont[k] = new double[nweights]; allcoeff[k] = new float[npar]; bool hasresponse = false; for (int j = 0; j < nweights; j++) { weightcont[k][j] = eventweights[j]; if (eventweights[j] != 1.0) hasresponse = true; } if (!hasresponse) delete weightcont[k]; } // Loop over ncores and process chunks // #pragma omp parallel for num_threads(ncores) for (int k = 0; k < neventsinchunk; k++) { if (weightcont[k]) { splwriterlist[ int(omp_get_thread_num()) ]->FitSplinesForEvent(weightcont[k], allcoeff[k]); } else { for (int j = 0; j < npar; j++) { allcoeff[k][j] = float(0.0); } } if (k + loweventinchunk % 500 == 0) { if (LOG_LEVEL(REC)) { printf("Using Thread %d to build event %d in chunk %d \n", int(omp_get_thread_num()), (int) loweventinchunk + k, ichunk ); } } } // Save Coeff To Tree std::cout << "Saving coeffs to Tree in Chunk " << ichunk << std::endl; for (int k = 0; k < neventsinchunk; k++) { for (int l = 0; l < npar; l++) { coeff[l] = allcoeff[k][l]; } // std::cout << "Coeff 0, 1, 2 = " << coeff[0] << " " << coeff[1] << " " << coeff[2] << std::endl; splinetree->Fill(); } // Delete the container. for (int k = 0; k < neventsinchunk; k++) { if (weightcont[k]) delete weightcont[k]; if (allcoeff[k]) delete allcoeff[k]; } delete allcoeff; delete weightcont; } // Save flux and close file outputfile->cd(); splinetree->Write(); if (procchunk == -1 or procchunk == 0) { outputfile->cd(); splwrite->Write("spline_reader"); TTree* nuisanceevents = (TTree*) weightsfile->Get("nuisance_events"); nuisanceevents->CloneTree()->Write(); weighttree->CloneTree()->Write(); TH1D* nuisance_fluxhist = (TH1D*) weightsfile->Get("nuisance_fluxhist"); TH1D* nuisance_eventhist = (TH1D*) weightsfile->Get("nuisance_eventhist"); nuisance_fluxhist->Write("nuisance_fluxhist"); nuisance_eventhist->Write("nuisance_eventhist"); } weightsfile->Close(); // Add option to build seperate chunks // Close Output outputfile->Close(); } // remove Keys eventkeys.clear(); } void SplineRoutines::MergeEventSplinesChunks() { if (fRW) delete fRW; SetupRWEngine(); // Setup the spline reader SplineWriter* splwrite = new SplineWriter(fRW); std::vector splinekeys = Config::QueryKeys("spline"); // Add splines to splinewriter for (std::vector::iterator iter = splinekeys.begin(); iter != splinekeys.end(); iter++) { nuiskey splkey = (*iter); // Add Spline Info To Reader splwrite->AddSpline(splkey); } splwrite->SetupSplineSet(); std::vector eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } // Make new outputfile TFile* outputfile = new TFile(outputfilename.c_str(), "RECREATE"); outputfile->cd(); // Get Weights File TFile* weightsfile = new TFile((outputfilename + ".weights.root").c_str(), "READ"); TTree* weighttree = (TTree*) weightsfile->Get("weight_tree"); // Get SPLWRite Info //splwrite->ReadWeightsFromTree(weighttree); int nevents = weighttree->GetEntries(); // int countwidth = (nevents / 1000); // int nweights = splwrite->GetNWeights(); int npar = splwrite->GetNPars(); // Make counter // int lasttime = time(NULL); // Setup Splines To Be Saved into TTree outputfile->cd(); TTree* splinetree = new TTree("spline_tree", "spline_tree"); float* coeff = new float[npar]; splinetree->Branch("SplineCoeff", coeff, Form("SplineCoeff[%d]/F", npar)); // Load N Chunks of the Weights into Memory // Split into N processing chunks int nchunks = FitPar::Config().GetParI("spline_chunks"); if (nchunks <= 0) nchunks = 1; if (nchunks >= nevents / 2) nchunks = nevents / 2; int neventsinchunk = nevents / nchunks; for (int ichunk = 0; ichunk < nchunks; ichunk++) { // Get Output File TFile* chunkfile = new TFile( (outputfilename + std::string(Form(".coeffchunk_%d.root", ichunk))).c_str() ); // Get TTree for spline coeffchunk TTree* splinetreechunk = (TTree*) chunkfile->Get("spline_tree"); // Set Branch Address to coeffchunk float* coeffchunk = new float[npar]; splinetreechunk->SetBranchAddress("SplineCoeff", coeffchunk); // Loop over nevents in chunk for (int k = 0; k < neventsinchunk; k++) { splinetreechunk->GetEntry(k); for (int j = 0; j < npar; j++) { coeff[j] = coeffchunk[j]; } splinetree->Fill(); } // Close up chunkfile->Close(); delete coeffchunk; std::cout << "Merged chunk " << ichunk << std::endl; } // Save flux and close file outputfile->cd(); splinetree->Write(); outputfile->cd(); splwrite->Write("spline_reader"); TTree* nuisanceevents = (TTree*) weightsfile->Get("nuisance_events"); nuisanceevents->CloneTree()->Write(); weighttree->CloneTree()->Write(); TH1D* nuisance_fluxhist = (TH1D*) weightsfile->Get("nuisance_fluxhist"); TH1D* nuisance_eventhist = (TH1D*) weightsfile->Get("nuisance_eventhist"); nuisance_fluxhist->Write("nuisance_fluxhist"); nuisance_eventhist->Write("nuisance_eventhist"); weightsfile->Close(); // Add option to build seperate chunks // Close Output outputfile->Close(); } // remove Keys eventkeys.clear(); } // void SplineRoutines::BuildSplineChunk(){ //} // void SplineRoutines::MergeSplineChunks(){ //} //************************************* void SplineRoutines::MergeSplines() { //************************************* // Loop over all 'splinemerge' keys. // Add them to the Merger. // Call setup splines. // Get the key with eventinput // - remaining keys should have splineinput // - Loop over number of entries. // - FillEntry in merger. // - Fill NUISANCEEvent into a new TTree. SplineMerger* splmerge = new SplineMerger(); std::vector splinekeys = Config::QueryKeys("splinemerge"); for (std::vector::iterator iter = splinekeys.begin(); iter != splinekeys.end(); iter++) { nuiskey splkey = (*iter); TFile* infile = new TFile(splkey.GetS("input").c_str(), "READ"); splmerge->AddSplineSetFromFile(infile); } splmerge->SetupSplineSet(); // Now get Event File std::vector eventkeys = Config::QueryKeys("eventmerge"); nuiskey key = eventkeys[0]; std::string inputfilename = key.GetS("input"); // Make a new input handler std::vector file_descriptor = GeneralUtils::ParseToStr(inputfilename, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfilename << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inptype = InputUtils::ParseInputType(file_descriptor[0]); InputHandlerBase* input = InputUtils::CreateInputHandler("eventsaver", inptype, file_descriptor[1]); std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } // Make new outputfile TFile* outputfile = new TFile(outputfilename.c_str(), "RECREATE"); outputfile->cd(); // Get info from inputhandler int nevents = input->GetNEvents(); int countwidth = (nevents / 1000); FitEvent* nuisevent = input->FirstNuisanceEvent(); // Setup a TTree to save the event outputfile->cd(); TTree* eventtree = new TTree("nuisance_events", "nuisance_events"); // Add a flag that allows just splines to be saved. nuisevent->AddBranchesToTree(eventtree); // Save the spline reader splmerge->Write("spline_reader"); // Setup the spline TTree TTree* splinetree = new TTree("spline_tree", "spline_tree"); splmerge->AddCoefficientsToTree(splinetree); int lasttime = time(NULL); int i = 0; // Loop over all events and fill the TTree while (nuisevent) { // Calculate the weights for each parameter set splmerge->FillMergedSplines(i); // Save everything eventtree->Fill(); splinetree->Fill(); // Logging if (i % countwidth == 0) { std::ostringstream timestring; int timeelapsed = time(NULL) - lasttime; if (i != 0 and timeelapsed) { lasttime = time(NULL); int eventsleft = nevents - i; float speed = float(countwidth) / float(timeelapsed); float proj = (float(eventsleft) / float(speed)) / 60 / 60; timestring << proj << " hours remaining."; } LOG(REC) << "Saved " << i << "/" << nevents << " nuisance spline events. " << timestring.str() << std::endl; } // Iterate i++; nuisevent = input->NextNuisanceEvent(); } // Save flux and close file outputfile->cd(); eventtree->Write(); splinetree->Write(); input->GetFluxHistogram()->Write("nuisance_fluxhist"); input->GetEventHistogram()->Write("nuisance_eventhist"); // Close Output outputfile->Close(); // Delete Inputs delete input; } //************************************* void SplineRoutines::TestSplines_1DEventScan() { //************************************* // Setup RW Engine if (fRW) delete fRW; SetupRWEngine(); // Make a spline RW Engine too. FitWeight* splweight = new FitWeight("splinerwaweight"); // std::vector splinekeys = Config::QueryKeys("spline"); std::vector parameterkeys = Config::QueryKeys("parameter"); TH1D* parhisttemplate = new TH1D("parhist", "parhist", parameterkeys.size(), 0.0, float(parameterkeys.size())); // Add Parameters for (size_t i = 0; i < parameterkeys.size(); i++) { nuiskey key = parameterkeys[i]; std::string parname = key.GetS("name"); std::string partype = key.GetS("type"); double nom = key.GetD("nominal"); parhisttemplate->SetBinContent(i + 1, nom); parhisttemplate->GetXaxis()->SetBinLabel(i + 1, parname.c_str()); splweight->IncludeDial( key.GetS("name"), kSPLINEPARAMETER, nom); splweight->SetDialValue( key.GetS("name"), key.GetD("nominal") ); } splweight->Reconfigure(); // Make a high resolution spline set. std::vector nomvals = fRW->GetDialValues(); // int testres = FitPar::Config().GetParI("spline_test_resolution"); std::vector< std::vector > scanparset_vals; std::vector< TH1D* > scanparset_hists; // Loop over all params // Add Parameters for (size_t i = 0; i < parameterkeys.size(); i++) { nuiskey key = parameterkeys[i]; // Get Par Name std::string name = key.GetS("name"); if (!key.Has("low") or !key.Has("high") or !key.Has("step")) { continue; } // Push Back Scan double low = key.GetD("low"); double high = key.GetD("high"); double cur = low; double step = key.GetD("step"); while (cur <= high) { // Make new set std::vector newvals = nomvals; newvals[i] = cur; // Add to vects scanparset_vals.push_back(newvals); TH1D* parhist = (TH1D*)parhisttemplate->Clone(); for (size_t j = 0; j < newvals.size(); j++) { parhist->SetBinContent(j + 1, newvals[j]); } scanparset_hists.push_back(parhist); // Move to next one cur += step; } } // Print out the parameter set to test for (uint i = 0; i < scanparset_vals.size(); i++) { std::cout << "Parset " << i; for (uint j = 0 ; j < scanparset_vals[i].size(); j++) { std::cout << " " << scanparset_vals[i][j]; } std::cout << std::endl; } // Weight holders double* rawweights = new double[scanparset_vals.size()]; double* splweights = new double[scanparset_vals.size()]; double* difweights = new double[scanparset_vals.size()]; int nweights = scanparset_vals.size(); // int NParSets = scanparset_vals.size(); // Loop over all event I/O std::vector eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } // Make a new input handler std::vector file_descriptor = GeneralUtils::ParseToStr(inputfilename, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfilename << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inptype = InputUtils::ParseInputType(file_descriptor[0]); // Make handlers for input and output InputHandlerBase* input = InputUtils::CreateInputHandler("rawevents", inptype, file_descriptor[1]); InputHandlerBase* output = InputUtils::CreateInputHandler("splineevents", InputUtils::kEVSPLN_Input, outputfilename); // Get Base Events for each case. FitEvent* rawevent = input->FirstNuisanceEvent(); FitEvent* splevent = output->FirstNuisanceEvent(); // Setup outputfile std::string outputtest = outputfilename + ".splinetest.1DEventScan.root"; TFile* outputtestfile = new TFile(outputtest.c_str(), "RECREATE"); outputtestfile->cd(); // Save Parameter Sets for (size_t i = 0; i < scanparset_hists.size(); i++) { scanparset_hists[i]->Write(Form("Paramater_Set_%i", (int)i)); } // Save a TTree of weights and differences. TTree* weighttree = new TTree("weightscan", "weightscan"); // Make a branch for each weight set for (size_t i = 0; i < scanparset_hists.size(); i++) { weighttree->Branch(Form("RawWeights_Set_%i", (int)i), &rawweights[i], Form("RawWeights_Set_%i/D", (int)i) ); weighttree->Branch(Form("SplineWeights_Set_%i", (int)i), &splweights[i], Form("SplineWeights_Set_%i/D", (int)i) ); weighttree->Branch(Form("DifWeights_Set_%i", (int)i), &difweights[i], Form("DifWeights_Set_%i/D", (int)i) ); } // Count // int i = 0; int nevents = input->GetNEvents(); int lasttime = time(NULL); // Load N Chunks of the Weights into Memory // Split into N processing chunks int nchunks = FitPar::Config().GetParI("spline_chunks"); if (nchunks <= 0) nchunks = 1; if (nchunks >= nevents / 2) nchunks = nevents / 2; std::cout << "Starting NChunks " << nchunks << std::endl; for (int ichunk = 0; ichunk < nchunks; ichunk++) { // Skip to only do one processing chunk // if (procchunk != -1 and procchunk != ichunk) continue; LOG(FIT) << "On Processing Chunk " << ichunk << std::endl; int neventsinchunk = nevents / nchunks; int loweventinchunk = neventsinchunk * ichunk; // int higheventinchunk = neventsinchunk * (ichunk + 1); double** allrawweights = new double*[neventsinchunk]; double** allsplweights = new double*[neventsinchunk]; double** alldifweights = new double*[neventsinchunk]; for (int k = 0; k < neventsinchunk; k++){ allrawweights[k] = new double[nweights]; allsplweights[k] = new double[nweights]; alldifweights[k] = new double[nweights]; } // Start Set Processing Here. for (int iset = 0; iset < nweights; iset++) { // Reconfigure fRW->SetAllDials(&scanparset_vals[iset][0], scanparset_vals[iset].size()); fRW->Reconfigure(); // Reconfigure spline RW splweight->SetAllDials(&scanparset_vals[iset][0], scanparset_vals[iset].size()); splweight->Reconfigure(); splevent->fSplineRead->SetNeedsReconfigure(true); // Could reorder this to save the weightconts in order instead of reconfiguring per event. // Loop over all events and fill the TTree for (int i = 0; i < neventsinchunk; i++){ rawevent = input->GetNuisanceEvent(i+loweventinchunk); splevent = output->GetNuisanceEvent(i+loweventinchunk); allrawweights[i][iset] = fRW->CalcWeight(rawevent); allsplweights[i][iset] = splweight->CalcWeight(splevent); alldifweights[i][iset] = allsplweights[i][iset] - allrawweights[i][iset]; } std::ostringstream timestring; int timeelapsed = time(NULL) - lasttime; if (timeelapsed) { lasttime = time(NULL); int setsleft = (nweights-iset-1) + (nweights * (nchunks - ichunk - 1)); float proj = (float(setsleft) *timeelapsed) / 60 / 60; timestring << setsleft << " sets remaining. Last one took " << timeelapsed << ". " << proj << " hours remaining."; } LOG(REC) << "Processed Set " << iset << "/" << nweights <<" in chunk " << ichunk << "/" << nchunks << " " << timestring.str() << std::endl; } // Fill weights for this chunk into the TTree for (int k = 0; k < neventsinchunk; k++){ for (int l = 0; l < nweights; l++){ rawweights[l] = allrawweights[k][l]; splweights[l] = allsplweights[k][l]; difweights[l] = alldifweights[k][l]; } weighttree->Fill(); } } // Loop over nchunks // Loop over parameter sets // Set All Dials and reconfigure // Loop over events in chunk // Fill Chunkweightcontainers // Once all dials are done, fill the weight tree // Iterator to next chunk outputtestfile->cd(); weighttree->Write(); outputtestfile->Close(); } } /* // Make a high resolution spline set. std::vector nomvals = fRW->GetDialValues(); int testres = FitPar::Config().GetParI("spline_test_resolution"); std::vector< std::vector > scanparset_vals; std::vector< TH1D* > scanparset_hists; // Loop over all params // Add Parameters for (size_t i = 0; i < parameterkeys.size(); i++) { nuiskey key = parameterkeys[i]; // Get Par Name std::string name = key.GetS("name"); if (!key.Has("low") or !key.Has("high") or !key.Has("step")) { continue; } // Push Back Scan double low = key.GetD("low"); double high = key.GetD("high"); double cur = low; double step = key.GetD("step"); while (cur <= high) { // Make new set std::vector newvals = nomvals; newvals[i] = cur; // Add to vects scanparset_vals.push_back(newvals); TH1D* parhist = (TH1D*)parhisttemplate->Clone(); for (size_t j = 0; j < newvals.size(); j++) { parhist->SetBinContent(j + 1, newvals[j]); } scanparset_hists.push_back(parhist); // Move to next one cur += step; } } // Print out the parameter set to test for (int i = 0; i < scanparset_vals.size(); i++) { std::cout << "Parset " << i; for (int j = 0 ; j < scanparset_vals[i].size(); j++) { std::cout << " " << scanparset_vals[i][j]; } std::cout << std::endl; } // Weight holders double* rawweights = new double[scanparset_vals.size()]; double* splweights = new double[scanparset_vals.size()]; double* difweights = new double[scanparset_vals.size()]; int NParSets = scanparset_vals.size(); // Loop over all event I/O std::vector eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } // Make a new input handler std::vector file_descriptor = GeneralUtils::ParseToStr(inputfilename, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfilename << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inptype = InputUtils::ParseInputType(file_descriptor[0]); // Make handlers for input and output InputHandlerBase* input = InputUtils::CreateInputHandler("rawevents", inptype, file_descriptor[1]); InputHandlerBase* output = InputUtils::CreateInputHandler("splineevents", InputUtils::kEVSPLN_Input, outputfilename); // Get Base Events for each case. FitEvent* rawevent = input->FirstNuisanceEvent(); FitEvent* splevent = output->FirstNuisanceEvent(); // Setup outputfile std::string outputtest = outputfilename + ".splinetest.1DEventScan.root"; TFile* outputtestfile = new TFile(outputtest.c_str(), "RECREATE"); outputtestfile->cd(); // Save Parameter Sets for (size_t i = 0; i < scanparset_hists.size(); i++) { scanparset_hists[i]->Write(Form("Paramater_Set_%i", (int)i)); } // Save a TTree of weights and differences. TTree* weighttree = new TTree("weightscan", "weightscan"); // Make a branch for each weight set for (size_t i = 0; i < scanparset_hists.size(); i++) { weighttree->Branch(Form("RawWeights_Set_%i", (int)i), &rawweights[i], Form("RawWeights_Set_%i/D", (int)i) ); weighttree->Branch(Form("SplineWeights_Set_%i", (int)i), &splweights[i], Form("SplineWeights_Set_%i/D", (int)i) ); weighttree->Branch(Form("DifWeights_Set_%i", (int)i), &difweights[i], Form("DifWeights_Set_%i/D", (int)i) ); } // Count int i = 0; int nevents = input->GetNEvents(); while (rawevent and splevent) { // Loop over 1D parameter sets. for (size_t j = 0; j < scanparset_vals.size(); j++) { // Reconfigure fRW->SetAllDials(&scanparset_vals[j][0], scanparset_vals[j].size()); fRW->Reconfigure(); // Reconfigure spline RW splweight->SetAllDials(&scanparset_vals[j][0], scanparset_vals[j].size()); splweight->Reconfigure(); splevent->fSplineRead->SetNeedsReconfigure(true); // Calc weight for both events rawweights[j] = fRW->CalcWeight(rawevent); splweights[j] = splweight->CalcWeight(splevent); difweights[j] = splweights[j] - rawweights[j]; } if (i % 1000 == 0) { LOG(FIT) << "Processed " << i << "/" << nevents << std::endl; } // Fill Array weighttree->Fill(); // Iterate to next event. i++; rawevent = input->NextNuisanceEvent(); splevent = output->NextNuisanceEvent(); } outputtestfile->cd(); weighttree->Write(); outputtestfile->Close(); } } */ //************************************* void SplineRoutines::TestSplines_NDEventThrow() { //************************************* // Setup RW Engine if (fRW) delete fRW; SetupRWEngine(); // Make a spline RW Engine too. FitWeight* splweight = new FitWeight("splinerwaweight"); std::vector parameterkeys = Config::QueryKeys("parameter"); TH1D* parhisttemplate = new TH1D("parhist", "parhist", parameterkeys.size(), 0.0, float(parameterkeys.size())); // Add Parameters for (size_t i = 0; i < parameterkeys.size(); i++) { nuiskey key = parameterkeys[i]; std::string parname = key.GetS("name"); std::string partype = key.GetS("type"); double nom = key.GetD("nominal"); parhisttemplate->SetBinContent(i + 1, nom); parhisttemplate->GetXaxis()->SetBinLabel(i + 1, parname.c_str()); splweight->IncludeDial( key.GetS("name"), kSPLINEPARAMETER, nom); splweight->SetDialValue( key.GetS("name"), key.GetD("nominal") ); } splweight->Reconfigure(); // Make a high resolution spline set. std::vector nomvals = fRW->GetDialValues(); // int testres = FitPar::Config().GetParI("spline_test_resolution"); std::vector< std::string > scanparset_names; std::vector< std::vector > scanparset_vals; std::vector< TH1D* > scanparset_hists; // Loop over all params // Add Parameters int nthrows = FitPar::Config().GetParI("spline_test_throws"); for (int i = 0; i < nthrows; i++) { std::vector newvals = nomvals; for (size_t j = 0; j < parameterkeys.size(); j++) { nuiskey key = parameterkeys[j]; if (!key.Has("low") or !key.Has("high") or !key.Has("step")) { continue; } // Push Back Scan double low = key.GetD("low"); double high = key.GetD("high"); newvals[j] = gRandom->Uniform(low, high); } // Add to vects scanparset_vals.push_back(newvals); TH1D* parhist = (TH1D*)parhisttemplate->Clone(); for (size_t j = 0; j < newvals.size(); j++) { parhist->SetBinContent(j + 1, newvals[j]); } scanparset_hists.push_back(parhist); } // Print out the parameter set to test for (uint i = 0; i < scanparset_vals.size(); i++) { std::cout << "Parset " << i; for (uint j = 0 ; j < scanparset_vals[i].size(); j++) { std::cout << " " << scanparset_vals[i][j]; } std::cout << std::endl; } // Weight holders double* rawweights = new double[scanparset_vals.size()]; double* splweights = new double[scanparset_vals.size()]; double* difweights = new double[scanparset_vals.size()]; int nweights = scanparset_vals.size(); // int NParSets = scanparset_vals.size(); // Loop over all event I/O std::vector eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } // Make a new input handler std::vector file_descriptor = GeneralUtils::ParseToStr(inputfilename, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfilename << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inptype = InputUtils::ParseInputType(file_descriptor[0]); // Make handlers for input and output InputHandlerBase* input = InputUtils::CreateInputHandler("rawevents", inptype, file_descriptor[1]); InputHandlerBase* output = InputUtils::CreateInputHandler("splineevents", InputUtils::kEVSPLN_Input, outputfilename); // Get Base Events for each case. FitEvent* rawevent = input->FirstNuisanceEvent(); FitEvent* splevent = output->FirstNuisanceEvent(); // Setup outputfile std::string outputtest = outputfilename + ".splinetest.NDEventThrow.root"; TFile* outputtestfile = new TFile(outputtest.c_str(), "RECREATE"); outputtestfile->cd(); // Save Parameter Sets for (size_t i = 0; i < scanparset_hists.size(); i++) { scanparset_hists[i]->Write(Form("Paramater_Set_%i", (int)i)); } // Save a TTree of weights and differences. TTree* weighttree = new TTree("weightscan", "weightscan"); // Make a branch for each weight set for (size_t i = 0; i < scanparset_hists.size(); i++) { weighttree->Branch(Form("RawWeights_Set_%i", (int)i), &rawweights[i], Form("RawWeights_Set_%i/D", (int)i) ); weighttree->Branch(Form("SplineWeights_Set_%i", (int)i), &splweights[i], Form("SplineWeights_Set_%i/D", (int)i) ); weighttree->Branch(Form("DifWeights_Set_%i", (int)i), &difweights[i], Form("DifWeights_Set_%i/D", (int)i) ); } // Count // int i = 0; int nevents = input->GetNEvents(); int lasttime = time(NULL); // Load N Chunks of the Weights into Memory // Split into N processing chunks int nchunks = FitPar::Config().GetParI("spline_chunks"); if (nchunks <= 0) nchunks = 1; if (nchunks >= nevents / 2) nchunks = nevents / 2; std::cout << "Starting NChunks " << nchunks << std::endl; for (int ichunk = 0; ichunk < nchunks; ichunk++) { // Skip to only do one processing chunk // if (procchunk != -1 and procchunk != ichunk) continue; LOG(FIT) << "On Processing Chunk " << ichunk << std::endl; int neventsinchunk = nevents / nchunks; int loweventinchunk = neventsinchunk * ichunk; // int higheventinchunk = neventsinchunk * (ichunk + 1); double** allrawweights = new double*[neventsinchunk]; double** allsplweights = new double*[neventsinchunk]; double** alldifweights = new double*[neventsinchunk]; for (int k = 0; k < neventsinchunk; k++){ allrawweights[k] = new double[nweights]; allsplweights[k] = new double[nweights]; alldifweights[k] = new double[nweights]; } // Start Set Processing Here. for (int iset = 0; iset < nweights; iset++) { // Reconfigure fRW->SetAllDials(&scanparset_vals[iset][0], scanparset_vals[iset].size()); fRW->Reconfigure(); // Reconfigure spline RW splweight->SetAllDials(&scanparset_vals[iset][0], scanparset_vals[iset].size()); splweight->Reconfigure(); splevent->fSplineRead->SetNeedsReconfigure(true); // Could reorder this to save the weightconts in order instead of reconfiguring per event. // Loop over all events and fill the TTree for (int i = 0; i < neventsinchunk; i++){ rawevent = input->GetNuisanceEvent(i+loweventinchunk); splevent = output->GetNuisanceEvent(i+loweventinchunk); allrawweights[i][iset] = fRW->CalcWeight(rawevent); allsplweights[i][iset] = splweight->CalcWeight(splevent); alldifweights[i][iset] = allsplweights[i][iset] - allrawweights[i][iset]; } std::ostringstream timestring; int timeelapsed = time(NULL) - lasttime; if (timeelapsed) { lasttime = time(NULL); int setsleft = (nweights-iset-1) + (nweights * (nchunks - ichunk - 1)); float proj = (float(setsleft) *timeelapsed) / 60 / 60; timestring << setsleft << " sets remaining. Last one took " << timeelapsed << ". " << proj << " hours remaining."; } LOG(REC) << "Processed Set " << iset << "/" << nweights <<" in chunk " << ichunk << "/" << nchunks << " " << timestring.str() << std::endl; } // Fill weights for this chunk into the TTree for (int k = 0; k < neventsinchunk; k++){ for (int l = 0; l < nweights; l++){ rawweights[l] = allrawweights[k][l]; splweights[l] = allsplweights[k][l]; difweights[l] = alldifweights[k][l]; } weighttree->Fill(); } } // Loop over nchunks // Loop over parameter sets // Set All Dials and reconfigure // Loop over events in chunk // Fill Chunkweightcontainers // Once all dials are done, fill the weight tree // Iterator to next chunk outputtestfile->cd(); weighttree->Write(); outputtestfile->Close(); } } void SplineRoutines::SaveSplinePlots() { if (fRW) delete fRW; SetupRWEngine(); // Setup the spline reader SplineWriter* splwrite = new SplineWriter(fRW); std::vector splinekeys = Config::QueryKeys("spline"); // Add splines to splinewriter for (std::vector::iterator iter = splinekeys.begin(); iter != splinekeys.end(); iter++) { nuiskey splkey = (*iter); // Add Spline Info To Reader splwrite->AddSpline(splkey); } splwrite->SetupSplineSet(); // Event Loop // Loop over all events and calculate weights for each parameter set. // Generate a set of nominal events // Method, Loop over inputs, create input handler, then create a ttree std::vector eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } // Make new outputfile outputfilename += ".SplinePlots.root"; TFile* outputfile = new TFile(outputfilename.c_str(), "RECREATE"); outputfile->cd(); // Make a new input handler std::vector file_descriptor = GeneralUtils::ParseToStr(inputfilename, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfilename << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inptype = InputUtils::ParseInputType(file_descriptor[0]); InputHandlerBase* input = InputUtils::CreateInputHandler("eventsaver", inptype, file_descriptor[1]); // Get info from inputhandler int nevents = input->GetNEvents(); int countwidth = (nevents / 1000); FitEvent* nuisevent = input->FirstNuisanceEvent(); outputfile->cd(); // int lasttime = time(NULL); TCanvas* fitcanvas = NULL; // Loop over all events and fill the TTree while (nuisevent) { // std::cout << "Fitting event " << i << std::endl; // Calculate the weights for each parameter set splwrite->GetWeightsForEvent(nuisevent); splwrite->FitSplinesForEvent(fitcanvas, true); if (fitcanvas) { outputfile->cd(); fitcanvas->Write(Form("Event_SplineCanvas_%i", (int)i)); } // Logging if (i % countwidth == 0) { LOG(REC) << "Saved " << i << "/" << nevents << " nuisance spline plots. " << std::endl; } // Iterate i++; nuisevent = input->NextNuisanceEvent(); } // Save flux and close file outputfile->cd(); // Close Output outputfile->Close(); // Delete Inputs delete input; } // remove Keys eventkeys.clear(); } void SplineRoutines::TestSplines_NDLikelihoodThrow() { // Setup RW Engine if (fRW) delete fRW; SetupRWEngine(); // Make a spline RW Engine too. FitWeight* splweight = new FitWeight("splinerwaweight"); std::vector parameterkeys = Config::QueryKeys("parameter"); TH1D* parhisttemplate = new TH1D("parhist", "parhist", parameterkeys.size(), 0.0, float(parameterkeys.size())); // Add Parameters for (size_t i = 0; i < parameterkeys.size(); i++) { nuiskey key = parameterkeys[i]; std::string parname = key.GetS("name"); std::string partype = key.GetS("type"); double nom = key.GetD("nominal"); parhisttemplate->SetBinContent(i + 1, nom); parhisttemplate->GetXaxis()->SetBinLabel(i + 1, parname.c_str()); splweight->IncludeDial( key.GetS("name"), kSPLINEPARAMETER, nom); splweight->SetDialValue( key.GetS("name"), key.GetD("nominal") ); } splweight->Reconfigure(); // Make a high resolution spline set. std::vector nomvals = fRW->GetDialValues(); // int testres = FitPar::Config().GetParI("spline_test_resolution"); std::vector< std::string > scanparset_names; std::vector< std::vector > scanparset_vals; std::vector< TH1D* > scanparset_hists; // Loop over all params // Add Parameters int nthrows = FitPar::Config().GetParI("spline_test_throws"); for (int i = 0; i < nthrows; i++) { std::vector newvals = nomvals; for (size_t j = 0; j < parameterkeys.size(); j++) { nuiskey key = parameterkeys[j]; if (!key.Has("low") or !key.Has("high") or !key.Has("step")) { continue; } // Push Back Scan double low = key.GetD("low"); double high = key.GetD("high"); newvals[j] = gRandom->Uniform(low, high); } // Add to vects scanparset_vals.push_back(newvals); TH1D* parhist = (TH1D*)parhisttemplate->Clone(); for (size_t j = 0; j < newvals.size(); j++) { parhist->SetBinContent(j + 1, newvals[j]); } scanparset_hists.push_back(parhist); } // Print out the parameter set to test for (uint i = 0; i < scanparset_vals.size(); i++) { std::cout << "Parset " << i; for (uint j = 0 ; j < scanparset_vals[i].size(); j++) { std::cout << " " << scanparset_vals[i][j]; } std::cout << std::endl; } // Make a new set of Raw/Spline Sample Keys std::vector eventkeys = Config::QueryKeys("events"); std::vector testkeys = Config::QueryKeys("sampletest"); std::vector rawkeys; std::vector splkeys; for (std::vector::iterator iter = testkeys.begin(); iter != testkeys.end(); iter++) { nuiskey key = (*iter); std::string samplename = key.GetS("name"); std::string eventsid = key.GetS("inputid"); nuiskey eventskey = Config::QueryLastKey("events", "id=" + eventsid); std::string rawfile = eventskey.GetS("input"); std::string splfile = eventskey.GetS("output"); nuiskey rawkeytemp = Config::CreateKey("sample"); rawkeytemp.SetS("name", samplename); rawkeytemp.SetS("input", rawfile); nuiskey splkeytemp = Config::CreateKey("sample"); splkeytemp.SetS("name", samplename); splkeytemp.SetS("input", "EVSPLN:" + splfile); rawkeys.push_back(rawkeytemp); splkeys.push_back(splkeytemp); } if (fOutputRootFile) delete fOutputRootFile; fOutputRootFile = new TFile(fOutputFile.c_str(), "RECREATE"); fOutputRootFile->ls(); // Make two new JointFCN JointFCN* rawfcn = new JointFCN(rawkeys, fOutputRootFile); JointFCN* splfcn = new JointFCN(splkeys, fOutputRootFile); // Create iteration tree in output file fOutputRootFile->cd(); rawfcn->CreateIterationTree("raw_iterations", fRW); splfcn->CreateIterationTree("spl_iterations", splweight); // Loop over parameter sets. for (size_t j = 0; j < scanparset_vals.size(); j++) { FitBase::SetRW(fRW); double rawtotal = rawfcn->DoEval(&scanparset_vals[j][0]); FitBase::SetRW(splweight); double spltotal = splfcn->DoEval(&scanparset_vals[j][0]); LOG(FIT) << "RAW SPLINE DIF = " << rawtotal << " " << spltotal << " " << spltotal - rawtotal << std::endl; } fOutputRootFile->cd(); rawfcn->WriteIterationTree(); splfcn->WriteIterationTree(); } void SplineRoutines::TestSplines_1DLikelihoodScan() { // Setup RW Engine. if (fRW) delete fRW; SetupRWEngine(); // Setup Parameter Set. // Make a spline RW Engine too. FitWeight* splweight = new FitWeight("splinerwaweight"); // std::vector splinekeys = Config::QueryKeys("spline"); std::vector parameterkeys = Config::QueryKeys("parameter"); TH1D* parhisttemplate = new TH1D("parhist", "parhist", parameterkeys.size(), 0.0, float(parameterkeys.size())); // Add Parameters for (size_t i = 0; i < parameterkeys.size(); i++) { nuiskey key = parameterkeys[i]; std::string parname = key.GetS("name"); std::string partype = key.GetS("type"); double nom = key.GetD("nominal"); parhisttemplate->SetBinContent(i + 1, nom); parhisttemplate->GetXaxis()->SetBinLabel(i + 1, parname.c_str()); splweight->IncludeDial( key.GetS("name"), kSPLINEPARAMETER, nom); splweight->SetDialValue( key.GetS("name"), key.GetD("nominal") ); } splweight->Reconfigure(); // Make a high resolution spline set. std::vector nomvals = fRW->GetDialValues(); // int testres = FitPar::Config().GetParI("spline_test_resolution"); std::vector< std::vector > scanparset_vals; std::vector< TH1D* > scanparset_hists; // Loop over all params // Add Parameters for (size_t i = 0; i < parameterkeys.size(); i++) { nuiskey key = parameterkeys[i]; // Get Par Name std::string name = key.GetS("name"); if (!key.Has("low") or !key.Has("high") or !key.Has("step")) { continue; } // Push Back Scan double low = key.GetD("low"); double high = key.GetD("high"); double cur = low; double step = key.GetD("step"); while (cur <= high) { // Make new set std::vector newvals = nomvals; newvals[i] = cur; // Add to vects scanparset_vals.push_back(newvals); TH1D* parhist = (TH1D*)parhisttemplate->Clone(); for (size_t j = 0; j < newvals.size(); j++) { parhist->SetBinContent(j + 1, newvals[j]); } scanparset_hists.push_back(parhist); // Move to next one cur += step; } } // Print out the parameter set to test for (uint i = 0; i < scanparset_vals.size(); i++) { std::cout << "Parset " << i; for (uint j = 0 ; j < scanparset_vals[i].size(); j++) { std::cout << " " << scanparset_vals[i][j]; } std::cout << std::endl; } // Make a new set of Raw/Spline Sample Keys std::vector eventkeys = Config::QueryKeys("events"); std::vector testkeys = Config::QueryKeys("sampletest"); std::vector rawkeys; std::vector splkeys; for (std::vector::iterator iter = testkeys.begin(); iter != testkeys.end(); iter++) { nuiskey key = (*iter); std::string samplename = key.GetS("name"); std::string eventsid = key.GetS("inputid"); nuiskey eventskey = Config::QueryLastKey("events", "id=" + eventsid); std::string rawfile = eventskey.GetS("input"); std::string splfile = eventskey.GetS("output"); nuiskey rawkeytemp = Config::CreateKey("sample"); rawkeytemp.SetS("name", samplename); rawkeytemp.SetS("input", rawfile); nuiskey splkeytemp = Config::CreateKey("sample"); splkeytemp.SetS("name", samplename); splkeytemp.SetS("input", "EVSPLN:" + splfile); rawkeys.push_back(rawkeytemp); splkeys.push_back(splkeytemp); } if (fOutputRootFile) delete fOutputRootFile; fOutputRootFile = new TFile(fOutputFile.c_str(), "RECREATE"); fOutputRootFile->ls(); // Make two new JointFCN JointFCN* rawfcn = new JointFCN(rawkeys, fOutputRootFile); JointFCN* splfcn = new JointFCN(splkeys, fOutputRootFile); // Create iteration tree in output file fOutputRootFile->cd(); rawfcn->CreateIterationTree("raw_iterations", fRW); splfcn->CreateIterationTree("spl_iterations", splweight); // Loop over parameter sets. for (size_t j = 0; j < scanparset_vals.size(); j++) { FitBase::SetRW(fRW); double rawtotal = rawfcn->DoEval(&scanparset_vals[j][0]); FitBase::SetRW(splweight); double spltotal = splfcn->DoEval(&scanparset_vals[j][0]); LOG(FIT) << "RAW SPLINE DIF = " << rawtotal << " " << spltotal << " " << spltotal - rawtotal << std::endl; } fOutputRootFile->cd(); rawfcn->WriteIterationTree(); splfcn->WriteIterationTree(); } /* MISC Functions */ //************************************* int SplineRoutines::GetStatus() { //************************************* return 0; } diff --git a/src/Routines/SplineRoutines.h b/src/Routines/SplineRoutines.h index a56f692..5cedfd2 100755 --- a/src/Routines/SplineRoutines.h +++ b/src/Routines/SplineRoutines.h @@ -1,197 +1,197 @@ // 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 SPLINE_ROUTINES_H #define SPLINE_ROUTINES_H /*! * \addtogroup Minimizer * @{ */ #include "TH1.h" #include "TF1.h" #include "TMatrixD.h" #include "TVectorD.h" #include "TSystem.h" #include "TFile.h" #include "TProfile.h" #include #include #include #include #include #include "FitEvent.h" #include "JointFCN.h" -#include "FitParameters.h" + #include "FitLogger.h" #include "BaseFitEvt.h" #include "NuisConfig.h" #include "NuisKey.h" #include "SplineReader.h" #include "SplineWriter.h" #include "SplineMerger.h" #include "ParserUtils.h" #include "OpenMPWrapper.h" enum minstate { kErrorStatus = -1, kGoodStatus, kFitError, kNoChange, kFitFinished, kFitUnfinished, kStateChange, }; //************************************* //! Collects all possible fit routines into a single class to avoid repeated code class SplineRoutines{ //************************************* public: /* Constructor/Destructor */ //! Constructor reads in arguments given at the command line for the fit here. SplineRoutines(int argc, char* argv[]); //! Default destructor ~SplineRoutines(); //! Reset everything to default/NULL void Init(); /* Input Functions */ //! Splits the arguments ready for initial setup void ParseArgs(int argc, char* argv[]); /* Setup Functions */ //! Setup the configuration given the arguments passed at the commandline and card file void SetupConfig(); //! Setups up our custom RW engine with all the parameters passed in the card file void SetupRWEngine(); void Run(); void SaveEvents(); void TestEvents(); void GenerateEventSplines(); void GenerateEventWeights(); void GenerateEventWeightChunks(int procchunk = -1); void BuildEventSplines(int procchunk = -1); void MergeEventSplinesChunks(); /* Testing Functions */ /// Scan parameter space in 1D at finer resolution than points. Compare Raw/Spline on an event by event basis. void TestSplines_1DEventScan(); /// Scan parameter space in 1D at finer resolution than points. Compare likelihoods for all testsamples. void TestSplines_1DLikelihoodScan(); /// Randomly throw in parameter space. For each throw, calc average weight difference. void TestSplines_NDEventThrow(); /// Randomly thow in parameter space. For each throw, calc likelihood difference for each sample. void TestSplines_NDLikelihoodThrow(); /// Generate a set of spline vs weight canvases and save to file void SaveSplinePlots(); /* Fitting Functions */ //! Given a new map change the values that the RW engine is currently set to void UpdateRWEngine(std::map& updateVals); /* MISC Functions */ //! Get previous fit status from a file Int_t GetStatus(); void MergeSplines(); protected: //! Our Custom ReWeight Object FitWeight* rw; FitWeight* fRW; std::string fOutputFile; std::string fInputFile; TFile* fInputRootFile; TFile* fOutputRootFile; JointFCN* fSampleFCN; std::list fSamples; std::string fCardFile; std::string fStrategy; std::vector fRoutines; std::string fAllowedRoutines; // Input Dial Vals //! Vector of dial names std::vector fParams; std::map fStateVals; std::map fStartVals; std::map fCurVals; std::map fErrorVals; std::map fMinVals; std::map fMaxVals; std::map fStepVals; std::map fTypeVals; std::map fFixVals; std::map fStartFixVals; std::vector fGenericInputNames; std::map fGenericInputFiles; std::map fGenericOutputFiles; std::map fGenericOutputTypes; std::map fGenericInputs; std::vector fSplineNames; std::map fSplineTypes; std::map fSplinePoints; nuiskey fCompKey; }; /*! @} */ #endif diff --git a/src/Routines/SystematicRoutines.cxx b/src/Routines/SystematicRoutines.cxx index 1afc9bd..dd13fda 100755 --- a/src/Routines/SystematicRoutines.cxx +++ b/src/Routines/SystematicRoutines.cxx @@ -1,1517 +1,1206 @@ // 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 "SystematicRoutines.h" void SystematicRoutines::Init(){ fInputFile = ""; fInputRootFile = NULL; fOutputFile = ""; fOutputRootFile = NULL; fCovar = fCovarFree = NULL; fCorrel = fCorrelFree = NULL; fDecomp = fDecompFree = NULL; fStrategy = "ErrorBands"; fRoutines.clear(); fRoutines.push_back("ErrorBands"); fCardFile = ""; fFakeDataInput = ""; fSampleFCN = NULL; fAllowedRoutines = ("ErrorBands,PlotLimits"); }; SystematicRoutines::~SystematicRoutines(){ }; SystematicRoutines::SystematicRoutines(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; fNThrows = 250; fStartThrows = 0; fThrowString = ""; // 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, "-s", fStartThrows, false, false); ParserUtils::ParseArgument(args, "-t", fNThrows, false, false); ParserUtils::ParseArgument(args, "-p", fThrowString, 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 if (Config::Get().GetNodes("nuiscomp").empty()) { fCompKey = Config::Get().CreateNode("nuiscomp"); } else { fCompKey = Config::Get().GetNodes("nuiscomp")[0]; } - if (!fCardFile.empty()) fCompKey.AddS("cardfile", fCardFile); - if (!fOutputFile.empty()) fCompKey.AddS("outputfile", fOutputFile); - if (!fStrategy.empty()) fCompKey.AddS("strategy", fStrategy); + 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.LoadConfig( fCompKey.GetS("cardfile"), ""); - - // Add CMD XML Structs - for (size_t i = 0; i < xmlcmds.size(); i++) { - configuration.AddXMLLine(xmlcmds[i]); - } + 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.FinaliseConfig(fCompKey.GetS("outputfile") + ".xml"); + configuration.FinaliseSettings(fCompKey.GetS("outputfile") + ".xml"); // Add Error Verbo Lines - verbocount += Config::Get().GetParI("VERBOSITY"); - errorcount += Config::Get().GetParI("ERROR"); + verbocount += Config::GetParI("VERBOSITY"); + errorcount += Config::GetParI("ERROR"); std::cout << "[ NUISANCE ]: Setting VERBOSITY=" << verbocount << std::endl; std::cout << "[ NUISANCE ]: Setting ERROR=" << errorcount << std::endl; SETVERBOSITY(verbocount); // Proper Setup if (fStrategy.find("ErrorBands") != std::string::npos || fStrategy.find("MergeErrors") != std::string::npos){ fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE"); } // fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE"); SetupSystematicsFromXML(); SetupCovariance(); SetupRWEngine(); SetupFCN(); GetCovarFromFCN(); // Run(); return; }; void SystematicRoutines::SetupSystematicsFromXML(){ 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 if state not 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; 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; } } -void SystematicRoutines::ReadCard(std::string cardfile){ - - // Read cardlines into vector - std::vector cardlines = GeneralUtils::ParseFileToStr(cardfile,"\n"); - FitPar::Config().cardLines = cardlines; - - // Read Samples first (norm params can be overridden) - int linecount = 0; - for (std::vector::iterator iter = cardlines.begin(); - iter != cardlines.end(); iter++){ - std::string line = (*iter); - linecount++; - - // Skip Empties - if (line.empty()) continue; - if (line.c_str()[0] == '#') continue; - - // Read Valid Samples - int samstatus = ReadSamples(line); - - // Show line if bad to help user - if (samstatus == kErrorStatus) { - ERR(FTL) << "Bad Input in cardfile " << fCardFile - << " at line " << linecount << "!" << std::endl; - LOG(FIT) << line << std::endl; - throw; - } - } - - // Read Parameters second - linecount = 0; - for (std::vector::iterator iter = cardlines.begin(); - iter != cardlines.end(); iter++){ - std::string line = (*iter); - linecount++; - - // Skip Empties - if (line.empty()) continue; - if (line.c_str()[0] == '#') continue; - - // Try Parameter Reads - int parstatus = ReadParameters(line); - int fakstatus = ReadFakeDataPars(line); - - // Show line if bad to help user - if (parstatus == kErrorStatus || - fakstatus == kErrorStatus ){ - ERR(FTL) << "Bad Parameter Input in cardfile " << fCardFile - << " at line " << linecount << "!" << std::endl; - LOG(FIT) << line << std::endl; - throw; - } - } - - return; -}; - -int SystematicRoutines::ReadParameters(std::string parstring){ - - std::string inputspec = "RW Dial Inputs Syntax \n" - "free input w/ limits: TYPE NAME START MIN MAX STEP [STATE] \n" - "fix input: TYPE NAME VALUE [STATE] \n" - "free input w/o limits: TYPE NAME START FREE,[STATE] \n" - "Allowed Types: \n" - "neut_parameter,niwg_parameter,t2k_parameter," - "nuwro_parameter,gibuu_parameter"; - - // Check sample input - if (parstring.find("parameter") == std::string::npos) return kGoodStatus; - - // Parse inputs - std::vector strvct = GeneralUtils::ParseToStr(parstring, " "); - - // Skip if comment or parameter somewhere later in line - if (strvct[0].c_str()[0] == '#' || - strvct[0].find("parameter") == std::string::npos){ - return kGoodStatus; - } - - // Check length - if (strvct.size() < 3){ - ERR(FTL) << "Input rw dials need to provide at least 3 inputs." << std::endl; - std::cout << inputspec << std::endl; - return kErrorStatus; - } - - // Setup default inputs - std::string partype = strvct[0]; - std::string parname = strvct[1]; - double parval = GeneralUtils::StrToDbl(strvct[2]); - double minval = parval - 1.0; - double maxval = parval + 1.0; - double stepval = 1.0; - std::string state = "FIX"; //[DEFAULT] - - // Check Type - if (FitBase::ConvDialType(partype) == kUNKNOWN){ - ERR(FTL) << "Unknown parameter type! " << partype << std::endl; - std::cout << inputspec << std::endl; - return kErrorStatus; - } - - // Check Parameter Name - if (FitBase::GetDialEnum(partype, parname) == -1){ - ERR(FTL) << "Bad RW parameter name! " << partype << " " << parname << std::endl; - std::cout << inputspec << std::endl; - return kErrorStatus; - } - - // Option Extra (No Limits) - if (strvct.size() == 4){ - state = strvct[3]; - } - - // Check for weirder inputs - if (strvct.size() > 4 && strvct.size() < 6){ - ERR(FTL) << "Provided incomplete limits for " << parname << std::endl; - std::cout << inputspec << std::endl; - return kErrorStatus; - } - - // Option Extra (With limits and steps) - if (strvct.size() >= 6){ - minval = GeneralUtils::StrToDbl(strvct[3]); - maxval = GeneralUtils::StrToDbl(strvct[4]); - stepval = GeneralUtils::StrToDbl(strvct[5]); - } - - // Option Extra (dial state after limits) - if (strvct.size() == 7){ - state = strvct[6]; - } - - // Run Parameter Conversion if needed - if (state.find("ABS") != std::string::npos){ - parval = FitBase::RWAbsToSigma( partype, parname, parval ); - minval = FitBase::RWAbsToSigma( partype, parname, minval ); - maxval = FitBase::RWAbsToSigma( partype, parname, maxval ); - stepval = FitBase::RWAbsToSigma( partype, parname, stepval ); - } else if (state.find("FRAC") != std::string::npos){ - parval = FitBase::RWFracToSigma( partype, parname, parval ); - minval = FitBase::RWFracToSigma( partype, parname, minval ); - maxval = FitBase::RWFracToSigma( partype, parname, maxval ); - stepval = FitBase::RWFracToSigma( partype, parname, stepval ); - } - - // Check no repeat params - if (std::find(fParams.begin(), fParams.end(), parname) != fParams.end()){ - ERR(FTL) << "Duplicate parameter names given for " << parname << std::endl; - throw; - } - - // Setup Containers - fParams.push_back(parname); - - fTypeVals[parname] = FitBase::ConvDialType(partype); - - fStartVals[parname] = parval; - fCurVals[parname] = fStartVals[parname]; - - fErrorVals[parname] = 0.0; - - fStateVals[parname] = state; - - bool fixstate = state.find("FIX") != std::string::npos; - fFixVals[parname] = fixstate; - fStartFixVals[parname] = fFixVals[parname]; - - fMinVals[parname] = minval; - fMaxVals[parname] = maxval; - fStepVals[parname] = stepval; - - // Print the parameter - LOG(MIN) << "Read Parameter " << parname << " " << parval << " " - << minval << " " << maxval << " " - << stepval << " " << state << std::endl; - - // Tell reader its all good - return kGoodStatus; -} - -//******************************************* -int SystematicRoutines::ReadFakeDataPars(std::string parstring){ -//****************************************** - - std::string inputspec = "Fake Data Dial Inputs Syntax \n" - "fake value: fake_parameter NAME VALUE \n" - "Name should match dialnames given in actual dial specification."; - - // Check sample input - if (parstring.find("fake_parameter") == std::string::npos) - return kGoodStatus; - - // Parse inputs - std::vector strvct = GeneralUtils::ParseToStr(parstring, " "); - - // Skip if comment or parameter somewhere later in line - if (strvct[0].c_str()[0] == '#' || - strvct[0] == "fake_parameter"){ - return kGoodStatus; - } - - // Check length - if (strvct.size() < 3){ - ERR(FTL) << "Fake dials need to provide at least 3 inputs." << std::endl; - std::cout << inputspec << std::endl; - return kErrorStatus; - } - - // Read Inputs - std::string parname = strvct[1]; - double parval = GeneralUtils::StrToDbl(strvct[2]); - - // Setup Container - fFakeVals[parname] = parval; - - // Print the fake parameter - LOG(MIN) << "Read Fake Parameter " << parname << " " << parval << std::endl; - - // Tell reader its all good - return kGoodStatus; -} - -//****************************************** -int SystematicRoutines::ReadSamples(std::string samstring){ -//****************************************** - const static std::string inputspec = - "\tsample :inputfile.root [OPTS] " - "[norm]\nsample_name: Name " - "of sample to include. e.g. MiniBooNE_CCQE_XSec_1DQ2_nu\ninput_type: The " - "input event format. e.g. NEUT, GENIE, EVSPLN, ...\nOPTS: Additional, " - "optional sample options.\nnorm: Additional, optional sample " - "normalisation factor."; - - // Check sample input - if (samstring.find("sample") == std::string::npos) - return kGoodStatus; - - // Parse inputs - std::vector strvct = GeneralUtils::ParseToStr(samstring, " "); - - // Skip if comment or parameter somewhere later in line - if (strvct[0].c_str()[0] == '#' || - strvct[0] != "sample"){ - return kGoodStatus; - } - - // Check length - if (strvct.size() < 3){ - ERR(FTL) << "Sample need to provide at least 3 inputs." << std::endl; - return kErrorStatus; - } - - // Setup default inputs - std::string samname = strvct[1]; - std::string samfile = strvct[2]; - - if (samfile == "FIX") { - ERR(FTL) << "Input filename was \"FIX\", this line is probably malformed " - "in the input card file. Line:\'" - << samstring << "\'" << std::endl; - ERR(FTL) << "Expect sample lines to look like:\n\t" << inputspec - << std::endl; - - throw; - } - - std::string samtype = "DEFAULT"; - double samnorm = 1.0; - - // Optional Type - if (strvct.size() > 3) { - samtype = strvct[3]; - // samname += "_"+samtype; - // Also get rid of the / and replace it with underscore because it might not be supported character - // while (samname.find("/") != std::string::npos) { - // samname.replace(samname.find("/"), 1, std::string("_")); - // } - } - - // Optional Norm - if (strvct.size() > 4) samnorm = GeneralUtils::StrToDbl(strvct[4]); - - // Add Sample Names as Norm Dials - std::string normname = samname + "_norm"; - - // Check no repeat params - if (std::find(fParams.begin(), fParams.end(), normname) != fParams.end()){ - ERR(FTL) << "Duplicate samples given for " << samname << std::endl; - throw; - } - - fParams.push_back(normname); - - fTypeVals[normname] = kNORM; - fStartVals[normname] = samnorm; - fCurVals[normname] = fStartVals[normname]; - fErrorVals[normname] = 0.0; - - fMinVals[normname] = 0.1; - fMaxVals[normname] = 10.0; - fStepVals[normname] = 0.5; - - bool state = samtype.find("FREE") == std::string::npos; - fFixVals[normname] = state; - fStartFixVals[normname] = state; - - // Print read in - LOG(MIN) << "Read sample " << samname << " " - << samfile << " " << samtype << " " - << samnorm << std::endl; - - // Tell reader its all good - return kGoodStatus; -} - /* Setup Functions */ //************************************* void SystematicRoutines::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 SystematicRoutines::SetupFCN(){ //************************************* LOG(FIT)<<"Making the jointFCN"<Reconfigure(); fSampleFCN->ReconfigureAllEvents(); fSampleFCN->SetFakeData("MC"); UpdateRWEngine(fCurVals); LOG(FIT)<<"Set all data to fake MC predictions."<SetFakeData(fFakeDataInput); } return; } //***************************************** void SystematicRoutines::GetCovarFromFCN(){ //***************************************** LOG(FIT) << "Loading ParamPull objects from FCN to build covar" << std::endl; // Make helperstring std::ostringstream helperstr; // Keep track of what is being thrown std::map dialthrowhandle; // Get Covariance Objects from FCN std::list inputpulls = fSampleFCN->GetPullList(); for (PullListConstIter iter = inputpulls.begin(); iter != inputpulls.end(); iter++){ ParamPull* pull = (*iter); if (pull->GetType().find("THROW")){ fInputThrows.push_back(pull); fInputCovar.push_back(pull->GetFullCovarMatrix()); fInputDials.push_back(pull->GetDataHist()); LOG(FIT) << "Read ParamPull: " << pull->GetName() << " " << pull->GetType() << std::endl; } TH1D dialhist = pull->GetDataHist(); TH1D minhist = pull->GetMinHist(); TH1D maxhist = pull->GetMaxHist(); TH1I typehist = pull->GetDialTypes(); for (int i = 0; i < dialhist.GetNbinsX(); i++){ std::string name = std::string(dialhist.GetXaxis()->GetBinLabel(i+1)); dialthrowhandle[name] = pull->GetName(); if (fCurVals.find(name) == fCurVals.end()){ // Add to Containers fParams.push_back(name); fCurVals[name] = dialhist.GetBinContent(i+1); fStartVals[name] = dialhist.GetBinContent(i+1); fMinVals[name] = minhist.GetBinContent(i+1); fMaxVals[name] = maxhist.GetBinContent(i+1); fStepVals[name] = 1.0; fFixVals[name] = false; fStartFixVals[name] = false; fTypeVals[name] = typehist.GetBinContent(i+1); fStateVals[name] = "FREE" + pull->GetType(); // Maker Helper helperstr << std::string(16, ' ' ) << FitBase::ConvDialType(fTypeVals[name]) << " " << name << " " << fMinVals[name] << " " << fMaxVals[name] << " " << fStepVals[name] << " " << fStateVals[name] << std::endl; } } } // Check if no throws given if (fInputThrows.empty()){ ERR(WRN) << "No covariances given to nuissyst" << std::endl; ERR(WRN) << "Pushing back an uncorrelated gaussian throw error for each free parameter using step size" << std::endl; for (UInt_t i = 0; i < fParams.size(); i++){ std::string syst = fParams[i]; if (fFixVals[syst]) continue; // Make Terms std::string name = syst + "_pull"; std::ostringstream pullterm; pullterm << "DIAL:" << syst << ";" << fStartVals[syst] << ";" << fStepVals[syst]; std::string type = "GAUSTHROW/NEUT"; // Push Back Pulls ParamPull* pull = new ParamPull( name, pullterm.str(), type ); fInputThrows.push_back(pull); fInputCovar.push_back(pull->GetFullCovarMatrix()); fInputDials.push_back(pull->GetDataHist()); // Print Whats added ERR(WRN) << "Added ParamPull : " << name << " " << pullterm.str() << " " << type << std::endl; // Add helper string for future fits helperstr << std::string(16, ' ' ) << "covar " << name << " " << pullterm.str() << " " << type << std::endl; // Keep Track of Throws dialthrowhandle[syst] = pull->GetName(); } } // Print Helper String if (!helperstr.str().empty()){ LOG(FIT) << "To remove these statements in future studies, add the lines below to your card:" << std::endl; // Can't use the logger properly because this can be multi-line. Use cout and added spaces to look better! std::cout << helperstr.str(); sleep(2); } // Print Throw State for (UInt_t i = 0; i < fParams.size(); i++){ std::string syst = fParams[i]; if (dialthrowhandle.find(syst) != dialthrowhandle.end()){ LOG(FIT) << "Dial " << i << ". " << setw(40) << syst << " = THROWING with " << dialthrowhandle[syst] << std::endl; } else { LOG(FIT) << "Dial " << i << ". " << setw(40) << syst << " = FIXED" << std::endl; } } // Pause anyway sleep(1); return; } /* Fitting Functions */ //************************************* void SystematicRoutines::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 SystematicRoutines::PrintState(){ //************************************* LOG(FIT)<<"------------"<GetLikelihood(); LOG(FIT) << std::left << std::setw(46) << "Likelihood for JointFCN: " << like << std::endl; LOG(FIT)<<"------------"<cd(); SaveCurrentState(); } //************************************* void SystematicRoutines::SaveCurrentState(std::string subdir){ //************************************* LOG(FIT)<<"Saving current full FCN predictions" <mkdir(subdir.c_str()); newdir->cd(); } FitBase::GetRW()->Reconfigure(); fSampleFCN->ReconfigureAllEvents(); fSampleFCN->Write(); // Change back to current DIR curdir->cd(); return; } //************************************* void SystematicRoutines::SaveNominal(){ //************************************* if (!fOutputRootFile) fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE"); fOutputRootFile->cd(); LOG(FIT)<<"Saving Nominal Predictions (be cautious with this)" <Reconfigure(); SaveCurrentState("nominal"); }; //************************************* void SystematicRoutines::SavePrefit(){ //************************************* if (!fOutputRootFile) fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE"); fOutputRootFile->cd(); LOG(FIT)<<"Saving Prefit Predictions"< 0){ fCovarFree = new TH2D("covariance_free", "covariance_free", NFREE,0,NFREE, NFREE,0,NFREE); } // Set Bin Labels int countall = 0; int countfree = 0; for (UInt_t i = 0; i < fParams.size(); i++){ 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){ fCovarFree->GetXaxis()->SetBinLabel(countfree+1,fParams[i].c_str()); fCovarFree->GetYaxis()->SetBinLabel(countfree+1,fParams[i].c_str()); countfree++; } } fCorrel = PlotUtils::GetCorrelationPlot(fCovar,"correlation"); fDecomp = PlotUtils::GetDecompPlot(fCovar,"decomposition"); if (NFREE > 0)fCorrelFree = PlotUtils::GetCorrelationPlot(fCovarFree, "correlation_free"); if (NFREE > 0)fDecompFree = PlotUtils::GetDecompPlot(fCovarFree,"decomposition_free"); return; }; //************************************* void SystematicRoutines::ThrowCovariance(bool uniformly){ //************************************* // Set fThrownVals to all values in currentVals for (UInt_t i = 0; i < fParams.size(); i++){ std::string name = fParams.at(i); fThrownVals[name] = fCurVals[name]; } for (PullListConstIter iter = fInputThrows.begin(); iter != fInputThrows.end(); iter++){ ParamPull* pull = *iter; pull->ThrowCovariance(); TH1D dialhist = pull->GetDataHist(); for (int i = 0; i < dialhist.GetNbinsX(); i++){ std::string name = std::string(dialhist.GetXaxis()->GetBinLabel(i+1)); if (fCurVals.find(name) != fCurVals.end()){ fThrownVals[name] = dialhist.GetBinContent(i+1); } } // Reset throw incase pulls are calculated. pull->ResetToy(); } return; }; //************************************* void SystematicRoutines::PlotLimits(){ //************************************* std::cout << "Plotting Limits" << std::endl; if (!fOutputRootFile) fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE"); TDirectory* limfolder = (TDirectory*) fOutputRootFile->mkdir("Limits"); limfolder->cd(); // Set all parameters at their starting values for (UInt_t i = 0; i < fParams.size(); i++){ fCurVals[fParams[i]] = fStartVals[fParams[i]]; } TDirectory* nomfolder = (TDirectory*) limfolder->mkdir("nominal"); nomfolder->cd(); UpdateRWEngine(fCurVals); fSampleFCN->ReconfigureAllEvents(); fSampleFCN->Write(); limfolder->cd(); std::vector allfolders; // Loop through each parameter for (UInt_t i = 0; i < fParams.size(); i++){ std::string syst = fParams[i]; std::cout << "Starting Param " << syst << std::endl; if (fFixVals[syst]) continue; // Loop Downwards while (fCurVals[syst] > fMinVals[syst]){ fCurVals[syst] = fCurVals[syst] - fStepVals[syst]; // Check Limit if (fCurVals[syst] < fMinVals[syst]) fCurVals[syst] = fMinVals[syst]; // Check folder exists std::string curvalstring = std::string( Form( (syst + "_%f").c_str(), fCurVals[syst] ) ); if (std::find(allfolders.begin(), allfolders.end(), curvalstring) != allfolders.end()) break; // Make new folder for variation TDirectory* minfolder = (TDirectory*) limfolder->mkdir(Form( (syst + "_%f").c_str(), fCurVals[syst] ) ); minfolder->cd(); allfolders.push_back(curvalstring); // Update Iterations double *vals = FitUtils::GetArrayFromMap( fParams, fCurVals ); fSampleFCN->DoEval( vals ); delete vals; // Save to folder fSampleFCN->Write(); } // Reset before next loop fCurVals[syst] = fStartVals[syst]; // Loop Upwards now while (fCurVals[syst] < fMaxVals[syst]){ fCurVals[syst] = fCurVals[syst] + fStepVals[syst]; // Check Limit if (fCurVals[syst] > fMaxVals[syst]) fCurVals[syst] = fMaxVals[syst]; // Check folder exists std::string curvalstring = std::string( Form( (syst + "_%f").c_str(), fCurVals[syst] ) ); if (std::find(allfolders.begin(), allfolders.end(), curvalstring) != allfolders.end()) break; // Make new folder TDirectory* maxfolder = (TDirectory*) limfolder->mkdir(Form( (syst + "_%f").c_str(), fCurVals[syst] ) ); maxfolder->cd(); allfolders.push_back(curvalstring); // Update Iterations double *vals = FitUtils::GetArrayFromMap( fParams, fCurVals ); fSampleFCN->DoEval( vals ); delete vals; // Save to file fSampleFCN->Write(); } // Reset before leaving fCurVals[syst] = fStartVals[syst]; UpdateRWEngine(fCurVals); } return; } //************************************* void SystematicRoutines::Run(){ //************************************* std::cout << "Running routines "<< std::endl; fRoutines = GeneralUtils::ParseToStr(fStrategy,","); for (UInt_t i = 0; i < fRoutines.size(); i++){ std::string routine = fRoutines.at(i); int fitstate = kFitUnfinished; LOG(FIT)<<"Running Routine: "<cd(); int nthrows = fNThrows; int startthrows = fStartThrows; int endthrows = startthrows + nthrows; if (nthrows < 0) nthrows = endthrows; if (startthrows < 0) startthrows = 0; if (endthrows < 0) endthrows = startthrows + nthrows; - int seed = (gRandom->Uniform(0.0,1.0)*100000 + 100000000*(startthrows + endthrows) + time(NULL) + int(getpid()) ); + // Setting Seed + // Matteo Mazzanti's Fix + struct timeval mytime; + gettimeofday(&mytime, NULL); + Double_t seed = time(NULL) + int(getpid())+ (mytime.tv_sec * 1000.) + (mytime.tv_usec / 1000.); gRandom->SetSeed(seed); + + // int seed = (gRandom->Uniform(0.0,1.0)*100000 + 100000000*(startthrows + endthrows) + time(NULL) + int(getpid()) ); + // gRandom->SetSeed(seed); LOG(FIT) << "Using Seed : " << seed << std::endl; LOG(FIT) << "nthrows = " << nthrows << std::endl; LOG(FIT) << "startthrows = " << startthrows << std::endl; LOG(FIT) << "endthrows = " << endthrows << std::endl; UpdateRWEngine(fCurVals); fSampleFCN->ReconfigureAllEvents(); if (startthrows == 0){ LOG(FIT) << "Making nominal " << std::endl; TDirectory* nominal = (TDirectory*) tempfile->mkdir("nominal"); nominal->cd(); fSampleFCN->Write(); } LOG(SAM) << "nthrows = " << nthrows << std::endl; LOG(SAM) << "startthrows = " << startthrows << std::endl; LOG(SAM) << "endthrows = " << endthrows << std::endl; 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"); fSampleFCN->CreateIterationTree("error_iterations", FitBase::GetRW()); // Would anybody actually want to do uniform throws of any parameter?? bool uniformly = FitPar::Config().GetParB("error_uniform"); // Run Throws and save for (Int_t i = 0; i < endthrows+1; i++){ LOG(FIT) << "Loop " << i << std::endl; ThrowCovariance(uniformly); if (i < startthrows) continue; if (i == 0) continue; LOG(FIT) << "Throw " << i << " ================================" << std::endl; // Generate Random Parameter Throw // ThrowCovariance(uniformly); TDirectory* throwfolder = (TDirectory*)tempfile->mkdir(Form("throw_%i",i)); throwfolder->cd(); // Run Eval double *vals = FitUtils::GetArrayFromMap( fParams, fThrownVals ); chi2 = fSampleFCN->DoEval( vals ); delete vals; // Save the FCN fSampleFCN->Write(); parameterTree->Fill(); } tempfile->cd(); fSampleFCN->WriteIterationTree(); tempfile->Close(); } void SystematicRoutines::MergeThrows(){ fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE"); fOutputRootFile->cd(); // Make a container folder TDirectory* errorDIR = (TDirectory*) fOutputRootFile->mkdir("error_bands"); errorDIR->cd(); TDirectory* outnominal = (TDirectory*) fOutputRootFile->mkdir("nominal_throw"); outnominal->cd(); // Split Input Files if (!fThrowString.empty()) fThrowList = GeneralUtils::ParseToStr(fThrowString,","); // Add default if no throwlist given if (fThrowList.size() < 1) fThrowList.push_back( fOutputFile + ".throws.root" ); /// Save location of file containing nominal std::string nominalfile; bool nominalfound; // Loop over files and check they exist. for (uint i = 0; i < fThrowList.size(); i++){ std::string file = fThrowList[i]; bool found = false; // normal std::string newfile = file; TFile* throwfile = new TFile(file.c_str(),"READ"); if (throwfile and !throwfile->IsZombie()){ found = true; } // normal.throws.root if (!found){ newfile = file + ".throws.root"; throwfile = new TFile((file + ".throws.root").c_str(),"READ"); if (throwfile and !throwfile->IsZombie()) { found = true; } } // If its found save to throwlist, else save empty. // Also search for nominal if (found){ fThrowList[i] = newfile; LOG(FIT) << "Throws File :" << newfile << std::endl; // Find input which contains nominal if (throwfile->Get("nominal")){ nominalfound = true; nominalfile = newfile; } throwfile->Close(); } else { fThrowList[i] = ""; } delete throwfile; } // Make sure we have a nominal file if (!nominalfound or nominalfile.empty()){ ERR(FTL) << "No nominal found when mergining! Exiting!" << std::endl; throw; } // Get the nominal throws file TFile* tempfile = new TFile((nominalfile).c_str(),"READ"); tempfile->cd(); TDirectory* nominal = (TDirectory*)tempfile->Get("nominal"); // int nthrows = FitPar::Config().GetParI("error_throws"); bool uniformly = FitPar::Config().GetParB("error_uniform"); // Check percentage of bad files is okay. int badfilecount = 0; for (uint i = 0; i < fThrowList.size(); i++){ if (!fThrowList[i].empty()){ LOG(FIT) << "Loading Throws From File " << i << " : " << fThrowList[i] << std::endl; } else { badfilecount++; } } // Check we have at least one good file if ((uint)badfilecount == fThrowList.size()){ ERR(FTL) << "Found no good throw files for MergeThrows" << std::endl; throw; } else if (badfilecount > fThrowList.size()*0.25){ ERR(WRN) << "Over 25% of your throw files are dodgy. Please check this is okay!" << std::endl; ERR(WRN) << "Will continue for the time being..." << std::endl; sleep(5); } // 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; TH1* baseplot = (TH1D*)key->ReadObj(); std::string plotname = std::string(baseplot->GetName()); LOG(FIT) << "Creating error bands for " << plotname; if (LOG_LEVEL(FIT)){ if (!uniformly) std::cout << " : Using COVARIANCE Throws! " << std::endl; else std::cout << " : Using UNIFORM THROWS!!! " << std::endl; } int nbins = 0; if (cl->InheritsFrom("TH1D")) nbins = ((TH1D*)baseplot)->GetNbinsX(); else nbins = ((TH1D*)baseplot)->GetNbinsX()* ((TH1D*)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)); } // Make new throw plot TH1* newplot; // Run Throw Merging. for (UInt_t i = 0; i < fThrowList.size(); i++){ TFile* throwfile = new TFile(fThrowList[i].c_str(), "READ"); // Loop over all throws in a folder TIter nextthrow(throwfile->GetListOfKeys()); TKey *throwkey; while ((throwkey = (TKey*)nextthrow())) { // Skip non throw folders if (std::string(throwkey->GetName()).find("throw_") == std::string::npos) continue; // Get Throw DIR TDirectory* throwdir = (TDirectory*)throwkey->ReadObj(); // Get Plot From Throw newplot = (TH1*)throwdir->Get(plotname.c_str()); if (!newplot) continue; // Loop Over Plot 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(); } + + throwfile->Close(); + delete throwfile; } errorDIR->cd(); if (uniformly){ LOG(FIT) << "Uniformly Calculating Plot Errors!" << std::endl; } TH1* statplot = (TH1*) baseplot->Clone(); for (Int_t j = 0; j < nbins; j++){ if (!uniformly){ // if ((baseplot->GetBinError(j+1)/baseplot->GetBinContent(j+1)) < 1.0) { // baseplot->SetBinError(j+1,sqrt(pow(tprof->GetBinError(j+1),2) + pow(baseplot->GetBinError(j+1),2))); // } else { baseplot->SetBinContent(j+1,tprof->GetBinContent(j+1)); baseplot->SetBinError(j+1,tprof->GetBinError(j+1)); // } } else { baseplot->SetBinContent(j+1, 0.0);//(binlowest[j] + binhighest[j]) / 2.0); baseplot->SetBinError(j+1, 0.0); //(binhighest[j] - binlowest[j])/2.0); } } errorDIR->cd(); baseplot->Write(); tprof->Write(); bintree->Write(); outnominal->cd(); for (int i = 0; i < nbins; i++){ baseplot->SetBinError(i+1, sqrt(pow(statplot->GetBinError(i+1),2) + pow(baseplot->GetBinError(i+1),2))); } baseplot->Write(); delete statplot; delete baseplot; delete tprof; delete bintree; delete [] bincontents; } return; }; diff --git a/src/Routines/SystematicRoutines.h b/src/Routines/SystematicRoutines.h index 97737aa..f726e07 100755 --- a/src/Routines/SystematicRoutines.h +++ b/src/Routines/SystematicRoutines.h @@ -1,267 +1,267 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #ifndef SYSTEMATIC_ROUTINES_H #define SYSTEMATIC_ROUTINES_H /*! * \addtogroup Minimizer * @{ */ #include "TH1.h" #include "TF1.h" #include "TMatrixD.h" #include "TVectorD.h" #include "TSystem.h" #include "TFile.h" #include "TProfile.h" - +#include #include #include #include #include #include #include "FitEvent.h" #include "JointFCN.h" -#include "FitParameters.h" + #include "ParserUtils.h" enum minstate { kErrorStatus = -1, kGoodStatus, kFitError, kNoChange, kFitFinished, kFitUnfinished, kStateChange, }; //************************************* //! Collects all possible fit routines into a single class to avoid repeated code class SystematicRoutines{ //************************************* public: /* Constructor/Destructor */ //! Constructor reads in arguments given at the command line for the fit here. SystematicRoutines(int argc, char* argv[]); //! Default destructor ~SystematicRoutines(); //! Reset everything to default/NULL void Init(); /* Input Functions */ //! Splits the arguments ready for initial setup void ParseArgs(int argc, char* argv[]); //! Sorts out configuration and verbosity right at the very start. //! Calls readCard to set everything else up. void InitialSetup(); //! Loops through each line of the card file and passes it to other read functions void ReadCard(std::string cardfile); //! Check for parameter string in the line and assign the correct type. //! Fills maps for each of the parameters int ReadParameters(std::string parstring); //! Reads in fake parameters and assigns them (Requires the parameter to be included as a normal parameter as well) int ReadFakeDataPars(std::string parstring); //! Read in the samples so we can set up the free normalisation dials if required int ReadSamples(std::string sampleString); /* Setup Functions */ void SetupSystematicsFromXML(); //! Setup the configuration given the arguments passed at the commandline and card file void SetupConfig(); //! Setups up our custom RW engine with all the parameters passed in the card file void SetupRWEngine(); //! Setups up the jointFCN. void SetupFCN(); //! Sets up the minimizerObj for ROOT. there are cases where this is called repeatedly, e.g. If you are using a brute force scan before using Migrad. void SetupFitter(std::string routine); //! Set the current data histograms in each sample to the fake data. void SetFakeData(); //! Setup the covariances with the correct dimensions. At the start this is either uncorrelated or merged given all the input covariances. //! At the end of the fit this produces the blank covariances which can then be filled by the minimizerObj with best fit covariances. void SetupCovariance(); void GetCovarFromFCN(); /* Fitting Functions */ //! Main function to actually start iterating over the different required fit routines void Run(); //! Given a new map change the values that the RW engine is currently set to void UpdateRWEngine(std::map& updateVals); //! Given a single routine (see tutorial for options) run that fit routine now. int RunFitRoutine(std::string routine); //! Print current value void PrintState(); //! Performs a fit routine where the input.maxevents is set to a much lower value to try and move closer to the best fit minimum. void LowStatRoutine(std::string routine); //! Perform a chi2 scan in 1D around the current point void Create1DScans(); //! Perform a chi2 scan in 2D around the current point void Chi2Scan2D(); //! Currently a placeholder NEEDS UPDATING void CreateContours(); //! If any currentVals are close to the limits set them to the limit and fix them int FixAtLimit(); //! Throw the current covariance of dial values we have, and fill the thrownVals and thrownNorms maps. //! If uniformly is true parameters will be thrown uniformly between their upper and lower limits. void ThrowCovariance(bool uniformly); //! Given the covariance we currently have generate error bands by throwing the covariance. //! The FitPar config "error_uniform" defines whether to throw using the covariance or uniformly. //! The FitPar config "error_throws" defines how many throws are needed. //! Currently only supports TH1D plots. void GenerateErrorBands(); void GenerateThrows(); void MergeThrows(); //! Step through each parameter one by one and create folders containing the MC predictions at each step. //! Doesn't handle correlated parameters well void PlotLimits(); /* Write Functions */ //! Save the sample plots for current MC //! dir if not empty forces plots to be saved in a subdirectory of outputfile void SaveCurrentState(std::string subdir=""); //! Save starting predictions into a seperate folder void SaveNominal(); //! Save predictions before the main study is ran into a seperate folder void SavePrefit(); //! Save final outputs void SaveResults(); /* MISC Functions */ //! Get previous fit status from a file Int_t GetStatus(); protected: //! Our Custom ReWeight Object FitWeight* rw; std::string fOutputFile; std::string fInputFile; TFile* fInputRootFile; TFile* fOutputRootFile; //! Flag for whether the fit should be continued if an output file is already found. bool fitContinue; //! Minimizer Object for handling roots different minimizer methods JointFCN* fSampleFCN; int nfreepars; std::string fCardFile; std::string fStrategy; std::vector fRoutines; std::string fAllowedRoutines; std::string fFakeDataInput; // Input Dial Vals //! Vector of dial names std::vector fParams; std::map fStateVals; std::map fStartVals; std::map fCurVals; std::map fErrorVals; std::map fMinVals; std::map fMaxVals; std::map fStepVals; std::map fTypeVals; std::map fFixVals; std::map fStartFixVals; //! Vector of fake parameter names std::map fFakeVals; //! Map of thrown parameter names and values (After ThrowCovariance) std::map fThrownVals; TH2D* fCorrel; TH2D* fDecomp; TH2D* fCovar; TH2D* fCorrelFree; TH2D* fDecompFree; TH2D* fCovarFree; std::list fInputThrows; //!< Pointers to pull terms std::vector fInputDials; //!< Vector of Input Histograms std::vector fInputCovar; //!< Vector of Input Covariances nuiskey fCompKey; std::vector fThrowList; std::string fThrowString; int fNThrows; int fStartThrows; }; /*! @} */ #endif diff --git a/src/SciBooNE/SciBooNEUtils.cxx b/src/SciBooNE/SciBooNEUtils.cxx index 90ad1cf..0a40a65 100644 --- a/src/SciBooNE/SciBooNEUtils.cxx +++ b/src/SciBooNE/SciBooNEUtils.cxx @@ -1,278 +1,278 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "SciBooNEUtils.h" -#include "FitParameters.h" + #include "FitUtils.h" namespace FitPar{ double SciBarDensity = FitPar::Config().GetParD("SciBarDensity"); double SciBarRecoDist = FitPar::Config().GetParD("SciBarRecoDist"); double PenetratingMuonE = FitPar::Config().GetParD("PenetratingMuonEnergy"); double NumRangeSteps = FitPar::Config().GetParI("NumRangeSteps"); } double SciBooNEUtils::StoppedEfficiency(TH2D *effHist, FitParticle *nu, FitParticle *muon){ double eff = 0.; if (!effHist) return eff; // For Morgan's efficiencies // eff = effHist->GetBinContent(effHist->FindBin(FitUtils::p(muon), FitUtils::th(nu, muon)/TMath::Pi()*180.)); // For Zack's efficiencies eff = effHist->GetBinContent(effHist->FindBin(FitUtils::th(nu, muon)/TMath::Pi()*180., FitUtils::p(muon)*1000.)); return eff; } double SciBooNEUtils::PenetratedEfficiency(FitParticle *nu, FitParticle *muon){ double eff = 0.; if (FitUtils::th(nu, muon)/TMath::Pi()*180. > 50) eff = 0.; if (FitUtils::p(muon) < 1.4) eff = 0.; return eff; } double SciBooNEUtils::BetheBlochCH(double E, double mass){ double beta2 = 1 - mass*mass/E/E; double gamma = 1./sqrt(1-beta2); double mass_ratio = PhysConst::mass_electron*1000./mass; // Argh, have to remember to convert to MeV or you'll hate yourself! double I2 = 68.7e-6*68.7e-6; double w_max = 2*PhysConst::mass_electron*1000.*beta2*gamma*gamma; w_max /= 1 + 2*gamma*mass_ratio + mass_ratio*mass_ratio; // Values taken from the PDG for K = 0.307075 MeV mol-1 cm2, mean ionization energy I = 68.7 eV (Polystyrene) // = 0.53768 (pdg.lbl.gov/AtomicNuclearProperties) double log_term = log(2*PhysConst::mass_electron*1000.*beta2*gamma*gamma*w_max/I2); double dedx = 0.307075*0.53768/beta2*(0.5*log_term - beta2); return dedx; } // This function returns an estimate of the range of the particle in scintillator. // It uses crude integration and Bethe-Bloch to approximate the range. double SciBooNEUtils::RangeInScintillator(FitParticle* particle, int nsteps){ // The particle energy double E = particle->fP.E(); double M = particle->fP.M(); double Ek = E - M; double step_size = Ek/float(nsteps+1); double range = 0; // Add an offset to make the integral a touch more accurate Ek -= step_size/2.; for (int i = 0; i < nsteps; ++i){ double dEdx = SciBooNEUtils::BetheBlochCH(Ek+M, M); Ek -= step_size; // dEdx is -ve range -= step_size/dEdx; } // Account for density of polystyrene range /= FitPar::SciBarDensity; // Range estimate is in cm return range; } // Function to calculate the distance the particle travels in scintillator bool SciBooNEUtils::PassesDistanceCut(FitParticle* beam, FitParticle* particle){ double dist = SciBooNEUtils::RangeInScintillator(particle, FitPar::NumRangeSteps); double zdist = dist*cos(FitUtils::th(beam, particle)); if (abs(zdist) < FitPar::SciBarRecoDist) return false; return true; } // Function to return the MainTrk int SciBooNEUtils::GetMainTrack(FitEvent *event, TH2D *effHist, FitParticle*& mainTrk, double& weight, bool penetrated){ FitParticle *nu = event->GetNeutrinoIn(); int index = 0; double thisWeight = 0; double highWeight = 0; mainTrk = NULL; // Loop over particles for (uint j = 2; j < event->Npart(); ++j){ // Final state only! if (!(event->PartInfo(j))->fIsAlive) continue; if (event->PartInfo(j)->fNEUTStatusCode != 0) continue; int PID = event->PartInfo(j)->fPID; // Only consider pions, muons for now if (abs(PID) != 211 && abs(PID) != 13) continue; // Get the track with the highest weight thisWeight = SciBooNEUtils::StoppedEfficiency(effHist, nu, event->PartInfo(j)); if (thisWeight < highWeight) continue; highWeight = thisWeight; index = j; mainTrk = event->PartInfo(j); } // end loop over particle stack // Pass the weight back (don't want to apply a weight twice by accident) weight *= highWeight; return index; } void SciBooNEUtils::GetOtherTrackInfo(FitEvent *event, int mainIndex, int& nProtons, int& nPiMus, int& nVertex, FitParticle*& secondTrk){ // Reset everything nPiMus = 0; nProtons = 0; nVertex = 0; secondTrk = NULL; double highestMom = 0.; // Loop over particles for (uint j = 2; j < event->Npart(); ++j){ // Don't re-count the main track if (j == (uint)mainIndex) continue; // Final state only! if (!(event->PartInfo(j))->fIsAlive) continue; if (event->PartInfo(j)->fNEUTStatusCode != 0) continue; int PID = event->PartInfo(j)->fPID; // Only consider pions, muons, protons if (abs(PID) != 211 && PID != 2212 && abs(PID) != 13) continue; // Must be reconstructed as a track in SciBooNE if (SciBooNEUtils::PassesDistanceCut(event->PartInfo(0), event->PartInfo(j))){ // Keep track of the second highest momentum track if (FitUtils::p(event->PartInfo(j)) > highestMom){ highestMom = FitUtils::p(event->PartInfo(j)); secondTrk = event->PartInfo(j); } if (PID == 2212) nProtons += 1; else nPiMus += 1; } else nVertex += 1; } // end loop over particle stack return; } // NOTE: need to adapt this to allow for penetrating events... // Simpler, but gives the same results as in Hirade-san's thesis double SciBooNEUtils::CalcThetaPr(FitEvent *event, FitParticle *main, FitParticle *second, bool penetrated){ FitParticle *nu = event->GetNeutrinoIn(); if (!main || !nu || !second) return -999; // Construct the vector p_pr = (-p_mux, -p_muy, Enurec - pmucosthetamu) // where p_mux, p_muy are the projections of the candidate muon momentum onto the x and y dimension respectively double pmu = main->fP.Vect().Mag(); double pmu_x = main->fP.Vect().X(); double pmu_y = main->fP.Vect().Y(); if (penetrated){ pmu = 1400.; double ratio = 1.4/main->fP.Vect().Mag(); TVector3 mod_mu = main->fP.Vect()*ratio; pmu_x = mod_mu.X(); pmu_y = mod_mu.Y(); } double Enuqe = FitUtils::EnuQErec(pmu/1000.,cos(FitUtils::th(nu, main)), 27., true)*1000.; double p_pr_z = Enuqe - pmu*cos(FitUtils::th(nu, main)); TVector3 p_pr = TVector3(-pmu_x, -pmu_y, p_pr_z); double thetapr = p_pr.Angle(second->fP.Vect())/TMath::Pi()*180.; return thetapr; } double SciBooNEUtils::CalcThetaPi(FitEvent *event, FitParticle *second){ FitParticle *nu = event->GetNeutrinoIn(); if (!second || !nu) return -999; double thetapi = FitUtils::th(nu, second)/TMath::Pi()*180.; return thetapi; } /// Functions to deal with the SB mode stacks SciBooNEUtils::ModeStack::ModeStack(std::string name, std::string title, TH1* hist) { fName = name; fTitle = title; AddMode(0, "CCCOH", "CCCOH", kGreen+2, 2, 3244); AddMode(1, "CCRES", "CCRES", kRed, 2, 3304); AddMode(2, "CCQE", "CCQE", kGray+2, 2, 1001); AddMode(3, "2p2h", "2p2h", kMagenta, 2, 1001); AddMode(4, "Other", "Other", kAzure+1, 2, 1001); StackBase::SetupStack(hist); }; int SciBooNEUtils::ModeStack::ConvertModeToIndex(int mode){ switch (abs(mode)){ case 16: return 0; // CCCOH case 11: case 12: case 13: return 1; // CCRES case 1: return 2; // CCQE case 2: return 3; // 2p2h default: return 4; // Other } }; void SciBooNEUtils::ModeStack::Fill(int mode, double x, double y, double z, double weight) { StackBase::FillStack(SciBooNEUtils::ModeStack::ConvertModeToIndex(mode), x, y, z, weight); }; void SciBooNEUtils::ModeStack::Fill(FitEvent* evt, double x, double y, double z, double weight) { StackBase::FillStack(SciBooNEUtils::ModeStack::ConvertModeToIndex(evt->Mode), x, y, z, weight); }; void SciBooNEUtils::ModeStack::Fill(BaseFitEvt* evt, double x, double y, double z, double weight) { StackBase::FillStack(SciBooNEUtils::ModeStack::ConvertModeToIndex(evt->Mode), x, y, z, weight); }; diff --git a/src/Splines/FitSpline.h b/src/Splines/FitSpline.h index 0c8a975..8185ccd 100644 --- a/src/Splines/FitSpline.h +++ b/src/Splines/FitSpline.h @@ -1,99 +1,99 @@ // 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 FIT_SPLINE_H #define FIT_SPLINE_H #include "TObject.h" -#include "FitParameters.h" + #include "PlotUtils.h" #include "FitUtils.h" #include "stdint.h" #include "stdlib.h" #include class FitSpline{ public: // Constructors FitSpline(); ~FitSpline(){}; FitSpline(std::string ident, std::string dist, std::vector list_enums, std::string points_def ); void ReconfigureSpline(std::vector dial_enums, std::vector dial_values); double operator()(const Double_t* x, const Double_t* par) const; double DoEval(const double* par) const; double DoEval(const double* x, const double* par, const bool use_offset=true) const; void SetType(std::string type); void SetType(int t, int p, int d, bool f=true); void SetOffset(int i){ offset = i; }; inline std::string GetIdent(){return id;}; inline std::string GetDist(){return form;}; inline std::string GetPoints(){return points;}; inline std::vector GetEnums(){return var_enums;}; std::vector GetSplineCoeff(double* weights); // Public Access Spline Variables std::vector var_enums; std::vector x; mutable std::vector< std::vector > x_vals; std::vector x_low; std::vector x_high; bool needs_fit; UInt_t offset; UInt_t npar; UInt_t ndim; UInt_t spline; std::string id; std::string form; std::string points; enum spline_types { k1DPol1 = 1, k1DPol2, k1DPol3, k1DPol4, k1DPol5, k1DPol6, k1DPol1C, k1DPol2C, k1DPol3C, k1DPol4C, k1DPol5C, k1DPol5C_LX, k1DPol10, k1DTSpline3, k1DPol25, k2DPol6 }; }; #endif diff --git a/src/Splines/FitSplineHead.h b/src/Splines/FitSplineHead.h index 64b039d..ca43c8c 100644 --- a/src/Splines/FitSplineHead.h +++ b/src/Splines/FitSplineHead.h @@ -1,54 +1,54 @@ // 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 SPLINES_HEAD_H #define SPLINES_HEAD_H #include "TObject.h" -#include "FitParameters.h" + #include "PlotUtils.h" #include "FitUtils.h" #include "stdint.h" #include "stdlib.h" #include "FitSpline.h" #include class FitSplineHead { public: FitSplineHead(){current_offset = 1;}; ~FitSplineHead(){}; // Function Reconf (Given current dial values and names set the values for each function) double CalcWeight(const Double_t* incoeff); void Reconfigure(std::vector dial_enums, std::vector dial_values); void SetupEventWeights(BaseFitEvt* event); void AddSpline(FitSpline* spl); void Write(std::string name="FitSplineHead"); FitSplineHead(TFile* infile, std::string name); void Read(TTree* tn); int GetCurrentOffset(); int ngen_events; // Number of events in the tree these were generated with (needed for scaling) int current_offset; std::list SplineObjects; }; #endif diff --git a/src/Splines/Spline.h b/src/Splines/Spline.h index 269ba3a..9966f6f 100644 --- a/src/Splines/Spline.h +++ b/src/Splines/Spline.h @@ -1,168 +1,168 @@ #ifndef SPLINE_H #define SPLINE_H #include #include "TObject.h" -#include "FitParameters.h" + #include "stdint.h" #include "stdlib.h" #include "TCanvas.h" #include #include "TF1.h" #include "TSpline.h" #include "SplineUtils.h" #include "TGraph2D.h" #include "TF2.h" #include "Math/Minimizer.h" #include "Math/Factory.h" #include "Math/Functor.h" #include "TH1D.h" #include "Math/IFunction.h" #include "Math/IParamFunction.h" #include "FitLogger.h" // Spline Class class Spline : public ROOT::Math::ParamFunctor { private: const double* pars; public: double DoEvalPar(const double* x, const double* p) const ; unsigned int NDim() const{ return fNDim; } // ROOT::Math::IParametricFunctionMultiDim* Clone() const{ // return new Spline(this->fName, this->fForm, this->fPoints); // } const double* Parameters() const{ return pars; } void SetParameters(const double* p){ pars = p; } unsigned int NPar() const{ return fNPar; } Spline(std::string splname, std::string form, std::string points); ~Spline() {}; void Setup(int type, int ndim, int npar); double operator()(const Double_t* x, const Double_t* par); float operator()(const Float_t* x, const Float_t* par) const; float DoEval(const Float_t* x, const Float_t* par) const; float DoEval(const Float_t* par, bool checkresponse = true) const; // void FitCoeff(int n, double* x, double* y, double* par, bool draw); void FitCoeff(std::vector< std::vector > v, std::vector w, float* coeff, bool draw); inline std::string GetName(void) { return fName; }; inline int GetNDim(void) { return fNDim; }; inline int GetType(void) { return fType; }; inline int GetNPar(void) { return fNPar; }; inline std::string GetForm() {return fForm;}; //void Reconfigure(double x); void Reconfigure(float x, int index = 0); void Reconfigure(std::string name, float x); // Available Spline Functions float Spline1DPol1(const Float_t* par) const; float Spline1DPol2(const Float_t* par) const; float Spline1DPol3(const Float_t* par) const; float Spline1DPol4(const Float_t* par) const; float Spline1DPol5(const Float_t* par) const; float Spline1DPol6(const Float_t* par) const; float Spline2DPol(const Float_t* par, int n) const; float Spline2DGaus(const Float_t* par) const; float Spline1DTSpline3(const Float_t* par) const; float Spline2DTSpline3(const Float_t* par) const; std::string fName; int fType; int fNDim; int fNPar; std::string fForm; std::string fPoints; bool fOutsideLimits; std::vector fSplitNames; std::vector fSplitPoints; mutable std::vector fVal; mutable std::vector fValMin; mutable std::vector fValMax; mutable std::vector< std::vector > fSplitScan; mutable std::vector fXScan; mutable float fX; mutable float fXMin; mutable float fXMax; mutable std::vector fYScan; mutable float fY; mutable float fYMin; mutable float fYMax; int fSplineOffset; // TSpline3 Objects. mutable std::vector::iterator iter_low; mutable std::vector::iterator iter_high; mutable int off; // Create a new function for fitting. ROOT::Math::Minimizer* minimizer; TF1* fROOTFunction; TF1* GetFunction(); }; namespace SplineUtils { double Func2DWrapper(double* x, double* p); extern Spline* gSpline; } namespace SplineUtils { // Spline List enum spline_types { k1DPol1 = 1, k1DPol2, k1DPol3, k1DPol4, k1DPol5, k1DPol6, k1DPol1C, k1DPol2C, k1DPol3C, k1DPol4C, k1DPol5C, k1DPol5C_LX, k1DPol10, k1DTSpline3, k1DPol25, k2DPol6, k2DGaus, k2DTSpline3 }; } #endif diff --git a/src/Splines/SplineMerger.h b/src/Splines/SplineMerger.h index 34dff97..0fee6b8 100644 --- a/src/Splines/SplineMerger.h +++ b/src/Splines/SplineMerger.h @@ -1,38 +1,38 @@ #ifndef SPLINEMerger_H #define SPLINEMerger_H #include "FitWeight.h" #include "Spline.h" -#include "FitParameters.h" + #include "SplineReader.h" class SplineMerger : public SplineReader { public: SplineMerger(){}; ~SplineMerger(){}; void AddSplineSetFromFile(TFile* file); void SetupSplineSet(); void Write(std::string name); void AddCoefficientsToTree(TTree* tree); void GetEntry(int entry); void FillMergedSplines(int entry); float* fCoEffStorer; int fNCoEff; std::vector< float[1000] > fSplineAddressList; std::vector< int > fSplineSizeList; std::vector< TTree* > fSplineTreeList; std::vector< std::vector > fParVect; std::vector< int > fSetIndex; std::vector< double > fWeightList; std::vector< double > fValList; }; #endif diff --git a/src/Splines/SplineReader.h b/src/Splines/SplineReader.h index cc8ae28..bb7d685 100644 --- a/src/Splines/SplineReader.h +++ b/src/Splines/SplineReader.h @@ -1,39 +1,42 @@ #ifndef SPLINEREADER_H #define SPLINEREADER_H // #include "FitWeight.h" #include "Spline.h" #include "TTree.h" #include "FitLogger.h" +#include "NuisConfig.h" +#include "NuisKey.h" + // #include "GeneralUtils.h" class SplineReader { public: SplineReader() {}; ~SplineReader() {}; void AddSpline(nuiskey splkey); void Read(TTree* tr); void Reconfigure(std::map< std::string, double >& vals); bool NeedsReconfigure(); void SetNeedsReconfigure(bool val = true); int GetNPar(); double CalcWeight(float* coeffs); std::vector fAllSplines; std::vector fSpline; std::vector fType; std::vector fForm; std::vector fPoints; std::vector fDialValues; std::vector fParValues; bool fNeedsReconfigure; }; #endif diff --git a/src/Splines/SplineWriter.h b/src/Splines/SplineWriter.h index b761f1d..ffc0655 100644 --- a/src/Splines/SplineWriter.h +++ b/src/Splines/SplineWriter.h @@ -1,92 +1,92 @@ #ifndef SPLINEWRITER_H #define SPLINEWRITER_H #include "FitWeight.h" #include "Spline.h" -#include "FitParameters.h" + #include "SplineUtils.h" #ifdef __MINUIT2_ENABLED__ #include "TFitterMinuit.h" #endif class SplineFCN { public: SplineFCN(Spline* spl, std::vector > v, std::vector w) { fSpl = spl; fVal = v; fWeight = w; }; ~SplineFCN() {}; double operator()(const double* x) const; double DoEval(const double *x) const; void SaveAs(std::string name, const float* fx); void UpdateWeights(std::vector& w); void SetCorrelated(bool state = true); bool uncorrelated; std::vector< std::vector > fVal; std::vector< double > fWeight; Spline* fSpl; }; class SplineWriter : public SplineReader { public: SplineWriter(FitWeight* fw) { fRW = fw; fDrawSplines = FitPar::Config().GetParB("drawsplines"); }; ~SplineWriter() {}; void SetupSplineSet(); void Write(std::string name); void AddCoefficientsToTree(TTree* tree); void FitSplinesForEvent(TCanvas* fitcanvas = NULL, bool saveplot = false); void AddWeightsToTree(TTree* tr); void ReadWeightsFromTree(TTree* tr); void FitSplinesForEvent(double* weightvals, float* coeff); void GetWeightsForEvent(FitEvent* event, double* weights); void GetWeightsForEvent(FitEvent* event); void ReconfigureSet(int iset); double GetWeightForThisSet(FitEvent* event, int iset=-1); void SetWeights(double* weights); inline int GetNWeights(){return fParVect.size();}; inline int GetNPars(){ return fNCoEff;}; int fNCoEff; // double* fCoEffStorer; float* fCoEffStorer; std::vector< std::vector > fParVect; std::vector< int > fSetIndex; double* fWeightList; std::vector< std::vector > fValList; int fCurrentSet; FitWeight* fRW; bool fDrawSplines; std::vector fAllDrawnHists; std::vector fAllDrawnGraphs; #ifdef __MINUIT2_ENABLED__ std::map fSplineFCNs; std::map fSplineFunctors; std::map fSplineMinimizers; #endif // Spline* gSpline; // Available Fitting Functions void FitCoeff(Spline* spl, std::vector< std::vector >& v, std::vector& w, float* coeff, bool draw); void FitCoeff1DGraph(Spline* spl, int n, double* x, double* y, float* coeff, bool draw); void GetCoeff1DTSpline3(Spline* spl, int n, double* x, double* y, float* coeff, bool draw); // void FitCoeff2DGraph(Spline* spl, std::vector< std::vector >& v, std::vector& w, float* coeff, bool draw); void FitCoeffNDGraph(Spline* spl, std::vector< std::vector >& v, std::vector& w, float* coeff, bool draw); void FitCoeff2DGraph(Spline* spl, int n, double* x, double* y, double* w, float* coeff, bool draw); //double Func2DWrapper(double* x, double* p); }; #endif diff --git a/src/Routines/CMakeLists.txt b/src/Statistical/CMakeLists.txt similarity index 79% copy from src/Routines/CMakeLists.txt copy to src/Statistical/CMakeLists.txt index 2c5cf1c..7512473 100644 --- a/src/Routines/CMakeLists.txt +++ b/src/Statistical/CMakeLists.txt @@ -1,66 +1,50 @@ # 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 . ################################################################################ -set(IMPLFILES -ComparisonRoutines.cxx -SystematicRoutines.cxx -SplineRoutines.cxx -) - -if(USE_MINIMIZER) - set(IMPLFILES ${IMPLFILES};MinimizerRoutines.cxx) -endif() - set(HEADERFILES -ComparisonRoutines.h -SystematicRoutines.h -SplineRoutines.h +StatUtils.h ) -if(USE_MINIMIZER) - set(HEADERFILES ${HEADERFILES};MinimizerRoutines.h) -endif() +set(IMPLFILES +StatUtils.cxx +) -set(LIBNAME Routines) +set(LIBNAME Statistical) if(CMAKE_BUILD_TYPE MATCHES DEBUG) add_library(${LIBNAME} STATIC ${IMPLFILES}) else(CMAKE_BUILD_TYPE MATCHES RELEASE) add_library(${LIBNAME} SHARED ${IMPLFILES}) endif() -include_directories(${EXP_INCLUDE_DIRECTORIES}) - include_directories(${MINIMUM_INCLUDE_DIRECTORIES}) -include_directories(${CMAKE_SOURCE_DIR}/src/FCN) -include_directories(${CMAKE_SOURCE_DIR}/src/MCStudies) - set_target_properties(${LIBNAME} PROPERTIES VERSION "${NUISANCE_VERSION_MAJOR}.${NUISANCE_VERSION_MINOR}.${NUISANCE_VERSION_REVISION}") + #set_target_properties(${LIBNAME} PROPERTIES LINK_FLAGS ${ROOT_LD_FLAGS}) if(DEFINED PROJECTWIDE_EXTRA_DEPENDENCIES) add_dependencies(${LIBNAME} ${PROJECTWIDE_EXTRA_DEPENDENCIES}) endif() install(TARGETS ${LIBNAME} DESTINATION lib) #Can uncomment this to install the headers... but is it really neccessary? #install(FILES ${HEADERFILES} DESTINATION include) set(MODULETargets ${MODULETargets} ${LIBNAME} PARENT_SCOPE) diff --git a/src/Utils/StatUtils.cxx b/src/Statistical/StatUtils.cxx similarity index 99% rename from src/Utils/StatUtils.cxx rename to src/Statistical/StatUtils.cxx index 24a458a..2648470 100644 --- a/src/Utils/StatUtils.cxx +++ b/src/Statistical/StatUtils.cxx @@ -1,1300 +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")) { for (int i = 0; i < calc_data->GetNbinsX(); i++) { double dterr = calc_data->GetBinError(i + 1); double mcerr = calc_mc->GetBinError(i + 1); if (dterr > 0.0) { calc_data->SetBinError(i + 1, sqrt(dterr * dterr + mcerr * mcerr)); } } } // Apply masking if required if (mask) { calc_data = ApplyHistogramMasking(data, mask); calc_mc = ApplyHistogramMasking(mc, mask); } // Iterate over bins in X for (int i = 0; i < calc_data->GetNbinsX(); i++) { // Ignore bins with zero data or zero bin error if (calc_data->GetBinError(i + 1) <= 0.0 || calc_data->GetBinContent(i + 1) == 0.0) continue; // Take mc data difference double diff = calc_data->GetBinContent(i + 1) - calc_mc->GetBinContent(i + 1); double err = calc_data->GetBinError(i + 1); Chi2 += (diff * diff) / (err * err); } // cleanup delete calc_data; delete calc_mc; return Chi2; }; //******************************************************************* Double_t StatUtils::GetChi2FromDiag(TH2D* data, TH2D* mc, TH2I* map, TH2I* mask) { //******************************************************************* // Generate a simple map if (!map) map = GenerateMap(data); // Convert to 1D Histograms TH1D* data_1D = MapToTH1D(data, map); TH1D* mc_1D = MapToTH1D(mc, map); TH1I* mask_1D = MapToMask(mask, map); // Calculate 1D chi2 from 1D Plots Double_t Chi2 = StatUtils:: GetChi2FromDiag(data_1D, mc_1D, mask_1D); // CleanUp delete data_1D; delete mc_1D; delete mask_1D; return Chi2; }; //******************************************************************* Double_t StatUtils::GetChi2FromCov(TH1D* data, TH1D* mc, TMatrixDSym* invcov, TH1I* mask, double data_scale, double covar_scale) { //******************************************************************* Double_t Chi2 = 0.0; TMatrixDSym* calc_cov = (TMatrixDSym*) invcov->Clone(); TH1D* calc_data = (TH1D*) data->Clone(); TH1D* calc_mc = (TH1D*) mc->Clone(); - calc_data->Scale(data_scale); - calc_mc ->Scale(data_scale); - (*calc_cov) *= covar_scale; - // If a mask if applied we need to apply it before the matrix is inverted if (mask) { calc_cov = ApplyInvertedMatrixMasking(invcov, mask); calc_data = ApplyHistogramMasking(data, mask); calc_mc = ApplyHistogramMasking(mc, mask); } // Add MC Error to data if required if (FitPar::Config().GetParB("statutils.addmcerror")) { // Make temp cov TMatrixDSym* newcov = StatUtils::GetInvert(calc_cov); // Add MC err to diag for (int i = 0; i < calc_data->GetNbinsX(); i++) { double mcerr = calc_mc->GetBinError(i + 1) * sqrt(covar_scale); double oldval = (*newcov)(i, i); + 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/Utils/StatUtils.h b/src/Statistical/StatUtils.h similarity index 99% rename from src/Utils/StatUtils.h rename to src/Statistical/StatUtils.h index bf26e90..f22e67c 100644 --- a/src/Utils/StatUtils.h +++ b/src/Statistical/StatUtils.h @@ -1,255 +1,255 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #ifndef STATUTILS_H #define STATUTILS_H // C Includes #include #include #include #include #include #include #include #include #include "assert.h" // Root Includes #include "TH1D.h" #include "TH2I.h" #include "TH2D.h" #include "TFile.h" #include "TMatrixDSym.h" #include "TDecompSVD.h" #include "TMath.h" #include "TRandom3.h" #include "TDecompChol.h" #include "TGraphErrors.h" // Fit Includes -#include "FitParameters.h" + #include "FitLogger.h" /*! * \addtogroup Utils * @{ */ //! Functions for handling statistics calculations namespace StatUtils{ /* Chi2 Functions */ //! Get Chi2 using diagonal bin errors from the histogram. Masking applied before calculation if mask provided. Double_t GetChi2FromDiag(TH1D* data, TH1D* mc, TH1I* mask=NULL); //! Get Chi2 using diagonal bin errors from the histogram. //! Plots converted to 1D histograms before using 1D calculation. Double_t GetChi2FromDiag(TH2D* data, TH2D* mc, TH2I* map=NULL, TH2I* mask=NULL); //! Get Chi2 using an inverted covariance for the data Double_t GetChi2FromCov( TH1D* data, TH1D* mc, TMatrixDSym* invcov, TH1I* mask=NULL, double data_scale=1, double covar_scale=1E76); //! Get Chi2 using an inverted covariance for the data //! Plots converted to 1D histograms before using 1D calculation. Double_t GetChi2FromCov( TH2D* data, TH2D* mc, TMatrixDSym* invcov, TH2I* map=NULL, TH2I* mask=NULL); //! Get Chi2 using an SVD method on the covariance before calculation. //! Method suggested by Rex at MiniBooNE. Shown that it doesn't actually work. Double_t GetChi2FromSVD( TH1D* data, TH1D* mc, TMatrixDSym* cov, TH1I* mask=NULL); //! Get Chi2 using an SVD method on the covariance before calculation. //! Method suggested by Rex at MiniBooNE. Shown that it doesn't actually work. //! Plots converted to 1D histograms before using 1D calculation. Double_t GetChi2FromSVD( TH2D* data, TH2D* mc, TMatrixDSym* cov, TH2I* map=NULL, TH2I* mask=NULL); //! Get Chi2 using only the raw event rates given in each bin using a -2LL method. Double_t GetChi2FromEventRate(TH1D* data, TH1D* mc, TH1I* mask=NULL); //! Get Chi2 using only the raw event rates given in each bin using a -2LL method. //! Plots converted to 1D histograms before using 1D calculation. Double_t GetChi2FromEventRate(TH2D* data, TH2D* mc, TH2I* map=NULL, TH2I* mask=NULL); // Likelihood Functions //! Placeholder for 1D binned likelihood method Double_t GetLikelihoodFromDiag(TH1D* data, TH1D* mc, TH1I* mask=NULL); //! Placeholder for 2D binned likelihood method Double_t GetLikelihoodFromDiag(TH2D* data, TH2D* mc, TH2I* map=NULL, TH2I* mask=NULL); //! Placeholder for 1D binned likelihood method Double_t GetLikelihoodFromCov( TH1D* data, TH1D* mc, TMatrixDSym* invcov, TH1I* mask=NULL); //! Placeholder for 2D binned likelihood method Double_t GetLikelihoodFromCov( TH2D* data, TH2D* mc, TMatrixDSym* invcov, TH2I* map=NULL, TH2I* mask=NULL); //! Placeholder for 1D binned likelihood method Double_t GetLikelihoodFromSVD( TH1D* data, TH1D* mc, TMatrixDSym* cov, TH1I* mask=NULL); //! Placeholder for 2D binned likelihood method Double_t GetLikelihoodFromSVD( TH2D* data, TH2D* mc, TMatrixDSym* cov, TH2I* map=NULL, TH2I* mask=NULL); //! Placeholder for 1D binned likelihood method Double_t GetLikelihoodFromEventRate(TH1D* data, TH1D* mc, TH1I* mask=NULL); //! Placeholder for 2D binned likelihood method Double_t GetLikelihoodFromEventRate(TH2D* data, TH2D* mc, TH2I* map=NULL, TH2I* mask=NULL); /* NDOF Functions */ //! Return 1D Histogram NDOF considering masking and empty bins Int_t GetNDOF(TH1D* hist, TH1I* mask=NULL); //! Return 2D Histogram NDOF considering masking and empty bins Int_t GetNDOF(TH2D* hist, TH2I* map=NULL, TH2I* mask=NULL); /* Fake Data Functions */ //! Given a full covariance for a 1D data set throw the decomposition to generate fake data. //! throwdiag determines whether diagonal statistical errors are thrown. //! If no covariance is provided only statistical errors are thrown. TH1D* ThrowHistogram(TH1D* hist, TMatrixDSym* cov, bool throwdiag=true, TH1I* mask=NULL); //! Given a full covariance for a 2D data set throw the decomposition to generate fake data. //! Plots are converted to 1D histograms and the 1D ThrowHistogram is used, before being converted back to 2D histograms. TH2D* ThrowHistogram(TH2D* hist, TMatrixDSym* cov, TH2I* map=NULL, bool throwdiag=true, TH2I* mask=NULL); /* Masking Functions */ //! Given a mask histogram, mask out any bins in hist with non zero entries in mask. TH1D* ApplyHistogramMasking(TH1D* hist, TH1I* mask); //! Given a mask histogram, mask out any bins in hist with non zero entries in mask. TH2D* ApplyHistogramMasking(TH2D* hist, TH2I* mask); //! Given a mask histogram apply the masking procedure to each of the rows/columns in a covariance, before recalculating its inverse. TMatrixDSym* ApplyInvertedMatrixMasking(TMatrixDSym* mat, TH1I* mask); //! Given a mask histogram apply the masking procedure to each of the rows/columns in a covariance, before recalculating its inverse. //! Converts to 1D data before using the 1D ApplyInvertedMatrixMasking function and converting back to 2D. TMatrixDSym* ApplyInvertedMatrixMasking(TMatrixDSym* mat, TH2D* data, TH2I* mask, TH2I* map=NULL); //! Given a mask histogram apply the masking procedure to each of the rows/columns in a covariance TMatrixDSym* ApplyMatrixMasking(TMatrixDSym* mat, TH1I* mask); //! Given a mask histogram apply the masking procedure to each of the rows/columns in a covariance //! Converts to 1D data before using the 1D ApplyInvertedMatrixMasking function and converting back to 2D. TMatrixDSym* ApplyMatrixMasking(TMatrixDSym* mat, TH2D* data, TH2I* mask, TH2I* map=NULL); /* Covariance Handling Functions */ //! Return inverted matrix of TMatrixDSym TMatrixDSym* GetInvert(TMatrixDSym* mat); //! Return Cholesky Decomposed matrix of TMatrixDSym TMatrixDSym* GetDecomp(TMatrixDSym* mat); //! Return full covariances TMatrixDSym* GetCovarFromCorrel(TMatrixDSym* correl, TH1D* data); //! Given a normalisation factor for a dataset add in a new normalisation term to the covariance. void ForceNormIntoCovar(TMatrixDSym* mat, TH1D* data, double norm); //! Given a normalisation factor for a dataset add in a new normalisation term to the covariance. //! Convertes 2D to 1D, before using 1D ForceNormIntoCovar void ForceNormIntoCovar(TMatrixDSym* mat, TH2D* data, double norm, TH2I* map=NULL); //! Given a dataset generate an uncorrelated covariance matrix using the bin errors. TMatrixDSym* MakeDiagonalCovarMatrix(TH1D* data, double scaleF=1E38); //! Given a dataset generate an uncorrelated covariance matrix using the bin errors. TMatrixDSym* MakeDiagonalCovarMatrix(TH2D* data, TH2I* map=NULL, double scaleF=1E38); //! Given a covariance set the errors in each bin on the data from the covariance diagonals. void SetDataErrorFromCov(TH1D* data, TMatrixDSym* cov, double scale=1.0); //! Given a covariance set the errors in each bin on the data from the covariance diagonals. void SetDataErrorFromCov(TH2D* data, TMatrixDSym* cov, TH2I* map=NULL, double scale=1.0); //! Given a covariance, extracts the shape-only matrix using the method from the MiniBooNE TN TMatrixDSym* ExtractShapeOnlyCovar(TMatrixDSym* full_covar, TH1* data_hist, double data_scale=1E38); /* Mapping Functions */ //! If no map is provided for the 2D histogram, generate one by counting up through the bins along x and y. TH2I* GenerateMap(TH2D* hist); //! Apply a map to a 2D histogram converting it into a 1D histogram. TH1D* MapToTH1D(TH2D* hist, TH2I* map); //! Apply a map to a 2D mask convering it into a 1D mask. TH1I* MapToMask(TH2I* hist, TH2I* map); /// \brief Read TMatrixD from a text file /// /// - covfile = full path to text file /// - dimx = x dimensions of matrix /// - dimy = y dimensions of matrix /// /// Format of textfile should be: \n /// cov_11 cov_12 ... cov_1N \n /// cov_21 cov_22 ... cov_2N \n /// ... ... ... ... \n /// cov_N1 ... ... cov_NN \n /// /// If no dimensions are given, dimx and dimy are determined from rows/columns /// inside textfile. /// /// If only dimx is given a symmetric matrix is assumed. TMatrixD* GetMatrixFromTextFile(std::string covfile, int dimx=-1, int dimy=-1); /// \brief Read TMatrixD from a ROOT file /// /// - covfile = full path to root file (+';histogram') /// - histname = histogram name /// /// If no histogram name is given function assumes it has been appended /// covfile path as: \n /// 'covfile.root;histname' /// /// histname can point to a TMatrixD object, a TMatrixDSym object, or /// a TH2D object. TMatrixD* GetMatrixFromRootFile(std::string covfile, std::string histname=""); /// \brief Calls GetMatrixFromTextFile and turns it into a TMatrixDSym TMatrixDSym* GetCovarFromTextFile(std::string covfile, int dim); /// \brief Calls GetMatrixFromRootFile and turns it into a TMatrixDSym TMatrixDSym* GetCovarFromRootFile(std::string covfile, std::string histname); }; /*! @} */ #endif diff --git a/src/Tests/ParserTests.cxx b/src/Tests/ParserTests.cxx index 566a0ff..55f1f3d 100644 --- a/src/Tests/ParserTests.cxx +++ b/src/Tests/ParserTests.cxx @@ -1,100 +1,103 @@ #include #include #include "FitLogger.h" -#include "FitParameters.h" +#include "GeneralUtils.h" +#include "NuisConfig.h" +#include "StatUtils.h" #include "InputUtils.h" int main(int argc, char const *argv[]) { LOG_VERB(SAM); LOG(FIT) << "* Running InputUtils Tests" << std::endl; LOG(FIT) << "***************************************************" << std::endl; - Config::Get().OverrideConfig("NEUT_DIR=/var/test/NEUT"); - Config::Get().OverrideConfig("NUWRO_DIR=/var/test/NUWRO"); - Config::Get().OverrideConfig("GENIE_DIR=/var/test/GENIE"); - Config::Get().OverrideConfig("GIBUU_DIR=/var/test/GIBUU"); + Config::SetPar("NEUT_DIR","/var/test/NEUT"); + Config::SetPar("NUWRO_DIR","/var/test/NUWRO"); + Config::SetPar("GIBUU_DIR","/var/test/NIBUU"); + Config::SetPar("GENIE_DIR","/var/test/GENIE"); std::string NEUTInp = "NEUT:@NEUT_DIR/file.root"; InputUtils::InputType NEUTInpt = InputUtils::ParseInputType(GeneralUtils::ParseToStr(NEUTInp, ":")[0]); std::string ExpandNEUT = InputUtils::ExpandInputDirectories( GeneralUtils::ParseToStr(NEUTInp, ":")[1]); bool IsJointNEUT_not = InputUtils::IsJointInput(GeneralUtils::ParseToStr(NEUTInp, ":")[1]); std::string NEUTJointInp = "NEUT:(@NEUT_DIR/file1.root,@NEUT_DIR/file2.root)"; bool IsJointNEUT = InputUtils::IsJointInput( GeneralUtils::ParseToStr(NEUTJointInp, ":")[1]); std::string ExpandNEUTJoint = InputUtils::ExpandInputDirectories( GeneralUtils::ParseToStr(NEUTJointInp, ":")[1]); std::string NEUTJointInp_MissFSlash = "NEUT:(@NEUT_DIR/file1.root,@NEUT_DIR/file2.root)"; std::string ExpandNEUTJoint_MissFSlash = InputUtils::ExpandInputDirectories( GeneralUtils::ParseToStr(NEUTJointInp_MissFSlash, ":")[1]); - Config::Get().OverrideConfig("NEUT_DIR=/var/test/NEUT/"); + Config::SetPar("NEUT_DIR","/var/test/NEUT/"); + std::string NEUTJointInp_DoubleFSlash = "NEUT:(@NEUT_DIR/file1.root,@NEUT_DIR/file2.root)"; std::string ExpandNEUTJoint_DoubleFSlash = InputUtils::ExpandInputDirectories( GeneralUtils::ParseToStr(NEUTJointInp_DoubleFSlash, ":")[1]); LOG(FIT) << " * Test input type parse" << std::endl; LOG(FIT) << " * Test parse 'NEUT'" << std::endl; if (!(NEUTInpt == InputUtils::kNEUT_Input)) { ERR(FTL) << GeneralUtils::ParseToStr(NEUTInp, ":")[0] << " parsed as type: " << NEUTInpt << std::endl; } assert(NEUTInpt == InputUtils::kNEUT_Input); LOG(FIT) << " * Test IsJoint check" << std::endl; LOG(FIT) << " * Test IsJoint on non joint" << std::endl; if (IsJointNEUT_not) { ERR(FTL) << GeneralUtils::ParseToStr(NEUTInp, ":")[1] << " parsed as Joint." << std::endl; } assert(!IsJointNEUT_not); LOG(FIT) << " * Test IsJoint on joint" << std::endl; if (!IsJointNEUT) { ERR(FTL) << GeneralUtils::ParseToStr(NEUTJointInp, ":")[1] << " parsed as not Joint." << std::endl; } assert(IsJointNEUT); LOG(FIT) << " * Test directory expansion" << std::endl; if ("/var/test/NEUT/file.root" != ExpandNEUT) { ERR(FTL) << GeneralUtils::ParseToStr(NEUTInp, ":")[1] << " expanded to: " << ExpandNEUT << std::endl; } assert("/var/test/NEUT/file.root" == ExpandNEUT); LOG(FIT) << " * Test joint directory expansion" << std::endl; if ("(/var/test/NEUT/file1.root,/var/test/NEUT/file2.root)" != ExpandNEUTJoint) { ERR(FTL) << GeneralUtils::ParseToStr(NEUTJointInp, ":")[1] << " expanded to: " << ExpandNEUTJoint << std::endl; } assert("(/var/test/NEUT/file1.root,/var/test/NEUT/file2.root)" == ExpandNEUTJoint); LOG(FIT) << " * Test joint directory expansion missing slash" << std::endl; if ("(/var/test/NEUT/file1.root,/var/test/NEUT/file2.root)" != ExpandNEUTJoint_MissFSlash) { ERR(FTL) << GeneralUtils::ParseToStr(NEUTJointInp_MissFSlash, ":")[1] << " expanded to: " << ExpandNEUTJoint_MissFSlash << std::endl; } assert("(/var/test/NEUT/file1.root,/var/test/NEUT/file2.root)" == ExpandNEUTJoint_MissFSlash); LOG(FIT) << " * Test joint directory expansion double slash" << std::endl; if ("(/var/test/NEUT/file1.root,/var/test/NEUT/file2.root)" != ExpandNEUTJoint_DoubleFSlash) { ERR(FTL) << GeneralUtils::ParseToStr(NEUTJointInp_DoubleFSlash, ":")[1] << " expanded to: " << ExpandNEUTJoint_DoubleFSlash << std::endl; } assert("(/var/test/NEUT/file1.root,/var/test/NEUT/file2.root)" == ExpandNEUTJoint_DoubleFSlash); LOG(FIT) << "* Passed InputUtils Tests" << std::endl; LOG(FIT) << "***************************************************" << std::endl; } diff --git a/src/Utils/CMakeLists.txt b/src/Utils/CMakeLists.txt index d96b8c6..25a22c4 100644 --- a/src/Utils/CMakeLists.txt +++ b/src/Utils/CMakeLists.txt @@ -1,93 +1,77 @@ # 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 . ################################################################################ set(HEADERFILES -FitLogger.h -FitParameters.h FitUtils.h GeneralUtils.h ParserUtils.h PlotUtils.h -StatUtils.h SignalDef.h -NuisConfig.h -NuisKey.h BeamUtils.h TargetUtils.h -StackBase.h -StandardStacks.h OpenMPWrapper.h PhysConst.h -Initialiser.h ) set(IMPLFILES -PythiaQuiet.f -FitLogger.cxx -FitParameters.cxx FitUtils.cxx GeneralUtils.cxx PlotUtils.cxx -StatUtils.cxx SignalDef.cxx -NuisConfig.cxx -NuisKey.cxx BeamUtils.cxx TargetUtils.cxx -StackBase.cxx ParserUtils.cxx -StandardStacks.cxx -Initialiser.cxx ) set(LIBNAME Utils) if(CMAKE_BUILD_TYPE MATCHES DEBUG) add_library(${LIBNAME} STATIC ${IMPLFILES}) else(CMAKE_BUILD_TYPE MATCHES RELEASE) add_library(${LIBNAME} SHARED ${IMPLFILES}) endif() include_directories(${MINIMUM_INCLUDE_DIRECTORIES}) +include_directories(${CMAKE_SOURCE_DIR}/src/Logger) +include_directories(${CMAKE_SOURCE_DIR}/src/Statistical) set_target_properties(${LIBNAME} PROPERTIES VERSION "${NUISANCE_VERSION_MAJOR}.${NUISANCE_VERSION_MINOR}.${NUISANCE_VERSION_REVISION}") #set_target_properties(${LIBNAME} PROPERTIES LINK_FLAGS ${ROOT_LD_FLAGS}) if(DEFINED PROJECTWIDE_EXTRA_DEPENDENCIES) add_dependencies(${LIBNAME} ${PROJECTWIDE_EXTRA_DEPENDENCIES}) endif() install(TARGETS ${LIBNAME} DESTINATION lib) #Can uncomment this to install the headers... but is it really neccessary? #install(FILES ${HEADERFILES} DESTINATION include) set(MODULETargets ${MODULETargets} ${LIBNAME} PARENT_SCOPE) -add_executable(DumpROOTClassesFromVector DumpROOTClassesFromVector.cxx GeneralUtils.cxx FitLogger.cxx PythiaQuiet.f) - - #Strip out -lNuWro_event1 - string(REPLACE "-lNuWro_event1" "" NWEVSTRIPPED_CDF ${CMAKE_DEPENDLIB_FLAGS}) - cmessage(DEBUG "Attempted to strip out nuwro library: \"${CMAKE_DEPENDLIB_FLAGS}\" -> \"${NWEVSTRIPPED_CDF}\"") - target_link_libraries(DumpROOTClassesFromVector ${NWEVSTRIPPED_CDF}) - if(NOT CMAKE_LINK_FLAGS STREQUAL "") - set_target_properties(DumpROOTClassesFromVector PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS}) - endif() - -install(TARGETS DumpROOTClassesFromVector DESTINATION bin) +#add_executable(DumpROOTClassesFromVector DumpROOTClassesFromVector.cxx GeneralUtils.cxx FitLogger.cxx PythiaQuiet.f) +# +# #Strip out -lNuWro_event1 +# string(REPLACE "-lNuWro_event1" "" NWEVSTRIPPED_CDF ${CMAKE_DEPENDLIB_FLAGS}) +# cmessage(DEBUG "Attempted to strip out nuwro library: \"${CMAKE_DEPENDLIB_FLAGS}\" -> \"${NWEVSTRIPPED_CDF}\"") +# target_link_libraries(DumpROOTClassesFromVector ${NWEVSTRIPPED_CDF}) +# if(NOT CMAKE_LINK_FLAGS STREQUAL "") +# set_target_properties(DumpROOTClassesFromVector PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS}) +# endif() +#install(TARGETS DumpROOTClassesFromVector DESTINATION bin) diff --git a/src/Utils/FitParameters.cxx b/src/Utils/FitParameters.cxx deleted file mode 100644 index 38271bf..0000000 --- a/src/Utils/FitParameters.cxx +++ /dev/null @@ -1,225 +0,0 @@ -// 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 "FitParameters.h" - -// Initialise the static members for the parameters class -FitParameters* FitParameters::m_fitparameterInstance = NULL; - -FitParameters& FitParameters::GetParams(void) { - if (!m_fitparameterInstance) { - m_fitparameterInstance = new FitParameters; - } - - return *m_fitparameterInstance; -}; - -FitParameters::~FitParameters() { parameterMap_all.clear(); }; - -FitParameters::FitParameters() { - this->iteration = 0; - - std::string NUISANCE_dir = GeneralUtils::GetTopLevelDir(); - this->ReadParamFile(NUISANCE_dir + "/parameters/fitter.config.dat"); -}; - -void FitParameters::SetParamFile(std::string fileName) { - parFileName = fileName; - return; -} - -// Parameter File Parser -void FitParameters::ReadParamFile(std::string fileName) { - std::string line; - std::ifstream card(fileName.c_str(), std::ifstream::in); - - while (std::getline(card >> std::ws, line, '\n')) { - std::vector inputlist = GeneralUtils::ParseToStr(line, " "); - - // Check the line length - if (inputlist.size() < 3) continue; - - // Check whether this is a comment - if (inputlist[0].c_str()[0] == '#') continue; - - // Check whether this is a relevant line - if (inputlist[0].compare("config") != 0) continue; - - std::string parName = inputlist[1]; - std::string parEntry = inputlist[2]; - if (parameterMap_all.find(parName) == parameterMap_all.end()) - parameterMap_all.insert( - std::map::value_type(parName, parEntry)); - else - parameterMap_all[parName] = parEntry; - } - card.close(); - return; -} - -// Used to override a parameter by the command line -void FitParameters::ForceParam(std::string parOption) { - unsigned first = parOption.find("="); - std::string parName = parOption.substr(0, first); - std::string parEntry = parOption.substr(first + 1, parOption.size()); - - QLOG(REC,"Read in Parameter Override : " << parName << " = " << parEntry); - - parameterMap_all.insert( - std::map::value_type(parName, parEntry)); - if (parameterMap_all.find(parName) == parameterMap_all.end()) - parameterMap_all.insert( - std::map::value_type(parName, parEntry)); - else - parameterMap_all[parName] = parEntry; - - return; -}; - -void FitParameters::SetParB(std::string parName, bool val) { - if (parameterMap_bool.find(parName) != parameterMap_bool.end()) { - parameterMap_bool[parName] = val; - } else { - parameterMap_bool.insert( - std::map::value_type(parName, val)); - } - - return; -} - -void FitParameters::SetParD(std::string parName, double val) { - // Check if it is saved in int map - if (parameterMap_double.find(parName) != parameterMap_double.end()) { - parameterMap_double[parName] = val; - } else { - parameterMap_double.insert( - std::map::value_type(parName, val)); - } - return; -} - -void FitParameters::SetParI(std::string parName, int val) { - // Check if it is saved in int map - if (parameterMap_int.find(parName) != parameterMap_int.end()) { - parameterMap_int[parName] = val; - } else { - parameterMap_int.insert( - std::map::value_type(parName, val)); - } - return; -} - -// Parameter fetch commands -int FitParameters::GetParI(std::string parName) { - return Config::Get().ConfI(parName); -}; - -// Parameter fetch commands -bool FitParameters::GetParB(std::string parName) { - return Config::Get().ConfB(parName); -}; - -double FitParameters::GetParD(std::string parName) { - return Config::Get().ConfD(parName); -}; - -std::string FitParameters::GetParS(std::string parName) { - return Config::Get().ConfS(parName); -}; - -std::string FitParameters::GetParDIR(std::string 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; -}; - -std::string FitParameters::GetAllParametersArg() { - std::map::iterator mystr = parameterMap_all.begin(); - std::string longlist = ""; - - for (; mystr != parameterMap_all.end(); mystr++) { - longlist += "-q " + mystr->first + "=" + mystr->second + " "; - } - - return longlist; -} - -void FitParameters::MakeParameterCard(std::string filename) { - std::ofstream parcard; - parcard.open((filename).c_str(), std::ios::out); - std::map::iterator mystr = parameterMap_all.begin(); - - for (; mystr != parameterMap_all.end(); mystr++) { - std::string name = (mystr->first); - parcard << "config " << name << " "; - - if (parameterMap_int.find(name) != parameterMap_int.end()) - parcard << parameterMap_int.at(name); - else if (parameterMap_double.find(name) != parameterMap_double.end()) - parcard << parameterMap_double.at(name); - else if (parameterMap_string.find(name) != parameterMap_string.end()) - parcard << parameterMap_string.at(name); - else if (parameterMap_all.find(name) != parameterMap_all.end()) - parcard << parameterMap_all.at(name); - parcard << "\n"; - } - - parcard.close(); - - return; -} - -void FitParameters::Write() { - // Loop through parameters - /* TTree* tr = new TTree("fit_header","fit_header"); - tr->Branch("par_name", &parNames); - tr->Branch("par_value", &parValues); - tr->Branch("card_input", &cardLines); - tr->Fill(); - - tr->Write(); - */ - return; -} - -// Global Access Namespace -//! Namespace to allow singletons to be accessed easily -namespace FitPar { - -//! Returns FitParameters singleton. Usually used for parameters, -//! e.g. FitPar::Config().GetParI("input.maxevents") -FitParameters& Config() { return FitParameters::GetParams(); }; - -std::string GetDataBase() { return GeneralUtils::GetTopLevelDir() + "/data/"; }; -} diff --git a/src/Utils/FitParameters.h b/src/Utils/FitParameters.h deleted file mode 100644 index b7261a5..0000000 --- a/src/Utils/FitParameters.h +++ /dev/null @@ -1,128 +0,0 @@ -// 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 FITPARAMETERS_H_SEEN -#define FITPARAMETERS_H_SEEN - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "TTree.h" -#include "TFile.h" -#include "TGraph.h" - -#include "GeneralUtils.h" -// #include "FitLogger.h" -#include "NuisConfig.h" -#include "NuisKey.h" -//using namespace std; - -/*! - * \addtogroup FitBase - * @{ - */ - -//! Singleton class to allow easy reading and modification of configuration -//! parameters -class FitParameters { - public: - static FitParameters& GetParams(void); - - virtual ~FitParameters(); - - FitParameters(); - - void SetParamFile(std::string fileName); - // Parameter File Parser - void ReadParamFile(std::string fileName); - - // Used to override a parameter by the command line - void ForceParam(std::string parOption); - - void SetParB(std::string parName, bool val); - - void SetParD(std::string parName, double val); - - void SetParI(std::string parName, int val); - - // Parameter fetch commands - int GetParI(std::string parName); - - // Parameter fetch commands - bool GetParB(std::string parName); - - double GetParD(std::string parName); - - std::string GetParS(std::string parName); - - std::string GetParDIR(std::string parName); - - // Variables - std::string parFileName; - std::map parameterMap_all; - - std::string GetAllParametersArg(); - - void MakeParameterCard(std::string filename); - - void Write(); - - TFile* out; // pointer to output file - std::string outputname; - std::map parameterMap_int; - std::map parameterMap_double; - std::map parameterMap_string; - std::map parameterMap_bool; - - std::vector parNames; - std::vector parValues; - std::vector cardLines; - int iteration; - - protected: - static FitParameters* m_fitparameterInstance; -}; - - -// Global Access Namespace -//! Namespace to allow singletons to be accessed easily -namespace FitPar { - -//! Returns FitParameters singleton. Usually used for parameters, -//! e.g. FitPar::Config().GetParI("input.maxevents") -FitParameters& Config(); - -//! Return Fitter DataBase -std::string GetDataBase(); -} - - -/*! @} */ -#endif -// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret - diff --git a/src/Utils/FitUtils.h b/src/Utils/FitUtils.h index bcb5729..fd7024c 100644 --- a/src/Utils/FitUtils.h +++ b/src/Utils/FitUtils.h @@ -1,177 +1,177 @@ // 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 FITUTILS_H_SEEN #define FITUTILS_H_SEEN #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "FitEvent.h" #include "TGraph.h" #include "TH2Poly.h" #include "FitEvent.h" -#include "FitParameters.h" + #include "FitLogger.h" /*! * \addtogroup Utils * @{ */ /// Functions needed by individual samples for calculating kinematic quantities. namespace FitUtils { /// Return a vector of all values saved in map double *GetArrayFromMap(std::vector invals, std::map inmap); /// Returns kinetic energy of particle double T(TLorentzVector part); /// Returns momentum of particle double p(TLorentzVector part); double p(FitParticle* part); /// Returns angle between particles (_NOT_ cosine!) double th(TLorentzVector part, TLorentzVector part2); double th(FitParticle* part1, FitParticle* part2); /// Hadronic mass reconstruction double Wrec(TLorentzVector pnu, TLorentzVector pmu); /// Hadronic mass true from initial state particles and muon; useful if the full /// FSI vectors aren't not saved and we for some reasons need W_true double Wtrue(TLorentzVector pnu, TLorentzVector pmu, TLorentzVector pnuc); double SumKE_PartVect(std::vector const fps); double SumTE_PartVect(std::vector const fps); /// Return E Hadronic for all FS Particles in Hadronic System double GetErecoil_TRUE(FitEvent *event); /// Return E Hadronic for all Charged FS Particles in Hadronic System double GetErecoil_CHARGED(FitEvent *event); /* CCQE MiniBooNE/MINERvA */ /// Function to calculate the reconstructed Q^{2}_{QE} double Q2QErec(TLorentzVector pmu, double costh, double binding, bool neutrino = true); /// Function returns the reconstructed E_{nu} values double EnuQErec(TLorentzVector pmu, double costh, double binding, bool neutrino = true); //! Function to calculate the reconstructed Q^{2}_{QE} double Q2QErec(double pl, double costh, double binding, bool neutrino = true); //! Function returns the reconstructed E_{nu} values double EnuQErec(double pl, double costh, double binding, bool neutrino = true); /* CCQE1p MINERvA */ /// Reconstruct Q2QE given just the maximum energy proton. double ProtonQ2QErec(double pE, double binding); /* E Recoil MINERvA */ double GetErecoil_MINERvA_LowRecoil(FitEvent *event); /* CC1pi0 MiniBooNE */ /// Reconstruct Enu from CCpi0 vectors and binding energy double EnuCC1pi0rec(TLorentzVector pnu, TLorentzVector pmu, TLorentzVector ppi0 = TLorentzVector(0, 0, 0, 0)); /// Reconstruct Q2 from CCpi0 vectors and binding energy double Q2CC1pi0rec(TLorentzVector pnu, TLorentzVector pmu, TLorentzVector ppi0 = TLorentzVector(0, 0, 0, 0)); /* CC1pi+ MiniBooNE */ /// returns reconstructed Enu a la MiniBooNE CCpi+ /// returns reconstructed Enu a la MiniBooNE CCpi+ // Also for when not having pion info (so when we have a Michel tag in T2K) double EnuCC1piprec(TLorentzVector pnu, TLorentzVector pmu, TLorentzVector ppip, bool pionInfo = true); /// returns reconstructed Enu assumming resonance interaction where intermediate /// resonance was a Delta double EnuCC1piprecDelta(TLorentzVector pnu, TLorentzVector pmu); /// returns reconstructed in a variety of flavours double Q2CC1piprec(TLorentzVector pnu, TLorentzVector pmu, TLorentzVector ppip, int enuType = 0, bool pionInfo = true); /* T2K CC1pi+ on CH */ double thq3pi_CC1pip_T2K(TLorentzVector pnu, TLorentzVector pmu, TLorentzVector ppi); double q3_CC1pip_T2K(TLorentzVector pnu, TLorentzVector pmu, TLorentzVector ppi); double WrecCC1pip_T2K_MB(TLorentzVector pnu, TLorentzVector pmu, TLorentzVector ppip); double EnuCC1piprec_T2K_eMB(TLorentzVector pnu, TLorentzVector pmu, TLorentzVector ppi); /* nucleon single pion */ double MpPi(TLorentzVector pp, TLorentzVector ppi); /// Gets delta p T as defined in Phys.Rev. C94 (2016) no.1, 015503 double Get_STV_dpt(FitEvent *event, int ISPDG, bool Is0pi); /// Gets delta phi T as defined in Phys.Rev. C94 (2016) no.1, 015503 double Get_STV_dphit(FitEvent *event, int ISPDG, bool Is0pi); /// Gets delta alpha T as defined in Phys.Rev. C94 (2016) no.1, 015503 double Get_STV_dalphat(FitEvent *event, int ISPDG, bool Is0pi); double CosThAdler(TLorentzVector Pnu, TLorentzVector Pmu, TLorentzVector Ppi, TLorentzVector Pprot); double PhiAdler(TLorentzVector Pnu, TLorentzVector Pmu, TLorentzVector Ppi, TLorentzVector Pprot); } /*! @} */ #endif diff --git a/src/Utils/NuisConfig.cxx b/src/Utils/NuisConfig.cxx deleted file mode 100644 index db5aabb..0000000 --- a/src/Utils/NuisConfig.cxx +++ /dev/null @@ -1,831 +0,0 @@ -// 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 "FitParameters.h" - -struct SXmlAttr_t { - SXmlAttr_t* fNext; - // after structure itself memory for attribute name is preserved - // if first byte is 0, this is special attribute - static inline char* Name(void* arg) { - return (char*)arg + sizeof(SXmlAttr_t); - } -}; - -enum EXmlNodeType { - kXML_NODE = 1, // normal node with children - kXML_COMMENT = 2, // comment (stored as value of node fName) - kXML_PI_NODE = 3, // processing instructions node (like - kXML_RAWLINE = 4, // just one line of xml code - kXML_CONTENT = - 5 // node content, can appear many times in between of normal nodes -}; - -struct SXmlNode_t { - EXmlNodeType fType; // this is node type - node, comment, processing - // instruction and so on - SXmlAttr_t* fAttr; // first attribute - SXmlAttr_t* fNs; // name space definition (if any) - SXmlNode_t* fNext; // next node on the same level of hierarchy - SXmlNode_t* fChild; // first child node - SXmlNode_t* fLastChild; // last child node - SXmlNode_t* fParent; // parent node - // consequent bytes after structure are node name - // if first byte is 0, next is node content - static inline char* Name(void* arg) { - return (char*)arg + sizeof(SXmlNode_t); - } -}; - -nuisconfig::nuisconfig() { - // Initial Setup - std::string filename = - GeneralUtils::GetTopLevelDir() + "/parameters/config.xml"; - std::cout << "[ NUISANCE ]: Loading DEFAULT config from : " << filename; - - // Create XML Engine - fXML = new TXMLEngine; - - // Load in documents - fXMLDocs.clear(); - fXML->SetSkipComments(true); - fXMLDocs.push_back(fXML->ParseFile(filename.c_str(), 1000000)); - - // Setup Main XML Node - fMainNode = fXML->DocGetRootElement(fXMLDocs[0]); - // RemoveIdenticalNodes(); - - std::cout << " -> DONE." << std::endl; -} - -nuisconfig::~nuisconfig() { - // Free all xml docs - // for (int i = 0; i < fXMLDocs.size(); i++){ - // fXML->FreeDoc( fXMLDocs.at(i) ); - // } - - // Remove XMLDocs - // fXMLDocs.clear(); - - // Delete Engine - // delete fXML; -} - -void nuisconfig::OverrideConfig(std::string conf) { - std::vector opts = GeneralUtils::ParseToStr(conf, "="); - SetConfS(opts[0], opts[1]); -} - -XMLNodePointer_t nuisconfig::GetConfigNode(std::string 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; -} - -/// Request a string config key -std::string nuisconfig::SetConfS(const std::string name, std::string val) { - XMLNodePointer_t node = GetConfigNode(name); - if (!node) node = CreateNode("config"); - SetS(node, name, val); - return val; -} - -/// Get nuisconfig::SetConfig Bool -bool nuisconfig::SetConfB(const std::string name, bool val) { - XMLNodePointer_t node = GetConfigNode(name); - if (!node) node = CreateNode("config"); - SetB(node, name, val); - return val; -} - -/// Get nuisconfig::SetConfig Int -int nuisconfig::SetConfI(const std::string name, int val) { - XMLNodePointer_t node = GetConfigNode(name); - if (!node) node = CreateNode("config"); - SetI(node, name, val); - return val; -} - -/// Get nuisconfig::SetConfig Double -double nuisconfig::SetConfD(const std::string name, double val) { - XMLNodePointer_t node = GetConfigNode(name); - if (!node) node = CreateNode("config"); - SetD(node, name, val); - return val; -} - -std::string nuisconfig::ConvertParameterLineToXML(std::string line) { - // Parse - std::vector parsed = GeneralUtils::ParseToStr(line, " "); - - // Min limits - if (parsed.size() < 2) { - ERR(FTL) << " Insufficient parameter options" << std::endl; - throw; - } - - // Setup XMLLine - std::string xmlline = "parameter"; - - // Name - xmlline += " name=\"" + parsed[0] + "\""; - - // Nominal - xmlline += " nominal=\"" + parsed[1] + "\""; - - // State - xmlline += " state=\"" + parsed[2] + "\""; - - return "<" + xmlline + "/>"; -} - -std::string nuisconfig::ConvertSampleLineToXML(std::string line) { - // Parse - std::vector parsed = GeneralUtils::ParseToStr(line, " "); - - // Min limits - if (parsed.size() < 2) { - ERR(FTL) << "Insufficient sample options" << std::endl; - } - - // Setup XMLLine - std::string xmlline = "sample"; - - // Name - xmlline += " name=\"" + parsed[1] + "\""; - - // InputFile - xmlline += " input=\"" + parsed[2] + "\""; - - // If option add it - if (parsed.size() > 3) { - xmlline += " state=\"" + parsed[3] + "\""; - } - - // If norm add it - if (parsed.size() > 4) { - xmlline += " norm=\"" + parsed[4] + "\""; - } - - return "<" + xmlline + "/>"; -} - -void nuisconfig::AddXMLLine(std::string line) { - // XMLLine - std::string xmlline = ""; - - // If = in it its not an xml - if (line.find("=") != std::string::npos) { - xmlline = "<" + line + "/>"; - - // Else Convert it to a line - } else { - // Parse XMLLine - std::vector parsed = GeneralUtils::ParseToStr(line, " "); - if (parsed.empty()) return; - - // Convert it to new fomat - if (!parsed[0].compare("sample")) { - xmlline = ConvertSampleLineToXML(line); - } else if (!parsed[0].compare("parameter")) { - xmlline = ConvertParameterLineToXML(line); - } - } - - // Ad the line - std::cout << "[ NUISANCE ]: Adding XMLLine in nuisconfig: '" << xmlline - << "'"; - - // Make XML Structure - fXMLDocs.push_back(fXML->ParseString(xmlline.c_str())); - - int nxml = fXMLDocs.size(); - XMLNodePointer_t newdocroot = fXML->DocGetRootElement(fXMLDocs[nxml - 1]); - fXML->AddChild(fMainNode, newdocroot); - - std::cout << " -> DONE." << std::endl; -} - -void nuisconfig::FinaliseConfig(std::string name) { - std::cout << "[ NUISANCE ]: Finalising configuration"; - // Save full config to file - WriteConfig(name); - RemoveEmptyNodes(); - RemoveIdenticalNodes(); - std::cout << "-> DONE." << std::endl; -} - -void nuisconfig::LoadXMLConfig(std::string filename, std::string state = "") { - std::cout << "[ NUISANCE ]: Loading XML config from : " << filename; - // Add new file to xml docs list - fXMLDocs.push_back(fXML->ParseFile(filename.c_str(), 1000000)); - - // Get New Doc ROOT - int nxml = fXMLDocs.size(); - XMLNodePointer_t newdocroot = fXML->DocGetRootElement(fXMLDocs[nxml - 1]); - - // Loop over children and add - XMLNodePointer_t child = fXML->GetChild(newdocroot); - while (child != 0) { - // Add additional state flag if given - if (!state.empty()) { - if (GetS(child, "source").empty()) { - fXML->NewAttr(child, 0, "source", state.c_str()); - } else { - // fXML->SetAttr - } - - // If its a config node, then remove previous attributes, overriding - if (!std::string(fXML->GetNodeName(child)).compare("config")) { - // Loop over attribues - XMLAttrPointer_t attr1 = fXML->GetFirstAttr(child); - while (attr1 != 0) { - if (!ConfS(fXML->GetAttrName(attr1)).empty()) { - std::vector confignodes = GetNodes("config"); - - for (size_t i = 0; i < confignodes.size(); i++) { - if (fXML->HasAttr(confignodes[i], fXML->GetAttrName(attr1))) { - std::cout << fXML->GetAttrName(attr1) << std::endl; - fXML->FreeAttr(confignodes[i], fXML->GetAttrName(attr1)); - break; - } - } - } - attr1 = fXML->GetNextAttr(attr1); - } - } - } - - // Add this child to the main config list - fXML->AddChild(fMainNode, child); - - // Get Next Child - child = fXML->GetNext(child); - } - // std::cout << "Removing Identical Nodes" << std::endl; - std::cout << " -> DONE." << std::endl; -} - -void nuisconfig::LoadConfig(std::string filename, std::string state) { - // Open file and see if its XML - std::cout << "[ NUISANCE ]: Trying to parse file : " << filename; - StopTalking(); - XMLDocPointer_t tempdoc = fXML->ParseFile(filename.c_str(), 1000000); - StartTalking(); - - if (tempdoc) { - std::cout << " -> Found XML file." << std::endl; - LoadXMLConfig(filename, state); - } else { - std::cout << " -> Assuming its a simple card file." << std::endl; - LoadCardConfig(filename, state); - } -} - -void nuisconfig::LoadCardConfig(std::string filename, std::string state) { - // Build XML Config from the card file - std::vector cardlines = - GeneralUtils::ParseFileToStr(filename, "\n"); - int linecount = 0; - - 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 - if (!id.compare("sample")) Config::CreateSampleKeyFromLine(line); - - if (id.find("_parameter") != std::string::npos) - Config::CreateParameterKeyFromLine(line); - - if (!id.compare("covar") || !id.compare("pull") || !id.compare("throw")) - Config::CreatePullKeyFromLine(line); - - if (!id.compare("config")) Config::CreateOldConfigKeyFromLine(line); - } - - return; -} - -XMLNodePointer_t nuisconfig::CreateNode(std::string name) { - return fXML->NewChild(fMainNode, 0, name.c_str()); -} - -void nuisconfig::WriteConfig(std::string outputname) { - // Create a New XML Doc - XMLDocPointer_t newxmldoc = fXML->NewDoc(); - fXML->DocSetRootElement(newxmldoc, fMainNode); - - // Save document to file - // fXML->SaveDoc(newxmldoc, outputname.c_str()); -} - -void nuisconfig::CheckCallCount(std::string name) { - // Add Count Warning Flag so we only warn once... - if (fConfigCallWarning.find(name) == fConfigCallWarning.end()) { - fConfigCallWarning[name] = false; - fConfigCallCount[name] = 0; - } - - // Check for inefficiency and warn if it happens - if (abs(time(NULL) - fCurrentTime) > 1) { - fCurrentTime = time(NULL); - - // Check count since last 10 seconds - if (!fConfigCallWarning[name] and fConfigCallCount[name] > 100) { - ERR(WRN) << "Config Parameter " << name << " has been requested " - << fConfigCallCount[name] << " times in the last second." - << std::endl; - ERR(WRN) << "This is very inefficient! Please try to change this." - << std::endl; - fConfigCallWarning[name] = true; - } - - // Reset counter - fConfigCallCount[name] = 0; - } - - // Add to Call Count - fConfigCallCount[name] += 1; -} - -std::string nuisconfig::ConfS(const std::string name) { - std::string temp = ""; - - CheckCallCount(name); - - // Loop over children and look for name - XMLNodePointer_t child = fXML->GetChild(fMainNode); - while (child != 0) { - // std::cout << "Child = " << fXML->GetNodeName(child) << std::endl; - // Select only config parameters - if (!std::string(fXML->GetNodeName(child)).compare("config")) { - // std::cout << "Found Config " << std::endl; - // Loop over config attributes and search for name - XMLAttrPointer_t attr = fXML->GetFirstAttr(child); - while (attr != 0) { - // Save name value - // std::cout << "Setting Temp " << std::string(fXML->GetAttrName(attr)) - // << " '" << fXML->GetAttrValue(attr) << "' " << std::endl; - if (std::string(fXML->GetAttrName(attr)) == name.c_str()) { - // std::cout << "Setting Temp " << - // std::string(fXML->GetAttrName(attr)) << " " << - // fXML->GetAttrValue(attr) << std::endl; - temp = fXML->GetAttrValue(attr); - } - - // Get Next Attribute - attr = fXML->GetNextAttr(attr); - } - } - - // Next Child - child = fXML->GetNext(child); - } - - // Return Config Value - return temp; -} - -bool nuisconfig::ConfB(const std::string name) { - std::string pars = ConfS(name); - return GeneralUtils::StrToBool(pars); -} - -int nuisconfig::ConfI(const std::string name) { - std::string pars = ConfS(name); - return GeneralUtils::StrToInt(pars); -} - -double nuisconfig::ConfD(const std::string name) { - std::string pars = ConfS(name); - return GeneralUtils::StrToDbl(pars); -} - -std::vector nuisconfig::GetChildNodes( - XMLNodePointer_t node, const std::string type) { - 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(const std::string type) { - return GetChildNodes(fMainNode, type); -} - -/// Get String from a given node -std::string nuisconfig::GetS(XMLNodePointer_t node, std::string name) { - // If node empty return empty - if (node == 0) return ""; - - // Check request count - CheckCallCount(name); - - // Get Attribute from child with name - XMLAttrPointer_t attr = fXML->GetFirstAttr(node); - std::string temp = ""; - - // Check if its a search or exact (should probs just add wildcards...) - bool exact = true; - if (name.size() > 0) { - if (name[0] == '*' and name[name.size() - 1] == '*') { - exact = false; - } - } - - if (!fXML) { - std::cout << "AAAAH NO XML" << std::endl; - throw; - } - - // Loop over all attributes - while (attr != 0) { - // Find value of correct name - if (exact) { - // std::cout << "Getting Attr name = " << attr << " " << name << - // std::endl; - if (std::string(fXML->GetAttrName(attr)) == name.c_str()) { - temp = fXML->GetAttrValue(attr); - } - } else { - } - - // Next Attribute - attr = fXML->GetNextAttr(attr); - } - - return temp; -} - -bool nuisconfig::Has(XMLNodePointer_t node, std::string name) { - // If node empty return empty - if (node == 0) return false; - - // Get Attribute from child with name - SXmlNode_t* snode = (SXmlNode_t*)node; - // SXmlAttr_t* sattr = snode->fAttr; - - XMLAttrPointer_t attr = fXML->GetFirstAttr(node); - - bool found = false; - - // Check if its a search or exact (should probs just add wildcards...) - bool exact = true; - if (name.size() > 0) { - if (name[0] == '*' and name[name.size() - 1] == '*') { - exact = false; - } - } - - // Loop over all attributes - while (attr != 0) { - // Find value of correct name - if (exact) { - if (std::string(fXML->GetAttrName(attr)) == name.c_str()) { - found = true; - } - } else { - } - - // Next Attribute - attr = fXML->GetNextAttr(attr); - } - - return found; -} - -/// Get Bools from a given node -bool nuisconfig::GetB(XMLNodePointer_t node, std::string name) { - std::string tempattr = GetS(node, name); - return GeneralUtils::StrToBool(tempattr); -} - -/// Get int from given node -int nuisconfig::GetI(XMLNodePointer_t node, std::string name) { - std::string tempattr = GetS(node, name); - return GeneralUtils::StrToInt(tempattr); -} - -/// Get double from given node -double nuisconfig::GetD(XMLNodePointer_t node, std::string name) { - std::string tempattr = GetS(node, name); - return GeneralUtils::StrToDbl(tempattr); -} - -std::vector nuisconfig::GetVS(XMLNodePointer_t node, - std::string name, const char* del) { - std::string tempattr = GetS(node, name); - return GeneralUtils::ParseToStr(tempattr, del); -} - -std::vector nuisconfig::GetVI(XMLNodePointer_t node, std::string name, - const char* del) { - std::string tempattr = GetS(node, name); - return GeneralUtils::ParseToInt(tempattr, del); -} - -std::vector nuisconfig::GetVD(XMLNodePointer_t node, std::string name, - const char* del) { - std::string tempattr = GetS(node, name); - return GeneralUtils::ParseToDbl(tempattr, del); -} - -namespace Config { -nuisconfig& Get() { return nuisconfig::GetConfig(); }; -} - -nuisconfig* nuisconfig::m_nuisconfigInstance = NULL; -nuisconfig& nuisconfig::GetConfig(void) { - if (!m_nuisconfigInstance) m_nuisconfigInstance = new nuisconfig; - return *m_nuisconfigInstance; -}; - -void nuisconfig::AddS(XMLNodePointer_t node, std::string name, - std::string val) { - fXML->NewAttr(node, 0, name.c_str(), val.c_str()); -} - -void nuisconfig::AddB(XMLNodePointer_t node, std::string name, bool val) { - AddS(node, name, GeneralUtils::BoolToStr(val)); -} - -void nuisconfig::AddI(XMLNodePointer_t node, std::string name, int val) { - AddS(node, name, GeneralUtils::IntToStr(val)); -} -void nuisconfig::AddD(XMLNodePointer_t node, std::string name, double val) { - AddS(node, name, GeneralUtils::DblToStr(val)); -} - -void nuisconfig::SetS(XMLNodePointer_t node, std::string name, - std::string val) { - // Remove and readd attribute - if (fXML->HasAttr(node, name.c_str())) { - fXML->FreeAttr(node, name.c_str()); - } - - AddS(node, name, val); -} - -void nuisconfig::SetB(XMLNodePointer_t node, std::string name, bool val) { - SetS(node, name, GeneralUtils::BoolToStr(val)); -} - -void nuisconfig::SetI(XMLNodePointer_t node, std::string name, int val) { - SetS(node, name, GeneralUtils::IntToStr(val)); -} -void nuisconfig::SetD(XMLNodePointer_t node, std::string name, double val) { - SetS(node, name, GeneralUtils::DblToStr(val)); -} - -void nuisconfig::ChangeS(XMLNodePointer_t node, std::string name, - std::string val) { - if (!fXML->HasAttr(node, name.c_str())) return; - SetS(node, name, val); -} - -void nuisconfig::ChangeB(XMLNodePointer_t node, std::string name, bool val) { - ChangeS(node, name, GeneralUtils::BoolToStr(val)); -} - -void nuisconfig::ChangeI(XMLNodePointer_t node, std::string name, int val) { - ChangeS(node, name, GeneralUtils::IntToStr(val)); -} -void nuisconfig::ChangeD(XMLNodePointer_t node, std::string name, double val) { - ChangeS(node, name, GeneralUtils::DblToStr(val)); -} - -void nuisconfig::RemoveEmptyNodes() { - std::vector nodelist = Config::Get().GetNodes(); - for (size_t i = 0; i < nodelist.size(); i++) { - if (fXML->IsEmptyNode(nodelist[i])) { - 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++) { - 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; - if (i == j) 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) { - 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; -} - -std::string nuisconfig::GetTag(std::string name) { - std::vector alltags = GetNodes("tag"); - std::string tagval = ""; - bool tagfound = false; - - for (size_t i = 0; i < alltags.size(); i++) { - if (!Has(alltags[i], name)) continue; - tagval = GetS(alltags[i], name); - tagfound = true; - } - - if (!tagfound) { - ERR(FTL) << "Cannot find tag " << name << " in global conig!" << std::endl; - throw; - } - - return tagval; -}; - -void nuisconfig::ExpandAllTags() { - return; - /* - // Loop over children and look for name - XMLNodePointer_t child = fXML->GetChild(fMainNode); - while (child != 0) { - - // Loop over attributes and search for tags - XMLAttrPointer_t attr = fXML->GetFirstAttr(child); - while ( attr != 0 ) { - - // Search attribute value for <> - std::string attrval = std::string(fXML->GetAttrValue(attr)); - std::string attrname = std::string(fXML->GetAttrName(attr)); - - // Search for <> - while (attrval.find("<") != std::string::npos and - attrval.find(">") != std::string::npos){ - - size_t startdel = 0; - size_t enddel = 0; - std::string replacestring = ""; - - for (size_t i = 0; i < attrval.size(); i++){ - - if (attrval[i] == '<'){ - replacestring = ""; - startdel = i; - } - - replacestring.push_back(attrval[i]); - - if (attrval[i] == '>'){ - enddel = i; - break; - } - } - - attrval.replace(startdel, replacestring, GetTag(replacestring) ); - } - - fXML->FreeAttr(child, attr); - attr = fXML->NewAttr(child, attr, attrname.c_str(), attrval.c_str()); - - // Get Next Attribute - attr = fXML->GetNextAttr(attr); - } - child = fXML->GetNext(child); - } - */ -}; - -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))); - // std::cout << "Pushing Back : " << - // std::string(fXML->GetAttrName(attr)) << std::endl; - } - attr = fXML->GetNextAttr(attr); - } - - // for (int i = 0; i < keys.size(); i++){ - // std::cout << "Got Key: " << keys[i] << std::endl; - // } - - return keys; -} diff --git a/src/Utils/NuisConfig.h b/src/Utils/NuisConfig.h deleted file mode 100644 index bbeea91..0000000 --- a/src/Utils/NuisConfig.h +++ /dev/null @@ -1,184 +0,0 @@ -// 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 NUISCONFIG_H_SEEN -#define NUISCONFIG_H_SEEN - -#include -#include - -#include "TXMLEngine.h" - -#include "GeneralUtils.h" - -// New NUISANCE Config Class -class nuisconfig { - public: - /// Singleton Get Function - static nuisconfig& GetConfig(void); - - /// Constructor \n - /// Loads defaults from $NUISANCE/parameters/config.xml - nuisconfig(); - - /// Desctructor \n Frees XML Docs - virtual ~nuisconfig(); - - /// Adds a new configuration list - void LoadConfig(std::string filename, std::string state); - - /// Adds a new config from new xml file format - void LoadXMLConfig(std::string filename, std::string state); - - /// Adds a new config from old card file format - void LoadCardConfig(std::string filename, std::string state); - - /// Save the config to file - void WriteConfig(std::string filename); - - void OverrideConfig(std::string conf); - - XMLNodePointer_t GetConfigNode(std::string name); - - /// Request a string config key - std::string SetConfS(const std::string name, std::string val); - - /// Get SetConfig Bool - bool SetConfB(const std::string name, bool val); - - /// Get SetConfig Int - int SetConfI(const std::string name, int val); - - /// Get SetConfig Double - double SetConfD(const std::string name, double val); - - // Set config - std::string ConfS(const std::string name); - - /// Get Config Bool - bool ConfB(const std::string name); - - /// Get Config Int - int ConfI(const std::string name); - - /// Get Config Double - double ConfD(const std::string name); - - /// Node Functions - void CheckCallCount(std::string name); - - /// Get list of child nodes of given element - std::vector GetChildNodes(XMLNodePointer_t node, - const std::string type); - - // Get List of child nodes of nuisance element - std::vector GetNodes(std::string type = ""); - - /// Get String from a given node - std::string GetS(XMLNodePointer_t node, std::string name); - - /// Get Bools from a given node - bool GetB(XMLNodePointer_t node, std::string name); - - /// Get int from given node - int GetI(XMLNodePointer_t node, std::string name); - - /// Get double from given node - double GetD(XMLNodePointer_t node, std::string name); - - // Add Children to root node - XMLNodePointer_t CreateNode(std::string name); - - // Add line - void AddXMLLine(std::string line); - - std::string ConvertSampleLineToXML(std::string line); - std::string ConvertParameterLineToXML(std::string line); - void FinaliseConfig(std::string name); - - // Add attribute to node - void AddS(XMLNodePointer_t node, std::string name, std::string val); - void AddB(XMLNodePointer_t node, std::string name, bool val); - void AddI(XMLNodePointer_t node, std::string name, int val); - void AddD(XMLNodePointer_t node, std::string name, double val); - - void SetS(XMLNodePointer_t node, std::string name, std::string val); - void SetB(XMLNodePointer_t node, std::string name, bool val); - void SetI(XMLNodePointer_t node, std::string name, int val); - void SetD(XMLNodePointer_t node, std::string name, double val); - - void ChangeS(XMLNodePointer_t node, std::string name, std::string val); - void ChangeB(XMLNodePointer_t node, std::string name, bool val); - void ChangeI(XMLNodePointer_t node, std::string name, int val); - void ChangeD(XMLNodePointer_t node, std::string name, double val); - - // Check has element - bool Has(XMLNodePointer_t node, std::string name); - - // Reconfigure (sorts overrides, logger, etc) - void Reconfigure(){}; - - /// OLD Wrapper Functions for GetParI,etc - inline std::string GetParS(std::string name) { return ConfS(name); }; - inline int GetParI(std::string name) { return ConfI(name); }; - inline double GetParD(std::string name) { return ConfD(name); }; - inline bool GetParB(std::string name) { return ConfB(name); }; - - // Get Vectors - std::vector GetVS(XMLNodePointer_t node, std::string name, - const char* del); - std::vector GetVI(XMLNodePointer_t node, std::string name, - const char* del); - std::vector GetVD(XMLNodePointer_t node, std::string name, - const char* del); - - void RemoveEmptyNodes(); - void RemoveIdenticalNodes(); - - std::vector GetAllKeysForNode(XMLNodePointer_t node); - - bool MatchingNodes(XMLNodePointer_t node1, XMLNodePointer_t node2); - void PrintNode(XMLNodePointer_t node); - void RemoveNode(XMLNodePointer_t node); - - std::string GetTag(std::string name); - - std::string GetElementName(XMLNodePointer_t node){ return fXML->GetNodeName(node); } - void ExpandAllTags(); - - private: - XMLNodePointer_t fMainNode; ///< Main XML Parent Node - TXMLEngine* fXML; ///< ROOT XML Engine - std::vector fXMLDocs; ///< List of all XML document inputs - - int fCurrentTime; ///< Unix time for inefficiency checking - std::map fConfigCallCount; ///< To check for inefficiency. - std::map fConfigCallWarning; ///< Only print warning once. - - protected: - static nuisconfig* m_nuisconfigInstance; -}; - -// Get Function for Singleton -namespace Config { -nuisconfig& Get(); -} - -/*! @} */ -#endif diff --git a/src/Utils/NuisKey.cxx b/src/Utils/NuisKey.cxx deleted file mode 100644 index c4d857e..0000000 --- a/src/Utils/NuisKey.cxx +++ /dev/null @@ -1,201 +0,0 @@ -#include "NuisKey.h" - -std::string nuiskey::GetS(std::string name) { - return Config::Get().GetS(fNode, name); -}; - -int nuiskey::GetI(std::string name) { return Config::Get().GetI(fNode, name); }; - -double nuiskey::GetD(std::string name) { - return Config::Get().GetD(fNode, name); -}; - -bool nuiskey::GetB(std::string name) { - return Config::Get().GetB(fNode, name); -}; - -std::vector nuiskey::GetVS(std::string name, const char* del) { - return Config::Get().GetVS(fNode, name, del); -}; - -std::vector nuiskey::GetVI(std::string name, const char* del) { - return Config::Get().GetVI(fNode, name, del); -}; - -std::vector nuiskey::GetVD(std::string name, const char* del) { - return Config::Get().GetVD(fNode, name, del); -}; - -std::vector Config::QueryKeys(const std::string type, - const std::string test1) { - // Get Vector of nodes - std::vector nodelist = Config::Get().GetNodes(type); - - // Convert List into a key list for easier access - std::vector keylist; - for (std::vector::const_iterator iter = nodelist.begin(); - iter != nodelist.end(); iter++) { - // Create new key - nuiskey newkey = nuiskey(*iter); - - // Add test1 - if (!test1.empty()) { - std::vector testvect = GeneralUtils::ParseToStr(test1, "="); - if (testvect.size() < 2) continue; - if (newkey.GetS(testvect[0]) != testvect[1]) continue; - } - - // Save node as nuiskey - keylist.push_back(newkey); - } - - // Return list of keys - return keylist; -} - -nuiskey Config::QueryLastKey(const std::string type, const std::string test1) { - // Loop over all for now because I'm lazy... - std::vector allkeys = Config::QueryKeys(type, test1); - if (allkeys.size() < 1) - return nuiskey(); - else - return allkeys[allkeys.size() - 1]; -} - -nuiskey Config::QueryFirstKey(const std::string type, const std::string test1) { - // Loop over all for now because I'm lazy... - std::vector allkeys = Config::QueryKeys(type, test1); - if (allkeys.size() < 1) - return nuiskey(); - else - return allkeys[allkeys.size() - 1]; -} - -nuiskey Config::CreateParameterKeyFromLine(const std::string line) { - nuiskey parameterkey = Config::CreateKey("parameter"); - - // Parse - std::vector strvct = GeneralUtils::ParseToStr(line, " "); - - // Add to key - parameterkey.AddS("type", strvct[0]); - parameterkey.AddS("name", strvct[1]); - parameterkey.AddS("nominal", strvct[2]); - - if (strvct.size() == 7) { - parameterkey.AddS("low", strvct[3]); - parameterkey.AddS("high", strvct[4]); - parameterkey.AddS("step", strvct[5]); - parameterkey.AddS("state", strvct[6]); - } else if (strvct.size() == 3) { - parameterkey.AddS("state", "FIX"); - } else if (strvct.size() == 4) { - parameterkey.AddS("state", strvct[3]); - } - - return parameterkey; -} - -bool nuiskey::Has(const std::string name) { - return Config::Get().Has(fNode, name); -} - -std::string nuiskey::GetElementName() { return Config::Get().GetElementName(fNode); } - -nuiskey Config::CreatePullKeyFromLine(const std::string line) { - nuiskey pullkey = Config::CreateKey("covar"); - - // Parse - std::vector strvct = GeneralUtils::ParseToStr(line, " "); - pullkey.AddS("name", strvct[1]); - pullkey.AddS("input", strvct[2]); - pullkey.AddS("type", strvct[3]); - - return pullkey; -} - -nuiskey Config::CreateOldConfigKeyFromLine(const std::string line) { - nuiskey configkey = Config::CreateKey("config"); - - std::vector strvct = GeneralUtils::ParseToStr(line, " "); - configkey.AddS(strvct[1], strvct[2]); - - return configkey; -} - -nuiskey Config::CreateSampleKeyFromLine(const std::string line) { - // Create new key - nuiskey samplekey = Config::CreateKey("sample"); - - // Parse - std::vector strvct = GeneralUtils::ParseToStr(line, " "); - - // Get elements - samplekey.AddS("name", strvct[1]); - samplekey.AddS("input", strvct[2]); - if (strvct.size() > 3) { - samplekey.AddS("type", strvct[3]); - } - if (strvct.size() > 4) { - samplekey.AddS("norm", strvct[4]); - } - - return samplekey; -} - -nuiskey Config::CreateKey(const std::string name) { - return nuiskey(Config::Get().CreateNode(name)); -} - -void nuiskey::AddS(std::string name, std::string newval) { - Config::Get().AddS(fNode, name, newval); -} -void nuiskey::AddI(std::string name, int newval) { - Config::Get().AddI(fNode, name, newval); -} -void nuiskey::AddD(std::string name, double newval) { - Config::Get().AddD(fNode, name, newval); -} -void nuiskey::AddB(std::string name, bool newval) { - Config::Get().AddB(fNode, name, newval); -} - -void nuiskey::SetS(std::string name, std::string newval) { - Config::Get().SetS(fNode, name, newval); -} -void nuiskey::SetI(std::string name, int newval) { - Config::Get().SetI(fNode, name, newval); -} -void nuiskey::SetD(std::string name, double newval) { - Config::Get().SetD(fNode, name, newval); -} -void nuiskey::SetB(std::string name, bool newval) { - Config::Get().SetB(fNode, name, newval); -} - -void nuiskey::ChangeS(std::string name, std::string newval) { - Config::Get().ChangeS(fNode, name, newval); -} -void nuiskey::ChangeI(std::string name, int newval) { - Config::Get().ChangeI(fNode, name, newval); -} -void nuiskey::ChangeD(std::string name, double newval) { - Config::Get().ChangeD(fNode, name, newval); -} -void nuiskey::ChangeB(std::string name, bool newval) { - Config::Get().ChangeB(fNode, name, newval); -} - -std::vector nuiskey::GetAllKeys() { - return Config::Get().GetAllKeysForNode(fNode); -} - -std::vector nuiskey::GetListOfChildNodes(std::string const& filter) { - std::vector nodelist = - Config::Get().GetChildNodes(fNode, filter); - std::vector keylist; - for (size_t n_it = 0; n_it < nodelist.size(); ++n_it) { - keylist.push_back(nuiskey(nodelist[n_it])); - } - return keylist; -} diff --git a/src/Utils/NuisKey.h b/src/Utils/NuisKey.h deleted file mode 100644 index 606d3be..0000000 --- a/src/Utils/NuisKey.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef NUISKEY_H -#define NUISKEY_H - -#include - -#include "NuisConfig.h" - -class nuiskey { - public: - nuiskey(){}; - - nuiskey(XMLNodePointer_t node) { fNode = node; }; - - ~nuiskey(){}; - - std::string GetS(std::string name); - int GetI(std::string name); - double GetD(std::string name); - bool GetB(std::string name); - - std::vector GetVS(std::string name, const char* del); - std::vector GetVI(std::string name, const char* del); - std::vector GetVD(std::string name, const char* del); - - void SetS(std::string name, std::string newval); - void SetI(std::string name, int newval); - void SetD(std::string name, double newval); - void SetB(std::string name, bool newval); - - void ChangeS(std::string name, std::string newval); - void ChangeI(std::string name, int newval); - void ChangeD(std::string name, double newval); - void ChangeB(std::string name, bool newval); - - void AddS(std::string name, std::string newval); - void AddI(std::string name, int newval); - void AddD(std::string name, double newval); - void AddB(std::string name, bool newval); - - bool Has(std::string name); - - std::string GetElementName(); - - std::vector GetAllKeys(); - - std::vector GetListOfChildNodes(std::string const& filter = ""); - - XMLNodePointer_t fNode; ///< XML Node in Config::Get().fXML for this key -}; - -namespace Config { - -// Return a vector of keys for use -std::vector QueryKeys(const std::string name, - const std::string test1 = ""); -nuiskey QueryFirstKey(const std::string name, const std::string test1 = ""); -nuiskey QueryLastKey(const std::string name, const std::string test1 = ""); - -// Create a new global config entry -nuiskey CreateKey(const std::string name); - -// void ConvertAndLoadCardToXMLFormat(const std::string cardfile); - -// Backwards compatible sample key options -nuiskey CreateSampleKeyFromLine(const std::string line); -nuiskey CreateParameterKeyFromLine(const std::string line); -nuiskey CreatePullKeyFromLine(const std::string line); -nuiskey CreateOldConfigKeyFromLine(const std::string line); -} -#endif diff --git a/src/Utils/ParserUtils.h b/src/Utils/ParserUtils.h index 475c7fb..e8151bd 100644 --- a/src/Utils/ParserUtils.h +++ b/src/Utils/ParserUtils.h @@ -1,40 +1,51 @@ #ifndef PARSER_UTILS_H #define PARSER_UTILS_H -#include "FitParameters.h" -#include "GeneralUtils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include "GeneralUtils.h" /// All functions used to parse input arguments. namespace ParserUtils { /// Checks a list of arguments for '-?' flags that have not been removed void CheckBadArguments(std::vector args); /// Parses the arguments looked for the 'opt' flag and saves it into val void ParseArgument(std::vector& args, std::string opt, int& val, bool required = false, bool duplicates = true); /// Parses the arguments looked for the 'opt' flag and saves it into val void ParseArgument(std::vector& args, std::string opt, std::string& val, bool required = false, bool duplicates = true); /// Parses the arguments looked for the 'opt' flag and saves it into val void ParseSplitArgument(std::vector& args, std::string opt, std::string& val, bool required = false, bool duplicates = true); /// Parses the arguments looked for the 'opt' flag and saves all proceeding values into val (UNSTABLE) void ParseSplitArgument(std::vector& args, std::string opt, std::vector& val, bool required = false, bool duplicates = true); // /// Take everything left in the string // void ParseRemainingXML(std::vector& args, std::vector& cmds); /// Parse arguments looking for '+/-opt' and add/subtract from counter when it occurs void ParseCounter(std::vector& args, std::string opt, int& count); /// In the case where duplicates can be given, parses all cases into the val vector void ParseArgument(std::vector& args, std::string opt, std::vector& val, bool required = false, bool duplicates = true); }; #endif diff --git a/src/Utils/PlotUtils.cxx b/src/Utils/PlotUtils.cxx index 309f826..4eabf23 100644 --- a/src/Utils/PlotUtils.cxx +++ b/src/Utils/PlotUtils.cxx @@ -1,999 +1,999 @@ // 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 "PlotUtils.h" #include "FitEvent.h" -#include "FitParameters.h" +#include "StatUtils.h" // MOVE TO MB UTILS! // This function is intended to be modified to enforce a consistent masking for // all models. TH2D* PlotUtils::SetMaskHist(std::string type, TH2D* data) { TH2D* fMaskHist = (TH2D*)data->Clone("fMaskHist"); for (int xBin = 0; xBin < fMaskHist->GetNbinsX(); ++xBin) { for (int yBin = 0; yBin < fMaskHist->GetNbinsY(); ++yBin) { if (data->GetBinContent(xBin + 1, yBin + 1) == 0) fMaskHist->SetBinContent(xBin + 1, yBin + 1, 0); else fMaskHist->SetBinContent(xBin + 1, yBin + 1, 0.5); if (!type.compare("MB_numu_2D")) { if (yBin == 19 && xBin < 8) fMaskHist->SetBinContent(xBin + 1, yBin + 1, 1.0); } else { if (yBin == 19 && xBin < 11) fMaskHist->SetBinContent(xBin + 1, yBin + 1, 1.0); } if (yBin == 18 && xBin < 3) fMaskHist->SetBinContent(xBin + 1, yBin + 1, 1.0); if (yBin == 17 && xBin < 2) fMaskHist->SetBinContent(xBin + 1, yBin + 1, 1.0); if (yBin == 16 && xBin < 1) fMaskHist->SetBinContent(xBin + 1, yBin + 1, 1.0); } } return fMaskHist; }; // MOVE TO GENERAL UTILS? bool PlotUtils::CheckObjectWithName(TFile* inFile, std::string substring) { TIter nextkey(inFile->GetListOfKeys()); TKey* key; while ((key = (TKey*)nextkey())) { std::string test(key->GetName()); if (test.find(substring) != std::string::npos) return true; } return false; }; // MOVE TO GENERAL UTILS? std::string PlotUtils::GetObjectWithName(TFile* inFile, std::string substring) { TIter nextkey(inFile->GetListOfKeys()); TKey* key; std::string output = ""; while ((key = (TKey*)nextkey())) { std::string test(key->GetName()); if (test.find(substring) != std::string::npos) output = test; } return output; }; void PlotUtils::CreateNeutModeArray(TH1* hist, TH1* neutarray[]) { for (int i = 0; i < 60; i++) { neutarray[i] = (TH1*)hist->Clone(Form("%s_NMODE_%i", hist->GetName(), i)); } return; }; void PlotUtils::DeleteNeutModeArray(TH1* neutarray[]) { for (int i = 0; i < 60; i++) { delete neutarray[i]; } return; }; void PlotUtils::FillNeutModeArray(TH1D* hist[], int mode, double xval, double weight) { if (abs(mode) > 60) return; hist[abs(mode)]->Fill(xval, weight); return; }; void PlotUtils::FillNeutModeArray(TH2D* hist[], int mode, double xval, double yval, double weight) { if (abs(mode) > 60) return; hist[abs(mode)]->Fill(xval, yval, weight); return; }; THStack PlotUtils::GetNeutModeStack(std::string title, TH1* ModeStack[], int option) { (void)option; THStack allmodes = THStack(title.c_str(), title.c_str()); for (int i = 0; i < 60; i++) { allmodes.Add(ModeStack[i]); } // Credit to Clarence for copying all this out. // CC ModeStack[1]->SetTitle("CCQE"); ModeStack[1]->SetFillColor(kBlue); // ModeStack[1]->SetFillStyle(3444); ModeStack[1]->SetLineColor(kBlue); ModeStack[2]->SetTitle("2p/2h Nieves"); ModeStack[2]->SetFillColor(kRed); // ModeStack[2]->SetFillStyle(3344); ModeStack[2]->SetLineColor(kRed); // ModeStack[11]->SetTitle("#it{#nu + p #rightarrow l^{-} + p + #pi^{+}}"); ModeStack[11]->SetTitle("CC1#pi^{+} on p"); ModeStack[11]->SetFillColor(kGreen); // ModeStack[11]->SetFillStyle(3004); ModeStack[11]->SetLineColor(kGreen); // ModeStack[12]->SetTitle("#it{#nu + n #rightarrow l^{-} + p + #pi^{0}}"); ModeStack[12]->SetTitle("CC1#pi^{0} on n"); ModeStack[12]->SetFillColor(kGreen + 3); // ModeStack[12]->SetFillStyle(3005); ModeStack[12]->SetLineColor(kGreen); // ModeStack[13]->SetTitle("#it{#nu + n #rightarrow l^{-} + n + #pi^{+}}"); ModeStack[13]->SetTitle("CC1#pi^{+} on n"); ModeStack[13]->SetFillColor(kGreen - 2); // ModeStack[13]->SetFillStyle(3004); ModeStack[13]->SetLineColor(kGreen); ModeStack[16]->SetTitle("CC coherent"); ModeStack[16]->SetFillColor(kBlue); // ModeStack[16]->SetFillStyle(3644); ModeStack[16]->SetLineColor(kBlue); // ModeStack[17]->SetTitle("#it{#nu + n #rightarrow l^{-} + p + #gamma}"); ModeStack[17]->SetTitle("CC1#gamma"); ModeStack[17]->SetFillColor(kMagenta); // ModeStack[17]->SetFillStyle(3001); ModeStack[17]->SetLineColor(kMagenta); ModeStack[21]->SetTitle("Multi #pi (1.3 < W < 2.0)"); ModeStack[21]->SetFillColor(kYellow); // ModeStack[21]->SetFillStyle(3005); ModeStack[21]->SetLineColor(kYellow); // ModeStack[22]->SetTitle("#it{#nu + n #rightarrow l^{-} + p + #eta^{0}}"); ModeStack[22]->SetTitle("CC1#eta^{0} on n"); ModeStack[22]->SetFillColor(kYellow - 2); // ModeStack[22]->SetFillStyle(3013); ModeStack[22]->SetLineColor(kYellow - 2); // ModeStack[23]->SetTitle("#it{#nu + n #rightarrow l^{-} + #Lambda + // K^{+}}"); ModeStack[23]->SetTitle("CC1#Labda1K^{+}"); ModeStack[23]->SetFillColor(kYellow - 6); // ModeStack[23]->SetFillStyle(3013); ModeStack[23]->SetLineColor(kYellow - 6); ModeStack[26]->SetTitle("DIS (W > 2.0)"); ModeStack[26]->SetFillColor(kRed); // ModeStack[26]->SetFillStyle(3006); ModeStack[26]->SetLineColor(kRed); // NC // ModeStack[31]->SetTitle("#it{#nu + n #rightarrow #nu + n + #pi^{0}}"); ModeStack[31]->SetTitle("NC1#pi^{0} on n"); ModeStack[31]->SetFillColor(kBlue); // ModeStack[31]->SetFillStyle(3004); ModeStack[31]->SetLineColor(kBlue); // ModeStack[32]->SetTitle("#it{#nu + p #rightarrow #nu + p + #pi^{0}}"); ModeStack[32]->SetTitle("NC1#pi^{0} on p"); ModeStack[32]->SetFillColor(kBlue + 3); // ModeStack[32]->SetFillStyle(3004); ModeStack[32]->SetLineColor(kBlue + 3); // ModeStack[33]->SetTitle("#it{#nu + n #rightarrow #nu + p + #pi^{-}}"); ModeStack[33]->SetTitle("NC1#pi^{-} on n"); ModeStack[33]->SetFillColor(kBlue - 2); // ModeStack[33]->SetFillStyle(3005); ModeStack[33]->SetLineColor(kBlue - 2); // ModeStack[34]->SetTitle("#it{#nu + p #rightarrow #nu + n + #pi^{+}}"); ModeStack[34]->SetTitle("NC1#pi^{+} on p"); ModeStack[34]->SetFillColor(kBlue - 8); // ModeStack[34]->SetFillStyle(3005); ModeStack[34]->SetLineColor(kBlue - 8); ModeStack[36]->SetTitle("NC Coherent"); ModeStack[36]->SetFillColor(kBlue + 8); // ModeStack[36]->SetFillStyle(3644); ModeStack[36]->SetLineColor(kBlue + 8); // ModeStack[38]->SetTitle("#it{#nu + n #rightarrow #nu + n + #gamma}"); ModeStack[38]->SetTitle("NC1#gamma on n"); ModeStack[38]->SetFillColor(kMagenta); // ModeStack[38]->SetFillStyle(3001); ModeStack[38]->SetLineColor(kMagenta); // ModeStack[39]->SetTitle("#it{#nu + p #rightarrow #nu + p + #gamma}"); ModeStack[39]->SetTitle("NC1#gamma on p"); ModeStack[39]->SetFillColor(kMagenta - 10); // ModeStack[39]->SetFillStyle(3001); ModeStack[39]->SetLineColor(kMagenta - 10); ModeStack[41]->SetTitle("Multi #pi (1.3 < W < 2.0)"); ModeStack[41]->SetFillColor(kBlue - 10); // ModeStack[41]->SetFillStyle(3005); ModeStack[41]->SetLineColor(kBlue - 10); // ModeStack[42]->SetTitle("#it{#nu + n #rightarrow #nu + n + #eta^{0}}"); ModeStack[42]->SetTitle("NC1#eta^{0} on n"); ModeStack[42]->SetFillColor(kYellow - 2); // ModeStack[42]->SetFillStyle(3013); ModeStack[42]->SetLineColor(kYellow - 2); // ModeStack[43]->SetTitle("#it{#nu + p #rightarrow #nu + p + #eta^{0}}"); ModeStack[43]->SetTitle("NC1#eta^{0} on p"); ModeStack[43]->SetFillColor(kYellow - 4); // ModeStack[43]->SetFillStyle(3013); ModeStack[43]->SetLineColor(kYellow - 4); // ModeStack[44]->SetTitle("#it{#nu + n #rightarrow #nu + #Lambda + K^{0}}"); ModeStack[44]->SetTitle("NC1#Lambda1K^{0} on n"); ModeStack[44]->SetFillColor(kYellow - 6); // ModeStack[44]->SetFillStyle(3014); ModeStack[44]->SetLineColor(kYellow - 6); // ModeStack[45]->SetTitle("#it{#nu + p #rightarrow #nu + #Lambda + K^{+}}"); ModeStack[45]->SetTitle("NC1#Lambda1K^{+}"); ModeStack[45]->SetFillColor(kYellow - 10); // ModeStack[45]->SetFillStyle(3014); ModeStack[45]->SetLineColor(kYellow - 10); ModeStack[46]->SetTitle("DIS (W > 2.0)"); ModeStack[46]->SetFillColor(kRed); // ModeStack[46]->SetFillStyle(3006); ModeStack[46]->SetLineColor(kRed); // ModeStack[51]->SetTitle("#it{#nu + p #rightarrow #nu + p}"); ModeStack[51]->SetTitle("NC on p"); ModeStack[51]->SetFillColor(kBlack); // ModeStack[51]->SetFillStyle(3444); ModeStack[51]->SetLineColor(kBlack); // ModeStack[52]->SetTitle("#it{#nu + n #rightarrow #nu + n}"); ModeStack[52]->SetTitle("NC on n"); ModeStack[52]->SetFillColor(kGray); // ModeStack[52]->SetFillStyle(3444); ModeStack[52]->SetLineColor(kGray); return allmodes; }; TLegend PlotUtils::GenerateStackLegend(THStack stack, int xlow, int ylow, int xhigh, int yhigh) { TLegend leg = TLegend(xlow, ylow, xhigh, yhigh); TObjArray* histarray = stack.GetStack(); int nhist = histarray->GetEntries(); for (int i = 0; i < nhist; i++) { TH1* hist = (TH1*)(histarray->At(i)); leg.AddEntry((hist), ((TH1*)histarray->At(i))->GetTitle(), "fl"); } leg.SetName(Form("%s_LEG", stack.GetName())); return leg; }; void PlotUtils::ScaleNeutModeArray(TH1* hist[], double factor, std::string option) { for (int i = 0; i < 60; i++) { if (hist[i]) hist[i]->Scale(factor, option.c_str()); } return; }; void PlotUtils::ResetNeutModeArray(TH1* hist[]) { for (int i = 0; i < 60; i++) { if (hist[i]) hist[i]->Reset(); } return; }; //******************************************************************** // This assumes the Enu axis is the x axis, as is the case for MiniBooNE 2D // distributions void PlotUtils::FluxUnfoldedScaling(TH2D* fMCHist, TH1D* fhist, TH1D* ehist, double scalefactor) { //******************************************************************** // Make clones to avoid changing stuff TH1D* eventhist = (TH1D*)ehist->Clone(); TH1D* fFluxHist = (TH1D*)fhist->Clone(); // Undo width integral in SF fMCHist->Scale(scalefactor / eventhist->Integral(1, eventhist->GetNbinsX() + 1, "width")); // Standardise The Flux eventhist->Scale(1.0 / fFluxHist->Integral()); fFluxHist->Scale(1.0 / fFluxHist->Integral()); // Do interpolation for 2D plots? // fFluxHist = PlotUtils::InterpolateFineHistogram(fFluxHist,100,"width"); // eventhist = PlotUtils::InterpolateFineHistogram(eventhist,100,"width"); // eventhist->Scale(1.0/fFluxHist->Integral()); // fFluxHist->Scale(1.0/fFluxHist->Integral()); // Scale fMCHist by eventhist integral fMCHist->Scale(eventhist->Integral(1, eventhist->GetNbinsX() + 1)); // Now Get a flux PDF assuming X axis is Enu TH1D* pdfflux = (TH1D*)fMCHist->ProjectionX()->Clone(); // pdfflux->Write( (std::string(fMCHist->GetName()) + "_PROJX").c_str()); pdfflux->Reset(); // Awful MiniBooNE Check for the time being bool ismb = std::string(fMCHist->GetName()).find("MiniBooNE") != std::string::npos; for (int i = 0; i < pdfflux->GetNbinsX(); i++) { double Ml = pdfflux->GetXaxis()->GetBinLowEdge(i + 1); double Mh = pdfflux->GetXaxis()->GetBinLowEdge(i + 2); // double Mc = pdfflux->GetXaxis()->GetBinCenter(i+1); // double Mw = pdfflux->GetBinWidth(i+1); double fluxint = 0.0; // Scaling to match flux for MB if (ismb) { Ml /= 1.E3; Mh /= 1.E3; // Mc /= 1.E3; // Mw /= 1.E3; } for (int j = 0; j < fFluxHist->GetNbinsX(); j++) { // double Fc = fFluxHist->GetXaxis()->GetBinCenter(j+1); double Fl = fFluxHist->GetXaxis()->GetBinLowEdge(j + 1); double Fh = fFluxHist->GetXaxis()->GetBinLowEdge(j + 2); double Fe = fFluxHist->GetBinContent(j + 1); double Fw = fFluxHist->GetXaxis()->GetBinWidth(j + 1); if (Fl >= Ml and Fh <= Mh) { fluxint += Fe; } else if (Fl < Ml and Fl < Mh and Fh > Ml and Fh < Mh) { fluxint += Fe * (Fh - Ml) / Fw; } else if (Fh > Mh and Fl < Mh and Fh > Ml and Fl > Ml) { fluxint += Fe * (Mh - Fl) / Fw; } else if (Ml >= Fl and Mh <= Fh) { fluxint += Fe * (Mh - Ml) / Fw; } else { continue; } } pdfflux->SetBinContent(i + 1, fluxint); } for (int i = 0; i < fMCHist->GetNbinsX(); i++) { for (int j = 0; j < fMCHist->GetNbinsY(); j++) { if (pdfflux->GetBinContent(i + 1) == 0.0) continue; double binWidth = fMCHist->GetYaxis()->GetBinLowEdge(j + 2) - fMCHist->GetYaxis()->GetBinLowEdge(j + 1); fMCHist->SetBinContent(i + 1, j + 1, fMCHist->GetBinContent(i + 1, j + 1) / pdfflux->GetBinContent(i + 1) / binWidth); fMCHist->SetBinError(i + 1, j + 1, fMCHist->GetBinError(i + 1, j + 1) / pdfflux->GetBinContent(i + 1) / binWidth); } } delete eventhist; delete fFluxHist; return; }; TH1D* PlotUtils::InterpolateFineHistogram(TH1D* hist, int res, std::string opt) { int nbins = hist->GetNbinsX(); double elow = hist->GetXaxis()->GetBinLowEdge(1); double ehigh = hist->GetXaxis()->GetBinLowEdge(nbins + 1); bool width = true; // opt.find("width") != std::string::npos; TH1D* fine = new TH1D("fine", "fine", nbins * res, elow, ehigh); TGraph* temp = new TGraph(); for (int i = 0; i < nbins; i++) { double E = hist->GetXaxis()->GetBinCenter(i + 1); double C = hist->GetBinContent(i + 1); double W = hist->GetXaxis()->GetBinWidth(i + 1); if (!width) W = 1.0; if (W != 0.0) temp->SetPoint(temp->GetN(), E, C / W); } for (int i = 0; i < fine->GetNbinsX(); i++) { double E = fine->GetXaxis()->GetBinCenter(i + 1); double W = fine->GetBinWidth(i + 1); if (!width) W = 1.0; fine->SetBinContent(i + 1, temp->Eval(E, 0, "S") * W); } fine->Scale(hist->Integral(1, hist->GetNbinsX() + 1) / fine->Integral(1, fine->GetNbinsX() + 1)); std::cout << "Interpolation Difference = " << fine->Integral(1, fine->GetNbinsX() + 1) << "/" << hist->Integral(1, hist->GetNbinsX() + 1) << std::endl; return fine; } //******************************************************************** // This interpolates the flux by a TGraph instead of requiring the flux and MC // flux to have the same binning void PlotUtils::FluxUnfoldedScaling(TH1D* mcHist, TH1D* fhist, TH1D* ehist, double scalefactor, int nevents) { //******************************************************************** TH1D* eventhist = (TH1D*)ehist->Clone(); TH1D* fFluxHist = (TH1D*)fhist->Clone(); if (FitPar::Config().GetParB("save_flux_debug")) { std::string name = std::string(mcHist->GetName()); mcHist->Write((name + "_UNF_MC").c_str()); fFluxHist->Write((name + "_UNF_FLUX").c_str()); eventhist->Write((name + "_UNF_EVT").c_str()); TH1D* scalehist = new TH1D("scalehist", "scalehist", 1, 0.0, 1.0); scalehist->SetBinContent(1, scalefactor); scalehist->SetBinContent(2, nevents); scalehist->Write((name + "_UNF_SCALE").c_str()); } // Undo width integral in SF mcHist->Scale(scalefactor / eventhist->Integral(1, eventhist->GetNbinsX() + 1, "width")); // Standardise The Flux eventhist->Scale(1.0 / fFluxHist->Integral()); fFluxHist->Scale(1.0 / fFluxHist->Integral()); // Scale mcHist by eventhist integral mcHist->Scale(eventhist->Integral(1, eventhist->GetNbinsX() + 1)); // Now Get a flux PDF TH1D* pdfflux = (TH1D*)mcHist->Clone(); pdfflux->Reset(); for (int i = 0; i < mcHist->GetNbinsX(); i++) { double Ml = mcHist->GetXaxis()->GetBinLowEdge(i + 1); double Mh = mcHist->GetXaxis()->GetBinLowEdge(i + 2); // double Mc = mcHist->GetXaxis()->GetBinCenter(i+1); // double Me = mcHist->GetBinContent(i+1); // double Mw = mcHist->GetBinWidth(i+1); double fluxint = 0.0; for (int j = 0; j < fFluxHist->GetNbinsX(); j++) { // double Fc = fFluxHist->GetXaxis()->GetBinCenter(j+1); double Fl = fFluxHist->GetXaxis()->GetBinLowEdge(j + 1); double Fh = fFluxHist->GetXaxis()->GetBinLowEdge(j + 2); double Fe = fFluxHist->GetBinContent(j + 1); double Fw = fFluxHist->GetXaxis()->GetBinWidth(j + 1); if (Fl >= Ml and Fh <= Mh) { fluxint += Fe; } else if (Fl < Ml and Fl < Mh and Fh > Ml and Fh < Mh) { fluxint += Fe * (Fh - Ml) / Fw; } else if (Fh > Mh and Fl < Mh and Fh > Ml and Fl > Ml) { fluxint += Fe * (Mh - Fl) / Fw; } else if (Ml >= Fl and Mh <= Fh) { fluxint += Fe * (Mh - Ml) / Fw; } else { continue; } } pdfflux->SetBinContent(i + 1, fluxint); } // Scale MC hist by pdfflux for (int i = 0; i < mcHist->GetNbinsX(); i++) { if (pdfflux->GetBinContent(i + 1) == 0.0) continue; mcHist->SetBinContent( i + 1, mcHist->GetBinContent(i + 1) / pdfflux->GetBinContent(i + 1)); mcHist->SetBinError( i + 1, mcHist->GetBinError(i + 1) / pdfflux->GetBinContent(i + 1)); } delete eventhist; delete fFluxHist; return; }; // MOVE TO GENERAL UTILS //******************************************************************** void PlotUtils::Set2DHistFromText(std::string dataFile, TH2* hist, double norm, bool skipbins) { //******************************************************************** std::string line; std::ifstream data(dataFile.c_str(), ifstream::in); int yBin = 0; while (std::getline(data >> std::ws, line, '\n')) { std::vector entries = GeneralUtils::ParseToDbl(line, " "); // Loop over entries and insert them into the histogram for (uint xBin = 0; xBin < entries.size(); xBin++) { if (!skipbins or entries[xBin] != -1.0) hist->SetBinContent(xBin + 1, yBin + 1, entries[xBin] * norm); } yBin++; } return; } // MOVE TO GENERAL UTILS TH1D* PlotUtils::GetTH1DFromFile(std::string dataFile, std::string title, std::string fPlotTitles, std::string alt_name) { TH1D* tempPlot; // If format is a root file if (dataFile.find(".root") != std::string::npos) { TFile* temp_infile = new TFile(dataFile.c_str(), "READ"); tempPlot = (TH1D*)temp_infile->Get(title.c_str()); tempPlot->SetDirectory(0); temp_infile->Close(); delete temp_infile; // Else its a space seperated txt file } else { // Make a TGraph Errors TGraphErrors* gr = new TGraphErrors(dataFile.c_str(), "%lg %lg %lg"); if (gr->IsZombie()) { exit(-1); } double* bins = gr->GetX(); double* values = gr->GetY(); double* errors = gr->GetEY(); int npoints = gr->GetN(); // Fill the histogram from it tempPlot = new TH1D(title.c_str(), title.c_str(), npoints - 1, bins); for (int i = 0; i < npoints; ++i) { tempPlot->SetBinContent(i + 1, values[i]); // If only two columns are present in the input file, use the sqrt(values) // as the error // equivalent to assuming that the error is statistical if (!errors[i]) tempPlot->SetBinError(i + 1, sqrt(values[i])); else tempPlot->SetBinError(i + 1, errors[i]); } delete gr; } // Allow alternate naming for root files if (!alt_name.empty()) { tempPlot->SetNameTitle(alt_name.c_str(), alt_name.c_str()); } // Allow alternate axis titles if (!fPlotTitles.empty()) { tempPlot->SetNameTitle( tempPlot->GetName(), (std::string(tempPlot->GetTitle()) + fPlotTitles).c_str()); } return tempPlot; }; TH1D* PlotUtils::GetRatioPlot(TH1D* hist1, TH1D* hist2) { // make copy of first hist TH1D* new_hist = (TH1D*)hist1->Clone(); // Do bins and errors ourselves as scales can go awkward for (int i = 0; i < new_hist->GetNbinsX(); i++) { if (hist2->GetBinContent(i + 1) == 0.0) { new_hist->SetBinContent(i + 1, 0.0); } new_hist->SetBinContent( i + 1, hist1->GetBinContent(i + 1) / hist2->GetBinContent(i + 1)); new_hist->SetBinError( i + 1, hist1->GetBinError(i + 1) / hist2->GetBinContent(i + 1)); } return new_hist; }; TH1D* PlotUtils::GetRenormalisedPlot(TH1D* hist1, TH1D* hist2) { // make copy of first hist TH1D* new_hist = (TH1D*)hist1->Clone(); if (hist1->Integral("width") == 0 or hist2->Integral("width") == 0) { new_hist->Reset(); return new_hist; } Double_t scaleF = hist2->Integral("width") / hist1->Integral("width"); new_hist->Scale(scaleF); return new_hist; }; TH1D* PlotUtils::GetShapePlot(TH1D* hist1) { // make copy of first hist TH1D* new_hist = (TH1D*)hist1->Clone(); if (hist1->Integral("width") == 0) { new_hist->Reset(); return new_hist; } Double_t scaleF1 = 1.0 / hist1->Integral("width"); new_hist->Scale(scaleF1); return new_hist; }; TH1D* PlotUtils::GetShapeRatio(TH1D* hist1, TH1D* hist2) { TH1D* new_hist1 = GetShapePlot(hist1); TH1D* new_hist2 = GetShapePlot(hist2); // Do bins and errors ourselves as scales can go awkward for (int i = 0; i < new_hist1->GetNbinsX(); i++) { if (hist2->GetBinContent(i + 1) == 0) { new_hist1->SetBinContent(i + 1, 0.0); } new_hist1->SetBinContent(i + 1, new_hist1->GetBinContent(i + 1) / new_hist2->GetBinContent(i + 1)); new_hist1->SetBinError( i + 1, new_hist1->GetBinError(i + 1) / new_hist2->GetBinContent(i + 1)); } delete new_hist2; return new_hist1; }; TH2D* PlotUtils::GetCovarPlot(TMatrixDSym* cov, std::string name, std::string title) { TH2D* CovarPlot; if (cov) CovarPlot = new TH2D((*cov)); else CovarPlot = new TH2D(name.c_str(), title.c_str(), 1, 0, 1, 1, 0, 1); CovarPlot->SetName(name.c_str()); CovarPlot->SetTitle(title.c_str()); return CovarPlot; } TH2D* PlotUtils::GetFullCovarPlot(TMatrixDSym* cov, std::string name) { return PlotUtils::GetCovarPlot( cov, name + "_COV", name + "_COV;Bins;Bins;Covariance (#times10^{-76})"); } TH2D* PlotUtils::GetInvCovarPlot(TMatrixDSym* cov, std::string name) { return PlotUtils::GetCovarPlot( cov, name + "_INVCOV", name + "_INVCOV;Bins;Bins;Inv. Covariance (#times10^{-76})"); } TH2D* PlotUtils::GetDecompCovarPlot(TMatrixDSym* cov, std::string name) { return PlotUtils::GetCovarPlot( cov, name + "_DECCOV", name + "_DECCOV;Bins;Bins;Decomp Covariance (#times10^{-76})"); } TH1D* PlotUtils::GetTH1DFromRootFile(std::string file, std::string name) { if (name.empty()) { std::vector tempfile = GeneralUtils::ParseToStr(file, ";"); file = tempfile[0]; name = tempfile[1]; } TFile* rootHistFile = new TFile(file.c_str(), "READ"); TH1D* tempHist = (TH1D*)rootHistFile->Get(name.c_str())->Clone(); tempHist->SetDirectory(0); rootHistFile->Close(); return tempHist; } TH2D* PlotUtils::GetTH2DFromRootFile(std::string file, std::string name) { if (name.empty()) { std::vector tempfile = GeneralUtils::ParseToStr(file, ";"); file = tempfile[0]; name = tempfile[1]; } TFile* rootHistFile = new TFile(file.c_str(), "READ"); TH2D* tempHist = (TH2D*)rootHistFile->Get(name.c_str())->Clone(); tempHist->SetDirectory(0); rootHistFile->Close(); return tempHist; } TH1* PlotUtils::GetTH1FromRootFile(std::string file, std::string name) { if (name.empty()) { std::vector tempfile = GeneralUtils::ParseToStr(file, ";"); file = tempfile[0]; name = tempfile[1]; } TFile* rootHistFile = new TFile(file.c_str(), "READ"); if (!rootHistFile || rootHistFile->IsZombie()) { THROW("Couldn't open root file: \"" << file << "\"."); } TH1* tempHist = dynamic_cast(rootHistFile->Get(name.c_str())->Clone()); if (!tempHist) { THROW("Couldn't retrieve: \"" << name << "\" from root file: \"" << file << "\"."); } tempHist->SetDirectory(0); rootHistFile->Close(); return tempHist; } /// Returns a vector of named TH1*s found in a single input file. /// /// Expects a descriptor like: file.root[hist1|hist2|...] std::vector PlotUtils::GetTH1sFromRootFile( std::string const& descriptor) { std::vector descriptors = GeneralUtils::ParseToStr(descriptor, ","); std::vector hists; for (size_t d_it = 0; d_it < descriptors.size(); ++d_it) { std::string& d = descriptors[d_it]; std::vector fname = GeneralUtils::ParseToStr(d, "["); if (!fname.size() || !fname[0].length()) { THROW("Couldn't find input file when attempting to parse : \"" << d << "\". Expected input.root[hist1|hist2|...]."); } if (fname[1][fname[1].length() - 1] == ']') { fname[1] = fname[1].substr(0, fname[1].length() - 1); } std::vector histnames = GeneralUtils::ParseToStr(fname[1], "|"); if (!histnames.size()) { THROW( "Couldn't find any histogram name specifiers when attempting to " "parse " ": \"" << fname[1] << "\". Expected hist1|hist2|..."); } TFile* rootHistFile = new TFile(fname[0].c_str(), "READ"); if (!rootHistFile || rootHistFile->IsZombie()) { THROW("Couldn't open root file: \"" << fname[0] << "\"."); } for (size_t i = 0; i < histnames.size(); ++i) { TH1* tempHist = dynamic_cast(rootHistFile->Get(histnames[i].c_str())->Clone()); if (!tempHist) { THROW("Couldn't retrieve: \"" << histnames[i] << "\" from root file: \"" << fname[0] << "\"."); } tempHist->SetDirectory(0); hists.push_back(tempHist); } rootHistFile->Close(); } return hists; } TH2D* PlotUtils::GetTH2DFromTextFile(std::string file) { /// Contents should be /// Low Edfe return NULL; } void PlotUtils::AddNeutModeArray(TH1D* hist1[], TH1D* hist2[], double scaling) { for (int i = 0; i < 60; i++) { if (!hist2[i]) continue; if (!hist1[i]) continue; hist1[i]->Add(hist2[i], scaling); } return; } void PlotUtils::ScaleToData(TH1D* data, TH1D* mc, TH1I* mask) { double scaleF = GetDataMCRatio(data, mc, mask); mc->Scale(scaleF); return; } void PlotUtils::MaskBins(TH1D* hist, TH1I* mask) { for (int i = 0; i < hist->GetNbinsX(); i++) { if (mask->GetBinContent(i + 1) <= 0.5) continue; hist->SetBinContent(i + 1, 0.0); hist->SetBinError(i + 1, 0.0); LOG(REC) << "MaskBins: Set " << hist->GetName() << " Bin " << i + 1 << " to 0.0 +- 0.0" << std::endl; } return; } void PlotUtils::MaskBins(TH2D* hist, TH2I* mask) { for (int i = 0; i < hist->GetNbinsX(); i++) { for (int j = 0; j < hist->GetNbinsY(); j++) { if (mask->GetBinContent(i + 1, j + 1) <= 0.5) continue; hist->SetBinContent(i + 1, j + 1, 0.0); hist->SetBinError(i + 1, j + 1, 0.0); LOG(REC) << "MaskBins: Set " << hist->GetName() << " Bin " << i + 1 << " " << j + 1 << " to 0.0 +- 0.0" << std::endl; } } return; } double PlotUtils::GetDataMCRatio(TH1D* data, TH1D* mc, TH1I* mask) { double rat = 1.0; TH1D* newmc = (TH1D*)mc->Clone(); TH1D* newdt = (TH1D*)data->Clone(); if (mask) { MaskBins(newmc, mask); MaskBins(newdt, mask); } rat = newdt->Integral() / newmc->Integral(); return rat; } TH2D* PlotUtils::GetCorrelationPlot(TH2D* cov, std::string name) { TH2D* cor = (TH2D*)cov->Clone(); cor->Reset(); for (int i = 0; i < cov->GetNbinsX(); i++) { for (int j = 0; j < cov->GetNbinsY(); j++) { if (cov->GetBinContent(i + 1, i + 1) != 0.0 and cov->GetBinContent(j + 1, j + 1) != 0.0) cor->SetBinContent(i + 1, j + 1, cov->GetBinContent(i + 1, j + 1) / (sqrt(cov->GetBinContent(i + 1, i + 1) * cov->GetBinContent(j + 1, j + 1)))); } } if (!name.empty()) { cor->SetNameTitle(name.c_str(), (name + ";;correlation").c_str()); } cor->SetMinimum(-1); cor->SetMaximum(1); return cor; } TH2D* PlotUtils::GetDecompPlot(TH2D* cov, std::string name) { TMatrixDSym* covarmat = new TMatrixDSym(cov->GetNbinsX()); for (int i = 0; i < cov->GetNbinsX(); i++) for (int j = 0; j < cov->GetNbinsY(); j++) (*covarmat)(i, j) = cov->GetBinContent(i + 1, j + 1); TMatrixDSym* decompmat = StatUtils::GetDecomp(covarmat); TH2D* dec = (TH2D*)cov->Clone(); for (int i = 0; i < cov->GetNbinsX(); i++) for (int j = 0; j < cov->GetNbinsY(); j++) dec->SetBinContent(i + 1, j + 1, (*decompmat)(i, j)); delete covarmat; delete decompmat; dec->SetNameTitle(name.c_str(), (name + ";;;decomposition").c_str()); return dec; } TH2D* PlotUtils::MergeIntoTH2D(TH1D* xhist, TH1D* yhist, std::string zname) { std::vector xedges, yedges; for (int i = 0; i < xhist->GetNbinsX() + 2; i++) { xedges.push_back(xhist->GetXaxis()->GetBinLowEdge(i + 1)); } for (int i = 0; i < yhist->GetNbinsX() + 2; i++) { yedges.push_back(yhist->GetXaxis()->GetBinLowEdge(i + 1)); } int nbinsx = xhist->GetNbinsX(); int nbinsy = yhist->GetNbinsX(); std::string name = std::string(xhist->GetName()) + "_vs_" + std::string(yhist->GetName()); std::string titles = ";" + std::string(xhist->GetXaxis()->GetTitle()) + ";" + std::string(yhist->GetXaxis()->GetTitle()) + ";" + zname; TH2D* newplot = new TH2D(name.c_str(), (name + titles).c_str(), nbinsx, &xedges[0], nbinsy, &yedges[0]); return newplot; } //*************************************************** void PlotUtils::MatchEmptyBins(TH1D* data, TH1D* mc) { //************************************************** for (int i = 0; i < data->GetNbinsX(); i++) { if (data->GetBinContent(i + 1) == 0.0 or data->GetBinError(i + 1) == 0.0) mc->SetBinContent(i + 1, 0.0); } return; } //*************************************************** void PlotUtils::MatchEmptyBins(TH2D* data, TH2D* mc) { //************************************************** for (int i = 0; i < data->GetNbinsX(); i++) { for (int j = 0; j < data->GetNbinsY(); j++) { if (data->GetBinContent(i + 1, j + 1) == 0.0 or data->GetBinError(i + 1, j + 1) == 0.0) mc->SetBinContent(i + 1, j + 1, 0.0); } } return; } //*************************************************** TH1D* PlotUtils::GetProjectionX(TH2D* hist, TH2I* mask) { //*************************************************** TH2D* maskedhist = StatUtils::ApplyHistogramMasking(hist, mask); TH1D* hist_X = maskedhist->ProjectionX(); delete maskedhist; return hist_X; } //*************************************************** TH1D* PlotUtils::GetProjectionY(TH2D* hist, TH2I* mask) { //*************************************************** TH2D* maskedhist = StatUtils::ApplyHistogramMasking(hist, mask); TH1D* hist_Y = maskedhist->ProjectionY(); delete maskedhist; return hist_Y; } diff --git a/src/Utils/PlotUtils.h b/src/Utils/PlotUtils.h index c326320..acd29da 100644 --- a/src/Utils/PlotUtils.h +++ b/src/Utils/PlotUtils.h @@ -1,241 +1,240 @@ // 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 PLOTUTILS_H_SEEN #define PLOTUTILS_H_SEEN #include "TF1.h" #include "TFile.h" #include "TH1.h" #include "TMatrixD.h" #include "TProfile.h" #include "TSystem.h" #include "TVectorD.h" #include #include #include #include #include // C Includes #include #include #include #include #include #include #include #include #include #include // ROOT includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "TGraphErrors.h" #include "TH2Poly.h" #include "TMatrixDSym.h" // Fit includes #include "FitEvent.h" #include "FitLogger.h" -#include "FitParameters.h" #include "GeneralUtils.h" #include "StatUtils.h" /*! * \addtogroup Utils * @{ */ //! Functions to handle different TH1s and TFiles namespace PlotUtils { /*! MISC Functions */ //! Check the root file has an object containing the given substring in its name bool CheckObjectWithName(TFile* inFile, std::string substring); //! Get object in a TFile that has a matching substring in its name std::string GetObjectWithName(TFile* inFile, std::string substring); /*! Interaction Mode Histogram Handling */ //! Fill the Histogram Array with 61 new histograms for interaction channels. void CreateNeutModeArray(TH1* hist, TH1* neutarray[]); //! Call Fill on the relevent Mode 1D Histogram void FillNeutModeArray(TH1D* hist[], int mode, double xval, double weight = 1.0); //! Call Fill on the relevant Mode 2D Histogram void FillNeutModeArray(TH2D* hist[], int mode, double xval, double yval, double weight = 1.0); //! Given two arrays of histograms for the NEUT interaction mode, hist1 = hist1 //! + scale*hist2 void AddNeutModeArray(TH1D* hist1[], TH1D* hist2[], double scaling = 1.0); //! Generate a legend for the THStack TLegend GenerateStackLegend(THStack stack, int xlow, int ylow, int xhigh, int yhigh); //! Turn the array of TH1 histograms into a stack of Modes THStack GetNeutModeStack(std::string title, TH1* ModeStack[], int option); //! Reset each histogram in the mode array void ResetNeutModeArray(TH1* hist[]); //! Scale each histogram in the mode array by a single scaling factor, option //! can be used to define "width" scaling. void ScaleNeutModeArray(TH1* hist[], double factor, std::string option = ""); //! Free up the memory used by each of the 61 mode histograms void DeleteNeutModeArray(TH1* neutarray[]); /*! Handling Functions */ //! Fill a mask histogram from a text file TH2D* SetMaskHist(std::string type, TH2D* data); //! Divide by the flux histogram for Enu Histograms void DivideByFlux(TH1D* fMCHist, TH1D* fFluxHist); TH1D* InterpolateFineHistogram(TH1D* hist, int res, std::string opt); //! Flux unfolded scaling, like DivideByFlux but uses interpolation. void FluxUnfoldedScaling(TH1D* plot, TH1D* flux, TH1D* events = NULL, double scalefactor = 1.0, int nevents = 1); //! Flux unfolded scaling for 2D histograms void FluxUnfoldedScaling(TH2D* plot, TH1D* flux, TH1D* events = NULL, double scalefactor = 1.0); //! Fill a 2D Histogram from a text file void Set2DHistFromText(std::string dataFile, TH2* hist, double norm, bool skipbins = false); //! Fill a 2D Poly Histogram from a text file void Set2PolyHistFromText(std::string dataFile, TH2Poly* hist, double norm, bool skipbins = false); //! Fill a 1D Histogram from a text file TH1D* GetTH1DFromFile(std::string dataFile, std::string title = "", std::string fPlotTitles = "", std::string alt_name = ""); TH1* GetTH1FromRootFile(std::string file, std::string name); std::vector GetTH1sFromRootFile(std::string const& descriptor); //! Grab a 1D Histrogram from a ROOT File TH1D* GetTH1DFromRootFile(std::string file, std::string name); //! Grab a 2D Histrogram from a ROOT File TH2D* GetTH2DFromRootFile(std::string file, std::string name); //! Grab a 2D Histrogram from a ROOT File TH2D* GetTH2DFromTextFile(std::string file); //! Scale mc to match data considering empty and masked bins void ScaleToData(TH1D* data, TH1D* mc, TH1I* mask); //! Apply bin masking (More cosmetic) void MaskBins(TH1D* hist, TH1I* mask); //! Apply bin masking (More cosmetic) void MaskBins(TH2D* hist, TH2I* mask); //! Get the data MC ratio considering empty and masked bins double GetDataMCRatio(TH1D* data, TH1D* mc, TH1I* mask = NULL); /*! Formatting Plot Utils */ //! Create new ratio plot. hist3 = hist1/hist2 TH1D* GetRatioPlot(TH1D* hist1, TH1D* hist2); //! Create new plot of hist2 normalised to hist1. hist2 = hist1 * //! (Integral(hist1)/Integral(hist2)) TH1D* GetRenormalisedPlot(TH1D* hist1, TH1D* hist2); //! Normalise histogram to area of unity. TH1D* GetShapePlot(TH1D* hist1); //! Normalise hist1 and hist2 to unity, before creating a new plot of their //! ratio. TH1D* GetShapeRatio(TH1D* hist1, TH1D* hist2); //! Create a covariance histogram from a TMatrixDSym and add titles given. TH2D* GetCovarPlot(TMatrixDSym* cov, std::string name, std::string title); //! Wrapper function to create full covariance plot TH2D* GetFullCovarPlot(TMatrixDSym* cov, std::string name); //! Wrapper function to create inverted covariance plot TH2D* GetInvCovarPlot(TMatrixDSym* cov, std::string name); //! Wrapper function to create decomposed covariance plot TH2D* GetDecompCovarPlot(TMatrixDSym* cov, std::string name); //! Given a covariance histogram, divide by errors to form a correlation plot. TH2D* GetCorrelationPlot(TH2D* cov, std::string name); //! Given a covariance histogram, calculate the decomposed matrix to form a //! decomposed plot. TH2D* GetDecompPlot(TH2D* cov, std::string name); //! Given two 1D histograms create a 2D histogram which uses their bin edges to //! define both axes. TH2D* MergeIntoTH2D(TH1D* xhist, TH1D* yhist, std::string zname = ""); //! Given a 1D Histogram, set any empty bins in Data to empty bins in MC void MatchEmptyBins(TH1D* data, TH1D* mc); //! Given a 2D Histogram, set any empty bins in Data to empty bins in MC void MatchEmptyBins(TH2D* data, TH2D* mc); //! Return a projection of a 2D Histogram onto X accounting for bin masking TH1D* GetProjectionX(TH2D* hist, TH2I* mask); //! Return a projection of a 2D Histogram onto Y accounting for bin masking TH1D* GetProjectionY(TH2D* hist, TH2I* mask); } /*! @} */ #endif