diff --git a/CMakeLists.txt b/CMakeLists.txt index 284f985..ceba75d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,190 +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 . ################################################################################ cmake_minimum_required (VERSION 2.6 FATAL_ERROR) project(NUISANCE) include(ExternalProject) enable_language(Fortran) -set (NUISANCE_VERSION_MAJOR 1) -set (NUISANCE_VERSION_MINOR 0) +set (NUISANCE_VERSION_MAJOR 2) +set (NUISANCE_VERSION_MINOR 7) set (NUISANCE_VERSION_REVISION 0) set (NUISANCE_VERSION_STRING "v${NUISANCE_VERSION_MAJOR}r${NUISANCE_VERSION_MINOR}") if(${NUISANCE_VERSION_REVISION} STRGREATER "0") set (NUISANCE_VERSION_STRING "${NUISANCE_VERSION_STRING}p${NUISANCE_VERSION_REVISION}") endif() #Set this to TRUE to enable build debugging messages set(BUILD_DEBUG_MSGS TRUE) include(${CMAKE_SOURCE_DIR}/cmake/cmessage.cmake) include(${CMAKE_SOURCE_DIR}/cmake/cacheVariables.cmake) cmessage(STATUS "CMAKE_INSTALL_PREFIX: \"${CMAKE_INSTALL_PREFIX}\"") cmessage(STATUS "CMAKE_BUILD_TYPE: \"${CMAKE_BUILD_TYPE}\"") ################################################################################ # Check Dependencies ################################################################################ ################################## ROOT ###################################### include(${CMAKE_SOURCE_DIR}/cmake/ROOTSetup.cmake) ################################# HEPMC ###################################### include(${CMAKE_SOURCE_DIR}/cmake/HepMC.cmake) ############################ Reweight Engines ################################ include(${CMAKE_SOURCE_DIR}/cmake/ReweightEnginesSetup.cmake) ############################ Other Generators ################################ include(${CMAKE_SOURCE_DIR}/cmake/GiBUUSetup.cmake) if(USE_NUANCE) LIST(APPEND EXTRA_CXX_FLAGS -D__NUANCE_ENABLED__) endif() ################################# Pythia6/8 #################################### include(${CMAKE_SOURCE_DIR}/cmake/pythia6Setup.cmake) include(${CMAKE_SOURCE_DIR}/cmake/pythia8Setup.cmake) ################################# gperftools ################################### include(${CMAKE_SOURCE_DIR}/cmake/gperfSetup.cmake) if(NOT NOTEST) enable_testing() endif() SET(GENERATOR_SUPPORT) foreach(gen NEUT;NuWro;GENIE;GiBUU;NUANCE) if(USE_${gen}) SET(GENERATOR_SUPPORT "${GENERATOR_SUPPORT}${gen} ") endif() endforeach(gen) cmessage(STATUS "Generator Input Support: ${GENERATOR_SUPPORT}") set(MINCODE Routines FCN) set(CORE MCStudies Genie FitBase + Config + Logger InputHandler Splines Reweight Utils + Statistical #Devel Smearceptance ) LIST(APPEND ALLEXPERIMENTS ANL ArgoNeuT BEBC BNL Electron FNAL GGM K2K MINERvA MiniBooNE SciBooNE T2K) foreach(exp ${ALLEXPERIMENTS}) if(NOT NO_${exp}) LIST(APPEND EXPERIMENTS_TO_BUILD ${exp}) else() LIST(REVERSE EXTRA_CXX_FLAGS) LIST(APPEND EXTRA_CXX_FLAGS -D__NO_${exp}__) LIST(REVERSE EXTRA_CXX_FLAGS) endif() endforeach() ################################## COMPILER #################################### include(${CMAKE_SOURCE_DIR}/cmake/c++CompilerSetup.cmake) ################################### doxygen ################################### include(${CMAKE_SOURCE_DIR}/cmake/docsSetup.cmake) ################################################################################ set(MINIMUM_INCLUDE_DIRECTORIES) LIST(APPEND MINIMUM_INCLUDE_DIRECTORIES ${RWENGINE_INCLUDE_DIRECTORIES} ${CMAKE_SOURCE_DIR}/src/FitBase ${CMAKE_SOURCE_DIR}/src/Reweight ${CMAKE_SOURCE_DIR}/src/InputHandler + ${CMAKE_SOURCE_DIR}/src/Config + ${CMAKE_SOURCE_DIR}/src/Logger + ${CMAKE_SOURCE_DIR}/src/Statistical ${CMAKE_SOURCE_DIR}/src/Splines ${CMAKE_SOURCE_DIR}/src/Utils ${CMAKE_SOURCE_DIR}/src/Genie) cmessage(DEBUG "Base include directories: ${MINIMUM_INCLUDE_DIRECTORIES}") set(EXP_INCLUDE_DIRECTORIES) foreach(edir ${EXPERIMENTS_TO_BUILD}) LIST(APPEND EXP_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/src/${edir}) endforeach() cmessage(DEBUG "Included experiments: ${EXP_INCLUDE_DIRECTORIES}") foreach(mdir ${MINCODE}) cmessage (DEBUG "Configuring directory: src/${mdir}") add_subdirectory(src/${mdir}) endforeach() foreach(edir ${EXPERIMENTS_TO_BUILD}) cmessage (DEBUG "Configuring directory: src/${edir}") add_subdirectory(src/${edir}) endforeach() foreach(cdir ${CORE}) cmessage (DEBUG "Configuring directory: src/${cdir}") add_subdirectory(src/${cdir}) endforeach() cmessage(DEBUG "Module targets: ${MODULETargets}") add_subdirectory(app) add_subdirectory(src/Tests) configure_file(cmake/setup.sh.in "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/setup.sh" @ONLY) install(FILES "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/setup.sh" DESTINATION ${CMAKE_INSTALL_PREFIX}) +if(USE_DYNSAMPLES) + SET(ALL_INCLUDES ${MINIMUM_INCLUDE_DIRECTORIES}) + LIST(APPEND ALL_INCLUDES ${CMAKE_SOURCE_DIR}/src/Smearceptance) + LIST(APPEND ALL_INCLUDES ${EXP_INCLUDE_DIRECTORIES}) + + string(REPLACE ";" " -I" ALL_INCLUDES_STR "${ALL_INCLUDES}") + + string(REPLACE ";" " -l" ALL_MODULETARGETS_STR "${MODULETargets}") + + configure_file(cmake/BuildDynamicSample.in + "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/BuildDynamicSample" @ONLY) + install(PROGRAMS + "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/BuildDynamicSample" DESTINATION + bin) + + configure_file(cmake/BuildDynamicSmearcepter.in + "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/BuildDynamicSmearcepter" @ONLY) + install(PROGRAMS + "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/BuildDynamicSmearcepter" DESTINATION + bin) +endif() install(PROGRAMS "${PROJECT_SOURCE_DIR}/scripts/nuiscardgen" DESTINATION bin) install(PROGRAMS "${PROJECT_SOURCE_DIR}/scripts/nuissamples" DESTINATION bin) diff --git a/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/PrepareGENIE.cxx b/app/PrepareGENIE.cxx index 60f02ca..442326b 100644 --- a/app/PrepareGENIE.cxx +++ b/app/PrepareGENIE.cxx @@ -1,386 +1,559 @@ #include #include +#include "FitLogger.h" +#include "PlotUtils.h" #include "TFile.h" #include "TH1D.h" #include "TTree.h" -#include "PlotUtils.h" -#include "FitLogger.h" #ifdef __GENIE_ENABLED__ #include "Conventions/Units.h" #include "GHEP/GHepParticle.h" #include "PDG/PDGUtils.h" #endif -bool gFlagMerge = false; std::string gInputFiles = ""; std::string gOutputFile = ""; -std::string gFluxFile = ""; -std::string gTarget = ""; +std::string gFluxFile = ""; +std::string gTarget = ""; +double MonoEnergy; +bool IsMonoE = false; void PrintOptions(); void ParseOptions(int argc, char* argv[]); -void RunGENIEMerger(std::string inputs, std::string output); -void RunGENIEPrepare(std::string input, std::string flux, std::string target, std::string output); +void RunGENIEPrepareMono(std::string input, std::string target, + std::string output); +void RunGENIEPrepare(std::string input, std::string flux, std::string target, + std::string output); int main(int argc, char* argv[]) { - - ParseOptions(argc, argv); - - if (gFlagMerge) RunGENIEMerger(gInputFiles, gOutputFile); - else RunGENIEPrepare(gInputFiles, gFluxFile, gTarget, gOutputFile); - + ParseOptions(argc, argv); + if (IsMonoE) { + RunGENIEPrepareMono(gInputFiles, gTarget, gOutputFile); + } else { + RunGENIEPrepare(gInputFiles, gFluxFile, gTarget, gOutputFile); + } } -void RunGENIEMerger(std::string inputs, std::string output) { - -}; - -void RunGENIEPrepare(std::string input, std::string flux, std::string target, std::string output) { - - LOG(FIT) << "Running GENIE Prepare" << std::endl; - - // Setup TTree - TChain* tn = new TChain("gtree"); - tn->AddFile(input.c_str()); - - int nevt = tn->GetEntries(); - NtpMCEventRecord * genientpl = NULL; - bool ismono = false; - tn->SetBranchAddress("gmcrec", &genientpl); - - // 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"); - if (!fluxfile->IsZombie()) { - fluxhist = (TH1D*) fluxfile->Get(fluxvect[1].c_str()); - fluxhist->SetDirectory(0); - } else { - - // Function with EnuRange - if (fluxvect.size() == 3) { - - ERR(FTL) << "FUNCTION WITH ENU RANGE NOT SUPPORTED SORRY!" << std::endl; - throw; - - // Single Enu - } - } - - } else if (fluxvect.size() == 1) { - - // double E = GeneralUtils::StrToDbl(fluxvect[0]); - // fluxhist = new TH1D("fluxhist","fluxhist",1, E-0.00001, E+0.00001); - // fluxhist->SetBinContent(1, 1.0); - double E = GeneralUtils::StrToDbl(fluxvect[0]); - LOG(FIT) << "Adding mono-energetic genie flux, E: " << E << std::endl; - - fluxhist = new TH1D("fluxhist", "fluxhist", 100, 0, E * 2); - fluxhist->SetBinContent(fluxhist->FindBin(E), 1); - ismono = true; - - // if (fluxvect[0] == '1.0') { - // fluxhist = new TH1D("fluxhist", "fluxhist", 40, GeneralUtils::StrToDbl(fluxvect[1]), GeneralUtils::StrToDbl(fluxvect[2])); - // for (int i = 0; i < fluxhist->GetNbinsX(); i++) { - // fluxhist->SetBinContent(i + 1, 1.0); - // } - // } else { - // // TF1 f1 = TF1("1.0", GeneralUtils::StrToDbl(fluxvect[1]), GeneralUtils::StrToDbl(fluxvect[2]), 1); - // // std::cout << "Created TF1 with '" << fluxvect[0].c_str()<<"' " << GeneralUtils::StrToDbl(fluxvect[1]) << " " << GeneralUtils::StrToDbl(fluxvect[2]) << std::endl; - // fluxhist = new TH1D("fluxhist", "fluxhist", 40, GeneralUtils::StrToDbl(fluxvect[1]), GeneralUtils::StrToDbl(fluxvect[2])); - // for (int i = 0; i < fluxhist->GetNbinsX(); i++) { - // fluxhist->SetBinContent(i + 1, 1.0); //f1.Eval(fluxhist->GetXaxis()->GetBinCenter(i+1))); - // // std::cout << "Filling Flux Hist " << f1.Eval(fluxhist->GetXaxis()->GetBinCenter(i+1)) << std::endl; - // } - // sleep(10); - - } else { - LOG(FTL) << "NO FLUX SPECIFIED" << std::endl; - throw; - } - - // Make Event Hist - TH1D* eventhist = (TH1D*)fluxhist->Clone(); - eventhist->Reset(); - - TH1D* xsechist = (TH1D*) eventhist->Clone(); - - // Create maps - std::map modexsec; - std::map modecount; - std::vector genieids; - std::vector targetids; - std::vector interids; - - - // Loop over all events - for (int i = 0; i < nevt; i++) { - tn->GetEntry(i); - - StopTalking(); - EventRecord& event = *(genientpl->event); - GHepParticle* neu = event.Probe(); - StartTalking(); - - // Get XSec From Spline - GHepRecord genie_record = static_cast(event); - double xsec = (genie_record.XSec() / (1E-38 * genie::units::cm2)); - - // Parse Interaction String - std::string mode = genie_record.Summary()->AsString(); - std::vector modevec = GeneralUtils::ParseToStr(mode, ";"); - std::string targ = ( modevec[0] + ";" + modevec[1] ); - std::string inter = mode; - - // Fill lists of Unique IDS - if (std::find(targetids.begin(), targetids.end(), targ) - == targetids.end()) { - targetids.push_back(targ); - } - - if (std::find(interids.begin(), interids.end(), inter) - == interids.end()) { - interids.push_back(inter); - } - - // Create entries Mode Maps - if (modexsec.find(mode) == modexsec.end()) { - genieids.push_back(mode); - - modexsec[mode] = (TH1D*)xsechist->Clone(); - modecount[mode] = (TH1D*)xsechist->Clone(); - } - - // Fill XSec Histograms - modexsec[mode]->Fill(neu->E(), xsec); - modecount[mode]->Fill(neu->E()); - - // Fill total event hist - eventhist->Fill(neu->E()); - - // Clear Event - genientpl->Clear(); - - if (i % (nevt / 20) == 0) { - LOG(FIT) << "Processed " << i << "/" << nevt << " GENIE events." << std::endl; - } - } - LOG(FIT) << "Processed all events" << std::endl; - - // If Mono// You have filled the total xsec for each event - // Then divided by the total number of events, and then multiplied by the flux integral * AvgXSec ) - // eventlist[pdg] -> Scale(1.0 / zeroevents->Integral()); - // eventlist[pdg] -> Scale( fluxlist[0]->Integral()*AvgXSec ); - - // Once event loop is done we can start saving stuff into the file - // bool savesplines = FitPar::Config().GetParB("save_genie_splines"); // Currently not implemented - - TFile* outputfile = new TFile(input.c_str(), "UPDATE"); - outputfile->cd(); - - LOG(FIT) << "Getting splines " << std::endl; - - // Save each of the reconstructed splines to file - std::map modeavg; - - - TDirectory* inddir = (TDirectory*) outputfile->Get("IndividualGENIESplines"); - if (!inddir) inddir = (TDirectory*)outputfile->mkdir("IndividualGENIESplines"); - inddir->cd(); - - // Loop over GENIE ID's and get MEC count - int MECcount = 0; - bool MECcorrect = FitPar::Config().GetParB("CorrectGENIEMECNorm"); - for (UInt_t i = 0; i < genieids.size(); i++) { - if (genieids[i].find("MEC") != std::string::npos) { - MECcount++; - } - } - LOG(FIT) << "Found " << MECcount << " repeated MEC instances." << std::endl; - - - for (UInt_t i = 0; i < genieids.size(); i++) { - std::string mode = genieids[i]; - - modexsec[mode]->Write( (mode + "_summed_xsec").c_str() , TObject::kOverwrite); - modecount[mode]->Write( (mode + "_summed_evt").c_str() , TObject::kOverwrite); - - //Form extra avg xsec map -> Reconstructed spline - modeavg[mode] = (TH1D*)modexsec[mode]->Clone(); - modeavg[mode]->Divide(modecount[mode]); - - if (MECcorrect && (mode.find("MEC") != std::string::npos)) { - modeavg[mode]->Scale(1.0 / double(MECcount) ); - } - - modeavg[mode]->Write( (mode + "_rec_spline").c_str() , TObject::kOverwrite); - } - - TDirectory* targdir = (TDirectory*) outputfile->Get("TargetGENIESplines"); - if (!targdir) targdir = (TDirectory*) outputfile->mkdir("TargetGENIESplines"); - targdir->cd(); - - LOG(FIT) << "Getting Target Splines" << std::endl; - // For each target save a total spline - std::map targetsplines; - - for (uint i = 0; i < targetids.size(); i++) { - LOG(FIT) << "Getting target " << i << std::endl; - std::string targ = targetids[i]; - targetsplines[targ] = (TH1D*) xsechist->Clone(); - LOG(FIT) << "Created target spline for " << targ << std::endl; - - for (uint j = 0; j < genieids.size(); j++) { - std::string mode = genieids[j]; - - // Look at all matching modes/targets - if (mode.find(targ) != std::string::npos) { - - LOG(FIT) << "Mode " << mode << " contains " << targ << " target!" << std::endl; - // modeavg[mode]->Write( (mode + "_cont_" + targ).c_str() , TObject::kOverwrite); - targetsplines[targ]->Add( modeavg[mode] ); - LOG(FIT) << "Finished with Mode " << mode << " " << modeavg[mode]->Integral() << std::endl; - } - } - - LOG(FIT) << "Saving target spline:" << targ << std::endl; - targetsplines[targ]->Write(("Total" + targ).c_str(), TObject::kOverwrite); - } - - LOG(FIT) << "Getting total splines" << std::endl; - // Now we have each of the targets we need to create a total cross-section. - int totalnucl = 0; - std::vector targprs = GeneralUtils::ParseToStr(target, ","); - TH1D* totalxsec = (TH1D*) xsechist->Clone(); - - for (uint i = 0; i < targprs.size(); i++) { - std::string targpdg = targprs[i]; - - for (std::map::iterator iter = targetsplines.begin(); - iter != targetsplines.end(); iter++) { - std::string targstr = iter->first; - TH1D* xsec = iter->second; - - if (targstr.find(targpdg) != std::string::npos) { - LOG(FIT) << "Adding target spline " << targstr << " Integral = " << xsec->Integral("width") << std::endl; - totalxsec->Add(xsec); - - int nucl = atoi( targpdg.c_str() ); - totalnucl += int((nucl % 10000) / 10); - - } - } - } - - if (!ismono){ - LOG(FIT) << "Total XSec Integral = " << totalxsec->Integral("width") << std::endl; - - outputfile->cd(); - totalxsec->Write("nuisance_xsec", TObject::kOverwrite); - eventhist = (TH1D*)fluxhist->Clone(); - eventhist->Multiply(totalxsec); - - LOG(FIT) << "Dividing by Total Nucl = " << totalnucl << std::endl; - eventhist->Scale(1.0 / double(totalnucl) ); - } else { - - outputfile->cd(); - totalxsec->Write("nuisance_Xsec", TObject::kOverwrite); - eventhist = (TH1D*) fluxhist->Clone(); - eventhist->Scale(totalxsec->Integral()); - - } - - eventhist->Write("nuisance_events", TObject::kOverwrite); - fluxhist->Write("nuisance_flux", TObject::kOverwrite); - - - LOG(FIT) << "Inclusive XSec Per Nucleon = " << eventhist->Integral("width") * 1E-38 / fluxhist->Integral("width") << std::endl; - std::cout << "XSec Hist Integral = " << xsechist->Integral("width") << std::endl; +void RunGENIEPrepareMono(std::string input, std::string target, + std::string output) { + // Setup TTree + TChain* tn = new TChain("gtree"); + tn->AddFile(input.c_str()); + + int nevt = tn->GetEntries(); + NtpMCEventRecord* genientpl = NULL; + tn->SetBranchAddress("gmcrec", &genientpl); + + TH1D* fluxhist = new TH1D("flux", "flux", 1000, 0, 10); + fluxhist->Fill(MonoEnergy); + fluxhist->Scale(1, "width"); + + // Make Event Hist + TH1D* eventhist = (TH1D*)fluxhist->Clone(); + eventhist->Reset(); + + TH1D* xsechist = (TH1D*)eventhist->Clone(); + + // Create maps + std::map modexsec; + std::map modecount; + std::vector genieids; + std::vector targetids; + std::vector interids; + + // Loop over all events + for (int i = 0; i < nevt; i++) { + tn->GetEntry(i); + + StopTalking(); + EventRecord& event = *(genientpl->event); + GHepParticle* neu = event.Probe(); + StartTalking(); + + // Get XSec From Spline + GHepRecord genie_record = static_cast(event); + double xsec = (genie_record.XSec() / (1E-38 * genie::units::cm2)); + + // Parse Interaction String + std::string mode = genie_record.Summary()->AsString(); + std::vector modevec = GeneralUtils::ParseToStr(mode, ";"); + std::string targ = (modevec[0] + ";" + modevec[1]); + std::string inter = mode; + + // Fill lists of Unique IDS + if (std::find(targetids.begin(), targetids.end(), targ) == + targetids.end()) { + targetids.push_back(targ); + } + + if (std::find(interids.begin(), interids.end(), inter) == interids.end()) { + interids.push_back(inter); + } + + // Create entries Mode Maps + if (modexsec.find(mode) == modexsec.end()) { + genieids.push_back(mode); + + modexsec[mode] = (TH1D*)xsechist->Clone(); + modecount[mode] = (TH1D*)xsechist->Clone(); + } + + // Fill XSec Histograms + modexsec[mode]->Fill(neu->E(), xsec); + modecount[mode]->Fill(neu->E()); + + // Fill total event hist + eventhist->Fill(neu->E()); + + // Clear Event + genientpl->Clear(); + + if (i % (nevt / 20) == 0) { + LOG(FIT) << "Processed " << i << "/" << nevt << " GENIE events." + << std::endl; + } + } + LOG(FIT) << "Processed all events" << std::endl; + + TFile* outputfile = new TFile(input.c_str(), "UPDATE"); + outputfile->cd(); + + LOG(FIT) << "Getting splines " << std::endl; + + // Save each of the reconstructed splines to file + std::map modeavg; + + TDirectory* inddir = (TDirectory*)outputfile->Get("IndividualGENIESplines"); + if (!inddir) + inddir = (TDirectory*)outputfile->mkdir("IndividualGENIESplines"); + inddir->cd(); + + // Loop over GENIE ID's and get MEC count + int MECcount = 0; + bool MECcorrect = FitPar::Config().GetParB("CorrectGENIEMECNorm"); + for (UInt_t i = 0; i < genieids.size(); i++) { + if (genieids[i].find("MEC") != std::string::npos) { + MECcount++; + } + } + LOG(FIT) << "Found " << MECcount << " repeated MEC instances." << std::endl; + + for (UInt_t i = 0; i < genieids.size(); i++) { + std::string mode = genieids[i]; + + modexsec[mode]->Write((mode + "_summed_xsec").c_str(), TObject::kOverwrite); + modecount[mode]->Write((mode + "_summed_evt").c_str(), TObject::kOverwrite); + + // Form extra avg xsec map -> Reconstructed spline + modeavg[mode] = (TH1D*)modexsec[mode]->Clone(); + modeavg[mode]->Divide(modecount[mode]); + + if (MECcorrect && (mode.find("MEC") != std::string::npos)) { + modeavg[mode]->Scale(1.0 / double(MECcount)); + } + + modeavg[mode]->Write((mode + "_rec_spline").c_str(), TObject::kOverwrite); + } + + TDirectory* targdir = (TDirectory*)outputfile->Get("TargetGENIESplines"); + if (!targdir) targdir = (TDirectory*)outputfile->mkdir("TargetGENIESplines"); + targdir->cd(); + + LOG(FIT) << "Getting Target Splines" << std::endl; + // For each target save a total spline + std::map targetsplines; + + for (uint i = 0; i < targetids.size(); i++) { + LOG(FIT) << "Getting target " << i << std::endl; + std::string targ = targetids[i]; + targetsplines[targ] = (TH1D*)xsechist->Clone(); + LOG(FIT) << "Created target spline for " << targ << std::endl; + + for (uint j = 0; j < genieids.size(); j++) { + std::string mode = genieids[j]; + + if (mode.find(targ) != std::string::npos) { + LOG(FIT) << "Mode " << mode << " contains " << targ << " target!" + << std::endl; + targetsplines[targ]->Add(modeavg[mode]); + LOG(FIT) << "Finished with Mode " << mode << " " + << modeavg[mode]->Integral() << std::endl; + } + } + + LOG(FIT) << "Saving target spline:" << targ << std::endl; + targetsplines[targ]->Write(("Total" + targ).c_str(), TObject::kOverwrite); + } + + LOG(FIT) << "Getting total splines" << std::endl; + // Now we have each of the targets we need to create a total cross-section. + int totalnucl = 0; + std::vector targprs = GeneralUtils::ParseToStr(target, ","); + TH1D* totalxsec = (TH1D*)xsechist->Clone(); + + for (uint i = 0; i < targprs.size(); i++) { + std::string targpdg = targprs[i]; + + for (std::map::iterator iter = targetsplines.begin(); + iter != targetsplines.end(); iter++) { + std::string targstr = iter->first; + TH1D* xsec = iter->second; + + if (targstr.find(targpdg) != std::string::npos) { + LOG(FIT) << "Adding target spline " << targstr + << " Integral = " << xsec->Integral("width") << std::endl; + totalxsec->Add(xsec); + + int nucl = atoi(targpdg.c_str()); + totalnucl += int((nucl % 10000) / 10); + } + } + } + + outputfile->cd(); + totalxsec->Write("nuisance_Xsec", TObject::kOverwrite); + eventhist = (TH1D*)totalxsec->Clone(); + eventhist->Multiply(fluxhist); + + eventhist->Write("nuisance_events", TObject::kOverwrite); + fluxhist->Write("nuisance_flux", TObject::kOverwrite); + + LOG(FIT) << "Inclusive XSec Per Nucleon = " + << eventhist->Integral("width") * 1E-38 / fluxhist->Integral("width") + << std::endl; + std::cout << "XSec Hist Integral = " << xsechist->Integral("width") + << std::endl; + + return; +} - return; +void RunGENIEPrepare(std::string input, std::string flux, std::string target, + std::string output) { + LOG(FIT) << "Running GENIE Prepare" << std::endl; + + // 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"); + if (!fluxfile->IsZombie()) { + fluxhist = dynamic_cast(fluxfile->Get(fluxvect[1].c_str())); + if (!fluxhist) { + ERR(FTL) << "Couldn't find histogram named: \"" << fluxvect[1] + << "\" in file: \"" << fluxvect[0] << std::endl; + throw; + } + fluxhist->SetDirectory(0); + } else { + // Function with EnuRange + if (fluxvect.size() == 3) { + ERR(FTL) << "FUNCTION WITH ENU RANGE NOT SUPPORTED SORRY!" << std::endl; + throw; + } + } + + } else if (fluxvect.size() == 1) { + MonoEnergy = GeneralUtils::StrToDbl(fluxvect[0]); + RunGENIEPrepareMono(input, target, output); + return; + } else { + LOG(FTL) << "NO FLUX SPECIFIED" << std::endl; + throw; + } + + // Setup TTree + TChain* tn = new TChain("gtree"); + tn->AddFile(input.c_str()); + + int nevt = tn->GetEntries(); + NtpMCEventRecord* genientpl = NULL; + tn->SetBranchAddress("gmcrec", &genientpl); + + // Make Event Hist + TH1D* eventhist = (TH1D*)fluxhist->Clone(); + eventhist->Reset(); + + TH1D* xsechist = (TH1D*)eventhist->Clone(); + + // Create maps + std::map modexsec; + std::map modecount; + std::vector genieids; + std::vector targetids; + std::vector interids; + + // Loop over all events + for (int i = 0; i < nevt; i++) { + tn->GetEntry(i); + + StopTalking(); + EventRecord& event = *(genientpl->event); + GHepParticle* neu = event.Probe(); + StartTalking(); + + // Get XSec From Spline + GHepRecord genie_record = static_cast(event); + double xsec = (genie_record.XSec() / (1E-38 * genie::units::cm2)); + + // Parse Interaction String + std::string mode = genie_record.Summary()->AsString(); + std::vector modevec = GeneralUtils::ParseToStr(mode, ";"); + std::string targ = (modevec[0] + ";" + modevec[1]); + std::string inter = mode; + + // Fill lists of Unique IDS + if (std::find(targetids.begin(), targetids.end(), targ) == + targetids.end()) { + targetids.push_back(targ); + } + + if (std::find(interids.begin(), interids.end(), inter) == interids.end()) { + interids.push_back(inter); + } + + // Create entries Mode Maps + if (modexsec.find(mode) == modexsec.end()) { + genieids.push_back(mode); + + modexsec[mode] = (TH1D*)xsechist->Clone(); + modecount[mode] = (TH1D*)xsechist->Clone(); + } + + // Fill XSec Histograms + modexsec[mode]->Fill(neu->E(), xsec); + modecount[mode]->Fill(neu->E()); + + // Fill total event hist + eventhist->Fill(neu->E()); + + // Clear Event + genientpl->Clear(); + + if (i % (nevt / 20) == 0) { + LOG(FIT) << "Processed " << i << "/" << nevt << " GENIE events." + << std::endl; + } + } + LOG(FIT) << "Processed all events" << std::endl; + + // Once event loop is done we can start saving stuff into the file + + TFile* outputfile = new TFile(input.c_str(), "UPDATE"); + outputfile->cd(); + + LOG(FIT) << "Getting splines " << std::endl; + + // Save each of the reconstructed splines to file + std::map modeavg; + + TDirectory* inddir = (TDirectory*)outputfile->Get("IndividualGENIESplines"); + if (!inddir) + inddir = (TDirectory*)outputfile->mkdir("IndividualGENIESplines"); + inddir->cd(); + + // Loop over GENIE ID's and get MEC count + int MECcount = 0; + bool MECcorrect = FitPar::Config().GetParB("CorrectGENIEMECNorm"); + for (UInt_t i = 0; i < genieids.size(); i++) { + if (genieids[i].find("MEC") != std::string::npos) { + MECcount++; + } + } + LOG(FIT) << "Found " << MECcount << " repeated MEC instances." << std::endl; + + for (UInt_t i = 0; i < genieids.size(); i++) { + std::string mode = genieids[i]; + + modexsec[mode]->Write((mode + "_summed_xsec").c_str(), TObject::kOverwrite); + modecount[mode]->Write((mode + "_summed_evt").c_str(), TObject::kOverwrite); + + // Form extra avg xsec map -> Reconstructed spline + modeavg[mode] = (TH1D*)modexsec[mode]->Clone(); + modeavg[mode]->Divide(modecount[mode]); + + if (MECcorrect && (mode.find("MEC") != std::string::npos)) { + modeavg[mode]->Scale(1.0 / double(MECcount)); + } + + modeavg[mode]->Write((mode + "_rec_spline").c_str(), TObject::kOverwrite); + } + + TDirectory* targdir = (TDirectory*)outputfile->Get("TargetGENIESplines"); + if (!targdir) targdir = (TDirectory*)outputfile->mkdir("TargetGENIESplines"); + targdir->cd(); + + LOG(FIT) << "Getting Target Splines" << std::endl; + // For each target save a total spline + std::map targetsplines; + + for (uint i = 0; i < targetids.size(); i++) { + LOG(FIT) << "Getting target " << i << std::endl; + std::string targ = targetids[i]; + targetsplines[targ] = (TH1D*)xsechist->Clone(); + LOG(FIT) << "Created target spline for " << targ << std::endl; + + for (uint j = 0; j < genieids.size(); j++) { + std::string mode = genieids[j]; + + // Look at all matching modes/targets + if (mode.find(targ) != std::string::npos) { + LOG(FIT) << "Mode " << mode << " contains " << targ << " target!" + << std::endl; + // modeavg[mode]->Write( (mode + "_cont_" + targ).c_str() , + // TObject::kOverwrite); + targetsplines[targ]->Add(modeavg[mode]); + LOG(FIT) << "Finished with Mode " << mode << " " + << modeavg[mode]->Integral() << std::endl; + } + } + + LOG(FIT) << "Saving target spline:" << targ << std::endl; + targetsplines[targ]->Write(("Total" + targ).c_str(), TObject::kOverwrite); + } + + LOG(FIT) << "Getting total splines" << std::endl; + // Now we have each of the targets we need to create a total cross-section. + int totalnucl = 0; + std::vector targprs = GeneralUtils::ParseToStr(target, ","); + TH1D* totalxsec = (TH1D*)xsechist->Clone(); + + for (uint i = 0; i < targprs.size(); i++) { + std::string targpdg = targprs[i]; + + for (std::map::iterator iter = targetsplines.begin(); + iter != targetsplines.end(); iter++) { + std::string targstr = iter->first; + TH1D* xsec = iter->second; + + if (targstr.find(targpdg) != std::string::npos) { + LOG(FIT) << "Adding target spline " << targstr + << " Integral = " << xsec->Integral("width") << std::endl; + totalxsec->Add(xsec); + + int nucl = atoi(targpdg.c_str()); + totalnucl += int((nucl % 10000) / 10); + } + } + } + LOG(FIT) << "Total XSec Integral = " << totalxsec->Integral("width") + << std::endl; + + outputfile->cd(); + totalxsec->Write("nuisance_xsec", TObject::kOverwrite); + eventhist = (TH1D*)fluxhist->Clone(); + eventhist->Multiply(totalxsec); + + LOG(FIT) << "Dividing by Total Nucl = " << totalnucl << std::endl; + eventhist->Scale(1.0 / double(totalnucl)); + + eventhist->Write("nuisance_events", TObject::kOverwrite); + fluxhist->Write("nuisance_flux", TObject::kOverwrite); + + LOG(FIT) << "Inclusive XSec Per Nucleon = " + << eventhist->Integral("width") * 1E-38 / fluxhist->Integral("width") + << std::endl; + std::cout << "XSec Hist Integral = " << xsechist->Integral("width") + << std::endl; + + return; }; - - void PrintOptions() { - - std::cout << "PrepareGENIEEvents NUISANCE app. " << std::endl - << "Takes GHep Outputs and prepares events for NUISANCE." << std::endl << std::endl - << "PrepareGENIEEvents [-h,-help,--h,--help] [-i inputfile1.root,inputfile2.root,inputfile3.root,...] " - << "[-f flux_root_file.root,flux_hist_name] [-t target1[frac1],target2[frac2],...]" - << std::endl << std::endl; - - std::cout << "Prepare Mode [Default] : Takes a single GHep file, reconstructs the original GENIE splines, " - << " and creates a duplicate file that also contains the flux, event rate, and xsec predictions that NUISANCE needs. " << std::endl; - std::cout << "Following options are required for Prepare Mode:" << std::endl; - std::cout << " [ -i inputfile.root ] : Reads in a single GHep input file that needs the xsec calculation ran on it. " << std::endl; - std::cout << " [ -f flux_file.root,hist_name ] : Path to root file containing the flux histogram the GHep records were generated with." - << " A simple method is to point this to the flux histogram genie generatrs '-f /path/to/events/input-flux.root,spectrum'. " << std::endl; - std::cout << " [ -t target ] : Target that GHepRecords were generated with. Comma seperated list. E.g. for CH2 target=1000060120,1000010010,1000010010" << std::endl; - - /* - std::cout << "Merger Mode [activate with -m] : Takes the list of input files assuming 'Prepare Mode' has already been ran on them and merges them " - << "into a single file with associated Friend Tree to help with conserving ratios of events (e.g. adding nue and nueb beams together into a single file" << std::endl; - std::cout << "Following optoins are required for Merger Mode:" << std::endl; - std::cout << " [ -i inputfile1.root,inputfile2.root ] : Comma Seperated list of files to be merged. " << std::endl; - std::cout << " [ -o outputfile.root ] : Output file for merger." << std::endl; - */ - + std::cout << "PrepareGENIEEvents NUISANCE app. " << std::endl + << "Takes GHep Outputs and prepares events for NUISANCE." + << std::endl + << std::endl + << "PrepareGENIEEvents [-h,-help,--h,--help] [-i " + "inputfile1.root,inputfile2.root,inputfile3.root,...] " + << "[-f flux_root_file.root,flux_hist_name] [-t " + "target1[frac1],target2[frac2],...]" + << std::endl + << std::endl; + + std::cout << "Prepare Mode [Default] : Takes a single GHep file, " + "reconstructs the original GENIE splines, " + << " and creates a duplicate file that also contains the flux, " + "event rate, and xsec predictions that NUISANCE needs. " + << std::endl; + std::cout << "Following options are required for Prepare Mode:" << std::endl; + std::cout << " [ -i inputfile.root ] : Reads in a single GHep input file " + "that needs the xsec calculation ran on it. " + << std::endl; + std::cout << " [ -f flux_file.root,hist_name ] : Path to root file " + "containing the flux histogram the GHep records were generated " + "with." + << " A simple method is to point this to the flux histogram genie " + "generatrs '-f /path/to/events/input-flux.root,spectrum'. " + << std::endl; + std::cout << " [ -t target ] : Target that GHepRecords were generated with. " + "Comma seperated list. E.g. for CH2 " + "target=1000060120,1000010010,1000010010" + << std::endl; + std::cout << " [ -o outputfile.root ] : File to write prepared input file to." + << std::endl; + std::cout << " [ -m Mono_E_nu_GeV ] : Run in mono-energetic mode." + << std::endl; } void ParseOptions(int argc, char* argv[]) { - bool flagopt = false; - - // If No Arguments print commands - for (int i = 1; i < argc; ++i) { - if (!std::strcmp(argv[i], "-h")) { flagopt = true; break; } - // if (!std::strcmp(argv[i], "-m")) { gFlagMerge = true; break; } - if (i + 1 != argc) { - - // Cardfile - if (!std::strcmp(argv[i], "-h")) { flagopt = true; break; } - else if (!std::strcmp(argv[i], "-i")) { gInputFiles = argv[i + 1]; ++i; } - else if (!std::strcmp(argv[i], "-o")) { gOutputFile = argv[i + 1]; ++i; } - else if (!std::strcmp(argv[i], "-f")) { gFluxFile = argv[i + 1]; ++i; } - else if (!std::strcmp(argv[i], "-t")) { gTarget = argv[i + 1]; ++i; } - else { - ERR(FTL) << "ERROR: unknown command line option given! - '" - << argv[i] << " " << argv[i + 1] << "'" << std::endl; - PrintOptions(); - break; - } - } - } - - /* - if (gOutputFile == "" && !flagopt){ - ERR(FTL) << "No output file specificed!" << std::endl; - flagopt = true; - } - */ - - if (gInputFiles == "" && !flagopt) { - ERR(FTL) << "No input file(s) specified!" << std::endl; - flagopt = true; - } - - if (!gFlagMerge && gFluxFile == "" && !flagopt) { - ERR(FTL) << "No flux input specified for Prepare Mode" << std::endl; - flagopt = true; - } - - if (!gFlagMerge && gTarget == "" && !flagopt) { - ERR(FTL) << "No target specified for Prepare Mode" << std::endl; - flagopt = true; - } - - if (argc < 1 || flagopt) { - PrintOptions(); - exit(-1); - } - - return; + bool flagopt = false; + + // If No Arguments print commands + for (int i = 1; i < argc; ++i) { + if (!std::strcmp(argv[i], "-h")) { + flagopt = true; + break; + } + if (i + 1 != argc) { + // Cardfile + if (!std::strcmp(argv[i], "-h")) { + flagopt = true; + break; + } else if (!std::strcmp(argv[i], "-i")) { + gInputFiles = argv[i + 1]; + ++i; + } else if (!std::strcmp(argv[i], "-o")) { + gOutputFile = argv[i + 1]; + ++i; + } else if (!std::strcmp(argv[i], "-f")) { + gFluxFile = argv[i + 1]; + ++i; + } else if (!std::strcmp(argv[i], "-t")) { + gTarget = argv[i + 1]; + ++i; + } else if (!std::strcmp(argv[i], "-m")) { + MonoEnergy = GeneralUtils::StrToDbl(argv[i + 1]); + IsMonoE = true; + ++i; + } else { + ERR(FTL) << "ERROR: unknown command line option given! - '" << argv[i] + << " " << argv[i + 1] << "'" << std::endl; + PrintOptions(); + break; + } + } + } + + if (gInputFiles == "" && !flagopt) { + ERR(FTL) << "No input file(s) specified!" << std::endl; + flagopt = true; + } + + if (gFluxFile == "" && !flagopt) { + ERR(FTL) << "No flux input specified for Prepare Mode" << std::endl; + flagopt = true; + } + + if (gTarget == "" && !flagopt) { + ERR(FTL) << "No target specified for Prepare Mode" << std::endl; + flagopt = true; + } + + if (argc < 1 || flagopt) { + PrintOptions(); + exit(-1); + } + + return; } diff --git a/app/PrepareNEUT.cxx b/app/PrepareNEUT.cxx index a4c31ed..8a0c67e 100644 --- a/app/PrepareNEUT.cxx +++ b/app/PrepareNEUT.cxx @@ -1,237 +1,422 @@ #include #include +#include "FitLogger.h" +#include "PlotUtils.h" +#include "StatUtils.h" #include "TFile.h" #include "TH1D.h" #include "TTree.h" -#include "PlotUtils.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 = ""; +std::string fFluxFile = ""; bool fFluxInGeV = false; +bool fIsMonoEFlux = false; +double fMonoEEnergy = 0xdeadbeef; void PrintOptions(); void ParseOptions(int argc, char* argv[]); -void CreateRateHistogram(std::string inputList, std::string flux, std::string output); +void AddMonoRateHistogram(std::string inputList, double MonoE, + std::string output); +void CreateRateHistogram(std::string inputList, std::string flux, + std::string output); //******************************* -int main(int argc, char* argv[]){ -//******************************* +int main(int argc, char* argv[]) { + //******************************* LOG_VERB(FitPar::Config().GetParI("VERBOSITY")); ERR_VERB(FitPar::Config().GetParI("ERROR")); ParseOptions(argc, argv); LOG(FIT) << "Running PrepareNEUT" << std::endl; - CreateRateHistogram(fInputFiles, fFluxFile, fOutputFile); + if (fIsMonoEFlux) { + AddMonoRateHistogram(fInputFiles, fMonoEEnergy, fOutputFile); + } else { + CreateRateHistogram(fInputFiles, fFluxFile, fOutputFile); + } }; +void AddMonoRateHistogram(std::string inputList, double MonoE, + std::string output) { + // Need to allow for more than one file... will do soon + TChain* tn = new TChain("neuttree"); + + 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..." + << std::endl; + throw; + } + + NeutVect* fNeutVect = NULL; + tn->SetBranchAddress("vectorbranch", &fNeutVect); + + TH1D* fluxHist = new TH1D("flux", "flux", 1000, 0, fFluxInGeV ? 10 : 10000); + fluxHist->Fill(MonoE); + fluxHist->Scale(1, "width"); + // Make Event Hist + TH1D* xsecHist = (TH1D*)fluxHist->Clone(); + xsecHist->Reset(); + + // Make a total cross section hist for shits and giggles + TH1D* entryHist = (TH1D*)xsecHist->Clone(); + + double MeanE = 0; + 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); + MeanE += E; + + if (i % (nevts / 20) == 0) { + LOG(FIT) << "Processed " << i << "/" << nevts << " NEUT events." + << std::endl; + } + } + MeanE /= double(nevts); + LOG(FIT) << "Processed all events" << std::endl; + + xsecHist->Divide(entryHist); + + // This will be the evtrt histogram + TH1D* evtHist = (TH1D*)xsecHist->Clone(); + 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 (MeanE = " << MeanE + << ", FluxHistoUpperLim: " + << fluxHist->GetXaxis()->GetBinUpEdge(1000) + << ")? Did you provide the correct flux file?" << std::endl; + ERR(WRN) << "Use output with caution..." << std::endl; + } + + // Pick where the output should go + TFile* outFile = NULL; + 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(); +} + //******************************* -void CreateRateHistogram(std::string inputList, std::string flux, std::string output){ -//******************************* +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,","); + std::vector inputs = GeneralUtils::ParseToStr(inputList, ","); for (std::vector::iterator it = inputs.begin(); - it != inputs.end(); ++it){ + 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; + 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,","); + 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()); + 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; + 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(); + TH1D* entryHist = (TH1D*)xsecHist->Clone(); - for (int i = 0; i < nevts; ++i){ + for (int i = 0; i < nevts; ++i) { tn->GetEntry(i); - NeutPart* part = fNeutVect->PartInfo(0); + NeutPart* part = fNeutVect->PartInfo(0); double E = part->fP.E(); double xsec = fNeutVect->Totcrs; // Unit conversion - if (fFluxInGeV) E*=1E-3; - - xsecHist ->Fill(E, xsec); + 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; + if (i % (nevts / 20) == 0) { + LOG(FIT) << "Processed " << i << "/" << nevts << " NEUT events." + << std::endl; } } LOG(FIT) << "Processed all events" << std::endl; - - xsecHist ->Divide(entryHist); + + 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; + + // 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())); + evtHist->Scale(fluxHist->Integral() / float(evtHist->Integral())); } else { evtHist = (TH1D*)xsecHist->Clone(); - evtHist ->Multiply(fluxHist); + 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; + // 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()){ + 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()){ + 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(); + 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; +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 << " -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 << " 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 + << " 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; - + std::cout << " Flux is assumed to be in MeV. This switch indicates " + "the input flux is in GeV" + << std::endl; + std::cout << " [-m E_nu]" << std::endl; + std::cout << " Used to add dummy flux and evt rate histograms to " + "mono-energetic vectors. Adheres to the -G flag." + << std::endl; } -void ParseOptions(int argc, char* argv[]){ +void ParseOptions(int argc, char* argv[]) { bool flagopt = false; - + // If No Arguments print commands - for (int i = 1; i< argc; ++i){ - if (!std::strcmp(argv[i], "-h")) { flagopt = true; break; } - else if (!std::strcmp(argv[i], "-G")) { fFluxInGeV = true; } - if (i+1 != argc){ - + for (int i = 1; i < argc; ++i) { + if (!std::strcmp(argv[i], "-h")) { + flagopt = true; + break; + } else if (!std::strcmp(argv[i], "-G")) { + fFluxInGeV = true; + continue; + } + if (i + 1 != argc) { // Cardfile - if (!std::strcmp(argv[i], "-h")) { flagopt = true; break; } - else if (!std::strcmp(argv[i], "-i")) { fInputFiles = argv[i+1]; ++i; } - else if (!std::strcmp(argv[i], "-o")) { fOutputFile = argv[i+1]; ++i; } - else if (!std::strcmp(argv[i], "-f")) { fFluxFile = argv[i+1]; ++i; } - else { - 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 5338a9a..c558d1f 100644 --- a/app/nuissmear.cxx +++ b/app/nuissmear.cxx @@ -1,172 +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 -f format [-o outfile] [-n nevents] [-t " + 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.AddS("name", "FlatTree"); - samplekey.AddS("input", gOptInputFile); - samplekey.AddS("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."); } - flattreecreator = - new Smearceptance_Tester(std::string("FlatTree_") + gOptOptions, - gOptInputFile, FitBase::GetRW(), gOptType, ""); + + 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/app/nuwro_NUISANCE.cxx b/app/nuwro_NUISANCE.cxx index fe8053c..a95b1ab 100644 --- a/app/nuwro_NUISANCE.cxx +++ b/app/nuwro_NUISANCE.cxx @@ -1,486 +1,512 @@ #ifdef __NUWRO_ENABLED__ #include "ComparisonRoutines.h" #include "ParserUtils.h" +#include "TargetUtils.h" // All possible inputs std::string gOptEnergyDef; std::vector gOptEnergyRange; int gOptNumberEvents = -1; int gOptNumberTestEvents = 5E6; std::string gOptGeneratorList = "Default"; -std::string gOptCrossSections = "Default"; // If default this will look in $NUISANCE/data/nuwro/default_params.txt +std::string gOptCrossSections = + "Default"; // If default this will look in + // $NUISANCE/data/nuwro/default_params.txt int gOptSeed = time(NULL); std::string gOptTargetDef = ""; std::string gOptFluxDef = ""; std::string gOptOutputFile = ""; int gOptRunNumber = -1; -void GetCommandLineArgs (int argc, char ** argv); -void PrintSyntax (void); - -std::string GetDynamicModes(std::string list){ +void GetCommandLineArgs(int argc, char** argv); +void PrintSyntax(void); +std::string GetDynamicModes(std::string list) { LOG(FIT) << "Using " << list << " to define interaction modes." << std::endl; std::map modes; - if (!list.compare("Default")){ + if (!list.compare("Default")) { modes["dyn_qel_cc"] = 1; // Quasi elastic charged current modes["dyn_qel_nc"] = 1; // Quasi elastic neutral current modes["dyn_res_cc"] = 1; // Resonant charged current modes["dyn_res_nc"] = 1; // Resonant neutral current modes["dyn_dis_cc"] = 1; // Deep inelastic charged current modes["dyn_dis_nc"] = 1; // Deep inelastic neutral current modes["dyn_coh_cc"] = 1; // Coherent charged current modes["dyn_coh_nc"] = 1; // Coherent neutral current modes["dyn_mec_cc"] = 0; // Meson exchange charged current modes["dyn_mec_nc"] = 0; // Meson exchange neutral current - } else if (!list.compare("DefaultFree")){ - modes["dyn_qel_cc"] = 1; // Quasi elastic charged current - modes["dyn_qel_nc"] = 1; // Quasi elastic neutral current - modes["dyn_res_cc"] = 1; // Resonant charged current - modes["dyn_res_nc"] = 1; // Resonant neutral current - modes["dyn_dis_cc"] = 1; // Deep inelastic charged current - modes["dyn_dis_nc"] = 1; // Deep inelastic neutral current - modes["dyn_coh_cc"] = 0; // Coherent charged current - modes["dyn_coh_nc"] = 0; // Coherent neutral current - modes["dyn_mec_cc"] = 0; // Meson exchange charged current - modes["dyn_mec_nc"] = 0; // Meson exchange neutral current - - } else if (!list.compare("Default+MEC")){ + } else if (!list.compare("DefaultFree")) { + modes["dyn_qel_cc"] = 1; // Quasi elastic charged current + modes["dyn_qel_nc"] = 1; // Quasi elastic neutral current + modes["dyn_res_cc"] = 1; // Resonant charged current + modes["dyn_res_nc"] = 1; // Resonant neutral current + modes["dyn_dis_cc"] = 1; // Deep inelastic charged current + modes["dyn_dis_nc"] = 1; // Deep inelastic neutral current + modes["dyn_coh_cc"] = 0; // Coherent charged current + modes["dyn_coh_nc"] = 0; // Coherent neutral current + modes["dyn_mec_cc"] = 0; // Meson exchange charged current + modes["dyn_mec_nc"] = 0; // Meson exchange neutral current + + } else if (!list.compare("Default+MEC")) { modes["dyn_qel_cc"] = 1; // Quasi elastic charged current modes["dyn_qel_nc"] = 1; // Quasi elastic neutral current modes["dyn_res_cc"] = 1; // Resonant charged current modes["dyn_res_nc"] = 1; // Resonant neutral current modes["dyn_dis_cc"] = 1; // Deep inelastic charged current modes["dyn_dis_nc"] = 1; // Deep inelastic neutral current modes["dyn_coh_cc"] = 1; // Coherent charged current modes["dyn_coh_nc"] = 1; // Coherent neutral current modes["dyn_mec_cc"] = 1; // Meson exchange charged current modes["dyn_mec_nc"] = 1; // Meson exchange neutral current } else { THROW("Event generator list " << list << " not found!"); } std::string modestring = ""; - for(std::map::iterator iter = modes.begin(); - iter != modes.end(); iter++){ + for (std::map::iterator iter = modes.begin(); + iter != modes.end(); iter++) { std::cout << " -> " << iter->first << " : " << iter->second << std::endl; - modestring += " -p \"" + iter->first + "=" + GeneralUtils::IntToStr(iter->second) + "\""; + modestring += " -p \"" + iter->first + "=" + + GeneralUtils::IntToStr(iter->second) + "\""; } return modestring; } -std::string GetFluxDefinition(std::string flux, std::string out){ +std::string GetFluxDefinition(std::string flux, std::string out) { LOG(FIT) << "Using " << flux << " to define NuWro beam." << std::endl; // By default the flux is type 6 with a root file - std::vector fluxargs = GeneralUtils::ParseToStr(flux,","); - if (fluxargs.size() < 2){ - THROW("Expected flux in the format: file.root,hist_name1[pdg1],... : reveived : " << flux); + std::vector fluxargs = GeneralUtils::ParseToStr(flux, ","); + if (fluxargs.size() < 2) { + THROW( + "Expected flux in the format: file.root,hist_name1[pdg1],... : " + "reveived : " + << flux); } // Build Map std::map fluxmap; fluxmap["beam_type"] = "6"; fluxmap["beam_inputroot"] = fluxargs[0]; - fluxmap["beam_inputroot_nue"] = ""; - fluxmap["beam_inputroot_nueb"] = ""; - fluxmap["beam_inputroot_numu"] = ""; - fluxmap["beam_inputroot_numub"] = ""; - fluxmap["beam_inputroot_nutau"] = ""; + fluxmap["beam_inputroot_nue"] = ""; + fluxmap["beam_inputroot_nueb"] = ""; + fluxmap["beam_inputroot_numu"] = ""; + fluxmap["beam_inputroot_numub"] = ""; + fluxmap["beam_inputroot_nutau"] = ""; fluxmap["beam_inputroot_nutaub"] = ""; // Split by beam bdgs - for (int i = 1; i < fluxargs.size(); i++){ + for (int i = 1; i < fluxargs.size(); i++) { std::string histdef = fluxargs[i]; - string::size_type open_bracket = histdef.find("["); + string::size_type open_bracket = histdef.find("["); string::size_type close_bracket = histdef.find("]"); string::size_type ibeg = 0; string::size_type iend = open_bracket; - string::size_type jbeg = open_bracket+1; - string::size_type jend = close_bracket-1; - std::string name = std::string(histdef.substr(ibeg,iend).c_str()); - int pdg = atoi(histdef.substr(jbeg,jend).c_str()); - - if (pdg == 12) fluxmap["beam_inputroot_nue"] = name; - else if (pdg ==-12) fluxmap["beam_inputroot_nueb"] = name; - else if (pdg == 14) fluxmap["beam_inputroot_numu"] = name; - else if (pdg ==-14) fluxmap["beam_inputroot_numub"] = name; - else if (pdg == 16) fluxmap["beam_inputroot_nutau"] = name; - else if (pdg ==-16) fluxmap["beam_inputroot_nutaub"] = name; + string::size_type jbeg = open_bracket + 1; + string::size_type jend = close_bracket - 1; + std::string name = std::string(histdef.substr(ibeg, iend).c_str()); + int pdg = atoi(histdef.substr(jbeg, jend).c_str()); + + if (pdg == 12) + fluxmap["beam_inputroot_nue"] = name; + else if (pdg == -12) + fluxmap["beam_inputroot_nueb"] = name; + else if (pdg == 14) + fluxmap["beam_inputroot_numu"] = name; + else if (pdg == -14) + fluxmap["beam_inputroot_numub"] = name; + else if (pdg == 16) + fluxmap["beam_inputroot_nutau"] = name; + else if (pdg == -16) + fluxmap["beam_inputroot_nutaub"] = name; } - - // Now create a new flux file matching the output file - std::cout << " -> Moving flux from '" + fluxmap["beam_inputroot"] + "' to current directory to keep everything organised." << std::endl; - TFile* fluxread = new TFile(fluxmap["beam_inputroot"].c_str(),"READ"); - TFile* fluxwrite = new TFile((out + ".flux.root").c_str(),"RECREATE"); - for(std::map::iterator iter = fluxmap.begin(); - iter != fluxmap.end(); iter++){ + // Now create a new flux file matching the output file + std::cout << " -> Moving flux from '" + fluxmap["beam_inputroot"] + + "' to current directory to keep everything organised." + << std::endl; + TFile* fluxread = new TFile(fluxmap["beam_inputroot"].c_str(), "READ"); + TFile* fluxwrite = new TFile((out + ".flux.root").c_str(), "RECREATE"); + + for (std::map::iterator iter = fluxmap.begin(); + iter != fluxmap.end(); iter++) { TH1* temp = (TH1*)fluxread->Get(iter->second.c_str()); if (!temp) continue; TH1D* cuthist = (TH1D*)temp->Clone(); // Restrict energy range if required - if (gOptEnergyRange.size() == 2){ - for (int i = 0; i < cuthist->GetNbinsX(); i++){ - if (cuthist->GetXaxis()->GetBinCenter(i+1) < gOptEnergyRange[0] or - cuthist->GetXaxis()->GetBinCenter(i+1) > gOptEnergyRange[1]){ - cuthist->SetBinContent(i+1, 0.0); - } + if (gOptEnergyRange.size() == 2) { + for (int i = 0; i < cuthist->GetNbinsX(); i++) { + if (cuthist->GetXaxis()->GetBinCenter(i + 1) < gOptEnergyRange[0] or + cuthist->GetXaxis()->GetBinCenter(i + 1) > gOptEnergyRange[1]) { + cuthist->SetBinContent(i + 1, 0.0); + } } } // Check Flux - if (cuthist->Integral() <= 0.0){ + if (cuthist->Integral() <= 0.0) { THROW("Flux histogram " << iter->second << " has integral <= 0.0"); } // Save fluxwrite->cd(); cuthist->Write(); } std::cout << " ->-> Saved to : " << (out + ".flux.root") << std::endl; fluxmap["beam_inputroot"] = (out + ".flux.root"); fluxwrite->Close(); // Return a parameters string std::string fluxstring = ""; - for(std::map::iterator iter = fluxmap.begin(); - iter != fluxmap.end(); iter++){ + for (std::map::iterator iter = fluxmap.begin(); + iter != fluxmap.end(); iter++) { std::cout << " -> " << iter->first << " : " << iter->second << std::endl; fluxstring += " -p \"" + iter->first + "=" + iter->second + "\""; } return fluxstring; } -std::string GetTargetDefinition(std::string target){ - +std::string GetTargetDefinition(std::string target) { LOG(FIT) << "Defining NuWro Target from : " << target << std::endl; - // Target is given as either a single PDG, or a combo with the total number of nucleons - std::vector trgts = GeneralUtils::ParseToStr(target,","); + // Target is given as either a single PDG, or a combo with the total number of + // nucleons + std::vector trgts = GeneralUtils::ParseToStr(target, ","); std::string targetstring = ""; // Single Target - if (trgts.size() == 1){ - + if (trgts.size() == 1) { int PDG = GeneralUtils::StrToInt(trgts[0]); int Z = TargetUtils::GetTargetZFromPDG(PDG); int N = TargetUtils::GetTargetAFromPDG(PDG) - Z; int TOTAL = 1; - targetstring += (" -p \"target_content=" - + GeneralUtils::IntToStr(Z) + " " - + GeneralUtils::IntToStr(N) + " " - + GeneralUtils::IntToStr(TOTAL) + "x" - + "\""); - - // Combined target - } else if (trgts.size() > 1){ - + targetstring += (" -p \"target_content=" + GeneralUtils::IntToStr(Z) + " " + + GeneralUtils::IntToStr(N) + " " + + GeneralUtils::IntToStr(TOTAL) + "x" + "\""); + + // Combined target + } else if (trgts.size() > 1) { int NUCLEONS = GeneralUtils::StrToInt(trgts[0]); // Loop over all targets - for (size_t i = 1; i < trgts.size(); i++){ - + for (size_t i = 1; i < trgts.size(); i++) { // Extra PDG and W std::string tgtdef = trgts[i]; - string::size_type open_bracket = tgtdef.find("["); + string::size_type open_bracket = tgtdef.find("["); string::size_type close_bracket = tgtdef.find("]"); string::size_type ibeg = 0; string::size_type iend = open_bracket; - string::size_type jbeg = open_bracket+1; - string::size_type jend = close_bracket-1; - int PDG = atoi(tgtdef.substr(ibeg,iend).c_str()); - double W = atof(tgtdef.substr(jbeg,jend).c_str()); + string::size_type jbeg = open_bracket + 1; + string::size_type jend = close_bracket - 1; + int PDG = atoi(tgtdef.substr(ibeg, iend).c_str()); + double W = atof(tgtdef.substr(jbeg, jend).c_str()); // extract Z N int Z = TargetUtils::GetTargetZFromPDG(PDG); - int A = TargetUtils::GetTargetAFromPDG(PDG); + int A = TargetUtils::GetTargetAFromPDG(PDG); int N = TargetUtils::GetTargetAFromPDG(PDG) - Z; std::cout << "Target " << PDG << " Z" << Z << " N" << N << std::endl; // extract weight - int TOTAL = round(double(NUCLEONS)*W / A); - - if (i == 1){ - targetstring += (" -p \"target_content=" - + GeneralUtils::IntToStr(Z) + " " - + GeneralUtils::IntToStr(N) + " " - + GeneralUtils::IntToStr(TOTAL) + "x" - + "\""); + int TOTAL = round(double(NUCLEONS) * W / A); + + if (i == 1) { + targetstring += (" -p \"target_content=" + GeneralUtils::IntToStr(Z) + + " " + GeneralUtils::IntToStr(N) + " " + + GeneralUtils::IntToStr(TOTAL) + "x" + "\""); } else { - targetstring += (" -p \"target_content+=" - + GeneralUtils::IntToStr(Z) + " " - + GeneralUtils::IntToStr(N) + " " - + GeneralUtils::IntToStr(TOTAL) + "x" - + "\""); - } + targetstring += (" -p \"target_content+=" + GeneralUtils::IntToStr(Z) + + " " + GeneralUtils::IntToStr(N) + " " + + GeneralUtils::IntToStr(TOTAL) + "x" + "\""); + } } - // No target given! + // No target given! } else { THROW("No target given : " << target); } std::cout << " -> " << targetstring << std::endl; return targetstring; } -std::string GetEventAndSeedDefinition(int nevents, int ntestevents, int seed){ - +std::string GetEventAndSeedDefinition(int nevents, int ntestevents, int seed) { std::string eventdef = ""; - eventdef += " -p \"number_of_events=" + GeneralUtils::IntToStr(nevents) + "\""; - eventdef += " -p \"number_of_test_events=" + GeneralUtils::IntToStr(ntestevents) + "\""; + eventdef += + " -p \"number_of_events=" + GeneralUtils::IntToStr(nevents) + "\""; + eventdef += " -p \"number_of_test_events=" + + GeneralUtils::IntToStr(ntestevents) + "\""; eventdef += " -p \"random_seed=" + GeneralUtils::IntToStr(seed) + "\""; LOG(FIT) << "Event Definition: " << std::endl; std::cout << " -> number_of_events : " << nevents << std::endl; std::cout << " -> number_of_test_events : " << ntestevents << std::endl; std::cout << " -> seed : " << seed << std::endl; return eventdef; } - - - //____________________________________________________________________________ -int main(int argc, char ** argv) -{ +int main(int argc, char** argv) { LOG(FIT) << "==== RUNNING nuwro_nuisance Event Generator =====" << std::endl; - GetCommandLineArgs(argc,argv); - + GetCommandLineArgs(argc, argv); + // Calculate the dynamic modes definition std::string dynparamsdef = GetDynamicModes(gOptGeneratorList); // Get Flux and Target definition std::string fluxparamsdef = GetFluxDefinition(gOptFluxDef, gOptOutputFile); std::string targetparamsdef = GetTargetDefinition(gOptTargetDef); // Get Run Definition - std::string eventparamsdef = GetEventAndSeedDefinition(gOptNumberEvents, - gOptNumberTestEvents, - gOptSeed); + std::string eventparamsdef = GetEventAndSeedDefinition( + gOptNumberEvents, gOptNumberTestEvents, gOptSeed); // Run NuWro Externally! LOG(FIT) << "==== Actually running nuwro! ===" << std::endl; std::string nuwrocommand = "nuwro"; nuwrocommand += " -i " + gOptCrossSections; nuwrocommand += " -o " + gOptOutputFile; nuwrocommand += " " + fluxparamsdef; nuwrocommand += " " + dynparamsdef; nuwrocommand += " " + eventparamsdef; nuwrocommand += " " + targetparamsdef; std::cout << nuwrocommand << std::endl; sleep(10); system((nuwrocommand).c_str()); return 0; } //____________________________________________________________________________ -void GetCommandLineArgs(int argc, char ** argv) -{ - +void GetCommandLineArgs(int argc, char** argv) { // Check for -h flag. - for (int i = 0; i < argc; i++){ + for (int i = 0; i < argc; i++) { if (!std::string(argv[i]).compare("-h")) PrintSyntax(); } - // Format is nuwro -r run_number -n n events + // Format is nuwro -r run_number -n n events std::vector args = GeneralUtils::LoadCharToVectStr(argc, argv); ParserUtils::ParseArgument(args, "-n", gOptNumberEvents, false); - if (gOptNumberEvents == -1){ - THROW( "No event count passed to nuwro_NUISANCE!"); + if (gOptNumberEvents == -1) { + THROW("No event count passed to nuwro_NUISANCE!"); } // Flux/Energy Specs ParserUtils::ParseArgument(args, "-e", gOptEnergyDef, false); - gOptEnergyRange = GeneralUtils::ParseToDbl(gOptEnergyDef,","); + gOptEnergyRange = GeneralUtils::ParseToDbl(gOptEnergyDef, ","); ParserUtils::ParseArgument(args, "-f", gOptFluxDef, false); - if (gOptFluxDef.empty() and gOptEnergyRange.size() < 1){ + if (gOptFluxDef.empty() and gOptEnergyRange.size() < 1) { THROW("No flux or energy range given to nuwro_nuisance!"); - } else if (gOptFluxDef.empty() and gOptEnergyRange.size() == 1){ + } else if (gOptFluxDef.empty() and gOptEnergyRange.size() == 1) { // Fixed energy, make sure -p is given THROW("nuwro_NUISANCE cannot yet do fixed energy!"); - - } else if (gOptFluxDef.empty() and gOptEnergyRange.size() == 2){ + + } else if (gOptFluxDef.empty() and gOptEnergyRange.size() == 2) { // Uniform energy range THROW("nuwro_NUISANCE cannot yet do a uniform energy range!"); - } else if (!gOptFluxDef.empty()){ + } else if (!gOptFluxDef.empty()) { // Try to convert the flux definition if possible. std::string convflux = BeamUtils::ConvertFluxIDs(gOptFluxDef); if (!convflux.empty()) gOptFluxDef = convflux; } else { THROW("Unknown flux energy range combination!"); } ParserUtils::ParseArgument(args, "-t", gOptTargetDef, false); - if (gOptTargetDef.empty()){ + if (gOptTargetDef.empty()) { THROW("No Target passed to nuwro_nuisance! use the '-t' argument."); } else { std::string convtarget = TargetUtils::ConvertTargetIDs(gOptTargetDef); if (!convtarget.empty()) gOptTargetDef = convtarget; } ParserUtils::ParseArgument(args, "-r", gOptRunNumber, false); ParserUtils::ParseArgument(args, "-o", gOptOutputFile, false); - if (gOptOutputFile.empty()){ + if (gOptOutputFile.empty()) { if (gOptRunNumber == -1) gOptRunNumber = 1; - LOG(FIT) << "No output file given! Saving file to : nuwrogen." << gOptRunNumber << ".event.root" << std::endl; - gOptOutputFile = "nuwrogen." + GeneralUtils::IntToStr(gOptRunNumber) + ".event.root"; + LOG(FIT) << "No output file given! Saving file to : nuwrogen." + << gOptRunNumber << ".event.root" << std::endl; + gOptOutputFile = + "nuwrogen." + GeneralUtils::IntToStr(gOptRunNumber) + ".event.root"; } else { // if no run number given leave as is, else add run number. - if (gOptRunNumber != -1){ + if (gOptRunNumber != -1) { gOptOutputFile += "." + GeneralUtils::IntToStr(gOptRunNumber) + ".root"; } else { gOptRunNumber = 0; } } ParserUtils::ParseArgument(args, "--cross-section", gOptCrossSections, false); - if (!gOptCrossSections.compare("Default")){ - LOG(FIT) << "No Parameters File passed. Using default NuWro one." << std::endl; - char * const var = getenv("NUISANCE"); + if (!gOptCrossSections.compare("Default")) { + LOG(FIT) << "No Parameters File passed. Using default NuWro one." + << std::endl; + char* const var = getenv("NUISANCE"); if (!var) { - std::cout << "Cannot find top level directory! Set the NUISANCE environmental variable" << std::endl; + std::cout << "Cannot find top level directory! Set the NUISANCE " + "environmental variable" + << std::endl; exit(-1); - } + } std::string topnuisancedir = string(var); gOptCrossSections = topnuisancedir + "/nuwro/Default_params.txt"; } - - ParserUtils::ParseArgument(args, "--event-generator-list", gOptGeneratorList, false); + + ParserUtils::ParseArgument(args, "--event-generator-list", gOptGeneratorList, + false); ParserUtils::ParseArgument(args, "--seed", gOptSeed, false); - ParserUtils::ParseArgument(args, "--test-events", gOptNumberTestEvents, false); + ParserUtils::ParseArgument(args, "--test-events", gOptNumberTestEvents, + false); // Final Check and output - if (args.size() > 0){ + if (args.size() > 0) { PrintSyntax(); ParserUtils::CheckBadArguments(args); } - LOG(FIT) << "Generating NuWro Events with the following properties:" << std::endl - << " -> Energy : " << gOptEnergyDef << " (" << gOptEnergyRange.size() << ")" << std::endl - << " -> NEvents : " << gOptNumberEvents << std::endl - << " -> NTestEvents : " << gOptNumberTestEvents << std::endl - << " -> Generators : " << gOptGeneratorList << std::endl - << " -> XSecPars : " << gOptCrossSections << std::endl - << " -> Seed : " << gOptSeed << std::endl - << " -> Target : " << gOptTargetDef << std::endl - << " -> Flux : " << gOptFluxDef << std::endl - << " -> Output : " << gOptOutputFile << std::endl - << " -> Run : " << gOptRunNumber << std::endl; + LOG(FIT) << "Generating NuWro Events with the following properties:" + << std::endl + << " -> Energy : " << gOptEnergyDef << " (" + << gOptEnergyRange.size() << ")" << std::endl + << " -> NEvents : " << gOptNumberEvents << std::endl + << " -> NTestEvents : " << gOptNumberTestEvents << std::endl + << " -> Generators : " << gOptGeneratorList << std::endl + << " -> XSecPars : " << gOptCrossSections << std::endl + << " -> Seed : " << gOptSeed << std::endl + << " -> Target : " << gOptTargetDef << std::endl + << " -> Flux : " << gOptFluxDef << std::endl + << " -> Output : " << gOptOutputFile << std::endl + << " -> Run : " << gOptRunNumber << std::endl; return; } //____________________________________________________________________________ -void PrintSyntax(void) -{ - LOG(FIT) - << "\n\n" << "Syntax:" << "\n" - << "\n nuwro_nuisance [-h]" - << "\n -n nev" - << "\n -f flux_description" - << "\n -t target_description" - << "\n [ -r run_number ]" - << "\n [ -o output_file ]" - << "\n [ --cross-section /path/to/params.txt ]" - << "\n [ --event-generator-list mode_definition ]" - << "\n [ --seed seed_value ]" - << "\n [ --test-events ntest ]" - << "\n \n"; +void PrintSyntax(void) { + LOG(FIT) << "\n\n" + << "Syntax:" + << "\n" + << "\n nuwro_nuisance [-h]" + << "\n -n nev" + << "\n -f flux_description" + << "\n -t target_description" + << "\n [ -r run_number ]" + << "\n [ -o output_file ]" + << "\n [ --cross-section /path/to/params.txt ]" + << "\n [ --event-generator-list mode_definition ]" + << "\n [ --seed seed_value ]" + << "\n [ --test-events ntest ]" + << "\n \n"; LOG(FIT) - << "\n\n Arguments:" << "\n" - << "\n -n nev" - << "\n -> Total number of events to generate (e.g. 2500000)" - << "\n" - << "\n -f flux_description" - << "\n Definition of the flux to be read in from a ROOT file." - << "\n" - << "\n Multiple histograms can be read in from the same file using" - << "\n the format '-f file.root,hist1[pdg1],hist2[pdg2]" - << "\n e.g. \'-f ./flux/myfluxfile.root,numu_flux[14],numubar_flux[-14]\'" - << "\n" - << "\n When passing in multiple histograms, the nuwro_nuisance will" - << "\n generate a single file containing both sets of events with the" - << "\n correct ratios for each set." - << "\n" - << "\n A flux can also be given according to any of the flux IDs shown" - << "\n at the end of this help message." - << "\n e.g. \' -f MINERvA_fhc_numu\' " - << "\n" - << "\n -t target_description" - << "\n Definition of the target to be used. Multiple targets can be given." - << "\n" - << "\n To pass a single target just provide the target PDG" - << "\n e.g. \' -t 1000060120 \'" - << "\n" - << "\n To pass a combined target provide a list containing the following" - << "\n \' -t TotalNucleons,Target1[Weight1],Target2[Weight2],.. where the " - << "\n TotalNucleons is the total nucleons combined, Target1 is the PDG " - << "\n of the first target, and Weight1 is the fractional weight of the " - << "\n first target." - << "\n e.g. \' -t 13,1000060120[0.9231],1000010010[0.0769] \'" - << "\n" - << "\n Target can also be specified by the target IDs given at the end of" - << "\n this help message." - << "\n e.g. \' -t CH2 \'" - << "\n" - << "\n -r run_number" - << "\n run number ID that can be used when generating large samples in small " - << "\n jobs. Must be an integer. When given nuwro_nuisance will update the " - << "\n output file from 'output.root' to 'output.root.run_number.root'" - << "\n" - << "\n -o output_file" - << "\n Path to the output_file you want to save events to." - << "\n" - << "\n If this is not given but '-r' is then events will be saved to " - << "\n the file 'nuwrogen.run_number.events.root'" - << "\n" - << "\n If a run number is given alongside '-o' then events will be saved " - << "\n to 'output.root.run_number.root'" - << "\n" - << "\n --cross-section /path/to/params.txt" - << "\n Path to the nuwro model definition. If this is not given, then this " - << "\n will default to $NUISANCE/data/nuwro/Default_params.txt" - << "\n" - << "\n Look in $NUISANCE/data/nuwro/Default_params.txt for examples when " - << "\n writing your own card files." - << "\n" - << "\n --event-generator-list mode_definition" - << "\n Name of modes to run. This sets the dynamic mode settings in nuwro." - << "\n e.g. --event-generator-list Default+MEC" - << "\n" - << "\n Allowed mode_definitions are given at the end of this help message." - << "\n" - << "\n --seed seed_value " - << "\n Value to use as the seed. If seed isn't given, time(NULL) is used." - << "\n" - << "\n --test-events ntest " - << "\n Sets the number of test events for Nuwro to use. If this option " - << "\n isn't given then we assume 5E6 test events by default." - << "\n\n"; - - std::cout << "-----------------"< Total number of events to generate (e.g. 2500000)" + << "\n" + << "\n -f flux_description" + << "\n Definition of the flux to be read in from a ROOT file." + << "\n" + << "\n Multiple histograms can be read in from the same file using" + << "\n the format '-f file.root,hist1[pdg1],hist2[pdg2]" + << "\n e.g. \'-f " + "./flux/myfluxfile.root,numu_flux[14],numubar_flux[-14]\'" + << "\n" + << "\n When passing in multiple histograms, the nuwro_nuisance will" + << "\n generate a single file containing both sets of events with the" + << "\n correct ratios for each set." + << "\n" + << "\n A flux can also be given according to any of the flux IDs shown" + << "\n at the end of this help message." + << "\n e.g. \' -f MINERvA_fhc_numu\' " + << "\n" + << "\n -t target_description" + << "\n Definition of the target to be used. Multiple targets can be " + "given." + << "\n" + << "\n To pass a single target just provide the target PDG" + << "\n e.g. \' -t 1000060120 \'" + << "\n" + << "\n To pass a combined target provide a list containing the " + "following" + << "\n \' -t TotalNucleons,Target1[Weight1],Target2[Weight2],.. where " + "the " + << "\n TotalNucleons is the total nucleons combined, Target1 is the " + "PDG " + << "\n of the first target, and Weight1 is the fractional weight of " + "the " + << "\n first target." + << "\n e.g. \' -t 13,1000060120[0.9231],1000010010[0.0769] \'" + << "\n" + << "\n Target can also be specified by the target IDs given at the " + "end of" + << "\n this help message." + << "\n e.g. \' -t CH2 \'" + << "\n" + << "\n -r run_number" + << "\n run number ID that can be used when generating large samples " + "in small " + << "\n jobs. Must be an integer. When given nuwro_nuisance will " + "update the " + << "\n output file from 'output.root' to 'output.root.run_number.root'" + << "\n" + << "\n -o output_file" + << "\n Path to the output_file you want to save events to." + << "\n" + << "\n If this is not given but '-r' is then events will be saved to " + << "\n the file 'nuwrogen.run_number.events.root'" + << "\n" + << "\n If a run number is given alongside '-o' then events will be " + "saved " + << "\n to 'output.root.run_number.root'" + << "\n" + << "\n --cross-section /path/to/params.txt" + << "\n Path to the nuwro model definition. If this is not given, then " + "this " + << "\n will default to $NUISANCE/data/nuwro/Default_params.txt" + << "\n" + << "\n Look in $NUISANCE/data/nuwro/Default_params.txt for examples " + "when " + << "\n writing your own card files." + << "\n" + << "\n --event-generator-list mode_definition" + << "\n Name of modes to run. This sets the dynamic mode settings in " + "nuwro." + << "\n e.g. --event-generator-list Default+MEC" + << "\n" + << "\n Allowed mode_definitions are given at the end of this help " + "message." + << "\n" + << "\n --seed seed_value " + << "\n Value to use as the seed. If seed isn't given, time(NULL) is " + "used." + << "\n" + << "\n --test-events ntest " + << "\n Sets the number of test events for Nuwro to use. If this " + "option " + << "\n isn't given then we assume 5E6 test events by default." + << "\n\n"; + + std::cout << "-----------------" << std::endl; TargetUtils::ListTargetIDs(); std::cout << "-----------------" << std::endl; BeamUtils::ListFluxIDs(); std::cout << "-----------------" << std::endl; LOG(FIT) << "Allowed Mode Definitions:" << std::endl - << " - Default : Default CC+NC modes, no MEC" << std::endl - << " - Default+MEC : Default CC+NC modes + 2p2h MEC " << std::endl - << " - DefaultFree : Default CC+NC modes, no Coherent or MEC " << std::endl; + << " - Default : Default CC+NC modes, no MEC" << std::endl + << " - Default+MEC : Default CC+NC modes + 2p2h MEC " << std::endl + << " - DefaultFree : Default CC+NC modes, no Coherent or MEC " + << std::endl; std::cout << "----------------" << std::endl; exit(0); } //____________________________________________________________________________ #endif diff --git a/cmake/BuildDynamicSample.in b/cmake/BuildDynamicSample.in new file mode 100644 index 0000000..6ed170f --- /dev/null +++ b/cmake/BuildDynamicSample.in @@ -0,0 +1,87 @@ +# Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +################################################################################ +# This file is part of NUISANCE. +# +# NUISANCE is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# NUISANCE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NUISANCE. If not, see . +################################################################################ + +#!/bin/bash + +if [ ! "${1}" ] || [ ! -e ${1} ] || [ ! "${2}" ]; then + echo "[USAGE]: ${0} input.cxx outputLibName.so [classname]" + exit 1 +fi + +if [ ! "${3}" ]; then + CN=$(grep "class .*" $1 | sed "s/^class \([0-9a-zA-Z]\+\).*$/\1/g") +else + CN=${3} +fi + +if [ ! "${CN}" ]; then + echo "[ERROR]: Couldn't find class name -- Expected to find a line like: \"class XXXX : public Measurement1D\" in \"$1\". You can also forcibly specify your classes name by passing a third argument to this script." + exit 1 +fi + +if [ ! -e compile.tmp ]; then + mkdir compile.tmp +fi + +cat $1 > compile.tmp/$1 + +echo -e "static char const * SampleNames[] = {\"${CN}\"};\n"\ +"static int const NSamples = 1;\n"\ +"\n"\ +"extern \"C\" {\n"\ +"int DSF_NSamples() { return NSamples; }\n"\ +"char const* DSF_GetSampleName(int i) {\n"\ +" if (i < NSamples) {\n"\ +" return SampleNames[i];\n"\ +" }\n"\ +" return 0;\n"\ +"}\n"\ +"MeasurementBase* DSF_GetSample(int i, void* samplekey) {\n"\ +" nuiskey* sk = reinterpret_cast(samplekey);\n"\ +" if (!sk) {\n"\ +" return 0;\n"\ +" }\n"\ +"\n"\ +" if (sk->GetS(\"name\") != DSF_GetSampleName(i)) {\n"\ +" std::cout\n"\ +" << \"[ERROR]: When instantiating dynamic sample. Samplekey named: \"\n"\ +" << sk->GetS(\"name\") << \", but requested sample named: \"\n"\ +" << DSF_GetSampleName(i)\n"\ +" << \". It is possible that the nuiskey object is lost in translation. \"\n"\ +" \"Was NUISANCE and this dynamic sample manifest built with the same \"\n"\ +" \"environment and compiler?\"\n"\ +" << std::endl;\n"\ +" }\n"\ +"\n"\ +" if (i == 0) {\n"\ +" return new ${CN}(*sk);\n"\ +" }\n"\ +" return 0;\n"\ +"}\n"\ +"void DSF_DestroySample(MeasurementBase* mb) { delete mb; }\n"\ +"}" >> compile.tmp/$1 + +echo "g++ ${DYNSAMPLE_EXTRA_BUILD_FLAGS} compile.tmp/$1 -shared -o $2 -fPIC @CMAKE_CXX_FLAGS@ -I. -I@ALL_INCLUDES_STR@ -L@CMAKE_INSTALL_PREFIX@/lib -l@ALL_MODULETARGETS_STR@ @CMAKE_LINK_FLAGS@ @CMAKE_DEPENDLIB_FLAGS@" + +if ! g++ ${DYNSAMPLE_EXTRA_BUILD_FLAGS} compile.tmp/$1 -shared -o $2 -fPIC @CMAKE_CXX_FLAGS@ -I. -I@ALL_INCLUDES_STR@ -L@CMAKE_INSTALL_PREFIX@/lib -l@ALL_MODULETARGETS_STR@ @CMAKE_LINK_FLAGS@ @CMAKE_DEPENDLIB_FLAGS@; then + echo "[ERROR]: Failed to compile $1. Generated code can be found in ./compile.tmp/$1" +else + rm -r compile.tmp + echo "Successfully build: $2." +fi diff --git a/cmake/BuildDynamicSmearcepter.in b/cmake/BuildDynamicSmearcepter.in new file mode 100644 index 0000000..dce4633 --- /dev/null +++ b/cmake/BuildDynamicSmearcepter.in @@ -0,0 +1,89 @@ +# Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +################################################################################ +# This file is part of NUISANCE. +# +# NUISANCE is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# NUISANCE is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with NUISANCE. If not, see . +################################################################################ + +#!/bin/bash + +if [ ! "${1}" ] || [ ! -e ${1} ] || [ ! "${2}" ]; then + echo "[USAGE]: ${0} input.cxx outputLibName.so [classname]" + exit 1 +fi + +if [ ! "${3}" ]; then + CN=$(grep "class .*" $1 | sed "s/^class \([0-9a-zA-Z]\+\).*$/\1/g") +else + CN=${3} +fi + +if [ ! "${CN}" ]; then + echo "[ERROR]: Couldn't find class name -- Expected to find a line like: \"class XXXX : public ISmearcepter\" in \"$1\". You can also forcibly specify your classes name by passing a third argument to this script." + exit 1 +fi + +if [ ! -e compile.tmp ]; then + mkdir compile.tmp +fi + +cat $1 > compile.tmp/$1 + +echo -e "static char const * SmearceptorNames[] = {\"${CN}\"};\n"\ +"static int const NSmearceptors = 1;\n"\ +"\n"\ +"extern \"C\" {\n"\ +"int DSF_NSmearceptors() { return NSmearceptors; }\n"\ +"char const* DSF_GetSmearceptorName(int i) {\n"\ +" if (i < NSmearceptors) {\n"\ +" return SmearceptorNames[i];\n"\ +" }\n"\ +" return 0;\n"\ +"}\n"\ +"ISmearcepter* DSF_GetSmearceptor(int i, void* smearceptorkey) {\n"\ +" nuiskey* sk = reinterpret_cast(smearceptorkey);\n"\ +" if (!sk) {\n"\ +" return 0;\n"\ +" }\n"\ +"\n"\ +" if (sk->GetElementName() != DSF_GetSmearceptorName(i)) {\n"\ +" std::cout\n"\ +" << \"[ERROR]: When instantiating dynamic smearceptor. Smearceptorkey named: \"\n"\ +" << sk->GetElementName() << \", but requested smearceptor named: \"\n"\ +" << DSF_GetSmearceptorName(i)\n"\ +" << \". It is possible that the nuiskey object is lost in translation. \"\n"\ +" \"Was NUISANCE and this dynamic smearceptor manifest built with the same \"\n"\ +" \"environment and compiler?\"\n"\ +" << std::endl;\n"\ +" }\n"\ +"\n"\ +" if (i == 0) {\n"\ +" ISmearcepter* sm = new ${CN}();\n"\ +" sm->Setup(*sk);\n"\ +" return sm;\n"\ +" }\n"\ +" return 0;\n"\ +"}\n"\ +"void DSF_DestroySmearceptor(ISmearcepter* mb) { delete mb; }\n"\ +"}" >> compile.tmp/$1 + +echo "g++ ${DYNSAMPLE_EXTRA_BUILD_FLAGS} compile.tmp/$1 -shared -o $2 -fPIC @CMAKE_CXX_FLAGS@ -I. -I@ALL_INCLUDES_STR@ -L@CMAKE_INSTALL_PREFIX@/lib -l@ALL_MODULETARGETS_STR@ @CMAKE_LINK_FLAGS@ @CMAKE_DEPENDLIB_FLAGS@" + +if ! g++ ${DYNSAMPLE_EXTRA_BUILD_FLAGS} compile.tmp/$1 -shared -o $2 -fPIC @CMAKE_CXX_FLAGS@ -I. -I@ALL_INCLUDES_STR@ -L@CMAKE_INSTALL_PREFIX@/lib -l@ALL_MODULETARGETS_STR@ @CMAKE_LINK_FLAGS@ @CMAKE_DEPENDLIB_FLAGS@; then + echo "[ERROR]: Failed to compile $1. Generated code can be found in ./compile.tmp/$1" +else + rm -r compile.tmp + echo "Successfully build: $2." +fi 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/Prob3++Setup.cmake b/cmake/Prob3++Setup.cmake index e82e0ee..03de820 100644 --- a/cmake/Prob3++Setup.cmake +++ b/cmake/Prob3++Setup.cmake @@ -1,42 +1,42 @@ # 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 . ################################################################################ if(USE_PROB3PP) LIST(APPEND EXTRA_CXX_FLAGS -D__PROB3PP_ENABLED__) ExternalProject_Add(prob3pp PREFIX "${CMAKE_BINARY_DIR}/Ext" URL "http://webhome.phy.duke.edu/~raw22/public/Prob3++/Prob3++.20121225.tar.gz" CONFIGURE_COMMAND "" BUILD_IN_SOURCE 1 UPDATE_COMMAND "" - BUILD_COMMAND make + BUILD_COMMAND CXXFLAGS=-fPIC CFLAGS=-fPIC make INSTALL_COMMAND "" ) LIST(APPEND RWENGINE_INCLUDE_DIRECTORIES ${CMAKE_BINARY_DIR}/Ext/src/prob3pp) LIST(APPEND EXTRA_LINK_DIRS ${CMAKE_BINARY_DIR}/Ext/src/prob3pp) LIST(APPEND EXTRA_LIBS ThreeProb_2.10) cmessage(STATUS "Using Prob3++ 2.10") endif() diff --git a/cmake/ReweightEnginesSetup.cmake b/cmake/ReweightEnginesSetup.cmake index 87f47d4..16b9e85 100644 --- a/cmake/ReweightEnginesSetup.cmake +++ b/cmake/ReweightEnginesSetup.cmake @@ -1,87 +1,87 @@ # 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 . ################################################################################ +################################## T2K ###################################### +if(USE_T2K) + include(${CMAKE_SOURCE_DIR}/cmake/T2KSetup.cmake) + cmessage(STATUS "Using T2K Reweight engine.") + set(USE_T2K TRUE CACHE BOOL "Whether to enable T2KReWeight support. Requires external libraries. " FORCE) +endif() +################################## NIWG ###################################### +if(USE_NIWG) + include(${CMAKE_SOURCE_DIR}/cmake/NIWGSetup.cmake) + cmessage(STATUS "Using NIWG Reweight engine.") + set(USE_NIWG TRUE CACHE BOOL "Whether to enable (T2K) NIWG ReWeight support. Requires external libraries. " FORCE) +endif() +################################## MINERvA ###################################### +if(USE_MINERvA_RW) + include(${CMAKE_SOURCE_DIR}/cmake/MINERvASetup.cmake) + cmessage(STATUS "Using MINERvA Reweight engine.") + set(USE_MINERvA_RW TRUE CACHE BOOL "Whether to enable MINERvA ReWeight support. " FORCE) +endif() ################################## NEUT ###################################### if(USE_NEUT) include(${CMAKE_SOURCE_DIR}/cmake/NEUTSetup.cmake) cmessage(STATUS "Using NEUT Reweight engine.") set(USE_NEUT TRUE CACHE BOOL "Whether to enable NEUT (reweight) support. Requires external libraries. " FORCE) endif() ################################# NuWro ###################################### if(USE_NuWro) include(${CMAKE_SOURCE_DIR}/cmake/NuWroSetup.cmake) cmessage(STATUS "Using NuWro Reweight engine.") set(USE_NuWro TRUE CACHE BOOL "Whether to enable NuWro support. " FORCE) endif() ################################## GENIE ##################################### if(USE_GENIE) include(${CMAKE_SOURCE_DIR}/cmake/GENIESetup.cmake) cmessage(STATUS "Using GENIE Reweight engine.") set(USE_GENIE TRUE CACHE BOOL "Whether to enable GENIE (reweight) support. Requires external libraries. " FORCE) endif() -################################## NIWG ###################################### -if(USE_NIWG) - include(${CMAKE_SOURCE_DIR}/cmake/NIWGSetup.cmake) - cmessage(STATUS "Using NIWG Reweight engine.") - set(USE_NIWG TRUE CACHE BOOL "Whether to enable (T2K) NIWG ReWeight support. Requires external libraries. " FORCE) -endif() -################################## T2K ###################################### -if(USE_T2K) - include(${CMAKE_SOURCE_DIR}/cmake/T2KSetup.cmake) - cmessage(STATUS "Using T2K Reweight engine.") - set(USE_T2K TRUE CACHE BOOL "Whether to enable T2KReWeight support. Requires external libraries. " FORCE) -endif() -################################## MINERvA ###################################### -if(USE_MINERvA_RW) - include(${CMAKE_SOURCE_DIR}/cmake/MINERvASetup.cmake) - cmessage(STATUS "Using MINERvA Reweight engine.") - set(USE_MINERvA_RW TRUE CACHE BOOL "Whether to enable MINERvA ReWeight support. " FORCE) -endif() ################################################################################ ################################ Prob3++ #################################### include(${CMAKE_SOURCE_DIR}/cmake/Prob3++Setup.cmake) ################################################################################ cmessage(STATUS "Reweight engine include directories: ${RWENGINE_INCLUDE_DIRECTORIES}") if(NEED_ROOTEVEGEN) cmessage(STATUS "Require ROOT eve generation libraries") LIST(REVERSE ROOT_LIBS) LIST(APPEND ROOT_LIBS Gui Ged Geom TreePlayer EG Eve) LIST(REVERSE ROOT_LIBS) endif() if(NEED_ROOTPYTHIA6) cmessage(STATUS "Require ROOT Pythia6 libraries") LIST(APPEND ROOT_LIBS EGPythia6 Pythia6) endif() LIST(APPEND EXTRA_LIBS ${ROOT_LIBS}) diff --git a/cmake/c++CompilerSetup.cmake b/cmake/c++CompilerSetup.cmake index 054661b..266b708 100644 --- a/cmake/c++CompilerSetup.cmake +++ b/cmake/c++CompilerSetup.cmake @@ -1,97 +1,109 @@ # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret ################################################################################ # This file is part of NUISANCE. # # NUISANCE is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # NUISANCE is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with NUISANCE. If not, see . ################################################################################ if(USE_OMP) LIST(APPEND EXTRA_CXX_FLAGS -fopenmp) endif() +if(USE_DYNSAMPLES) + LIST(APPEND EXTRA_LIBS dl) + LIST(APPEND EXTRA_CXX_FLAGS -D__USE_DYNSAMPLES__) +endif() + set(CXX_WARNINGS -Wall ) cmessage(DEBUG "EXTRA_CXX_FLAGS: ${EXTRA_CXX_FLAGS}") string(REPLACE ";" " " STR_EXTRA_CXX_FLAGS "${EXTRA_CXX_FLAGS}") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${STR_EXTRA_CXX_FLAGS} ${CXX_WARNINGS}") - + set(CMAKE_Fortran_FLAGS_RELEASE "-fPIC") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0") + +if(USE_DYNSAMPLES) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fPIC") + set(CMAKE_Fortran_FLAGS_DEBUG "-fPIC") +endif() + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fPIC -O3") if(CMAKE_BUILD_TYPE MATCHES DEBUG) set(CURRENT_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_DEBUG}) elseif(CMAKE_BUILD_TYPE MATCHES RELEASE) set(CURRENT_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS_RELEASE}) else() cmessage(FATAL_ERROR "[ERROR]: Unknown CMAKE_BUILD_TYPE (\"${CMAKE_BUILD_TYPE}\"): Should be \"DEBUG\" or \"RELEASE\".") endif() SET(STR_EXTRA_LINK_DIRS) if(NOT EXTRA_LINK_DIRS STREQUAL "") string(REPLACE ";" " -L" STR_EXTRA_LINK_DIRS "-L${EXTRA_LINK_DIRS}") endif() SET(STR_EXTRA_LIBS) if(NOT EXTRA_LIBS STREQUAL "") string(REPLACE ";" " -l" STR_EXTRA_LIBS "-l${EXTRA_LIBS}") endif() SET(STR_EXTRA_SHAREDOBJS) if(NOT EXTRA_SHAREDOBJS STREQUAL "") string(REPLACE ";" " " STR_EXTRA_SHAREDOBJS "${EXTRA_SHAREDOBJS}") endif() + SET(STR_EXTRA_LINK_FLAGS) if(NOT EXTRA_LINK_FLAGS STREQUAL "") string(REPLACE ";" " " STR_EXTRA_LINK_FLAGS "${EXTRA_LINK_FLAGS}") endif() cmessage(DEBUG "EXTRA_LINK_DIRS: ${STR_EXTRA_LINK_DIRS}") cmessage(DEBUG "EXTRA_LIBS: ${STR_EXTRA_LIBS}") cmessage(DEBUG "EXTRA_SHAREDOBJS: ${STR_EXTRA_SHAREDOBJS}") cmessage(DEBUG "EXTRA_LINK_FLAGS: ${STR_EXTRA_LINK_FLAGS}") if(NOT STR_EXTRA_LINK_DIRS STREQUAL "" AND NOT STR_EXTRA_LIBS STREQUAL "") SET(CMAKE_DEPENDLIB_FLAGS "${STR_EXTRA_LINK_DIRS} ${STR_EXTRA_LIBS}") endif() if(NOT EXTRA_SHAREDOBJS STREQUAL "") if(NOT STR_EXTRA_LINK_FLAGS STREQUAL "") SET(STR_EXTRA_LINK_FLAGS "${STR_EXTRA_SHAREDOBJS} ${STR_EXTRA_LINK_FLAGS}") else() SET(STR_EXTRA_LINK_FLAGS "${STR_EXTRA_SHAREDOBJS}") endif() endif() if(NOT EXTRA_LINK_FLAGS STREQUAL "") if(NOT CMAKE_LINK_FLAGS STREQUAL "") SET(CMAKE_LINK_FLAGS "${CMAKE_LINK_FLAGS} ${STR_EXTRA_LINK_FLAGS}") else() SET(CMAKE_LINK_FLAGS "${STR_EXTRA_LINK_FLAGS}") endif() endif() if(USE_OMP) cmessage(FATAL_ERROR "No OMP features currently enabled so this is a FATAL_ERROR to let you know that you don't gain anything with this declaration.") endif() if (VERBOSE) cmessage (STATUS "C++ Compiler : ${CXX_COMPILER_NAME}") cmessage (STATUS " flags : ${CMAKE_CXX_FLAGS}") cmessage (STATUS " Release flags : ${CMAKE_CXX_FLAGS_RELEASE}") cmessage (STATUS " Debug flags : ${CMAKE_CXX_FLAGS_DEBUG}") cmessage (STATUS " Link Flags : ${CMAKE_LINK_FLAGS}") cmessage (STATUS " Lib Flags : ${CMAKE_DEPENDLIB_FLAGS}") endif() diff --git a/cmake/cacheVariables.cmake b/cmake/cacheVariables.cmake index 1c75a96..94d4019 100644 --- a/cmake/cacheVariables.cmake +++ b/cmake/cacheVariables.cmake @@ -1,208 +1,213 @@ # 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(EXTRA_SETUP_SCRIPT "" PATH "The path to an extra script to inject into the NUISANCE setup script. <>") + CheckAndSetDefaultCache(USE_MINIMIZER TRUE INTERNAL "Whether we are using the ROOT minimization libraries. ") 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...). ") +CheckAndSetDefaultCache(USE_DYNSAMPLES FALSE BOOL "Whether to enable the dynamic sample loader. ") + CheckAndSetDefault(NO_EXPERIMENTS FALSE) cmessage(STATUS "NO_EXPERIMENTS: ${NO_EXPERIMENTS}") CheckAndSetDefaultCache(NO_ANL ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build ANL samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_ArgoNeuT ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build ArgoNeuT samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_BEBC ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build BEBC samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_BNL ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build BNL samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_FNAL ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build FNAL samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_GGM ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build GGM samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_K2K ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build K2K samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_MINERvA ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build MINERvA samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_MiniBooNE ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build MiniBooNE samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_T2K ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build T2K samples. <-DNO_EXPERIMENTS=FALSE>") CheckAndSetDefaultCache(NO_SciBooNE ${NO_EXPERIMENTS} BOOL "Whether to *NOT* build SciBooNE samples. <-DNO_EXPERIMENTS=FALSE>") function(SAYVARS) LIST(APPEND VARS USE_HEPMC HEPMC HEPMC_MOMUNIT HEPMC_LENUNIT HEPMC_USED_EP USE_NEUT NEUT_ROOT CERN CERN_LEVEL USE_NuWro NUWRO NUWRO_INC NUWRO_INPUT_FILE NUWRO_BUILT_FROM_FILE USE_GENIE GENIE LHAPDF_LIB LHAPDF_INC LIBXML2_LIB LIBXML2_INC LOG4CPP_LIB GENIE_LOG4CPP_INC BUILD_GEVGEN USE_T2K USE_NIWG USE_GiBUU BUILD_GiBUU USE_NUANCE NO_EXTERNAL_UPDATE USE_GPERFTOOLS NO_ANL NO_ArgoNeuT NO_BEBC NO_BNL NO_FNAL NO_GGM NO_K2K NO_MINERvA NO_MiniBooNE NO_T2K NO_SciBooNE) foreach(v ${VARS}) if(DEFINED ${v}) cmessage(DEBUG "VARIABLE: \"${v}\" = \"${${v}}\"") endif() endforeach(v) endfunction() diff --git a/cmake/docsSetup.cmake b/cmake/docsSetup.cmake index abe7f9f..618a51f 100644 --- a/cmake/docsSetup.cmake +++ b/cmake/docsSetup.cmake @@ -1,43 +1,43 @@ # 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 . ################################################################################ # add a target to generate API documentation with Doxygen find_package(Doxygen) if(DOXYGEN_FOUND) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc) configure_file(${CMAKE_SOURCE_DIR}/doc/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/doc/Doxyfile @ONLY) add_custom_target(doc_generate ${DOXYGEN_EXECUTABLE} ${CMAKE_BINARY_DIR}/doc/Doxyfile WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/doc COMMENT "Generating documentation with Doxygen... (this will take a while)" VERBATIM ) add_custom_target(docs make WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/doc/latex COMMENT "Building latex documentation with Doxygen... (this will also take a while)" VERBATIM ) add_dependencies(docs doc_generate) install(FILES ${CMAKE_BINARY_DIR}/doc/latex/refman.pdf DESTINATION ${CMAKE_BINARY_DIR}/doc - RENAME ExtFit_${NUISANCE_VERSION_STRING}.pdf OPTIONAL) + RENAME NUISANCE_${NUISANCE_VERSION_STRING}.pdf OPTIONAL) endif(DOXYGEN_FOUND) diff --git a/cmake/setup.sh.in b/cmake/setup.sh.in index f5ef12e..2fbbe90 100644 --- a/cmake/setup.sh.in +++ b/cmake/setup.sh.in @@ -1,134 +1,155 @@ # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret ################################################################################ # This file is part of NUISANCE. # # NUISANCE is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # NUISANCE is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with NUISANCE. If not, see . ################################################################################ #!/bin/sh -if ! [[ ":$PATH:" == *":@CMAKE_INSTALL_PREFIX@/bin:"* ]]; then - export PATH=@CMAKE_INSTALL_PREFIX@/bin:$PATH -fi -if ! [[ ":$LD_LIBRARY_PATH:" == *":@CMAKE_INSTALL_PREFIX@/lib:"* ]]; then - export LD_LIBRARY_PATH=@CMAKE_INSTALL_PREFIX@/lib:$LD_LIBRARY_PATH +### Adapted from https://unix.stackexchange.com/questions/4965/keep-duplicates-out-of-path-on-source +function add_to_PATH () { + for d; do + + d=$(cd -- "$d" && { pwd -P || pwd; }) 2>/dev/null # canonicalize symbolic links + if [ -z "$d" ]; then continue; fi # skip nonexistent directory + + if [ "$d" == "/usr/bin" ] || [ "$d" == "/usr/bin64" ] || [ "$d" == "/usr/local/bin" ] || [ "$d" == "/usr/local/bin64" ]; then + case ":$PATH:" in + *":$d:"*) :;; + *) export PATH=$PATH:$d;; + esac + else + case ":$PATH:" in + *":$d:"*) :;; + *) export PATH=$d:$PATH;; + esac + fi + done +} + +function add_to_LD_LIBRARY_PATH () { + for d; do + + d=$(cd -- "$d" && { pwd -P || pwd; }) 2>/dev/null # canonicalize symbolic links + if [ -z "$d" ]; then continue; fi # skip nonexistent directory + + if [ "$d" == "/usr/lib" ] || [ "$d" == "/usr/lib64" ] || [ "$d" == "/usr/local/lib" ] || [ "$d" == "/usr/local/lib64" ]; then + case ":$LD_LIBRARY_PATH:" in + *":$d:"*) :;; + *) export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$d;; + esac + else + case ":$LD_LIBRARY_PATH:" in + *":$d:"*) :;; + *) export LD_LIBRARY_PATH=$d:$LD_LIBRARY_PATH;; + esac + fi + done +} + +if [ "@EXTRA_SETUP_SCRIPT@" ]; then + if [ ! -e @EXTRA_SETUP_SCRIPT@ ]; then + echo "[WARN]: Extra setup script \"@EXTRA_SETUP_SCRIPT@\" requested, but could not be found. Skipping..." + else + echo "[INFO]: Sourcing extra setup from \"@EXTRA_SETUP_SCRIPT@\"." + . @EXTRA_SETUP_SCRIPT@ + fi fi -if [[ ! "${ROOTSYS}" ]]; then +add_to_PATH "@CMAKE_INSTALL_PREFIX@/bin" + +add_to_LD_LIBRARY_PATH "@CMAKE_INSTALL_PREFIX@/lib" + +if [ ! "${ROOTSYS}" ]; then echo "[INFO]: Sourcing ROOT from: @CMAKE_ROOTSYS@" source "@CMAKE_ROOTSYS@/bin/thisroot.sh" fi +if [ "@USE_T2K@" != "FALSE" ]; then + echo "[INFO]: Adding T2K paths to the environment." + export T2KREWEIGHT=@T2KREWEIGHT@ + add_to_LD_LIBRARY_PATH "@T2KREWEIGHT@/lib" +fi -if [[ "@USE_NEUT@" != "FALSE" ]]; then +if [ "@USE_NIWG@" != "FALSE" ]; then + echo "[INFO]: Adding NIWG paths to the environment." + export NIWG=@NIWG_ROOT@ + export NIWGREWEIGHT_INPUTS=@NIWG_ROOT@/inputs + add_to_LD_LIBRARY_PATH "@NIWG_ROOT@" +fi + +if [ "@USE_NEUT@" != "FALSE" ]; then echo "[INFO]: Adding NEUT library paths to the environment." export NEUT_ROOT=@NEUT_ROOT@ export CERN=@CERN@ export CERN_LEVEL=@CERN_LEVEL@ - if ! [[ ":$LD_LIBRARY_PATH:" == *":${NEUT_ROOT}/lib/Linux_pc:"* ]]; then - export LD_LIBRARY_PATH=${NEUT_ROOT}/lib/Linux_pc:$LD_LIBRARY_PATH - fi - if ! [[ ":$LD_LIBRARY_PATH:" == *":${NEUT_ROOT}/src/reweight:"* ]]; then - export LD_LIBRARY_PATH=${NEUT_ROOT}/src/reweight:$LD_LIBRARY_PATH - fi + add_to_LD_LIBRARY_PATH "${NEUT_ROOT}/lib/Linux_pc" "${NEUT_ROOT}/src/reweight" fi -if [[ "@USE_NuWro@" != "FALSE" ]]; then - if [[ "@NUWRO_BUILT_FROM_FILE@" == "FALSE" ]]; then +if [ "@USE_NuWro@" != "FALSE" ]; then + if [ "@NUWRO_BUILT_FROM_FILE@" == "FALSE" ]; then echo "[INFO]: Adding NuWro library paths to the environment." export NUWRO="@NUWRO@" - if ! [[ ":$LD_LIBRARY_PATH:" == *":@NUWRO@/build/@CMAKE_SYSTEM_NAME@/lib:"* ]]; then - export LD_LIBRARY_PATH=@NUWRO@/build/@CMAKE_SYSTEM_NAME@/lib:$LD_LIBRARY_PATH - fi - if [[ "@NUWRO_INC@" ]]; then + add_to_PATH "@NUWRO@/bin" + add_to_LD_LIBRARY_PATH "@NUWRO@/build/@CMAKE_SYSTEM_NAME@/lib" + + if [ "@NUWRO_INC@" ]; then export NUWRO_INC=@NUWRO_INC@ fi + else echo "[INFO]: NuWro support included from input event file." fi fi -if [[ "@NEED_PYTHIA6@" != "FALSE" ]]; then +if [ "@NEED_PYTHIA6@" != "FALSE" ]; then echo "[INFO]: Adding PYTHIA6 library paths to the environment." export PYTHIA6="@PYTHIA6@" - if ! [[ ":$LD_LIBRARY_PATH:" == *":@PYTHIA6@:"* ]]; then - export LD_LIBRARY_PATH=@PYTHIA6@:$LD_LIBRARY_PATH - fi + + add_to_LD_LIBRARY_PATH "@PYTHIA6@" fi -if [[ "@USE_GENIE@" != "FALSE" ]]; then +if [ "@USE_GENIE@" != "FALSE" ]; then echo "[INFO]: Adding GENIE paths to the environment." export GENIE="@GENIE@" export LHAPDF_LIB="@LHAPDF_LIB@" export LHAPDF_INC="@LHAPDF_INC@" export LIBXML2_LIB="@LIBXML2_LIB@" export LIBXML2_INC="@LIBXML2_INC@" export LOG4CPP_LIB="@LOG4CPP_LIB@" export LOG4CPP_INC="@LOG4CPP_INC@" - if [[ "@LHAPATH@" ]]; then + if [ "@LHAPATH@" ]; then export LHAPATH="@LHAPATH@" fi - if ! [[ ":$PATH:" == *":@GENIE@/bin:"* ]]; then - export PATH=@GENIE@/bin:$PATH - fi - - if ! [[ ":$LD_LIBRARY_PATH:" == *":@GENIE@/lib:"* ]]; then - export LD_LIBRARY_PATH=@GENIE@/lib:$LD_LIBRARY_PATH - fi + add_to_PATH "@GENIE@/bin" - if ! [[ ":$LD_LIBRARY_PATH:" == *":@LHAPDF_LIB@:"* ]]; then - export LD_LIBRARY_PATH=@LHAPDF_LIB@:$LD_LIBRARY_PATH - fi - - if ! [[ ":$LD_LIBRARY_PATH:" == *":@LIBXML2_LIB@:"* ]]; then - export LD_LIBRARY_PATH=@LIBXML2_LIB@:$LD_LIBRARY_PATH - fi - - if ! [[ ":$LD_LIBRARY_PATH:" == *":@LOG4CPP_LIB@:"* ]]; then - export LD_LIBRARY_PATH=@LOG4CPP_LIB@:$LD_LIBRARY_PATH - fi -fi + add_to_LD_LIBRARY_PATH "@GENIE@/lib" "@LHAPDF_LIB@" "@LIBXML2_LIB@" "@LOG4CPP_LIB@" -if [[ "@USE_NIWG@" != "FALSE" ]]; then - echo "[INFO]: Adding NIWG paths to the environment." - export NIWG=@NIWG_ROOT@ - export NIWGREWEIGHT_INPUTS=@NIWG_ROOT@/inputs - if ! [[ ":$LD_LIBRARY_PATH:" == *":@NIWG_ROOT@:"* ]]; then - export LD_LIBRARY_PATH=${NIWG}:${LD_LIBRARY_PATH} - fi - -fi - -if [[ "@USE_T2K@" != "FALSE" ]]; then - echo "[INFO]: Adding T2K paths to the environment." - export T2KREWEIGHT=@T2KREWEIGHT@ - if ! [[ ":$LD_LIBRARY_PATH:" == *":@T2KREWEIGHT@/lib:"* ]]; then - export LD_LIBRARY_PATH=${T2KREWEIGHT}/lib:${LD_LIBRARY_PATH} - fi fi -if [[ "@BUILD_GiBUU@" != "FALSE" ]]; then +if [ "@BUILD_GiBUU@" != "FALSE" ]; then echo "[INFO]: Sourcing GiBUU tools." source @CMAKE_BINARY_DIR@/GiBUUTools/src/GiBUUTools-build/Linux/setup.sh fi export NUISANCE="@CMAKE_SOURCE_DIR@" diff --git a/data/ANL/ANL_Data_PRD26_537.root b/data/ANL/ANL_Data_PRD26_537.root index 29fec1a..965ec79 100644 Binary files a/data/ANL/ANL_Data_PRD26_537.root and b/data/ANL/ANL_Data_PRD26_537.root differ diff --git a/data/BNL/BNL_Data_PRD23_2499.root b/data/BNL/BNL_Data_PRD23_2499.root index b666e3a..101e558 100755 Binary files a/data/BNL/BNL_Data_PRD23_2499.root and b/data/BNL/BNL_Data_PRD23_2499.root differ diff --git a/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_Delta_pi_phi_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_Delta_pi_phi_xsec.csv new file mode 100755 index 0000000..de6ad46 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_Delta_pi_phi_xsec.csv @@ -0,0 +1,8 @@ +1.0000 0.7551 0.7954 0.4031 0.6946 0.6541 0.5751 0.8834 +0.7551 1.0000 0.8918 0.5419 0.7185 0.7853 0.6566 0.8065 +0.7954 0.8918 1.0000 0.5994 0.7319 0.7890 0.6980 0.8104 +0.4031 0.5419 0.5994 1.0000 0.7704 0.7303 0.7335 0.6346 +0.6946 0.7185 0.7319 0.7704 1.0000 0.6866 0.6478 0.7405 +0.6541 0.7853 0.7890 0.7303 0.6866 1.0000 0.7989 0.7732 +0.5751 0.6566 0.6980 0.7335 0.6478 0.7989 1.0000 0.7237 +0.8834 0.8065 0.8104 0.6346 0.7405 0.7732 0.7237 1.0000 diff --git a/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_Delta_pi_theta_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_Delta_pi_theta_xsec.csv new file mode 100755 index 0000000..9d1b8d2 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_Delta_pi_theta_xsec.csv @@ -0,0 +1,10 @@ +1.0000 0.8270 0.7806 0.8058 0.7789 0.6888 0.5792 0.3831 0.2354 0.2427 +0.8270 1.0000 0.9103 0.8787 0.7744 0.7824 0.6199 0.4824 0.2403 0.2507 +0.7806 0.9103 1.0000 0.8994 0.7570 0.7543 0.6495 0.5182 0.2264 0.2536 +0.8058 0.8787 0.8994 1.0000 0.8506 0.8027 0.6888 0.5938 0.4161 0.3540 +0.7789 0.7744 0.7570 0.8506 1.0000 0.9164 0.8352 0.6761 0.4859 0.4205 +0.6888 0.7824 0.7543 0.8027 0.9164 1.0000 0.8555 0.7058 0.4772 0.4954 +0.5792 0.6199 0.6495 0.6888 0.8352 0.8555 1.0000 0.7957 0.6591 0.6767 +0.3831 0.4824 0.5182 0.5938 0.6761 0.7058 0.7957 1.0000 0.8844 0.7545 +0.2354 0.2403 0.2264 0.4161 0.4859 0.4772 0.6591 0.8844 1.0000 0.8149 +0.2427 0.2507 0.2536 0.3540 0.4205 0.4954 0.6767 0.7545 0.8149 1.0000 diff --git a/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_Enu_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_Enu_xsec.csv new file mode 100755 index 0000000..60244ea --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_Enu_xsec.csv @@ -0,0 +1,10 @@ +1.0000 0.6649 -0.0840 -0.3894 -0.1217 0.1483 0.1622 0.0765 0.1177 -0.4642 +0.6649 1.0000 0.5805 0.2108 0.2546 0.2290 0.2183 0.2061 0.1711 -0.1266 +-0.0840 0.5805 1.0000 0.8601 0.5748 -0.0079 -0.0461 0.0101 -0.0786 0.0647 +-0.3894 0.2108 0.8601 1.0000 0.7304 0.0151 -0.0804 -0.0500 -0.1120 0.1627 +-0.1217 0.2546 0.5748 0.7304 1.0000 0.5583 0.4139 0.3710 0.3083 0.3293 +0.1483 0.2290 -0.0079 0.0151 0.5583 1.0000 0.8416 0.7116 0.7865 0.5736 +0.1622 0.2183 -0.0461 -0.0804 0.4139 0.8416 1.0000 0.8929 0.8941 0.5991 +0.0765 0.2061 0.0101 -0.0500 0.3710 0.7116 0.8929 1.0000 0.8905 0.6844 +0.1177 0.1711 -0.0786 -0.1120 0.3083 0.7865 0.8941 0.8905 1.0000 0.6809 +-0.4642 -0.1266 0.0647 0.1627 0.3293 0.5736 0.5991 0.6844 0.6809 1.0000 diff --git a/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_QSq_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_QSq_xsec.csv new file mode 100755 index 0000000..541b83d --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_QSq_xsec.csv @@ -0,0 +1,8 @@ +1.0000 0.8945 0.6991 0.4436 0.0654 -0.1590 -0.2359 -0.3167 +0.8945 1.0000 0.8540 0.5864 0.1982 -0.0762 -0.2024 -0.3814 +0.6991 0.8540 1.0000 0.8524 0.5658 0.3308 0.2144 -0.0223 +0.4436 0.5864 0.8524 1.0000 0.7953 0.6330 0.5405 0.3327 +0.0654 0.1982 0.5658 0.7953 1.0000 0.9043 0.8283 0.6956 +-0.1590 -0.0762 0.3308 0.6330 0.9043 1.0000 0.9436 0.8575 +-0.2359 -0.2024 0.2144 0.5405 0.8283 0.9436 1.0000 0.9176 +-0.3167 -0.3814 -0.0223 0.3327 0.6956 0.8575 0.9176 1.0000 diff --git a/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_QSq_xsec_HighEnu.csv b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_QSq_xsec_HighEnu.csv new file mode 100755 index 0000000..959a47c --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_QSq_xsec_HighEnu.csv @@ -0,0 +1,8 @@ +1.0000 0.7545 0.5531 0.4876 0.1916 0.1307 -0.0911 -0.1402 +0.7545 1.0000 0.8116 0.6338 0.3504 0.1632 -0.2233 -0.4114 +0.5531 0.8116 1.0000 0.8450 0.6544 0.4504 0.2069 -0.0653 +0.4876 0.6338 0.8450 1.0000 0.7552 0.5296 0.3665 0.0508 +0.1916 0.3504 0.6544 0.7552 1.0000 0.7792 0.6410 0.4757 +0.1307 0.1632 0.4504 0.5296 0.7792 1.0000 0.7405 0.6436 +-0.0911 -0.2233 0.2069 0.3665 0.6410 0.7405 1.0000 0.8252 +-0.1402 -0.4114 -0.0653 0.0508 0.4757 0.6436 0.8252 1.0000 diff --git a/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_QSq_xsec_LowEnu.csv b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_QSq_xsec_LowEnu.csv new file mode 100755 index 0000000..d228c80 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_QSq_xsec_LowEnu.csv @@ -0,0 +1,8 @@ +1.0000 0.9016 0.6036 0.2085 -0.0665 -0.3070 -0.3550 0.2579 +0.9016 1.0000 0.7653 0.3268 0.0832 -0.2120 -0.3315 0.2850 +0.6036 0.7653 1.0000 0.6999 0.5061 0.2409 0.1604 0.0542 +0.2085 0.3268 0.6999 1.0000 0.8694 0.7126 0.6587 0.0023 +-0.0665 0.0832 0.5061 0.8694 1.0000 0.8523 0.7616 0.0408 +-0.3070 -0.2120 0.2409 0.7126 0.8523 1.0000 0.8315 -0.0658 +-0.3550 -0.3315 0.1604 0.6587 0.7616 0.8315 1.0000 -0.1999 +0.2579 0.2850 0.0542 0.0023 0.0408 -0.0658 -0.1999 1.0000 diff --git a/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_W_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_W_xsec.csv new file mode 100755 index 0000000..9d32f17 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_W_xsec.csv @@ -0,0 +1,10 @@ +1.0000 0.9571 0.8665 0.4905 -0.1848 -0.3564 -0.3660 -0.3962 -0.4097 -0.5517 +0.9571 1.0000 0.9431 0.5882 -0.1706 -0.3473 -0.3543 -0.3706 -0.3780 -0.5264 +0.8665 0.9431 1.0000 0.7623 -0.0371 -0.2673 -0.2732 -0.2847 -0.3114 -0.4568 +0.4905 0.5882 0.7623 1.0000 0.5270 0.2171 0.1687 0.1231 0.0279 -0.1392 +-0.1848 -0.1706 -0.0371 0.5270 1.0000 0.8933 0.8036 0.7155 0.5933 0.4032 +-0.3564 -0.3473 -0.2673 0.2171 0.8933 1.0000 0.9557 0.8984 0.8123 0.5995 +-0.3660 -0.3543 -0.2732 0.1687 0.8036 0.9557 1.0000 0.9764 0.9005 0.6547 +-0.3962 -0.3706 -0.2847 0.1231 0.7155 0.8984 0.9764 1.0000 0.9613 0.7555 +-0.4097 -0.3780 -0.3114 0.0279 0.5933 0.8123 0.9005 0.9613 1.0000 0.8713 +-0.5517 -0.5264 -0.4568 -0.1392 0.4032 0.5995 0.6547 0.7555 0.8713 1.0000 diff --git a/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_deltaInvMass_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_deltaInvMass_xsec.csv new file mode 100755 index 0000000..9566fee --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_deltaInvMass_xsec.csv @@ -0,0 +1,8 @@ +1.0000 0.9756 0.8176 0.3901 0.1345 0.1264 -0.2020 -0.2446 +0.9756 1.0000 0.8982 0.4595 0.2186 0.2456 -0.1020 -0.2136 +0.8176 0.8982 1.0000 0.6937 0.5074 0.4992 0.1744 -0.0506 +0.3901 0.4595 0.6937 1.0000 0.9013 0.7926 0.6489 0.3860 +0.1345 0.2186 0.5074 0.9013 1.0000 0.9176 0.8379 0.6175 +0.1264 0.2456 0.4992 0.7926 0.9176 1.0000 0.8240 0.5351 +-0.2020 -0.1020 0.1744 0.6489 0.8379 0.8240 1.0000 0.8508 +-0.2446 -0.2136 -0.0506 0.3860 0.6175 0.5351 0.8508 1.0000 diff --git a/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_deltaInvMass_xsec_DeltaRich.csv b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_deltaInvMass_xsec_DeltaRich.csv new file mode 100755 index 0000000..b117948 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_deltaInvMass_xsec_DeltaRich.csv @@ -0,0 +1,7 @@ +1.0000 0.9251 0.6374 0.1129 -0.1836 0.0957 0.0379 +0.9251 1.0000 0.8207 0.2414 -0.1515 -0.0040 -0.0950 +0.6374 0.8207 1.0000 0.6146 0.2096 0.0140 -0.1690 +0.1129 0.2414 0.6146 1.0000 0.8227 0.4101 0.2648 +-0.1836 -0.1515 0.2096 0.8227 1.0000 0.6932 0.5369 +0.0957 -0.0040 0.0140 0.4101 0.6932 1.0000 0.9123 +0.0379 -0.0950 -0.1690 0.2648 0.5369 0.9123 1.0000 diff --git a/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_muon_P_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_muon_P_xsec.csv new file mode 100755 index 0000000..1591e98 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_muon_P_xsec.csv @@ -0,0 +1,8 @@ +1.0000 0.9011 0.5251 -0.1997 -0.3380 -0.2946 0.0947 0.0649 +0.9011 1.0000 0.7950 0.1666 -0.0016 0.0141 0.3061 0.3013 +0.5251 0.7950 1.0000 0.6962 0.5666 0.5397 0.4964 0.5433 +-0.1997 0.1666 0.6962 1.0000 0.9645 0.8862 0.4821 0.5288 +-0.3380 -0.0016 0.5666 0.9645 1.0000 0.9274 0.4699 0.4946 +-0.2946 0.0141 0.5397 0.8862 0.9274 1.0000 0.6831 0.5986 +0.0947 0.3061 0.4964 0.4821 0.4699 0.6831 1.0000 0.8371 +0.0649 0.3013 0.5433 0.5288 0.4946 0.5986 0.8371 1.0000 diff --git a/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_muon_theta_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_muon_theta_xsec.csv new file mode 100755 index 0000000..42a3260 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_muon_theta_xsec.csv @@ -0,0 +1,9 @@ +1.0000 0.9606 0.8724 0.8064 0.6734 0.6045 0.5072 0.3725 0.3390 +0.9606 1.0000 0.9321 0.8605 0.7530 0.6807 0.5862 0.4658 0.3859 +0.8724 0.9321 1.0000 0.9658 0.8941 0.8512 0.7746 0.6424 0.5572 +0.8064 0.8605 0.9658 1.0000 0.9510 0.9136 0.8551 0.7398 0.6752 +0.6734 0.7530 0.8941 0.9510 1.0000 0.9678 0.9460 0.8817 0.7909 +0.6045 0.6807 0.8512 0.9136 0.9678 1.0000 0.9793 0.9030 0.8459 +0.5072 0.5862 0.7746 0.8551 0.9460 0.9793 1.0000 0.9456 0.8884 +0.3725 0.4658 0.6424 0.7398 0.8817 0.9030 0.9456 1.0000 0.9509 +0.3390 0.3859 0.5572 0.6752 0.7909 0.8459 0.8884 0.9509 1.0000 diff --git a/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_pi0_KE_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_pi0_KE_xsec.csv new file mode 100755 index 0000000..95b06c4 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_pi0_KE_xsec.csv @@ -0,0 +1,7 @@ +1.0000 0.7498 0.2174 0.0613 0.2618 0.2688 0.1138 +0.7498 1.0000 0.7250 0.6070 0.6531 0.5901 0.4528 +0.2174 0.7250 1.0000 0.9347 0.8606 0.8006 0.7595 +0.0613 0.6070 0.9347 1.0000 0.9055 0.8161 0.7710 +0.2618 0.6531 0.8606 0.9055 1.0000 0.9267 0.7907 +0.2688 0.5901 0.8006 0.8161 0.9267 1.0000 0.8417 +0.1138 0.4528 0.7595 0.7710 0.7907 0.8417 1.0000 diff --git a/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_pi0_theta_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_pi0_theta_xsec.csv new file mode 100755 index 0000000..346909a --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/corr/Correlation_Table_pi0_theta_xsec.csv @@ -0,0 +1,11 @@ +1.0000 0.9253 0.8221 0.7625 0.6427 0.5885 0.5511 0.3667 0.3621 0.4444 0.3518 +0.9253 1.0000 0.9120 0.8755 0.8134 0.7110 0.6719 0.5570 0.4676 0.5896 0.4649 +0.8221 0.9120 1.0000 0.9342 0.8194 0.7848 0.7212 0.6059 0.4937 0.5916 0.6029 +0.7625 0.8755 0.9342 1.0000 0.9165 0.8528 0.7988 0.7193 0.5874 0.7408 0.7605 +0.6427 0.8134 0.8194 0.9165 1.0000 0.8883 0.8523 0.7985 0.6443 0.7121 0.6585 +0.5885 0.7110 0.7848 0.8528 0.8883 1.0000 0.9515 0.8550 0.8100 0.7776 0.6797 +0.5511 0.6719 0.7212 0.7988 0.8523 0.9515 1.0000 0.9294 0.8821 0.8164 0.6432 +0.3667 0.5570 0.6059 0.7193 0.7985 0.8550 0.9294 1.0000 0.8974 0.8808 0.6651 +0.3621 0.4676 0.4937 0.5874 0.6443 0.8100 0.8821 0.8974 1.0000 0.7952 0.5143 +0.4444 0.5896 0.5916 0.7408 0.7121 0.7776 0.8164 0.8808 0.7952 1.0000 0.8277 +0.3518 0.4649 0.6029 0.7605 0.6585 0.6797 0.6432 0.6651 0.5143 0.8277 1.0000 diff --git a/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_Delta_pi_phi_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_Delta_pi_phi_xsec.csv new file mode 100755 index 0000000..3503235 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_Delta_pi_phi_xsec.csv @@ -0,0 +1,9 @@ +0.00 0.0140 34 +45.00 0.0118 34 +90.00 0.0125 30 +135.00 0.0209 21 +180.00 0.0225 20 +225.00 0.0198 22 +270.00 0.0202 23 +315.00 0.0175 29 +360.00 0.00 0.00 diff --git a/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_Delta_pi_theta_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_Delta_pi_theta_xsec.csv new file mode 100755 index 0000000..0cb5fab --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_Delta_pi_theta_xsec.csv @@ -0,0 +1,11 @@ +-1.00 3.86 21 +-0.80 2.92 22 +-0.60 2.70 25 +-0.40 2.92 23 +-0.20 2.95 23 +0.00 3.27 23 +0.20 3.06 25 +0.40 2.94 27 +0.60 3.39 29 +0.80 4.51 26 +1.00 0.00 0.00 diff --git a/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_Enu_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_Enu_xsec.csv new file mode 100755 index 0000000..929d2a9 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_Enu_xsec.csv @@ -0,0 +1,12 @@ +0.00 0.00 0 +1.50 11.80 19 +3.00 15.47 11 +3.50 15.47 13 +4.00 15.96 19 +5.00 20.77 18 +6.00 21.96 20 +8.00 31.90 18 +10.00 33.46 20 +12.00 25.30 23 +15.00 25.59 31 +20.00 0.00 0.00 diff --git a/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_QSq_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_QSq_xsec.csv new file mode 100755 index 0000000..c75662e --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_QSq_xsec.csv @@ -0,0 +1,9 @@ +0.00 9.04 19 +0.10 18.24 12 +0.25 19.02 10 +0.40 14.86 11 +0.60 11.27 12 +0.85 6.53 16 +1.15 4.65 19 +1.55 1.57 36 +2.00 0.00 0 diff --git a/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_QSq_xsec_HighEnu.csv b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_QSq_xsec_HighEnu.csv new file mode 100755 index 0000000..cc40458 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_QSq_xsec_HighEnu.csv @@ -0,0 +1,9 @@ +0.00 3.72 45 +0.10 10.37 19 +0.25 14.02 16 +0.40 11.94 15 +0.60 9.50 17 +0.85 6.66 20 +1.15 7.14 23 +1.55 3.07 42 +2.00 0.00 0.00 diff --git a/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_QSq_xsec_LowEnu.csv b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_QSq_xsec_LowEnu.csv new file mode 100755 index 0000000..3b6d60b --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_QSq_xsec_LowEnu.csv @@ -0,0 +1,9 @@ +0.00 10.28 19 +0.10 19.69 12 +0.25 21.64 12 +0.40 14.16 16 +0.60 10.97 20 +0.85 6.08 33 +1.15 2.34 60 +1.55 0.22 129 +2.00 0.00 0.00 diff --git a/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_W_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_W_xsec.csv new file mode 100755 index 0000000..87a3250 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_W_xsec.csv @@ -0,0 +1,11 @@ +0.60 0.72 50 +0.90 3.23 43 +1.00 11.01 24 +1.10 25.45 12 +1.20 29.45 10 +1.30 22.24 12 +1.40 17.82 12 +1.50 18.77 13 +1.60 16.66 15 +1.70 11.80 21 +1.80 0.00 0 diff --git a/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_deltaInvMass_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_deltaInvMass_xsec.csv new file mode 100755 index 0000000..5d423e8 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_deltaInvMass_xsec.csv @@ -0,0 +1,9 @@ +1.00 3.61 43 +1.10 26.38 24 +1.15 40.21 14 +1.20 43.36 11 +1.25 27.32 11 +1.30 15.74 12 +1.40 10.03 13 +1.60 3.45 25 +1.80 0.00 0 diff --git a/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_deltaInvMass_xsec_DeltaRich.csv b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_deltaInvMass_xsec_DeltaRich.csv new file mode 100755 index 0000000..296d3a3 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_deltaInvMass_xsec_DeltaRich.csv @@ -0,0 +1,8 @@ +1.00 2.05 60 +1.10 21.55 24 +1.15 32.67 15 +1.20 31.23 14 +1.25 15.37 18 +1.30 5.91 30 +1.40 2.06 57 +1.60 0.00 0.00 diff --git a/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_muon_P_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_muon_P_xsec.csv new file mode 100755 index 0000000..e0f3c01 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_muon_P_xsec.csv @@ -0,0 +1,9 @@ +1.00 3.55 21 +2.00 5.24 13 +2.50 5.08 10 +3.00 3.13 12 +3.50 1.82 14 +4.00 0.96 14 +5.00 0.55 15 +7.00 0.45 13 +10.00 0.00 0 diff --git a/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_muon_theta_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_muon_theta_xsec.csv new file mode 100755 index 0000000..5eee04c --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_muon_theta_xsec.csv @@ -0,0 +1,10 @@ +0.00 0.166 19 +2.00 0.488 12 +4.00 0.771 10 +6.00 0.846 10 +8.00 0.921 9 +10.00 0.856 10 +12.00 0.879 9 +16.00 0.830 11 +20.00 0.566 19 +25.00 0.00 0 diff --git a/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_pi0_KE_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_pi0_KE_xsec.csv new file mode 100755 index 0000000..993dc60 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_pi0_KE_xsec.csv @@ -0,0 +1,8 @@ +0.00 29.80 22 +0.05 42.78 11 +0.15 27.14 10 +0.25 16.95 10 +0.40 10.11 11 +0.55 7.96 11 +0.75 4.44 14 +1.00 0.00 0 diff --git a/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_pi0_theta_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_pi0_theta_xsec.csv new file mode 100755 index 0000000..a5fab8f --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/data/XSec_Table_pi0_theta_xsec.csv @@ -0,0 +1,12 @@ +0.00 0.039 30 +10.00 0.112 18 +20.00 0.175 14 +30.00 0.200 12 +40.00 0.169 12 +50.00 0.155 13 +60.00 0.149 13 +70.00 0.133 14 +80.00 0.077 19 +90.00 0.064 13 +120.00 0.028 13 +180.00 0.00 0.00 diff --git a/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_Delta_pi_phi_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_Delta_pi_phi_xsec.csv new file mode 100755 index 0000000..bdc638b --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_Delta_pi_phi_xsec.csv @@ -0,0 +1,10 @@ +Delta_pi_phi_xsec +Bin Min , Bin Max , Detector, X-Sec Model, FSI, Flux, Other, Total +0.00 , 45.00 , 4.8 , 6.2 , 13.2 , 3.2 , 2.2 , 15.9 +45.00 , 90.00 , 6.5 , 8.2 , 10.0 , 2.6 , 2.5 , 14.9 +90.00 , 135.00 , 5.2 , 6.6 , 8.5 , 2.8 , 2.2 , 12.5 +135.00 , 180.00 , 3.4 , 3.8 , 2.5 , 4.9 , 1.3 , 7.7 +180.00 , 225.00 , 2.8 , 3.9 , 4.6 , 4.5 , 1.3 , 8.2 +225.00 , 270.00 , 5.2 , 5.1 , 5.6 , 4.2 , 1.5 , 10.2 +270.00 , 315.00 , 3.3 , 4.4 , 3.8 , 4.6 , 1.5 , 8.3 +315.00 , 360.00 , 5.7 , 5.9 , 7.6 , 4.0 , 1.8 , 12.0 diff --git a/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_Delta_pi_theta_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_Delta_pi_theta_xsec.csv new file mode 100755 index 0000000..5e87a27 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_Delta_pi_theta_xsec.csv @@ -0,0 +1,12 @@ +Delta_pi_theta_xsec +Bin Min , Bin Max , Detector, X-Sec Model, FSI, Flux, Other, Total +-1.00 , -0.80 , 6.2 , 3.9 , 2.4 , 5.4 , 1.2 , 9.5 +-0.80 , -0.60 , 5.7 , 4.8 , 6.3 , 4.8 , 1.3 , 10.9 +-0.60 , -0.40 , 7.1 , 5.0 , 7.6 , 4.6 , 1.6 , 12.5 +-0.40 , -0.20 , 5.0 , 5.1 , 5.2 , 4.8 , 1.6 , 10.2 +-0.20 , 0.00 , 5.6 , 5.5 , 4.5 , 4.1 , 1.8 , 10.1 +0.00 , 0.20 , 4.3 , 5.5 , 4.4 , 3.7 , 1.7 , 9.2 +0.20 , 0.40 , 4.7 , 6.4 , 7.3 , 3.1 , 2.0 , 11.4 +0.40 , 0.60 , 6.7 , 6.3 , 9.2 , 3.0 , 2.1 , 13.5 +0.60 , 0.80 , 7.0 , 6.7 , 10.5 , 2.8 , 2.1 , 14.7 +0.80 , 1.00 , 5.5 , 6.7 , 7.5 , 3.8 , 1.8 , 12.2 diff --git a/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_Enu_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_Enu_xsec.csv new file mode 100755 index 0000000..6725496 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_Enu_xsec.csv @@ -0,0 +1,13 @@ +Enu_xsec +Bin Min , Bin Max , Detector, X-Sec Model, FSI, Flux, Other, Total +0.00 , 1.50 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , 0.0 +1.50 , 3.00 , 14.9 , 3.9 , 2.5 , 7.2 , 0.7 , 17.2 +3.00 , 3.50 , 4.7 , 3.8 , 1.8 , 5.4 , 0.7 , 8.4 +3.50 , 4.00 , 5.3 , 4.0 , 2.5 , 7.5 , 0.6 , 10.3 +4.00 , 5.00 , 8.7 , 4.8 , 3.4 , 12.9 , 0.4 , 16.7 +5.00 , 6.00 , 4.2 , 5.7 , 4.5 , 8.5 , 0.4 , 11.9 +6.00 , 8.00 , 5.0 , 8.4 , 6.6 , 9.4 , 0.1 , 15.1 +8.00 , 10.00 , 3.2 , 4.2 , 4.0 , 10.3 , 0.5 , 12.3 +10.00 , 12.00 , 4.5 , 4.3 , 3.7 , 10.2 , 0.6 , 12.6 +12.00 , 15.00 , 4.7 , 4.9 , 3.8 , 10.6 , 0.5 , 13.1 +15.00 , 20.00 , 17.0 , 7.0 , 6.3 , 13.4 , 0.2 , 23.6 diff --git a/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_QSq_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_QSq_xsec.csv new file mode 100755 index 0000000..d480185 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_QSq_xsec.csv @@ -0,0 +1,10 @@ +QSq_xsec +Bin Min , Bin Max , Detector, X-Sec Model, FSI, Flux, Other, Total +0.00 , 0.10 , 12.4 , 8.6 , 4.5 , 3.6 , 0.5 , 16.2 +0.10 , 0.25 , 7.2 , 4.2 , 3.1 , 4.4 , 0.6 , 9.9 +0.25 , 0.40 , 3.6 , 3.6 , 2.6 , 4.1 , 0.6 , 7.1 +0.40 , 0.60 , 3.3 , 3.3 , 2.9 , 4.0 , 0.5 , 6.8 +0.60 , 0.85 , 5.0 , 2.7 , 4.1 , 4.4 , 0.5 , 8.3 +0.85 , 1.15 , 7.7 , 4.5 , 4.4 , 4.3 , 0.5 , 10.8 +1.15 , 1.55 , 10.9 , 4.5 , 4.8 , 5.4 , 0.5 , 13.9 +1.55 , 2.00 , 24.2 , 9.2 , 10.7 , 6.8 , 0.2 , 28.8 diff --git a/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_QSq_xsec_HighEnu.csv b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_QSq_xsec_HighEnu.csv new file mode 100755 index 0000000..7f30aca --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_QSq_xsec_HighEnu.csv @@ -0,0 +1,10 @@ +QSq_xsec +Bin Min , Bin Max , Detector, X-Sec Model, FSI, Flux, Other, Total +0.00 , 0.10 , 18.5 , 20.6 , 8.7 , 3.8 , 2.6 , 29.4 +0.10 , 0.25 , 9.0 , 6.6 , 3.7 , 4.0 , 1.2 , 12.5 +0.25 , 0.40 , 3.9 , 4.3 , 4.1 , 4.7 , 1.2 , 8.6 +0.40 , 0.60 , 3.5 , 4.0 , 4.0 , 4.6 , 1.3 , 8.1 +0.60 , 0.85 , 4.3 , 2.6 , 4.5 , 4.4 , 1.3 , 8.2 +0.85 , 1.15 , 5.6 , 4.9 , 4.8 , 3.5 , 1.5 , 9.7 +1.15 , 1.55 , 10.4 , 4.9 , 5.0 , 4.2 , 1.4 , 13.3 +1.55 , 2.00 , 22.3 , 8.6 , 12.7 , 4.9 , 2.4 , 27.6 diff --git a/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_QSq_xsec_LowEnu.csv b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_QSq_xsec_LowEnu.csv new file mode 100755 index 0000000..46a4dc6 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_QSq_xsec_LowEnu.csv @@ -0,0 +1,10 @@ +QSq_xsec +Bin Min , Bin Max , Detector, X-Sec Model, FSI, Flux, Other, Total +0.00 , 0.10 , 10.8 , 7.6 , 4.8 , 3.5 , 0.5 , 14.5 +0.10 , 0.25 , 6.3 , 3.8 , 3.7 , 4.2 , 0.6 , 9.3 +0.25 , 0.40 , 3.1 , 3.5 , 3.0 , 4.0 , 0.6 , 6.9 +0.40 , 0.60 , 5.9 , 4.2 , 4.2 , 3.1 , 0.4 , 8.9 +0.60 , 0.85 , 8.0 , 4.0 , 5.6 , 3.6 , 0.5 , 11.2 +0.85 , 1.15 , 17.5 , 8.1 , 8.0 , 3.1 , 0.4 , 21.1 +1.15 , 1.55 , 33.4 , 10.2 , 11.3 , 3.2 , 0.4 , 36.8 +1.55 , 2.00 , 64.6 , 20.7 , 17.5 , 1.7 , 0.4 , 70.1 diff --git a/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_W_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_W_xsec.csv new file mode 100755 index 0000000..5749e9f --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_W_xsec.csv @@ -0,0 +1,12 @@ +W_xsec +Bin Min , Bin Max , Detector, X-Sec Model, FSI, Flux, Other, Total +0.60 , 0.90 , 35.5 , 10.0 , 12.3 , 4.1 , 0.4 , 39.1 +0.90 , 1.00 , 33.3 , 8.8 , 10.1 , 4.0 , 0.3 , 36.1 +1.00 , 1.10 , 17.8 , 4.8 , 7.4 , 3.6 , 0.4 , 20.2 +1.10 , 1.20 , 6.3 , 3.1 , 5.1 , 4.4 , 0.6 , 9.8 +1.20 , 1.30 , 5.1 , 3.8 , 3.2 , 4.6 , 0.6 , 8.5 +1.30 , 1.40 , 5.0 , 5.1 , 5.5 , 3.9 , 0.5 , 9.8 +1.40 , 1.50 , 5.1 , 6.2 , 5.4 , 3.5 , 0.5 , 10.3 +1.50 , 1.60 , 5.4 , 6.6 , 5.3 , 3.5 , 0.4 , 10.6 +1.60 , 1.70 , 6.5 , 7.5 , 6.3 , 3.2 , 0.4 , 12.2 +1.70 , 1.80 , 11.3 , 8.9 , 8.7 , 2.7 , 0.3 , 17.0 diff --git a/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_deltaInvMass_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_deltaInvMass_xsec.csv new file mode 100755 index 0000000..8802c0b --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_deltaInvMass_xsec.csv @@ -0,0 +1,10 @@ +deltaInvMass_xsec +Bin Min , Bin Max , Detector, X-Sec Model, FSI, Flux, Other, Total +1.00 , 1.10 , 21.7 , 14.2 , 12.2 , 4.1 , 2.9 , 29.1 +1.10 , 1.15 , 14.6 , 9.3 , 6.4 , 1.7 , 2.0 , 18.7 +1.15 , 1.20 , 7.1 , 5.2 , 3.2 , 3.5 , 1.4 , 10.0 +1.20 , 1.25 , 2.8 , 3.9 , 4.0 , 4.4 , 1.3 , 7.7 +1.25 , 1.30 , 3.4 , 3.5 , 3.0 , 4.3 , 1.5 , 7.3 +1.30 , 1.40 , 2.9 , 4.2 , 2.4 , 4.2 , 1.5 , 7.2 +1.40 , 1.60 , 5.0 , 4.7 , 2.3 , 4.4 , 1.3 , 8.6 +1.60 , 1.80 , 11.7 , 8.7 , 6.9 , 2.5 , 1.8 , 16.5 diff --git a/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_deltaInvMass_xsec_DeltaRich.csv b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_deltaInvMass_xsec_DeltaRich.csv new file mode 100755 index 0000000..5274c90 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_deltaInvMass_xsec_DeltaRich.csv @@ -0,0 +1,9 @@ +deltaInvMass_xsec +Bin Min , Bin Max , Detector, X-Sec Model, FSI, Flux, Other, Total +1.00 , 1.10 , 26.6 , 14.5 , 14.2 , 2.9 , 4.2 , 33.9 +1.10 , 1.15 , 13.7 , 5.9 , 5.4 , 3.4 , 2.0 , 16.3 +1.15 , 1.20 , 6.1 , 3.2 , 3.7 , 5.6 , 1.2 , 9.7 +1.20 , 1.25 , 3.1 , 3.0 , 4.8 , 5.6 , 1.2 , 8.6 +1.25 , 1.30 , 7.3 , 4.3 , 5.8 , 4.7 , 1.5 , 11.4 +1.30 , 1.40 , 10.1 , 12.4 , 10.1 , 3.0 , 3.2 , 19.4 +1.40 , 1.60 , 19.7 , 22.9 , 19.7 , 6.2 , 5.1 , 36.9 diff --git a/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_muon_P_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_muon_P_xsec.csv new file mode 100755 index 0000000..d444c0f --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_muon_P_xsec.csv @@ -0,0 +1,10 @@ +muon_P_xsec +Bin Min , Bin Max , Detector, X-Sec Model, FSI, Flux, Other, Total +1.00 , 2.00 , 17.7 , 4.5 , 2.6 , 5.5 , 0.6 , 19.3 +2.00 , 2.50 , 8.5 , 4.3 , 2.2 , 5.2 , 0.6 , 11.1 +2.50 , 3.00 , 3.9 , 3.8 , 2.4 , 4.8 , 0.6 , 7.7 +3.00 , 3.50 , 6.4 , 3.9 , 2.8 , 5.1 , 0.6 , 9.5 +3.50 , 4.00 , 7.6 , 4.1 , 2.8 , 5.7 , 0.5 , 10.7 +4.00 , 5.00 , 6.9 , 5.5 , 3.7 , 4.9 , 0.4 , 10.7 +5.00 , 7.00 , 4.2 , 7.9 , 6.3 , 3.7 , 0.2 , 11.6 +7.00 , 10.00 , 3.9 , 4.5 , 3.3 , 5.5 , 0.5 , 8.7 diff --git a/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_muon_theta_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_muon_theta_xsec.csv new file mode 100755 index 0000000..1cba579 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_muon_theta_xsec.csv @@ -0,0 +1,11 @@ +muon_theta_xsec +Bin Min , Bin Max , Detector, X-Sec Model, FSI, Flux, Other, Total +0.00 , 2.00 , 7.5 , 7.9 , 5.7 , 3.8 , 0.4 , 12.9 +2.00 , 4.00 , 4.4 , 6.5 , 3.3 , 3.4 , 0.4 , 9.2 +4.00 , 6.00 , 3.0 , 5.1 , 3.4 , 3.5 , 0.5 , 7.7 +6.00 , 8.00 , 3.5 , 4.2 , 3.3 , 4.0 , 0.5 , 7.5 +8.00 , 10.00 , 3.0 , 3.3 , 2.9 , 4.5 , 0.6 , 7.0 +10.00 , 12.00 , 3.0 , 3.1 , 3.5 , 4.3 , 0.5 , 7.0 +12.00 , 16.00 , 3.2 , 2.6 , 3.3 , 4.6 , 0.6 , 7.0 +16.00 , 20.00 , 3.0 , 3.0 , 3.4 , 4.5 , 0.6 , 7.1 +20.00 , 25.00 , 4.0 , 3.3 , 4.4 , 4.8 , 0.6 , 8.3 diff --git a/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_pi0_KE_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_pi0_KE_xsec.csv new file mode 100755 index 0000000..4de320b --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_pi0_KE_xsec.csv @@ -0,0 +1,9 @@ +pi0_KE_xsec +Bin Min , Bin Max , Detector, X-Sec Model, FSI, Flux, Other, Total +0.00 , 0.05 , 14.3 , 9.2 , 7.1 , 1.4 , 0.1 , 18.5 +0.05 , 0.15 , 5.0 , 4.9 , 4.2 , 3.4 , 0.5 , 8.9 +0.15 , 0.25 , 3.5 , 3.4 , 2.3 , 4.5 , 0.6 , 7.1 +0.25 , 0.40 , 3.7 , 3.5 , 1.8 , 4.6 , 0.6 , 7.2 +0.40 , 0.55 , 2.7 , 3.5 , 2.9 , 4.9 , 0.6 , 7.3 +0.55 , 0.75 , 2.4 , 2.9 , 3.4 , 5.7 , 0.7 , 7.6 +0.75 , 1.00 , 3.7 , 4.7 , 5.2 , 4.8 , 0.6 , 9.3 diff --git a/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_pi0_theta_xsec.csv b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_pi0_theta_xsec.csv new file mode 100755 index 0000000..a37d116 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/errors/Errors_Table_pi0_theta_xsec.csv @@ -0,0 +1,13 @@ +pi0_theta_xsec +Bin Min , Bin Max , Detector, X-Sec Model, FSI, Flux, Other, Total +0.00 , 10.00 , 8.5 , 9.0 , 5.5 , 2.5 , 0.4 , 13.8 +10.00 , 20.00 , 6.1 , 6.4 , 5.3 , 3.7 , 0.5 , 10.9 +20.00 , 30.00 , 5.2 , 4.8 , 3.2 , 4.0 , 0.5 , 8.7 +30.00 , 40.00 , 3.6 , 3.9 , 2.4 , 4.4 , 0.6 , 7.3 +40.00 , 50.00 , 2.3 , 3.5 , 3.4 , 4.0 , 0.5 , 6.8 +50.00 , 60.00 , 2.3 , 4.1 , 3.6 , 3.6 , 0.5 , 6.9 +60.00 , 70.00 , 2.1 , 5.2 , 3.3 , 3.0 , 0.4 , 7.2 +70.00 , 80.00 , 3.5 , 4.9 , 4.6 , 3.3 , 0.5 , 8.3 +80.00 , 90.00 , 4.4 , 6.2 , 6.9 , 2.4 , 0.4 , 10.6 +90.00 , 120.00 , 5.6 , 4.6 , 3.6 , 3.8 , 0.5 , 9.0 +120.00 , 180.00 , 5.1 , 3.2 , 2.1 , 5.5 , 0.7 , 8.4 diff --git a/data/MINERvA/CC1pi0/2017_nu/flux/Flux_Table.csv b/data/MINERvA/CC1pi0/2017_nu/flux/Flux_Table.csv new file mode 100755 index 0000000..b103441 --- /dev/null +++ b/data/MINERvA/CC1pi0/2017_nu/flux/Flux_Table.csv @@ -0,0 +1,31 @@ +Bin Min, Bin Max, Neutrino flux (nu/m^2/GeV/POT) + 0.0 , 0.5 , 8.58e-10 + 0.5 , 1.0 , 1.38e-09 + 1.0 , 1.5 , 3.45e-09 + 1.5 , 2.0 , 5.06e-09 + 2.0 , 2.5 , 6.66e-09 + 2.5 , 3.0 , 8.18e-09 + 3.0 , 3.5 , 8.53e-09 + 3.5 , 4.0 , 6.81e-09 + 4.0 , 4.5 , 4.06e-09 + 4.5 , 5.0 , 2.20e-09 + 5.0 , 5.5 , 1.35e-09 + 5.5 , 6.0 , 9.72e-10 + 6.0 , 6.5 , 7.90e-10 + 6.5 , 7.0 , 6.67e-10 + 7.0 , 7.5 , 5.82e-10 + 7.5 , 8.0 , 5.09e-10 + 8.0 , 8.5 , 4.58e-10 + 8.5 , 9.0 , 4.10e-10 + 9.0 , 9.5 , 3.71e-10 + 9.5 , 10.0 , 3.40e-10 + 10.0 , 11.0 , 2.95e-10 + 11.0 , 12.0 , 2.46e-10 + 12.0 , 13.0 , 2.06e-10 + 13.0 , 14.0 , 1.75e-10 + 14.0 , 15.0 , 1.45e-10 + 15.0 , 16.0 , 1.20e-10 + 16.0 , 17.0 , 1.01e-10 + 17.0 , 18.0 , 8.42e-11 + 18.0 , 19.0 , 7.11e-11 + 19.0 , 20.0 , 6.07e-11 diff --git a/data/MiniBooNE/anti-ccqe/asqq_bkg_ccqe.txt b/data/MiniBooNE/anti-ccqe/asqq_bkg_ccqe.txt index d30ab7d..ce43181 100755 --- a/data/MiniBooNE/anti-ccqe/asqq_bkg_ccqe.txt +++ b/data/MiniBooNE/anti-ccqe/asqq_bkg_ccqe.txt @@ -1,17 +1,18 @@ -0.00 4.400e-39 0.0 -0.05 3.023e-39 0.0 -0.10 1.920e-39 0.0 -0.20 1.297e-39 0.0 -0.25 8.972e-40 0.0 -0.30 6.183e-40 0.0 -0.35 4.397e-40 0.0 -0.40 3.126e-40 0.0 -0.45 2.260e-40 0.0 -0.50 1.661e-40 0.0 -0.60 1.081e-40 0.0 -0.70 6.207e-41 0.0 -0.80 3.882e-41 0.0 -1.00 2.119e-41 0.0 -1.20 9.146e-42 0.0 -1.50 2.368e-42 0.0 -2.00 1.037e-43 0.0 +0.00 4.400e-39 0.0 +0.05 3.023e-39 0.0 +0.10 1.920e-39 0.0 +0.15 1.297e-39 0.0 +0.20 8.972e-40 0.0 +0.25 6.183e-40 0.0 +0.30 4.397e-40 0.0 +0.35 3.126e-40 0.0 +0.40 2.260e-40 0.0 +0.45 1.661e-40 0.0 +0.50 1.081e-40 0.0 +0.60 6.207e-41 0.0 +0.70 3.882e-41 0.0 +0.80 2.119e-41 0.0 +1.00 9.146e-42 0.0 +1.20 2.368e-42 0.0 +1.50 1.037e-43 0.0 +2.00 0.0 0.0 diff --git a/data/T2K/CC0pi/T2K_CC0PI_2DPmuCosmu_Data.root b/data/T2K/CC0pi/T2K_CC0PI_2DPmuCosmu_Data.root index e6d858f..d61ec36 100644 Binary files a/data/T2K/CC0pi/T2K_CC0PI_2DPmuCosmu_Data.root and b/data/T2K/CC0pi/T2K_CC0PI_2DPmuCosmu_Data.root differ diff --git a/data/T2K/CC0pi/makedatafile_t2kcc0pi.py b/data/T2K/CC0pi/makedatafile_t2kcc0pi.py index acc5297..e80c5ba 100644 --- a/data/T2K/CC0pi/makedatafile_t2kcc0pi.py +++ b/data/T2K/CC0pi/makedatafile_t2kcc0pi.py @@ -1,294 +1,296 @@ from ROOT import * from array import * def GetMiddle(mystr): lims = mystr.strip().split(" - ") val = (float(lims[0]) + float(lims[1]))/2.0 return val def GetLowEdge(mystr): lims = mystr.strip().split(" - ") val = (float(lims[0]) + 0.00001) return val def GetHighEdge(mystr): lims = mystr.strip().split(" - ") val = (float(lims[1]) - 0.00001) return val def GetIndex(mystr): lims = mystr.split("-") return int(lims[0]), int(lims[1]) outfile = TFile("T2K_CC0PI_2DPmuCosmu_Data.root","RECREATE") # ANALYSIS I #______________________________ xedge = [0.0, 0.3, 0.4, 0.5, 0.65, 0.8, 0.95, 1.1, 1.25, 1.5, 2.0, 3.0, 5.0, 30.0] yedge = [-1.0, 0.0, 0.6, 0.7, 0.8, 0.85, 0.9, 0.94, 0.98, 1.0] datahist = TH2D("analysis1_data","analysis1_data", len(xedge)-1, array('f',xedge), len(yedge)-1, array('f',yedge)) maphist = datahist.Clone("analysis1_map") maphist.SetTitle("analysis1_map") counthist = datahist.Clone("analysis1_entrycount") datapoly = TH2Poly("datapoly","datapoly", 0.0,30.0, -1.0, 1.0) hist = None binedges = [] histedgeslist = [] xsecvals = [] histxseclist = [] binlimits = [3,8,15,22,30,39,47,58,67] with open("cross-section_analysisI.txt") as f: count = 0 for line in f: count += 1 if (count < 4): continue data = line.strip().split("|") if (len(data) < 1): continue ibin = int( data[0] ) + 1 xval = round(float(GetLowEdge( data[2] )),4) yval = round(float(GetLowEdge( data[1] )),4) xhig = round(float(GetHighEdge( data[2] )),4) yhig = round(float(GetHighEdge( data[1] )),4) xsec = float( data[3] ) * 1E-38 datapoly.AddBin( xval, yval, xhig, yhig ) datapoly.SetBinContent( datapoly.GetNumberOfBins(), xsec) binedges.append( xval ) xsecvals.append( xsec ) if ibin in binlimits: binedges.append( xhig ) histedgeslist.append(binedges) histxseclist.append(xsecvals) binedges = [] xsecvals = [] datahist.Fill(xval, yval, xsec) counthist.Fill(xval, yval, 1.0) for i in range(maphist.GetNbinsX()): for j in range(maphist.GetNbinsY()): xcent = maphist.GetXaxis().GetBinCenter(i+1) ycent = maphist.GetYaxis().GetBinCenter(j+1) if (xcent > xval and xcent < xhig and ycent > yval and ycent < yhig): maphist.SetBinContent(i+1,j+1, ibin) -data1D = TH1D("datahist","datahist", datapoly.GetNumberOfBins(), 0.0, float(datapoly.GetNumberOfBins())); -for i in range(datapoly.GetNumberOfBins()): - data1D.SetBinContent(i+1, datapoly.GetBinContent(i+1)); - -outfile.cd() -datahist.Write() -counthist.Write() -maphist.Write() -datapoly.Write() -data1D.Write() - -for i, obj in enumerate(histedgeslist): - print obj - hist = TH1D("dataslice_" + str(i), "dataslice_" + str(i), len(obj)-1, array('f',obj)) - for j in range(hist.GetNbinsX()): - hist.SetBinContent(j+1, histxseclist[i][j]) - - hist.GetXaxis().SetRangeUser(obj[0], obj[len(obj)-2]) - hist.Draw("HIST") - gPad.Update() - - hist.SetNameTitle("dataslice_" + str(i),"dataslice_" + str(i)) - hist.Write() - -# Get N Bins +# Get Covariances (keep in 1E-38 cm^2) \ nbins = 67 -print "NBins I = ", nbins -# Get Covariances (keep in 1E-38 cm^2) statcov = TH2D("analysis1_statcov","analysis1_statcov", nbins, 0.0, float(nbins), nbins, 0.0, float(nbins)); systcov = TH2D("analysis1_systcov","analysis1_systcov", nbins, 0.0, float(nbins), nbins, 0.0, float(nbins)); normcov = TH2D("analysis1_normcov","analysis1_normcov", nbins, 0.0, float(nbins), nbins, 0.0, float(nbins)); totcov = TH2D("analysis1_totcov","analysis1_totcov", nbins, 0.0, float(nbins), nbins, 0.0, float(nbins)); with open("covariance_statisticUncertainty_analysisI.txt") as f: count = 0 for line in f: count += 1 if (count < 4): continue data = line.strip().split("|") if (len(data) < 1): continue xi, yi = GetIndex(data[0]) cov = float(data[1]) - statcov.SetBinContent(xi, yi, cov) + statcov.SetBinContent(xi + 1, yi + 1, cov) with open("covariance_shapeSystematics_analysisI.txt") as f: count = 0 for line in f: count += 1 if (count < 4): continue data = line.strip().split("|") if (len(data) < 1): continue xi, yi = GetIndex(data[0]) cov = float(data[1]) systcov.SetBinContent(xi + 1, yi + 1, cov) with open("covariance_fluxNormalizationSystematics_analysisI.txt") as f: count = 0 for line in f: count += 1 if (count < 4): continue data = line.strip().split("|") if (len(data) < 1): continue xi, yi = GetIndex(data[0]) cov = float(data[1]) normcov.SetBinContent(xi + 1, yi + 1, cov) totcov.Add(systcov) totcov.Add(statcov) totcov.Add(normcov) + +data1D = TH1D("datahist","datahist", datapoly.GetNumberOfBins(), 0.0, float(datapoly.GetNumberOfBins())); +for i in range(datapoly.GetNumberOfBins()): + data1D.SetBinContent(i+1, datapoly.GetBinContent(i+1)); + data1D.SetBinError(i+1, sqrt(totcov.GetBinContent(i+1,i+1))*1E-38) + +outfile.cd() + +for i, obj in enumerate(histedgeslist): + print obj + + hist = TH1D("dataslice_" + str(i), "dataslice_" + str(i), len(obj)-1, array('f',obj)) + for j in range(hist.GetNbinsX()): + hist.SetBinContent(j+1, histxseclist[i][j]) + + hist.GetXaxis().SetRangeUser(obj[0], obj[len(obj)-2]) + hist.Draw("HIST") + gPad.Update() + + hist.SetNameTitle("dataslice_" + str(i),"dataslice_" + str(i)) + hist.Write() + + outfile.cd() +datahist.Write() +counthist.Write() +maphist.Write() +datapoly.Write() +data1D.Write() statcov.Write() systcov.Write() totcov.Write() normcov.Write() # ANALYSIS II #______________________________ xedge = [0.2, 0.35, 0.5, 0.65, 0.8, 0.95, 1.1, 1.25, 1.5, 2.0, 3.0, 5.0, 30.0] yedge = [0.6, 0.7, 0.8, 0.85, 0.9, 0.925, 0.95, 0.975, 1.0] datahist = TH2D("analysis2_data","analysis2_data", len(xedge)-1, array('f',xedge), len(yedge)-1, array('f',yedge)) maphist = datahist.Clone("analysis2_map") maphist.SetTitle("analysis2_map") counthist = datahist.Clone("analysis2_entrycount") # Get Data Entries entries = [] count = 0 with open("rps_crossSection_analysis2.txt") as f: for line in f: count += 1 if (count < 4): continue data = line.strip().split("|") if (len(data) < 1): continue ibin = int( data[0] ) + 1 xval = GetMiddle( data[2] ) yval = GetMiddle( data[1] ) xsec = float( data[3] ) * 1E-38 datahist.Fill(xval, yval, xsec) maphist.Fill(xval, yval, ibin) counthist.Fill(xval, yval, 1.0) # print ibin, "Map Value" # Get N Bins nbins = int(maphist.GetMaximum()) print "NBins I = ", nbins # Get Covariances (keep in 1E-38 cm^2) statcov = TH2D("analysis2_statcov","analysis2_statcov", nbins, 0.0, float(nbins), nbins, 0.0, float(nbins)); systcov = TH2D("analysis2_systcov","analysis2_systcov", nbins, 0.0, float(nbins), nbins, 0.0, float(nbins)); normcov = TH2D("analysis2_normcov","analysis2_normcov", nbins, 0.0, float(nbins), nbins, 0.0, float(nbins)); totcov = TH2D("analysis2_totcov","analysis2_totcov", nbins, 0.0, float(nbins), nbins, 0.0, float(nbins)); with open("rps_statsCov_analysis2.txt") as f: count = 0 for line in f: count += 1 if (count < 4): continue data = line.strip().split("|") if (len(data) < 1): continue xi, yi = GetIndex(data[0]) cov = float(data[1]) - statcov.SetBinContent(xi, yi, cov) + statcov.SetBinContent(xi + 1, yi + 1, cov) with open("rps_systCov_analysis2.txt") as f: count = 0 for line in f: count += 1 if (count < 4): continue data = line.strip().split("|") if (len(data) < 1): continue xi, yi = GetIndex(data[0]) cov = float(data[1]) systcov.SetBinContent(xi + 1, yi + 1, cov) with open("rps_fluxNormCov_analysis2.txt") as f: count = 0 for line in f: count += 1 if (count < 4): continue data = line.strip().split("|") if (len(data) < 1): continue xi, yi = GetIndex(data[0]) cov = float(data[1]) normcov.SetBinContent(xi + 1, yi + 1, cov) totcov.Add(systcov) totcov.Add(statcov) totcov.Add(normcov) outfile.cd() datahist.Write() maphist.Write() counthist.Write() statcov.Write() systcov.Write() totcov.Write() normcov.Write() # LocalWords: xval diff --git a/data/T2K/CC0pi/rps_systCov_analysis2.txt b/data/T2K/CC0pi/rps_systCov_analysis2.txt index c5742a2..3c6d968 100644 --- a/data/T2K/CC0pi/rps_systCov_analysis2.txt +++ b/data/T2K/CC0pi/rps_systCov_analysis2.txt @@ -1,9219 +1,9219 @@ Units: cross-section (10^-38 cm2/(nucleon x GeV)) row (bin i) - column (bin j) | sigma_i x sigma_j x rho_ij 0 - 0 | 0.01032782641 0 - 1 | 0.0108180208299 0 - 2 | 0.00786964606803 0 - 3 | 0.00193139030968 0 - 4 | 0.00024987106812 0 - 5 | 0.000199263562451 0 - 6 | -5.61197638164e-05 0 - 7 | -1.04371850562e-05 0 - 8 | 0.0 0 - 9 | 0.0 0 - 10 | 0.0 0 - 11 | 0.0 0 - 12 | 0.00725724234117 0 - 13 | 0.00925039953685 0 - 14 | 0.00701414334472 0 - 15 | 0.00196275612097 0 - 16 | 0.00218592771666 0 - 17 | 0.000526274761454 0 - 18 | 0.000118864327899 0 - 19 | 0.000153699768568 0 - 20 | -1.06059542869e-05 0 - 21 | 0.0 0 - 22 | 0.0 0 - 23 | 0.0 0 - 24 | 0.00762330621865 0 - 25 | 0.00936702233237 0 - 26 | 0.00734724411651 0 - 27 | 0.0026991733176 0 - 28 | 0.00258441597314 0 - 29 | 0.00197362259173 0 - 30 | 0.000473234066476 0 - 31 | 0.000320513316156 0 - 32 | -0.000948168810462 0 - 33 | -0.000136434280686 0 - 34 | 0.0 0 - 35 | 0.0 0 - 36 | 0.00857885443639 0 - 37 | 0.0100386068366 0 - 38 | 0.00823549177393 0 - 39 | 0.00725690539939 0 - 40 | 0.00324561803762 0 - 41 | 0.00246960104105 0 - 42 | 0.00128498202076 0 - 43 | 0.00077631261023 0 - 44 | -0.000338015547979 0 - 45 | -0.000765836740289 0 - 46 | 0.0 0 - 47 | 0.0 0 - 48 | 0.00807993387852 0 - 49 | 0.00616382006363 0 - 50 | 0.00742085943667 0 - 51 | 0.00531037922662 0 - 52 | 0.00404220571018 0 - 53 | 0.00535248707498 0 - 54 | 0.00131424253197 0 - 55 | 0.0222488557125 0 - 56 | 0.000743196781925 0 - 57 | -4.39992678139e-05 0 - 58 | 1.67500068122e-07 0 - 59 | 0.0 0 - 60 | 0.00757011500512 0 - 61 | 0.00279485588595 0 - 62 | 0.000574069419969 0 - 63 | -0.00186754485194 0 - 64 | -0.0015099728354 0 - 65 | 0.00424116677819 0 - 66 | 0.00470429596863 0 - 67 | 0.00197113830862 0 - 68 | 0.00102743617456 0 - 69 | -8.9502972186e-05 0 - 70 | -3.87039978083e-05 0 - 71 | 0.0 0 - 72 | 0.00626571121633 0 - 73 | 0.0101652144923 0 - 74 | 0.0152565774931 0 - 75 | 0.0172984228592 0 - 76 | 0.0144494146074 0 - 77 | 0.00215971301558 0 - 78 | 0.00320018389697 0 - 79 | 0.00252287353601 0 - 80 | 0.00146432512511 0 - 81 | 0.00118290409502 0 - 82 | 0.000308989244786 0 - 83 | 3.13326041213e-07 0 - 84 | 0.00229149359019 0 - 85 | 0.00481620895723 0 - 86 | 0.00473625865517 0 - 87 | 0.006340450537 0 - 88 | 0.00447960875436 0 - 89 | 0.000906874287803 0 - 90 | 0.00230199524518 0 - 91 | 0.00254598026848 0 - 92 | 0.00172735378144 0 - 93 | 0.00125301107251 0 - 94 | 0.00104598311201 0 - 95 | 3.60236316688e-05 1 - 0 | 0.0108180208299 1 - 1 | 0.0145778273894 1 - 2 | 0.0090820202126 1 - 3 | 0.00248932537785 1 - 4 | 0.000543518499895 1 - 5 | 0.000345274800472 1 - 6 | 2.39035772153e-05 1 - 7 | 2.08810767598e-05 1 - 8 | 0.0 1 - 9 | 0.0 1 - 10 | 0.0 1 - 11 | 0.0 1 - 12 | 0.00830431957504 1 - 13 | 0.0114178972261 1 - 14 | 0.00820267464135 1 - 15 | 0.00278787478704 1 - 16 | 0.0025782770829 1 - 17 | 0.000860617988881 1 - 18 | 0.000324911663803 1 - 19 | 0.00024920507364 1 - 20 | 1.62389166501e-05 1 - 21 | 0.0 1 - 22 | 0.0 1 - 23 | 0.0 1 - 24 | 0.00880773826827 1 - 25 | 0.011494512972 1 - 26 | 0.00888362476058 1 - 27 | 0.00387500625896 1 - 28 | 0.00326007668979 1 - 29 | 0.00238345177095 1 - 30 | 0.00092106383001 1 - 31 | 0.000569742762073 1 - 32 | -0.000936303030456 1 - 33 | -0.00014345730992 1 - 34 | 0.0 1 - 35 | 0.0 1 - 36 | 0.00957049485976 1 - 37 | 0.0118402794482 1 - 38 | 0.00962235818452 1 - 39 | 0.00812396116569 1 - 40 | 0.0040870865094 1 - 41 | 0.00309052571364 1 - 42 | 0.0019290717455 1 - 43 | 0.00127901795903 1 - 44 | -0.000118396593961 1 - 45 | -0.000825387156266 1 - 46 | 0.0 1 - 47 | 0.0 1 - 48 | 0.00900812997902 1 - 49 | 0.00818637462594 1 - 50 | 0.00926080489665 1 - 51 | 0.00671978297538 1 - 52 | 0.00515235250991 1 - 53 | 0.00617448367916 1 - 54 | 0.00206233946089 1 - 55 | 0.021253284664 1 - 56 | 0.0011473662762 1 - 57 | 0.000102529425147 1 - 58 | 1.54693203685e-05 1 - 59 | 0.0 1 - 60 | 0.00864535454908 1 - 61 | 0.00491304299721 1 - 62 | 0.00334721030457 1 - 63 | 0.000647558077231 1 - 64 | 0.000368887789053 1 - 65 | 0.00514142752885 1 - 66 | 0.00546268144522 1 - 67 | 0.00274657032443 1 - 68 | 0.00167395868741 1 - 69 | 0.000224982899631 1 - 70 | 2.47553656086e-05 1 - 71 | 0.0 1 - 72 | 0.0072260698718 1 - 73 | 0.0117721993042 1 - 74 | 0.0159759563853 1 - 75 | 0.0172867507994 1 - 76 | 0.0145989538982 1 - 77 | 0.00359663809602 1 - 78 | 0.00414500797315 1 - 79 | 0.00357508857343 1 - 80 | 0.00235942944117 1 - 81 | 0.0017191806711 1 - 82 | 0.000490638824414 1 - 83 | 2.12561622041e-06 1 - 84 | 0.0030850025486 1 - 85 | 0.00612857737993 1 - 86 | 0.00601995008058 1 - 87 | 0.00723738364666 1 - 88 | 0.00515742562265 1 - 89 | 0.00203672925602 1 - 90 | 0.00321652691664 1 - 91 | 0.00343058166403 1 - 92 | 0.00265928243105 1 - 93 | 0.00203462625572 1 - 94 | 0.00152840995187 1 - 95 | 6.10118531234e-05 2 - 0 | 0.00786964606803 2 - 1 | 0.0090820202126 2 - 2 | 0.00797110120867 2 - 3 | 0.00203526682356 2 - 4 | 0.000475647333105 2 - 5 | 0.000277339726086 2 - 6 | 8.06402635155e-06 2 - 7 | 4.74473389075e-06 2 - 8 | 0.0 2 - 9 | 0.0 2 - 10 | 0.0 2 - 11 | 0.0 2 - 12 | 0.00599770253652 2 - 13 | 0.00721400229273 2 - 14 | 0.00628016178814 2 - 15 | 0.00211595635276 2 - 16 | 0.00192482772257 2 - 17 | 0.000673891083816 2 - 18 | 0.000264372487888 2 - 19 | 0.000198611516928 2 - 20 | 1.13431953358e-05 2 - 21 | 0.0 2 - 22 | 0.0 2 - 23 | 0.0 2 - 24 | 0.00637550053162 2 - 25 | 0.00727272495208 2 - 26 | 0.00644467632049 2 - 27 | 0.00271235453541 2 - 28 | 0.00236091168401 2 - 29 | 0.00184081754738 2 - 30 | 0.000690646784464 2 - 31 | 0.000464324733051 2 - 32 | -0.000712200603335 2 - 33 | -0.000114446249989 2 - 34 | 0.0 2 - 35 | 0.0 2 - 36 | 0.00715442083662 2 - 37 | 0.00772043448083 2 - 38 | 0.0070146157462 2 - 39 | 0.00589903669955 2 - 40 | 0.00299458976578 2 - 41 | 0.00224012088209 2 - 42 | 0.00134154280523 2 - 43 | 0.00100825719067 2 - 44 | -7.67605804839e-05 2 - 45 | -0.000665592533033 2 - 46 | 0.0 2 - 47 | 0.0 2 - 48 | 0.00675823989816 2 - 49 | 0.00500914823664 2 - 50 | 0.00628367329594 2 - 51 | 0.00462982918735 2 - 52 | 0.00367652404787 2 - 53 | 0.00434811509019 2 - 54 | 0.0014494710316 2 - 55 | 0.0176846269943 2 - 56 | 0.000926893691946 2 - 57 | 9.57296915295e-05 2 - 58 | 1.24033586313e-05 2 - 59 | 0.0 2 - 60 | 0.006444257335 2 - 61 | 0.00276724267823 2 - 62 | 0.00163662686412 2 - 63 | -0.000248290501065 2 - 64 | -0.000222544588559 2 - 65 | 0.00364362981625 2 - 66 | 0.00389739988712 2 - 67 | 0.00207876795473 2 - 68 | 0.00131082601607 2 - 69 | 0.000235969443513 2 - 70 | 2.02931363556e-05 2 - 71 | 0.0 2 - 72 | 0.00539105506912 2 - 73 | 0.0078430203291 2 - 74 | 0.011521647503 2 - 75 | 0.0130743357289 2 - 76 | 0.0106054649129 2 - 77 | 0.00220009254348 2 - 78 | 0.00289380096499 2 - 79 | 0.00241431422527 2 - 80 | 0.00177146812115 2 - 81 | 0.00148459386456 2 - 82 | 0.000490915534417 2 - 83 | 1.63135619153e-06 2 - 84 | 0.00225565245924 2 - 85 | 0.00392170889588 2 - 86 | 0.00392191373561 2 - 87 | 0.00523790953475 2 - 88 | 0.00362181112298 2 - 89 | 0.00120977448322 2 - 90 | 0.00212668159646 2 - 91 | 0.00228214810817 2 - 92 | 0.00183276394893 2 - 93 | 0.00162944691279 2 - 94 | 0.00162098262583 2 - 95 | 7.7193312075e-05 3 - 0 | 0.00193139030968 3 - 1 | 0.00248932537785 3 - 2 | 0.00203526682356 3 - 3 | 0.00100371305736 3 - 4 | 0.000411256262232 3 - 5 | 0.000170496065323 3 - 6 | 5.96100344844e-05 3 - 7 | 2.40094045965e-05 3 - 8 | 0.0 3 - 9 | 0.0 3 - 10 | 0.0 3 - 11 | 0.0 3 - 12 | 0.00151467240963 3 - 13 | 0.00195832478714 3 - 14 | 0.00194477108428 3 - 15 | 0.00100788193687 3 - 16 | 0.000605630862435 3 - 17 | 0.000372336829169 3 - 18 | 0.00019190419152 3 - 19 | 0.000103874301554 3 - 20 | 2.80038893394e-05 3 - 21 | 0.0 3 - 22 | 0.0 3 - 23 | 0.0 3 - 24 | 0.00152413046255 3 - 25 | 0.00199655347462 3 - 26 | 0.00197882934222 3 - 27 | 0.00121970948978 3 - 28 | 0.000843317007876 3 - 29 | 0.00059534887138 3 - 30 | 0.000419210778702 3 - 31 | 0.000259564367011 3 - 32 | -3.32514558697e-05 3 - 33 | -1.08416158182e-05 3 - 34 | 0.0 3 - 35 | 0.0 3 - 36 | 0.00151055940987 3 - 37 | 0.00193124783588 3 - 38 | 0.0022327151604 3 - 39 | 0.00159261064054 3 - 40 | 0.00102429384775 3 - 41 | 0.000799139125693 3 - 42 | 0.000632916439185 3 - 43 | 0.000510774525678 3 - 44 | 0.000182104939083 3 - 45 | -0.000104990588284 3 - 46 | 0.0 3 - 47 | 0.0 3 - 48 | 0.00136106470763 3 - 49 | 0.00155705910607 3 - 50 | 0.00191522426907 3 - 51 | 0.00150883349691 3 - 52 | 0.00115379863261 3 - 53 | 0.00117043449644 3 - 54 | 0.000801322164357 3 - 55 | 0.00267370840868 3 - 56 | 0.000460328203253 3 - 57 | 0.000154930915758 3 - 58 | 1.67220244601e-05 3 - 59 | 0.0 3 - 60 | 0.00136616902433 3 - 61 | 0.00128001458474 3 - 62 | 0.00149751768415 3 - 63 | 0.00114388535449 3 - 64 | 0.000875378910179 3 - 65 | 0.00112257351049 3 - 66 | 0.0010579681949 3 - 67 | 0.000877961358449 3 - 68 | 0.000725116090676 3 - 69 | 0.000329864720182 3 - 70 | 5.74852684985e-05 3 - 71 | 0.0 3 - 72 | 0.00124882198415 3 - 73 | 0.00169482139509 3 - 74 | 0.00223287970077 3 - 75 | 0.00222718945288 3 - 76 | 0.00177599801539 3 - 77 | 0.00100356713005 3 - 78 | 0.0010353344609 3 - 79 | 0.001018738971 3 - 80 | 0.000929684276775 3 - 81 | 0.00069622915753 3 - 82 | 0.000257543082579 3 - 83 | 1.63567939637e-06 3 - 84 | 0.000863059894371 3 - 85 | 0.00100607580953 3 - 86 | 0.00120711818272 3 - 87 | 0.00124032600841 3 - 88 | 0.000943896580766 3 - 89 | 0.000706469933582 3 - 90 | 0.000773755756163 3 - 91 | 0.000817446352964 3 - 92 | 0.00082894342513 3 - 93 | 0.000840404153384 3 - 94 | 0.000850018588175 3 - 95 | 4.75029801892e-05 4 - 0 | 0.00024987106812 4 - 1 | 0.000543518499895 4 - 2 | 0.000475647333105 4 - 3 | 0.000411256262232 4 - 4 | 0.000422677081972 4 - 5 | 0.000144891114137 4 - 6 | 6.73646855421e-05 4 - 7 | 3.15472360545e-05 4 - 8 | 0.0 4 - 9 | 0.0 4 - 10 | 0.0 4 - 11 | 0.0 4 - 12 | 0.000195857761927 4 - 13 | 0.000194542424835 4 - 14 | 0.000790979257901 4 - 15 | 0.000676359730394 4 - 16 | 0.000186176381066 4 - 17 | 0.000281573723441 4 - 18 | 0.000181172760934 4 - 19 | 7.64854039587e-05 4 - 20 | 3.59698430932e-05 4 - 21 | 0.0 4 - 22 | 0.0 4 - 23 | 0.0 4 - 24 | 6.98244201596e-05 4 - 25 | 0.000234348797883 4 - 26 | 0.00077582942514 4 - 27 | 0.000817212753504 4 - 28 | 0.000384012135093 4 - 29 | 0.000223459274496 4 - 30 | 0.000343436329951 4 - 31 | 0.000199899733383 4 - 32 | 0.000191016664303 4 - 33 | 2.62315045872e-05 4 - 34 | 0.0 4 - 35 | 0.0 4 - 36 | -0.000180212461121 4 - 37 | -5.58562452363e-05 4 - 38 | 0.000918086499105 4 - 39 | 0.000249918074144 4 - 40 | 0.00041763955931 4 - 41 | 0.000334093006774 4 - 42 | 0.00036978475863 4 - 43 | 0.000373914034192 4 - 44 | 0.000262366374296 4 - 45 | 0.000108389940064 4 - 46 | 0.0 4 - 47 | 0.0 4 - 48 | -0.000197638577156 4 - 49 | 0.000382213092023 4 - 50 | 0.000609352257668 4 - 51 | 0.000561058814602 4 - 52 | 0.000439272290678 4 - 53 | 5.64844797571e-05 4 - 54 | 0.000543039959911 4 - 55 | -0.00135874604582 4 - 56 | 0.000306489784752 4 - 57 | 0.000162141765686 4 - 58 | 1.57925803469e-05 4 - 59 | 0.0 4 - 60 | -6.39926182246e-05 4 - 61 | 0.000786602340772 4 - 62 | 0.00161636009138 4 - 63 | 0.00173938442693 4 - 64 | 0.00133635502195 4 - 65 | 0.000291068648789 4 - 66 | 0.00010201213672 4 - 67 | 0.000570420418135 4 - 68 | 0.000500800928101 4 - 69 | 0.000337638614512 4 - 70 | 5.87501901555e-05 4 - 71 | 0.0 4 - 72 | 4.92409478168e-05 4 - 73 | -0.000503782089994 4 - 74 | -0.000943792813395 4 - 75 | -0.0013427413171 4 - 76 | -0.00124704708138 4 - 77 | 0.000602874364142 4 - 78 | 0.000379165340937 4 - 79 | 0.000473813815811 4 - 80 | 0.000629598515159 4 - 81 | 0.000427348324794 4 - 82 | 0.000174753055025 4 - 83 | 1.26661479731e-06 4 - 84 | 0.000565403371192 4 - 85 | 1.43071257275e-05 4 - 86 | 0.000284634008729 4 - 87 | -1.50388179219e-05 4 - 88 | -2.57015360191e-06 4 - 89 | 0.000563578772703 4 - 90 | 0.000297770109144 4 - 91 | 0.000226650311371 4 - 92 | 0.000422975814312 4 - 93 | 0.000556359168046 4 - 94 | 0.00065373773787 4 - 95 | 4.39538659098e-05 5 - 0 | 0.000199263562451 5 - 1 | 0.000345274800472 5 - 2 | 0.000277339726086 5 - 3 | 0.000170496065323 5 - 4 | 0.000144891114137 5 - 5 | 9.11015221894e-05 5 - 6 | 4.3151215665e-05 5 - 7 | 1.09619973348e-05 5 - 8 | 0.0 5 - 9 | 0.0 5 - 10 | 0.0 5 - 11 | 0.0 5 - 12 | 0.000165055226165 5 - 13 | 0.000196735864132 5 - 14 | 0.000388498497676 5 - 15 | 0.000301131247354 5 - 16 | 9.16317853728e-05 5 - 17 | 0.000122519590494 5 - 18 | 7.85526503431e-05 5 - 19 | 3.67625561623e-05 5 - 20 | 1.35908830685e-05 5 - 21 | 0.0 5 - 22 | 0.0 5 - 23 | 0.0 5 - 24 | 0.000125277194954 5 - 25 | 0.000212223546694 5 - 26 | 0.000408021393223 5 - 27 | 0.0003655187842 5 - 28 | 0.00017242654804 5 - 29 | 9.39231315333e-05 5 - 30 | 0.00014462304496 5 - 31 | 9.79357544531e-05 5 - 32 | 8.33617929122e-05 5 - 33 | 1.07316257138e-05 5 - 34 | 0.0 5 - 35 | 0.0 5 - 36 | 3.01691097574e-05 5 - 37 | 7.69947164245e-05 5 - 38 | 0.000379855585957 5 - 39 | 0.000173961970896 5 - 40 | 0.000205968717766 5 - 41 | 0.000151166945609 5 - 42 | 0.000159229890968 5 - 43 | 0.000167562237335 5 - 44 | 0.000108581816737 5 - 45 | 3.25797986691e-05 5 - 46 | 0.0 5 - 47 | 0.0 5 - 48 | -1.52919636222e-06 5 - 49 | 0.000237527652783 5 - 50 | 0.000337701802197 5 - 51 | 0.000304965188473 5 - 52 | 0.000239784195442 5 - 53 | 7.15054489408e-05 5 - 54 | 0.000221979217055 5 - 55 | -0.000790630088618 5 - 56 | 0.000128859324727 5 - 57 | 5.90153066843e-05 5 - 58 | 5.01149593197e-06 5 - 59 | 0.0 5 - 60 | 5.7182887464e-05 5 - 61 | 0.000338105588959 5 - 62 | 0.000692538090623 5 - 63 | 0.000711002559225 5 - 64 | 0.000548917207044 5 - 65 | 0.000161408812184 5 - 66 | 4.51845208554e-05 5 - 67 | 0.000209680830718 5 - 68 | 0.000226336595278 5 - 69 | 0.000132307409299 5 - 70 | 2.02323147279e-05 5 - 71 | 0.0 5 - 72 | 7.72217396064e-05 5 - 73 | -0.000106372894504 5 - 74 | -0.000235822701035 5 - 75 | -0.000348267705941 5 - 76 | -0.000344403790757 5 - 77 | 0.000266216918922 5 - 78 | 0.000173807091395 5 - 79 | 0.000206155713091 5 - 80 | 0.000268253859488 5 - 81 | 0.000188414524185 5 - 82 | 6.49758934587e-05 5 - 83 | 4.52720100477e-07 5 - 84 | 0.000204476650376 5 - 85 | 4.65672016148e-05 5 - 86 | 0.000154200077751 5 - 87 | 7.30548558005e-05 5 - 88 | 0.000103389716695 5 - 89 | 0.000257229679212 5 - 90 | 0.000133880645795 5 - 91 | 9.09902446366e-05 5 - 92 | 0.000194423582576 5 - 93 | 0.000253656072122 5 - 94 | 0.000259836281434 5 - 95 | 1.60833419184e-05 6 - 0 | -5.61197638164e-05 6 - 1 | 2.39035772153e-05 6 - 2 | 8.06402635155e-06 6 - 3 | 5.96100344844e-05 6 - 4 | 6.73646855421e-05 6 - 5 | 4.3151215665e-05 6 - 6 | 3.79184880439e-05 6 - 7 | 9.3438707238e-06 6 - 8 | 0.0 6 - 9 | 0.0 6 - 10 | 0.0 6 - 11 | 0.0 6 - 12 | -2.55794977571e-05 6 - 13 | -3.29665951459e-05 6 - 14 | 9.46609014262e-05 6 - 15 | 0.000152673476472 6 - 16 | 1.43722019347e-05 6 - 17 | 6.78762510082e-05 6 - 18 | 4.85619043674e-05 6 - 19 | 2.62904764127e-05 6 - 20 | 1.23353331468e-05 6 - 21 | 0.0 6 - 22 | 0.0 6 - 23 | 0.0 6 - 24 | -6.22582773382e-05 6 - 25 | -3.53861717235e-05 6 - 26 | 0.000102687052228 6 - 27 | 0.000168343840016 6 - 28 | 6.01472316231e-05 6 - 29 | 2.1109969309e-05 6 - 30 | 8.63346615764e-05 6 - 31 | 6.83658005248e-05 6 - 32 | 9.48107921386e-05 6 - 33 | 1.35166091493e-05 6 - 34 | 0.0 6 - 35 | 0.0 6 - 36 | -0.000140884840801 6 - 37 | -0.000133157292645 6 - 38 | 6.04375947908e-05 6 - 39 | -2.49774994853e-05 6 - 40 | 6.90839345334e-05 6 - 41 | 5.52116592621e-05 6 - 42 | 8.36419915312e-05 6 - 43 | 9.04395114222e-05 6 - 44 | 8.42088535844e-05 6 - 45 | 4.13197604423e-05 6 - 46 | 0.0 6 - 47 | 0.0 6 - 48 | -0.000168026965167 6 - 49 | 4.74579450367e-05 6 - 50 | 6.69002930528e-05 6 - 51 | 8.99280809456e-05 6 - 52 | 6.96032963994e-05 6 - 53 | -4.96572096858e-05 6 - 54 | 0.000122284618367 6 - 55 | -0.00115975427219 6 - 56 | 6.03488582007e-05 6 - 57 | 3.83435327592e-05 6 - 58 | 4.0870035457e-06 6 - 59 | 0.0 6 - 60 | -0.000113259837316 6 - 61 | 0.000151065724463 6 - 62 | 0.00040703243719 6 - 63 | 0.000466815651379 6 - 64 | 0.000361205727599 6 - 65 | 2.06965286956e-05 6 - 66 | -5.92069490779e-05 6 - 67 | 7.99040437523e-05 6 - 68 | 0.000116319765078 6 - 69 | 8.39825861541e-05 6 - 70 | 1.42877260508e-05 6 - 71 | 0.0 6 - 72 | -7.98452315403e-05 6 - 73 | -0.00023907852461 6 - 74 | -0.000412343847133 6 - 75 | -0.000497528867014 6 - 76 | -0.000450559410052 6 - 77 | 0.000128463521603 6 - 78 | 5.5585256659e-05 6 - 79 | 8.92787871023e-05 6 - 80 | 0.000137137446817 6 - 81 | 8.96498946338e-05 6 - 82 | 3.1628135217e-05 6 - 83 | 2.77319257244e-07 6 - 84 | 5.318355987e-05 6 - 85 | -5.26235267137e-05 6 - 86 | 8.56562044085e-06 6 - 87 | -6.59927900925e-05 6 - 88 | 1.20847867903e-05 6 - 89 | 0.000150554797854 6 - 90 | 4.87922470406e-05 6 - 91 | 1.83575947219e-05 6 - 92 | 0.000101225251295 6 - 93 | 0.000135693731911 6 - 94 | 0.000134885606349 6 - 95 | 8.06396721e-06 7 - 0 | -1.04371850562e-05 7 - 1 | 2.08810767598e-05 7 - 2 | 4.74473389075e-06 7 - 3 | 2.40094045965e-05 7 - 4 | 3.15472360545e-05 7 - 5 | 1.09619973348e-05 7 - 6 | 9.3438707238e-06 7 - 7 | 7.32676868519e-06 7 - 8 | 0.0 7 - 9 | 0.0 7 - 10 | 0.0 7 - 11 | 0.0 7 - 12 | -1.12744840893e-05 7 - 13 | -9.52629662504e-06 7 - 14 | 3.39147105503e-05 7 - 15 | 4.69591494583e-05 7 - 16 | 2.86991256371e-06 7 - 17 | 2.46179928104e-05 7 - 18 | 1.78954537394e-05 7 - 19 | 1.00470395344e-05 7 - 20 | 5.62175167229e-06 7 - 21 | 0.0 7 - 22 | 0.0 7 - 23 | 0.0 7 - 24 | -3.20123373222e-05 7 - 25 | -1.33590670109e-05 7 - 26 | 2.74128059635e-05 7 - 27 | 5.45821702377e-05 7 - 28 | 2.15887008284e-05 7 - 29 | 1.06714275681e-05 7 - 30 | 3.04477764098e-05 7 - 31 | 2.12055178535e-05 7 - 32 | 2.9923955519e-05 7 - 33 | 5.28732911025e-06 7 - 34 | 0.0 7 - 35 | 0.0 7 - 36 | -5.22782096483e-05 7 - 37 | -3.66841097292e-05 7 - 38 | 4.28463623168e-05 7 - 39 | -1.07572701676e-05 7 - 40 | 1.95205076565e-05 7 - 41 | 1.45427975584e-05 7 - 42 | 2.6243894944e-05 7 - 43 | 3.00568240889e-05 7 - 44 | 2.78872724315e-05 7 - 45 | 1.61796399291e-05 7 - 46 | 0.0 7 - 47 | 0.0 7 - 48 | -5.75558116344e-05 7 - 49 | 1.14183110248e-05 7 - 50 | 1.53458676961e-05 7 - 51 | 2.12696496771e-05 7 - 52 | 1.59656984486e-05 7 - 53 | -1.94680732731e-05 7 - 54 | 3.46321147719e-05 7 - 55 | -0.000240758628149 7 - 56 | 2.16508583258e-05 7 - 57 | 1.61931611827e-05 7 - 58 | 2.44744938937e-06 7 - 59 | 0.0 7 - 60 | -4.18760117072e-05 7 - 61 | 5.19360115654e-05 7 - 62 | 0.000127838845475 7 - 63 | 0.000146396246169 7 - 64 | 0.000114892405 7 - 65 | 9.66668904312e-07 7 - 66 | -1.10230634106e-05 7 - 67 | 4.58583651109e-05 7 - 68 | 3.29882402491e-05 7 - 69 | 2.87264297197e-05 7 - 70 | 5.50040780745e-06 7 - 71 | 0.0 7 - 72 | -2.67635989695e-05 7 - 73 | -8.01185969771e-05 7 - 74 | -0.000136149276658 7 - 75 | -0.000180496763689 7 - 76 | -0.000150684387764 7 - 77 | 4.05840905305e-05 7 - 78 | 1.3124126616e-05 7 - 79 | 3.05281452225e-05 7 - 80 | 5.00890612776e-05 7 - 81 | 3.36005224848e-05 7 - 82 | 1.11758289942e-05 7 - 83 | 1.18150047906e-07 7 - 84 | 1.98300169732e-05 7 - 85 | -1.5980348131e-05 7 - 86 | 1.91110975354e-06 7 - 87 | -2.86507010327e-05 7 - 88 | -1.97616394945e-05 7 - 89 | 4.04630644302e-05 7 - 90 | 1.23884958941e-05 7 - 91 | 7.85667780722e-06 7 - 92 | 3.60963477671e-05 7 - 93 | 4.9725636217e-05 7 - 94 | 4.53272707252e-05 7 - 95 | 3.24060679452e-06 8 - 0 | 0.0 8 - 1 | 0.0 8 - 2 | 0.0 8 - 3 | 0.0 8 - 4 | 0.0 8 - 5 | 0.0 8 - 6 | 0.0 8 - 7 | 0.0 8 - 8 | 0.0 8 - 9 | 0.0 8 - 10 | 0.0 8 - 11 | 0.0 8 - 12 | 0.0 8 - 13 | 0.0 8 - 14 | 0.0 8 - 15 | 0.0 8 - 16 | 0.0 8 - 17 | 0.0 8 - 18 | 0.0 8 - 19 | 0.0 8 - 20 | 0.0 8 - 21 | 0.0 8 - 22 | 0.0 8 - 23 | 0.0 8 - 24 | 0.0 8 - 25 | 0.0 8 - 26 | 0.0 8 - 27 | 0.0 8 - 28 | 0.0 8 - 29 | 0.0 8 - 30 | 0.0 8 - 31 | 0.0 8 - 32 | 0.0 8 - 33 | 0.0 8 - 34 | 0.0 8 - 35 | 0.0 8 - 36 | 0.0 8 - 37 | 0.0 8 - 38 | 0.0 8 - 39 | 0.0 8 - 40 | 0.0 8 - 41 | 0.0 8 - 42 | 0.0 8 - 43 | 0.0 8 - 44 | 0.0 8 - 45 | 0.0 8 - 46 | 0.0 8 - 47 | 0.0 8 - 48 | 0.0 8 - 49 | 0.0 8 - 50 | 0.0 8 - 51 | 0.0 8 - 52 | 0.0 8 - 53 | 0.0 8 - 54 | 0.0 8 - 55 | 0.0 8 - 56 | 0.0 8 - 57 | 0.0 8 - 58 | 0.0 8 - 59 | 0.0 8 - 60 | 0.0 8 - 61 | 0.0 8 - 62 | 0.0 8 - 63 | 0.0 8 - 64 | 0.0 8 - 65 | 0.0 8 - 66 | 0.0 8 - 67 | 0.0 8 - 68 | 0.0 8 - 69 | 0.0 8 - 70 | 0.0 8 - 71 | 0.0 8 - 72 | 0.0 8 - 73 | 0.0 8 - 74 | 0.0 8 - 75 | 0.0 8 - 76 | 0.0 8 - 77 | 0.0 8 - 78 | 0.0 8 - 79 | 0.0 8 - 80 | 0.0 8 - 81 | 0.0 8 - 82 | 0.0 8 - 83 | 0.0 8 - 84 | 0.0 8 - 85 | 0.0 8 - 86 | 0.0 8 - 87 | 0.0 8 - 88 | 0.0 8 - 89 | 0.0 8 - 90 | 0.0 8 - 91 | 0.0 8 - 92 | 0.0 8 - 93 | 0.0 8 - 94 | 0.0 8 - 95 | 0.0 9 - 0 | 0.0 9 - 1 | 0.0 9 - 2 | 0.0 9 - 3 | 0.0 9 - 4 | 0.0 9 - 5 | 0.0 9 - 6 | 0.0 9 - 7 | 0.0 9 - 8 | 0.0 9 - 9 | 0.0 9 - 10 | 0.0 9 - 11 | 0.0 9 - 12 | 0.0 9 - 13 | 0.0 9 - 14 | 0.0 9 - 15 | 0.0 9 - 16 | 0.0 9 - 17 | 0.0 9 - 18 | 0.0 9 - 19 | 0.0 9 - 20 | 0.0 9 - 21 | 0.0 9 - 22 | 0.0 9 - 23 | 0.0 9 - 24 | 0.0 9 - 25 | 0.0 9 - 26 | 0.0 9 - 27 | 0.0 9 - 28 | 0.0 9 - 29 | 0.0 9 - 30 | 0.0 9 - 31 | 0.0 9 - 32 | 0.0 9 - 33 | 0.0 9 - 34 | 0.0 9 - 35 | 0.0 9 - 36 | 0.0 9 - 37 | 0.0 9 - 38 | 0.0 9 - 39 | 0.0 9 - 40 | 0.0 9 - 41 | 0.0 9 - 42 | 0.0 9 - 43 | 0.0 9 - 44 | 0.0 9 - 45 | 0.0 9 - 46 | 0.0 9 - 47 | 0.0 9 - 48 | 0.0 9 - 49 | 0.0 9 - 50 | 0.0 9 - 51 | 0.0 9 - 52 | 0.0 9 - 53 | 0.0 9 - 54 | 0.0 9 - 55 | 0.0 9 - 56 | 0.0 9 - 57 | 0.0 9 - 58 | 0.0 9 - 59 | 0.0 9 - 60 | 0.0 9 - 61 | 0.0 9 - 62 | 0.0 9 - 63 | 0.0 9 - 64 | 0.0 9 - 65 | 0.0 9 - 66 | 0.0 9 - 67 | 0.0 9 - 68 | 0.0 9 - 69 | 0.0 9 - 70 | 0.0 9 - 71 | 0.0 9 - 72 | 0.0 9 - 73 | 0.0 9 - 74 | 0.0 9 - 75 | 0.0 9 - 76 | 0.0 9 - 77 | 0.0 9 - 78 | 0.0 9 - 79 | 0.0 9 - 80 | 0.0 9 - 81 | 0.0 9 - 82 | 0.0 9 - 83 | 0.0 9 - 84 | 0.0 9 - 85 | 0.0 9 - 86 | 0.0 9 - 87 | 0.0 9 - 88 | 0.0 9 - 89 | 0.0 9 - 90 | 0.0 9 - 91 | 0.0 9 - 92 | 0.0 9 - 93 | 0.0 9 - 94 | 0.0 9 - 95 | 0.0 10 - 0 | 0.0 10 - 1 | 0.0 10 - 2 | 0.0 10 - 3 | 0.0 10 - 4 | 0.0 10 - 5 | 0.0 10 - 6 | 0.0 10 - 7 | 0.0 10 - 8 | 0.0 10 - 9 | 0.0 10 - 10 | 0.0 10 - 11 | 0.0 10 - 12 | 0.0 10 - 13 | 0.0 10 - 14 | 0.0 10 - 15 | 0.0 10 - 16 | 0.0 10 - 17 | 0.0 10 - 18 | 0.0 10 - 19 | 0.0 10 - 20 | 0.0 10 - 21 | 0.0 10 - 22 | 0.0 10 - 23 | 0.0 10 - 24 | 0.0 10 - 25 | 0.0 10 - 26 | 0.0 10 - 27 | 0.0 10 - 28 | 0.0 10 - 29 | 0.0 10 - 30 | 0.0 10 - 31 | 0.0 10 - 32 | 0.0 10 - 33 | 0.0 10 - 34 | 0.0 10 - 35 | 0.0 10 - 36 | 0.0 10 - 37 | 0.0 10 - 38 | 0.0 10 - 39 | 0.0 10 - 40 | 0.0 10 - 41 | 0.0 10 - 42 | 0.0 10 - 43 | 0.0 10 - 44 | 0.0 10 - 45 | 0.0 10 - 46 | 0.0 10 - 47 | 0.0 10 - 48 | 0.0 10 - 49 | 0.0 10 - 50 | 0.0 10 - 51 | 0.0 10 - 52 | 0.0 10 - 53 | 0.0 10 - 54 | 0.0 10 - 55 | 0.0 10 - 56 | 0.0 10 - 57 | 0.0 10 - 58 | 0.0 10 - 59 | 0.0 10 - 60 | 0.0 10 - 61 | 0.0 10 - 62 | 0.0 10 - 63 | 0.0 10 - 64 | 0.0 10 - 65 | 0.0 10 - 66 | 0.0 10 - 67 | 0.0 10 - 68 | 0.0 10 - 69 | 0.0 10 - 70 | 0.0 10 - 71 | 0.0 10 - 72 | 0.0 10 - 73 | 0.0 10 - 74 | 0.0 10 - 75 | 0.0 10 - 76 | 0.0 10 - 77 | 0.0 10 - 78 | 0.0 10 - 79 | 0.0 10 - 80 | 0.0 10 - 81 | 0.0 10 - 82 | 0.0 10 - 83 | 0.0 10 - 84 | 0.0 10 - 85 | 0.0 10 - 86 | 0.0 10 - 87 | 0.0 10 - 88 | 0.0 10 - 89 | 0.0 10 - 90 | 0.0 10 - 91 | 0.0 10 - 92 | 0.0 10 - 93 | 0.0 10 - 94 | 0.0 10 - 95 | 0.0 11 - 0 | 0.0 11 - 1 | 0.0 11 - 2 | 0.0 11 - 3 | 0.0 11 - 4 | 0.0 11 - 5 | 0.0 11 - 6 | 0.0 11 - 7 | 0.0 11 - 8 | 0.0 11 - 9 | 0.0 11 - 10 | 0.0 11 - 11 | 0.0 11 - 12 | 0.0 11 - 13 | 0.0 11 - 14 | 0.0 11 - 15 | 0.0 11 - 16 | 0.0 11 - 17 | 0.0 11 - 18 | 0.0 11 - 19 | 0.0 11 - 20 | 0.0 11 - 21 | 0.0 11 - 22 | 0.0 11 - 23 | 0.0 11 - 24 | 0.0 11 - 25 | 0.0 11 - 26 | 0.0 11 - 27 | 0.0 11 - 28 | 0.0 11 - 29 | 0.0 11 - 30 | 0.0 11 - 31 | 0.0 11 - 32 | 0.0 11 - 33 | 0.0 11 - 34 | 0.0 11 - 35 | 0.0 11 - 36 | 0.0 11 - 37 | 0.0 11 - 38 | 0.0 11 - 39 | 0.0 11 - 40 | 0.0 11 - 41 | 0.0 11 - 42 | 0.0 11 - 43 | 0.0 11 - 44 | 0.0 11 - 45 | 0.0 11 - 46 | 0.0 11 - 47 | 0.0 11 - 48 | 0.0 11 - 49 | 0.0 11 - 50 | 0.0 11 - 51 | 0.0 11 - 52 | 0.0 11 - 53 | 0.0 11 - 54 | 0.0 11 - 55 | 0.0 11 - 56 | 0.0 11 - 57 | 0.0 11 - 58 | 0.0 11 - 59 | 0.0 11 - 60 | 0.0 11 - 61 | 0.0 11 - 62 | 0.0 11 - 63 | 0.0 11 - 64 | 0.0 11 - 65 | 0.0 11 - 66 | 0.0 11 - 67 | 0.0 11 - 68 | 0.0 11 - 69 | 0.0 11 - 70 | 0.0 11 - 71 | 0.0 11 - 72 | 0.0 11 - 73 | 0.0 11 - 74 | 0.0 11 - 75 | 0.0 11 - 76 | 0.0 11 - 77 | 0.0 11 - 78 | 0.0 11 - 79 | 0.0 11 - 80 | 0.0 11 - 81 | 0.0 11 - 82 | 0.0 11 - 83 | 0.0 11 - 84 | 0.0 11 - 85 | 0.0 11 - 86 | 0.0 11 - 87 | 0.0 11 - 88 | 0.0 11 - 89 | 0.0 11 - 90 | 0.0 11 - 91 | 0.0 11 - 92 | 0.0 11 - 93 | 0.0 11 - 94 | 0.0 11 - 95 | 0.0 12 - 0 | 0.00725724234117 12 - 1 | 0.00830431957504 12 - 2 | 0.00599770253652 12 - 3 | 0.00151467240963 12 - 4 | 0.000195857761927 12 - 5 | 0.000165055226165 12 - 6 | -2.55794977571e-05 12 - 7 | -1.12744840893e-05 12 - 8 | 0.0 12 - 9 | 0.0 12 - 10 | 0.0 12 - 11 | 0.0 12 - 12 | 0.00606279712736 12 - 13 | 0.00738495490201 12 - 14 | 0.00547495619336 12 - 15 | 0.00161162933552 12 - 16 | 0.00171596427143 12 - 17 | 0.000430490562737 12 - 18 | 0.000101558946076 12 - 19 | 0.000122124206135 12 - 20 | -5.76239183576e-06 12 - 21 | 0.0 12 - 22 | 0.0 12 - 23 | 0.0 12 - 24 | 0.00610951292372 12 - 25 | 0.00742800797302 12 - 26 | 0.00585025459469 12 - 27 | 0.00223424525331 12 - 28 | 0.00205357802755 12 - 29 | 0.00153585521953 12 - 30 | 0.00040081750912 12 - 31 | 0.000277482673197 12 - 32 | -0.000687643833987 12 - 33 | -0.000102258307301 12 - 34 | 0.0 12 - 35 | 0.0 12 - 36 | 0.00662083718748 12 - 37 | 0.00785344201364 12 - 38 | 0.00639625053925 12 - 39 | 0.00567354999767 12 - 40 | 0.00259780826718 12 - 41 | 0.00198181114548 12 - 42 | 0.0010828073938 12 - 43 | 0.000629775665814 12 - 44 | -0.00023055549196 12 - 45 | -0.000581470259347 12 - 46 | 0.0 12 - 47 | 0.0 12 - 48 | 0.00622202559637 12 - 49 | 0.00497287466506 12 - 50 | 0.0058818087985 12 - 51 | 0.00428122003691 12 - 52 | 0.00327056153943 12 - 53 | 0.00419873690242 12 - 54 | 0.0011083932876 12 - 55 | 0.0161297584957 12 - 56 | 0.000578627256413 12 - 57 | -3.25891042718e-05 12 - 58 | -3.38202019192e-07 12 - 59 | 0.0 12 - 60 | 0.00586223927756 12 - 61 | 0.00241778445179 12 - 62 | 0.000907709559216 12 - 63 | -0.000948990255407 12 - 64 | -0.000781369902774 12 - 65 | 0.00335553192477 12 - 66 | 0.00367801008527 12 - 67 | 0.00153309269583 12 - 68 | 0.00085399823275 12 - 69 | -4.76236568959e-05 12 - 70 | -2.42311296725e-05 12 - 71 | 0.0 12 - 72 | 0.00487704524262 12 - 73 | 0.00792026484135 12 - 74 | 0.0115725607421 12 - 75 | 0.0130757894272 12 - 76 | 0.0109553075376 12 - 77 | 0.00189865826564 12 - 78 | 0.00259303108222 12 - 79 | 0.0020872322784 12 - 80 | 0.00118978582366 12 - 81 | 0.000915710296527 12 - 82 | 0.000243458629137 12 - 83 | 4.15413622361e-07 12 - 84 | 0.00182808096654 12 - 85 | 0.00382907425086 12 - 86 | 0.00377818077254 12 - 87 | 0.00491378017153 12 - 88 | 0.0035295522578 12 - 89 | 0.000895026295766 12 - 90 | 0.00192917468639 12 - 91 | 0.00210458821759 12 - 92 | 0.00143325653292 12 - 93 | 0.000998206255637 12 - 94 | 0.000783566757454 12 - 95 | 2.40824546492e-05 13 - 0 | 0.00925039953685 13 - 1 | 0.0114178972261 13 - 2 | 0.00721400229273 13 - 3 | 0.00195832478714 13 - 4 | 0.000194542424835 13 - 5 | 0.000196735864132 13 - 6 | -3.29665951459e-05 13 - 7 | -9.52629662504e-06 13 - 8 | 0.0 13 - 9 | 0.0 13 - 10 | 0.0 13 - 11 | 0.0 13 - 12 | 0.00738495490201 13 - 13 | 0.0112871422638 13 - 14 | 0.0065561655133 13 - 15 | 0.00173834456214 13 - 16 | 0.00223290821685 13 - 17 | 0.000557896581682 13 - 18 | 0.000148397778411 13 - 19 | 0.000170360697007 13 - 20 | -7.86924611921e-06 13 - 21 | 0.0 13 - 22 | 0.0 13 - 23 | 0.0 13 - 24 | 0.00796363832398 13 - 25 | 0.0106313499222 13 - 26 | 0.00693364400455 13 - 27 | 0.00247012245543 13 - 28 | 0.00260291532728 13 - 29 | 0.00198494640747 13 - 30 | 0.00058804226409 13 - 31 | 0.000377258778082 13 - 32 | -0.00108238817391 13 - 33 | -0.000172769880751 13 - 34 | 0.0 13 - 35 | 0.0 13 - 36 | 0.00886881081 13 - 37 | 0.0113072163305 13 - 38 | 0.00783915460536 13 - 39 | 0.00715171630418 13 - 40 | 0.00330611360472 13 - 41 | 0.00252085217408 13 - 42 | 0.00149711589378 13 - 43 | 0.000837978247683 13 - 44 | -0.000348165722607 13 - 45 | -0.000914450981313 13 - 46 | 0.0 13 - 47 | 0.0 13 - 48 | 0.00833886450612 13 - 49 | 0.00734454532743 13 - 50 | 0.00774135969966 13 - 51 | 0.0054135330859 13 - 52 | 0.00406653233867 13 - 53 | 0.00573979536839 13 - 54 | 0.00142716913038 13 - 55 | 0.022812038697 13 - 56 | 0.000796782741658 13 - 57 | -2.52284661e-05 13 - 58 | 7.82857988645e-06 13 - 59 | 0.0 13 - 60 | 0.00776009528636 13 - 61 | 0.00387687637469 13 - 62 | 0.00116495942012 13 - 63 | -0.00152441868254 13 - 64 | -0.00125313628052 13 - 65 | 0.00444434119722 13 - 66 | 0.00496931783339 13 - 67 | 0.00197112086859 13 - 68 | 0.00115729945144 13 - 69 | -2.46169387136e-05 13 - 70 | -2.47618794125e-06 13 - 71 | 0.0 13 - 72 | 0.0065018232222 13 - 73 | 0.01179131568 13 - 74 | 0.0159902367356 13 - 75 | 0.0172882263506 13 - 76 | 0.0149191673677 13 - 77 | 0.00269097012582 13 - 78 | 0.0034752072758 13 - 79 | 0.00301101701349 13 - 80 | 0.00165282341897 13 - 81 | 0.00121538522833 13 - 82 | 0.000305680951194 13 - 83 | 1.60413405321e-06 13 - 84 | 0.00237824954516 13 - 85 | 0.00588916360739 13 - 86 | 0.00556987585579 13 - 87 | 0.00661225539675 13 - 88 | 0.00474861922987 13 - 89 | 0.00126859444928 13 - 90 | 0.00281213761845 13 - 91 | 0.00325402630619 13 - 92 | 0.00227960773679 13 - 93 | 0.00145762081629 13 - 94 | 0.000709777532503 13 - 95 | 8.00226061321e-06 14 - 0 | 0.00701414334472 14 - 1 | 0.00820267464135 14 - 2 | 0.00628016178814 14 - 3 | 0.00194477108428 14 - 4 | 0.000790979257901 14 - 5 | 0.000388498497676 14 - 6 | 9.46609014262e-05 14 - 7 | 3.39147105503e-05 14 - 8 | 0.0 14 - 9 | 0.0 14 - 10 | 0.0 14 - 11 | 0.0 14 - 12 | 0.00547495619336 14 - 13 | 0.0065561655133 14 - 14 | 0.00709028347928 14 - 15 | 0.00278077245064 14 - 16 | 0.00180377135867 14 - 17 | 0.000900371234336 14 - 18 | 0.000439468065963 14 - 19 | 0.000253153216742 14 - 20 | 5.06016704466e-05 14 - 21 | 0.0 14 - 22 | 0.0 14 - 23 | 0.0 14 - 24 | 0.00566494641328 14 - 25 | 0.00660518702999 14 - 26 | 0.00679439349494 14 - 27 | 0.00352945575801 14 - 28 | 0.00243841750601 14 - 29 | 0.00177169458615 14 - 30 | 0.00103193975038 14 - 31 | 0.000665932518666 14 - 32 | -0.000316859362331 14 - 33 | -6.34546487023e-05 14 - 34 | 0.0 14 - 35 | 0.0 14 - 36 | 0.00599458040769 14 - 37 | 0.00640728535568 14 - 38 | 0.00690672455254 14 - 39 | 0.00515107986717 14 - 40 | 0.00307982045507 14 - 41 | 0.0023214886812 14 - 42 | 0.00162313512132 14 - 43 | 0.0013310152611 14 - 44 | 0.000285762817459 14 - 45 | -0.000443158069752 14 - 46 | 0.0 14 - 47 | 0.0 14 - 48 | 0.00570775261146 14 - 49 | 0.00502489598376 14 - 50 | 0.00637613507715 14 - 51 | 0.00483738655846 14 - 52 | 0.00388355976446 14 - 53 | 0.00358550985961 14 - 54 | 0.00189580232369 14 - 55 | 0.0114599489359 14 - 56 | 0.00115008526045 14 - 57 | 0.000266294772333 14 - 58 | 2.5164888014e-05 14 - 59 | 0.0 14 - 60 | 0.00566537069901 14 - 61 | 0.00380732772459 14 - 62 | 0.00441958185205 14 - 63 | 0.00308019427296 14 - 64 | 0.00225721712128 14 - 65 | 0.00346360539975 14 - 66 | 0.00339469880782 14 - 67 | 0.0024543081437 14 - 68 | 0.0017129684139 14 - 69 | 0.000599681228219 14 - 70 | 8.2245791309e-05 14 - 71 | 0.0 14 - 72 | 0.00472039946108 14 - 73 | 0.00584939830844 14 - 74 | 0.00775106688838 14 - 75 | 0.00843159185614 14 - 76 | 0.00661537307958 14 - 77 | 0.0030025074562 14 - 78 | 0.00305616445496 14 - 79 | 0.00270688323905 14 - 80 | 0.00224743975742 14 - 81 | 0.00172922063907 14 - 82 | 0.00061572695175 14 - 83 | 2.79634930964e-06 14 - 84 | 0.00273757625198 14 - 85 | 0.00353325445569 14 - 86 | 0.00375891588839 14 - 87 | 0.00436477753721 14 - 88 | 0.00306126325257 14 - 89 | 0.00209407270783 14 - 90 | 0.00236924922463 14 - 91 | 0.00231578421108 14 - 92 | 0.00209437098026 14 - 93 | 0.00200695946297 14 - 94 | 0.00211488788243 14 - 95 | 0.000114160740723 15 - 0 | 0.00196275612097 15 - 1 | 0.00278787478704 15 - 2 | 0.00211595635276 15 - 3 | 0.00100788193687 15 - 4 | 0.000676359730394 15 - 5 | 0.000301131247354 15 - 6 | 0.000152673476472 15 - 7 | 4.69591494583e-05 15 - 8 | 0.0 15 - 9 | 0.0 15 - 10 | 0.0 15 - 11 | 0.0 15 - 12 | 0.00161162933552 15 - 13 | 0.00173834456214 15 - 14 | 0.00278077245064 15 - 15 | 0.00211773200788 15 - 16 | 0.000711758784727 15 - 17 | 0.00064120354352 15 - 18 | 0.000380540107515 15 - 19 | 0.000177697921257 15 - 20 | 5.94942673253e-05 15 - 21 | 0.0 15 - 22 | 0.0 15 - 23 | 0.0 15 - 24 | 0.00146764602336 15 - 25 | 0.00192069389633 15 - 26 | 0.00297437448157 15 - 27 | 0.00245828709059 15 - 28 | 0.00118273570724 15 - 29 | 0.000717857843064 15 - 30 | 0.000764163390249 15 - 31 | 0.000474206398427 15 - 32 | 0.000253320168408 15 - 33 | 2.68237387248e-05 15 - 34 | 0.0 15 - 35 | 0.0 15 - 36 | 0.00114177150848 15 - 37 | 0.00118980939033 15 - 38 | 0.00262900079543 15 - 39 | 0.00152014580008 15 - 40 | 0.00143530746785 15 - 41 | 0.0010671989346 15 - 42 | 0.000982553879127 15 - 43 | 0.00089229234333 15 - 44 | 0.000492474076416 15 - 45 | 6.40101536591e-05 15 - 46 | 0.0 15 - 47 | 0.0 15 - 48 | 0.00106435414763 15 - 49 | 0.00193304240255 15 - 50 | 0.00256734858771 15 - 51 | 0.00226320580332 15 - 52 | 0.00185228828746 15 - 53 | 0.000853798858056 15 - 54 | 0.00138104554655 15 - 55 | -0.00207581435516 15 - 56 | 0.000727017592617 15 - 57 | 0.000296309625168 15 - 58 | 2.5799445536e-05 15 - 59 | 0.0 15 - 60 | 0.00138429345514 15 - 61 | 0.00245555603155 15 - 62 | 0.00441542057133 15 - 63 | 0.00449648515342 15 - 64 | 0.00338717098102 15 - 65 | 0.00129225538067 15 - 66 | 0.000929632546129 15 - 67 | 0.00134748613721 15 - 68 | 0.00117281906948 15 - 69 | 0.000655366110081 15 - 70 | 0.000107273132427 15 - 71 | 0.0 15 - 72 | 0.00118541635665 15 - 73 | 0.000245606738472 15 - 74 | -0.000504895891191 15 - 75 | -0.000982872860752 15 - 76 | -0.0011857648411 15 - 77 | 0.00200845327509 15 - 78 | 0.00142311490492 15 - 79 | 0.00141916840516 15 - 80 | 0.00149507292872 15 - 81 | 0.00104136940636 15 - 82 | 0.000416557801807 15 - 83 | 2.46376449701e-06 15 - 84 | 0.00146355093023 15 - 85 | 0.000854561638168 15 - 86 | 0.00124364125129 15 - 87 | 0.000971873789125 15 - 88 | 0.000769119500356 15 - 89 | 0.00170173650989 15 - 90 | 0.00114216252521 15 - 91 | 0.000919177964981 15 - 92 | 0.00114713495716 15 - 93 | 0.0012920445037 15 - 94 | 0.00152627568981 15 - 95 | 9.22706509619e-05 16 - 0 | 0.00218592771666 16 - 1 | 0.0025782770829 16 - 2 | 0.00192482772257 16 - 3 | 0.000605630862435 16 - 4 | 0.000186176381066 16 - 5 | 9.16317853728e-05 16 - 6 | 1.43722019347e-05 16 - 7 | 2.86991256371e-06 16 - 8 | 0.0 16 - 9 | 0.0 16 - 10 | 0.0 16 - 11 | 0.0 16 - 12 | 0.00171596427143 16 - 13 | 0.00223290821685 16 - 14 | 0.00180377135867 16 - 15 | 0.000711758784727 16 - 16 | 0.00077804393371 16 - 17 | 0.000276792616421 16 - 18 | 9.39018761016e-05 16 - 19 | 7.0518252298e-05 16 - 20 | 1.09823491307e-05 16 - 21 | 0.0 16 - 22 | 0.0 16 - 23 | 0.0 16 - 24 | 0.00181617936575 16 - 25 | 0.00224092625965 16 - 26 | 0.00179039355959 16 - 27 | 0.000785074197095 16 - 28 | 0.000788082568938 16 - 29 | 0.000589406984104 16 - 30 | 0.000244104035441 16 - 31 | 0.000159495856988 16 - 32 | -0.00017249651998 16 - 33 | -2.80073801755e-05 16 - 34 | 0.0 16 - 35 | 0.0 16 - 36 | 0.00198971091558 16 - 37 | 0.0024212584551 16 - 38 | 0.0021757268031 16 - 39 | 0.00179276821116 16 - 40 | 0.000904577230632 16 - 41 | 0.000755364674392 16 - 42 | 0.000480111245934 16 - 43 | 0.000316267644237 16 - 44 | 1.95941590839e-05 16 - 45 | -0.000176265084179 16 - 46 | 0.0 16 - 47 | 0.0 16 - 48 | 0.00183512876058 16 - 49 | 0.00154436568096 16 - 50 | 0.00181362146222 16 - 51 | 0.00130405376537 16 - 52 | 0.00100226010705 16 - 53 | 0.00138257528972 16 - 54 | 0.000572799003831 16 - 55 | 0.00500045706079 16 - 56 | 0.000304551110857 16 - 57 | 5.62479500469e-05 16 - 58 | 7.78661210308e-06 16 - 59 | 0.0 16 - 60 | 0.00173019344471 16 - 61 | 0.000813041627697 16 - 62 | 0.0002888252758 16 - 63 | -0.000305437872496 16 - 64 | -0.00021352928326 16 - 65 | 0.00114429563474 16 - 66 | 0.00122802165952 16 - 67 | 0.000612757465804 16 - 68 | 0.000444335656066 16 - 69 | 0.000122529289649 16 - 70 | 2.34930635979e-05 16 - 71 | 0.0 16 - 72 | 0.00148924121463 16 - 73 | 0.0024729878623 16 - 74 | 0.00368848486164 16 - 75 | 0.00405457911648 16 - 76 | 0.00334597335519 16 - 77 | 0.00061476565534 16 - 78 | 0.000935539233953 16 - 79 | 0.000803881014436 16 - 80 | 0.000577699353159 16 - 81 | 0.0004631048629 16 - 82 | 0.000173152704311 16 - 83 | 8.48383212098e-07 16 - 84 | 0.000695460851309 16 - 85 | 0.00121277162448 16 - 86 | 0.00129029355397 16 - 87 | 0.00153099793592 16 - 88 | 0.00118168873857 16 - 89 | 0.000341391218293 16 - 90 | 0.000682595428772 16 - 91 | 0.000776493963073 16 - 92 | 0.000609938712503 16 - 93 | 0.000529318406691 16 - 94 | 0.00054356606817 16 - 95 | 2.53156969404e-05 17 - 0 | 0.000526274761454 17 - 1 | 0.000860617988881 17 - 2 | 0.000673891083816 17 - 3 | 0.000372336829169 17 - 4 | 0.000281573723441 17 - 5 | 0.000122519590494 17 - 6 | 6.78762510082e-05 17 - 7 | 2.46179928104e-05 17 - 8 | 0.0 17 - 9 | 0.0 17 - 10 | 0.0 17 - 11 | 0.0 17 - 12 | 0.000430490562737 17 - 13 | 0.000557896581682 17 - 14 | 0.000900371234336 17 - 15 | 0.00064120354352 17 - 16 | 0.000276792616421 17 - 17 | 0.000324798685576 17 - 18 | 0.000169748531677 17 - 19 | 8.02335826783e-05 17 - 20 | 3.28532394612e-05 17 - 21 | 0.0 17 - 22 | 0.0 17 - 23 | 0.0 17 - 24 | 0.000339330121996 17 - 25 | 0.000544821118153 17 - 26 | 0.000880962658508 17 - 27 | 0.000739309834366 17 - 28 | 0.000426480075966 17 - 29 | 0.000273725261666 17 - 30 | 0.000327115550824 17 - 31 | 0.000212556957804 17 - 32 | 0.000170606587726 17 - 33 | 2.17930555629e-05 17 - 34 | 0.0 17 - 35 | 0.0 17 - 36 | 0.000179418662233 17 - 37 | 0.000356816014571 17 - 38 | 0.000997744663346 17 - 39 | 0.000479393383001 17 - 40 | 0.000470574381718 17 - 41 | 0.00038427714671 17 - 42 | 0.000375872603941 17 - 43 | 0.00034631674949 17 - 44 | 0.000224164820638 17 - 45 | 4.89348302556e-05 17 - 46 | 0.0 17 - 47 | 0.0 17 - 48 | 0.000113177975731 17 - 49 | 0.000589691477253 17 - 50 | 0.00075928791182 17 - 51 | 0.000639699370921 17 - 52 | 0.000496190399231 17 - 53 | 0.00027132793234 17 - 54 | 0.000503181435557 17 - 55 | -0.00107016892116 17 - 56 | 0.000277732048766 17 - 57 | 0.000129403592883 17 - 58 | 1.37137609581e-05 17 - 59 | 0.0 17 - 60 | 0.00020342009987 17 - 61 | 0.000715207796175 17 - 62 | 0.00125674533621 17 - 63 | 0.00124497643652 17 - 64 | 0.000971030730058 17 - 65 | 0.000415420310237 17 - 66 | 0.000254464817321 17 - 67 | 0.000505384846876 17 - 68 | 0.000458106186948 17 - 69 | 0.000276049729958 17 - 70 | 4.75902457336e-05 17 - 71 | 0.0 17 - 72 | 0.000225923684571 17 - 73 | 1.95830830867e-05 17 - 74 | -5.22980886156e-05 17 - 75 | -0.000248339030904 17 - 76 | -0.000317472482531 17 - 77 | 0.000553121291578 17 - 78 | 0.000452947975198 17 - 79 | 0.000516885160013 17 - 80 | 0.000589336346224 17 - 81 | 0.000412633775641 17 - 82 | 0.000163146031535 17 - 83 | 1.10571143935e-06 17 - 84 | 0.000437981784059 17 - 85 | 0.000211379757869 17 - 86 | 0.000428015846882 17 - 87 | 0.000261547816219 17 - 88 | 0.0002646666016 17 - 89 | 0.000493147438129 17 - 90 | 0.000333912779089 17 - 91 | 0.000304624593477 17 - 92 | 0.00046343161874 17 - 93 | 0.000541785124794 17 - 94 | 0.000597738487733 17 - 95 | 3.60881149899e-05 18 - 0 | 0.000118864327899 18 - 1 | 0.000324911663803 18 - 2 | 0.000264372487888 18 - 3 | 0.00019190419152 18 - 4 | 0.000181172760934 18 - 5 | 7.85526503431e-05 18 - 6 | 4.85619043674e-05 18 - 7 | 1.78954537394e-05 18 - 8 | 0.0 18 - 9 | 0.0 18 - 10 | 0.0 18 - 11 | 0.0 18 - 12 | 0.000101558946076 18 - 13 | 0.000148397778411 18 - 14 | 0.000439468065963 18 - 15 | 0.000380540107515 18 - 16 | 9.39018761016e-05 18 - 17 | 0.000169748531677 18 - 18 | 0.000127555330645 18 - 19 | 5.5567658946e-05 18 - 20 | 2.15761279402e-05 18 - 21 | 0.0 18 - 22 | 0.0 18 - 23 | 0.0 18 - 24 | 2.88857620464e-05 18 - 25 | 0.000152340884351 18 - 26 | 0.000438611714118 18 - 27 | 0.000456220855083 18 - 28 | 0.00020437947403 18 - 29 | 0.000112319186085 18 - 30 | 0.00020716554096 18 - 31 | 0.00013215393449 18 - 32 | 0.000115466517649 18 - 33 | 1.55564698471e-05 18 - 34 | 0.0 18 - 35 | 0.0 18 - 36 | -0.000107960636928 18 - 37 | -2.17784912597e-05 18 - 38 | 0.00045440265606 18 - 39 | 0.000127892614565 18 - 40 | 0.00022859945611 18 - 41 | 0.000161999895422 18 - 42 | 0.000197814703892 18 - 43 | 0.000228723909561 18 - 44 | 0.000153082320126 18 - 45 | 5.73322176284e-05 18 - 46 | 0.0 18 - 47 | 0.0 18 - 48 | -0.000126753831304 18 - 49 | 0.00022718221415 18 - 50 | 0.000343846015831 18 - 51 | 0.000321467919741 18 - 52 | 0.000254322273049 18 - 53 | 2.58825771672e-05 18 - 54 | 0.000271759331398 18 - 55 | -0.000892914944398 18 - 56 | 0.000177501886089 18 - 57 | 8.70027487742e-05 18 - 58 | 8.70154414347e-06 18 - 59 | 0.0 18 - 60 | -4.97111545211e-05 18 - 61 | 0.000430338589326 18 - 62 | 0.000918187833653 18 - 63 | 0.000988218387516 18 - 64 | 0.00075810328622 18 - 65 | 0.000143738665592 18 - 66 | 3.23893263978e-06 18 - 67 | 0.000297532888634 18 - 68 | 0.000301947094339 18 - 69 | 0.000189295620218 18 - 70 | 2.99804612078e-05 18 - 71 | 0.0 18 - 72 | 2.54032809827e-07 18 - 73 | -0.000284718068091 18 - 74 | -0.000520231807983 18 - 75 | -0.000729508200303 18 - 76 | -0.000685125607051 18 - 77 | 0.000333050070988 18 - 78 | 0.000165703767009 18 - 79 | 0.000251117032279 18 - 80 | 0.000375949846666 18 - 81 | 0.00025827099998 18 - 82 | 8.64062360184e-05 18 - 83 | 6.65127775293e-07 18 - 84 | 0.000262161218164 18 - 85 | 7.88450726967e-06 18 - 86 | 0.000158470331452 18 - 87 | -5.22247884546e-06 18 - 88 | 1.37374421694e-05 18 - 89 | 0.000311852553481 18 - 90 | 0.000138656988571 18 - 91 | 8.9954803605e-05 18 - 92 | 0.000268952010863 18 - 93 | 0.000366127891345 18 - 94 | 0.000354646350379 18 - 95 | 2.310816281e-05 19 - 0 | 0.000153699768568 19 - 1 | 0.00024920507364 19 - 2 | 0.000198611516928 19 - 3 | 0.000103874301554 19 - 4 | 7.64854039587e-05 19 - 5 | 3.67625561623e-05 19 - 6 | 2.62904764127e-05 19 - 7 | 1.00470395344e-05 19 - 8 | 0.0 19 - 9 | 0.0 19 - 10 | 0.0 19 - 11 | 0.0 19 - 12 | 0.000122124206135 19 - 13 | 0.000170360697007 19 - 14 | 0.000253153216742 19 - 15 | 0.000177697921257 19 - 16 | 7.0518252298e-05 19 - 17 | 8.02335826783e-05 19 - 18 | 5.5567658946e-05 19 - 19 | 3.60599396758e-05 19 - 20 | 1.46376366435e-05 19 - 21 | 0.0 19 - 22 | 0.0 19 - 23 | 0.0 19 - 24 | 9.16512913949e-05 19 - 25 | 0.000162767053062 19 - 26 | 0.000248335060461 19 - 27 | 0.0002045842223 19 - 28 | 0.000118029980445 19 - 29 | 7.49281420187e-05 19 - 30 | 9.55578749366e-05 19 - 31 | 7.67817358921e-05 19 - 32 | 5.94129962513e-05 19 - 33 | 9.13439165198e-06 19 - 34 | 0.0 19 - 35 | 0.0 19 - 36 | 5.7944923863e-05 19 - 37 | 0.000103421977998 19 - 38 | 0.000250212162391 19 - 39 | 0.000136543695034 19 - 40 | 0.000137678018191 19 - 41 | 9.99595748323e-05 19 - 42 | 0.00010440808527 19 - 43 | 0.000105652801889 19 - 44 | 7.05911840137e-05 19 - 45 | 1.81163342554e-05 19 - 46 | 0.0 19 - 47 | 0.0 19 - 48 | 2.80094317198e-05 19 - 49 | 0.000146789880318 19 - 50 | 0.000201626024913 19 - 51 | 0.000184142707965 19 - 52 | 0.000148617608606 19 - 53 | 8.08150320655e-05 19 - 54 | 0.000133614217643 19 - 55 | 5.93505482591e-05 19 - 56 | 8.39324347371e-05 19 - 57 | 4.13566034186e-05 19 - 58 | 5.46413482885e-06 19 - 59 | 0.0 19 - 60 | 5.08897636169e-05 19 - 61 | 0.000165219514515 19 - 62 | 0.000346606361882 19 - 63 | 0.000349766233691 19 - 64 | 0.000269643786557 19 - 65 | 0.000106983093251 19 - 66 | 6.59527573768e-05 19 - 67 | 0.000134282100757 19 - 68 | 0.000137187147623 19 - 69 | 8.40667288962e-05 19 - 70 | 1.52189210677e-05 19 - 71 | 0.0 19 - 72 | 6.61736154919e-05 19 - 73 | -1.48177106728e-05 19 - 74 | -2.37502394493e-05 19 - 75 | -6.06279056594e-05 19 - 76 | -8.12783090711e-05 19 - 77 | 0.000146680209447 19 - 78 | 0.000112005450232 19 - 79 | 0.000137721970303 19 - 80 | 0.000175380348059 19 - 81 | 0.000131123728824 19 - 82 | 4.68615979227e-05 19 - 83 | 3.35187150971e-07 19 - 84 | 0.000110580685534 19 - 85 | 5.05537189692e-05 19 - 86 | 0.0001160567703 19 - 87 | 7.30396151324e-05 19 - 88 | 5.99261380982e-05 19 - 89 | 0.000125523068849 19 - 90 | 7.94130473013e-05 19 - 91 | 7.24978995631e-05 19 - 92 | 0.000141128674853 19 - 93 | 0.000177015282715 19 - 94 | 0.000182400427173 19 - 95 | 1.06503082887e-05 20 - 0 | -1.06059542869e-05 20 - 1 | 1.62389166501e-05 20 - 2 | 1.13431953358e-05 20 - 3 | 2.80038893394e-05 20 - 4 | 3.59698430932e-05 20 - 5 | 1.35908830685e-05 20 - 6 | 1.23353331468e-05 20 - 7 | 5.62175167229e-06 20 - 8 | 0.0 20 - 9 | 0.0 20 - 10 | 0.0 20 - 11 | 0.0 20 - 12 | -5.76239183576e-06 20 - 13 | -7.86924611921e-06 20 - 14 | 5.06016704466e-05 20 - 15 | 5.94942673253e-05 20 - 16 | 1.09823491307e-05 20 - 17 | 3.28532394612e-05 20 - 18 | 2.15761279402e-05 20 - 19 | 1.46376366435e-05 20 - 20 | 9.73977321123e-06 20 - 21 | 0.0 20 - 22 | 0.0 20 - 23 | 0.0 20 - 24 | -2.81980431362e-05 20 - 25 | -1.08235953837e-05 20 - 26 | 4.33547295304e-05 20 - 27 | 6.65486998527e-05 20 - 28 | 3.33745038867e-05 20 - 29 | 1.80412646569e-05 20 - 30 | 4.20237346431e-05 20 - 31 | 3.78711291129e-05 20 - 32 | 5.16528142834e-05 20 - 33 | 7.58773888664e-06 20 - 34 | 0.0 20 - 35 | 0.0 20 - 36 | -4.81483884194e-05 20 - 37 | -4.23860841996e-05 20 - 38 | 4.7707996186e-05 20 - 39 | -3.40933224574e-06 20 - 40 | 3.41865784696e-05 20 - 41 | 2.55554436084e-05 20 - 42 | 3.71890124568e-05 20 - 43 | 3.55524771759e-05 20 - 44 | 3.75124163178e-05 20 - 45 | 1.7588916496e-05 20 - 46 | 0.0 20 - 47 | 0.0 20 - 48 | -5.35637847066e-05 20 - 49 | 1.37290431604e-05 20 - 50 | 2.5347759359e-05 20 - 51 | 3.37305146644e-05 20 - 52 | 3.08939395807e-05 20 - 53 | -1.89073511327e-05 20 - 54 | 3.82638709817e-05 20 - 55 | -2.07310790605e-05 20 - 56 | 2.2494140942e-05 20 - 57 | 1.77877963647e-05 20 - 58 | 3.07679505237e-06 20 - 59 | 0.0 20 - 60 | -4.22519148636e-05 20 - 61 | 4.63719738142e-05 20 - 62 | 0.00015907842925 20 - 63 | 0.000182299400462 20 - 64 | 0.000139081471277 20 - 65 | 8.38247095585e-06 20 - 66 | -7.98247970154e-06 20 - 67 | 4.57717953188e-05 20 - 68 | 3.9275845623e-05 20 - 69 | 3.45003388756e-05 20 - 70 | 6.50266772165e-06 20 - 71 | 0.0 20 - 72 | -2.45729459774e-05 20 - 73 | -0.00010968945764 20 - 74 | -0.000155939817195 20 - 75 | -0.000192317449157 20 - 76 | -0.000170189089934 20 - 77 | 4.90186141977e-05 20 - 78 | 2.57108335718e-05 20 - 79 | 4.1157705062e-05 20 - 80 | 5.09745409787e-05 20 - 81 | 3.63230475461e-05 20 - 82 | 1.55979660256e-05 20 - 83 | 1.4905664864e-07 20 - 84 | 3.20642187595e-05 20 - 85 | -1.43980051954e-05 20 - 86 | 1.40870933455e-05 20 - 87 | -2.51672187618e-05 20 - 88 | -2.54958755208e-05 20 - 89 | 4.71610461667e-05 20 - 90 | 1.91389252777e-05 20 - 91 | 1.56237009275e-05 20 - 92 | 4.07713416332e-05 20 - 93 | 4.77818388183e-05 20 - 94 | 5.50023108642e-05 20 - 95 | 3.52111379177e-06 21 - 0 | 0.0 21 - 1 | 0.0 21 - 2 | 0.0 21 - 3 | 0.0 21 - 4 | 0.0 21 - 5 | 0.0 21 - 6 | 0.0 21 - 7 | 0.0 21 - 8 | 0.0 21 - 9 | 0.0 21 - 10 | 0.0 21 - 11 | 0.0 21 - 12 | 0.0 21 - 13 | 0.0 21 - 14 | 0.0 21 - 15 | 0.0 21 - 16 | 0.0 21 - 17 | 0.0 21 - 18 | 0.0 21 - 19 | 0.0 21 - 20 | 0.0 21 - 21 | 0.0 21 - 22 | 0.0 21 - 23 | 0.0 21 - 24 | 0.0 21 - 25 | 0.0 21 - 26 | 0.0 21 - 27 | 0.0 21 - 28 | 0.0 21 - 29 | 0.0 21 - 30 | 0.0 21 - 31 | 0.0 21 - 32 | 0.0 21 - 33 | 0.0 21 - 34 | 0.0 21 - 35 | 0.0 21 - 36 | 0.0 21 - 37 | 0.0 21 - 38 | 0.0 21 - 39 | 0.0 21 - 40 | 0.0 21 - 41 | 0.0 21 - 42 | 0.0 21 - 43 | 0.0 21 - 44 | 0.0 21 - 45 | 0.0 21 - 46 | 0.0 21 - 47 | 0.0 21 - 48 | 0.0 21 - 49 | 0.0 21 - 50 | 0.0 21 - 51 | 0.0 21 - 52 | 0.0 21 - 53 | 0.0 21 - 54 | 0.0 21 - 55 | 0.0 21 - 56 | 0.0 21 - 57 | 0.0 21 - 58 | 0.0 21 - 59 | 0.0 21 - 60 | 0.0 21 - 61 | 0.0 21 - 62 | 0.0 21 - 63 | 0.0 21 - 64 | 0.0 21 - 65 | 0.0 21 - 66 | 0.0 21 - 67 | 0.0 21 - 68 | 0.0 21 - 69 | 0.0 21 - 70 | 0.0 21 - 71 | 0.0 21 - 72 | 0.0 21 - 73 | 0.0 21 - 74 | 0.0 21 - 75 | 0.0 21 - 76 | 0.0 21 - 77 | 0.0 21 - 78 | 0.0 21 - 79 | 0.0 21 - 80 | 0.0 21 - 81 | 0.0 21 - 82 | 0.0 21 - 83 | 0.0 21 - 84 | 0.0 21 - 85 | 0.0 21 - 86 | 0.0 21 - 87 | 0.0 21 - 88 | 0.0 21 - 89 | 0.0 21 - 90 | 0.0 21 - 91 | 0.0 21 - 92 | 0.0 21 - 93 | 0.0 21 - 94 | 0.0 21 - 95 | 0.0 22 - 0 | 0.0 22 - 1 | 0.0 22 - 2 | 0.0 22 - 3 | 0.0 22 - 4 | 0.0 22 - 5 | 0.0 22 - 6 | 0.0 22 - 7 | 0.0 22 - 8 | 0.0 22 - 9 | 0.0 22 - 10 | 0.0 22 - 11 | 0.0 22 - 12 | 0.0 22 - 13 | 0.0 22 - 14 | 0.0 22 - 15 | 0.0 22 - 16 | 0.0 22 - 17 | 0.0 22 - 18 | 0.0 22 - 19 | 0.0 22 - 20 | 0.0 22 - 21 | 0.0 22 - 22 | 0.0 22 - 23 | 0.0 22 - 24 | 0.0 22 - 25 | 0.0 22 - 26 | 0.0 22 - 27 | 0.0 22 - 28 | 0.0 22 - 29 | 0.0 22 - 30 | 0.0 22 - 31 | 0.0 22 - 32 | 0.0 22 - 33 | 0.0 22 - 34 | 0.0 22 - 35 | 0.0 22 - 36 | 0.0 22 - 37 | 0.0 22 - 38 | 0.0 22 - 39 | 0.0 22 - 40 | 0.0 22 - 41 | 0.0 22 - 42 | 0.0 22 - 43 | 0.0 22 - 44 | 0.0 22 - 45 | 0.0 22 - 46 | 0.0 22 - 47 | 0.0 22 - 48 | 0.0 22 - 49 | 0.0 22 - 50 | 0.0 22 - 51 | 0.0 22 - 52 | 0.0 22 - 53 | 0.0 22 - 54 | 0.0 22 - 55 | 0.0 22 - 56 | 0.0 22 - 57 | 0.0 22 - 58 | 0.0 22 - 59 | 0.0 22 - 60 | 0.0 22 - 61 | 0.0 22 - 62 | 0.0 22 - 63 | 0.0 22 - 64 | 0.0 22 - 65 | 0.0 22 - 66 | 0.0 22 - 67 | 0.0 22 - 68 | 0.0 22 - 69 | 0.0 22 - 70 | 0.0 22 - 71 | 0.0 22 - 72 | 0.0 22 - 73 | 0.0 22 - 74 | 0.0 22 - 75 | 0.0 22 - 76 | 0.0 22 - 77 | 0.0 22 - 78 | 0.0 22 - 79 | 0.0 22 - 80 | 0.0 22 - 81 | 0.0 22 - 82 | 0.0 22 - 83 | 0.0 22 - 84 | 0.0 22 - 85 | 0.0 22 - 86 | 0.0 22 - 87 | 0.0 22 - 88 | 0.0 22 - 89 | 0.0 22 - 90 | 0.0 22 - 91 | 0.0 22 - 92 | 0.0 22 - 93 | 0.0 22 - 94 | 0.0 22 - 95 | 0.0 23 - 0 | 0.0 23 - 1 | 0.0 23 - 2 | 0.0 23 - 3 | 0.0 23 - 4 | 0.0 23 - 5 | 0.0 23 - 6 | 0.0 23 - 7 | 0.0 23 - 8 | 0.0 23 - 9 | 0.0 23 - 10 | 0.0 23 - 11 | 0.0 23 - 12 | 0.0 23 - 13 | 0.0 23 - 14 | 0.0 23 - 15 | 0.0 23 - 16 | 0.0 23 - 17 | 0.0 23 - 18 | 0.0 23 - 19 | 0.0 23 - 20 | 0.0 23 - 21 | 0.0 23 - 22 | 0.0 23 - 23 | 0.0 23 - 24 | 0.0 23 - 25 | 0.0 23 - 26 | 0.0 23 - 27 | 0.0 23 - 28 | 0.0 23 - 29 | 0.0 23 - 30 | 0.0 23 - 31 | 0.0 23 - 32 | 0.0 23 - 33 | 0.0 23 - 34 | 0.0 23 - 35 | 0.0 23 - 36 | 0.0 23 - 37 | 0.0 23 - 38 | 0.0 23 - 39 | 0.0 23 - 40 | 0.0 23 - 41 | 0.0 23 - 42 | 0.0 23 - 43 | 0.0 23 - 44 | 0.0 23 - 45 | 0.0 23 - 46 | 0.0 23 - 47 | 0.0 23 - 48 | 0.0 23 - 49 | 0.0 23 - 50 | 0.0 23 - 51 | 0.0 23 - 52 | 0.0 23 - 53 | 0.0 23 - 54 | 0.0 23 - 55 | 0.0 23 - 56 | 0.0 23 - 57 | 0.0 23 - 58 | 0.0 23 - 59 | 0.0 23 - 60 | 0.0 23 - 61 | 0.0 23 - 62 | 0.0 23 - 63 | 0.0 23 - 64 | 0.0 23 - 65 | 0.0 23 - 66 | 0.0 23 - 67 | 0.0 23 - 68 | 0.0 23 - 69 | 0.0 23 - 70 | 0.0 23 - 71 | 0.0 23 - 72 | 0.0 23 - 73 | 0.0 23 - 74 | 0.0 23 - 75 | 0.0 23 - 76 | 0.0 23 - 77 | 0.0 23 - 78 | 0.0 23 - 79 | 0.0 23 - 80 | 0.0 23 - 81 | 0.0 23 - 82 | 0.0 23 - 83 | 0.0 23 - 84 | 0.0 23 - 85 | 0.0 23 - 86 | 0.0 23 - 87 | 0.0 23 - 88 | 0.0 23 - 89 | 0.0 23 - 90 | 0.0 23 - 91 | 0.0 23 - 92 | 0.0 23 - 93 | 0.0 23 - 94 | 0.0 23 - 95 | 0.0 24 - 0 | 0.00762330621865 24 - 1 | 0.00880773826827 24 - 2 | 0.00637550053162 24 - 3 | 0.00152413046255 24 - 4 | 6.98244201596e-05 24 - 5 | 0.000125277194954 24 - 6 | -6.22582773382e-05 24 - 7 | -3.20123373222e-05 24 - 8 | 0.0 24 - 9 | 0.0 24 - 10 | 0.0 24 - 11 | 0.0 24 - 12 | 0.00610951292372 24 - 13 | 0.00796363832398 24 - 14 | 0.00566494641328 24 - 15 | 0.00146764602336 24 - 16 | 0.00181617936575 24 - 17 | 0.000339330121996 24 - 18 | 2.88857620464e-05 24 - 19 | 9.16512913949e-05 24 - 20 | -2.81980431362e-05 24 - 21 | 0.0 24 - 22 | 0.0 24 - 23 | 0.0 24 - 24 | 0.00729843397779 24 - 25 | 0.0082226355438 24 - 26 | 0.00608989016277 24 - 27 | 0.00210727927853 24 - 28 | 0.00209807883343 24 - 29 | 0.00159608206625 24 - 30 | 0.00029091502533 24 - 31 | 0.000194577871844 24 - 32 | -0.000886706082562 24 - 33 | -0.000131635247536 24 - 34 | 0.0 24 - 35 | 0.0 24 - 36 | 0.00755836828425 24 - 37 | 0.00880153370631 24 - 38 | 0.0066961231369 24 - 39 | 0.00613273433524 24 - 40 | 0.00268978456885 24 - 41 | 0.00205547955153 24 - 42 | 0.00104474748091 24 - 43 | 0.000534505670249 24 - 44 | -0.0003742962925 24 - 45 | -0.000680917956586 24 - 46 | 0.0 24 - 47 | 0.0 24 - 48 | 0.00694031726491 24 - 49 | 0.00539465070426 24 - 50 | 0.00630980660677 24 - 51 | 0.00449708235683 24 - 52 | 0.00339591774762 24 - 53 | 0.0046292147363 24 - 54 | 0.00103330268225 24 - 55 | 0.0187622608484 24 - 56 | 0.000517571552276 24 - 57 | -9.66817171023e-05 24 - 58 | -7.7627228912e-06 24 - 59 | 0.0 24 - 60 | 0.00645039998304 24 - 61 | 0.00242598737111 24 - 62 | 0.000382946569996 24 - 63 | -0.00172310430856 24 - 64 | -0.00140575675297 24 - 65 | 0.00364381801342 24 - 66 | 0.00406659717659 24 - 67 | 0.00143905724683 24 - 68 | 0.000770523457419 24 - 69 | -0.000168287948648 24 - 70 | -4.32218518861e-05 24 - 71 | 0.0 24 - 72 | 0.00536284652328 24 - 73 | 0.00897916824969 24 - 74 | 0.0130895589273 24 - 75 | 0.0148591021385 24 - 76 | 0.0124876138553 24 - 77 | 0.00190324824599 24 - 78 | 0.00274120816438 24 - 79 | 0.00213002684137 24 - 80 | 0.00105173884526 24 - 81 | 0.000822529079113 24 - 82 | 0.000192442202741 24 - 83 | 9.7427520798e-08 24 - 84 | 0.00186741783405 24 - 85 | 0.00424264303091 24 - 86 | 0.0041739835671 24 - 87 | 0.00548545479525 24 - 88 | 0.00391019543057 24 - 89 | 0.000801479969185 24 - 90 | 0.00206899683556 24 - 91 | 0.00229698066262 24 - 92 | 0.00143258194655 24 - 93 | 0.000883526579267 24 - 94 | 0.000567729207548 24 - 95 | 7.49168332211e-06 25 - 0 | 0.00936702233237 25 - 1 | 0.011494512972 25 - 2 | 0.00727272495208 25 - 3 | 0.00199655347462 25 - 4 | 0.000234348797883 25 - 5 | 0.000212223546694 25 - 6 | -3.53861717235e-05 25 - 7 | -1.33590670109e-05 25 - 8 | 0.0 25 - 9 | 0.0 25 - 10 | 0.0 25 - 11 | 0.0 25 - 12 | 0.00742800797302 25 - 13 | 0.0106313499222 25 - 14 | 0.00660518702999 25 - 15 | 0.00192069389633 25 - 16 | 0.00224092625965 25 - 17 | 0.000544821118153 25 - 18 | 0.000152340884351 25 - 19 | 0.000162767053062 25 - 20 | -1.08235953837e-05 25 - 21 | 0.0 25 - 22 | 0.0 25 - 23 | 0.0 25 - 24 | 0.0082226355438 25 - 25 | 0.0121909409814 25 - 26 | 0.00760575239636 25 - 27 | 0.00298844297282 25 - 28 | 0.00271559589209 25 - 29 | 0.00199529930882 25 - 30 | 0.000566831445952 25 - 31 | 0.000343599179279 25 - 32 | -0.00110475782172 25 - 33 | -0.000173525012203 25 - 34 | 0.0 25 - 35 | 0.0 25 - 36 | 0.00897007402567 25 - 37 | 0.0116337000202 25 - 38 | 0.00796629301938 25 - 39 | 0.00721122553312 25 - 40 | 0.00344302423209 25 - 41 | 0.00257269484997 25 - 42 | 0.00153550789296 25 - 43 | 0.000847833086298 25 - 44 | -0.000359049950103 25 - 45 | -0.000882638112287 25 - 46 | 0.0 25 - 47 | 0.0 25 - 48 | 0.00855285250618 25 - 49 | 0.00770945440432 25 - 50 | 0.00817052640204 25 - 51 | 0.00588643102091 25 - 52 | 0.00447184852875 25 - 53 | 0.00574108048127 25 - 54 | 0.0015155368849 25 - 55 | 0.0237299833546 25 - 56 | 0.000798862439156 25 - 57 | -3.01559583416e-05 25 - 58 | 5.81518808194e-06 25 - 59 | 0.0 25 - 60 | 0.00809675711598 25 - 61 | 0.00438794258518 25 - 62 | 0.00231753952056 25 - 63 | -0.000149151044963 25 - 64 | -0.000247025029155 25 - 65 | 0.00456765444483 25 - 66 | 0.00505836523059 25 - 67 | 0.00203679209119 25 - 68 | 0.00120708955503 25 - 69 | -2.66448207759e-05 25 - 70 | -1.02737750169e-05 25 - 71 | 0.0 25 - 72 | 0.00670938259616 25 - 73 | 0.0114337627827 25 - 74 | 0.0149634697841 25 - 75 | 0.0161143823176 25 - 76 | 0.0139461131887 25 - 77 | 0.00317332584799 25 - 78 | 0.0036282822218 25 - 79 | 0.0030502665183 25 - 80 | 0.00162966087037 25 - 81 | 0.00116695924817 25 - 82 | 0.000287824351026 25 - 83 | 1.49451239487e-06 25 - 84 | 0.00270325082135 25 - 85 | 0.00599294118269 25 - 86 | 0.00571920787824 25 - 87 | 0.00668410753825 25 - 88 | 0.00469749088513 25 - 89 | 0.00168895146958 25 - 90 | 0.00300495683681 25 - 91 | 0.00328006657358 25 - 92 | 0.00223103317178 25 - 93 | 0.00138503696596 25 - 94 | 0.000688713978931 25 - 95 | 9.46763661834e-06 26 - 0 | 0.00734724411651 26 - 1 | 0.00888362476058 26 - 2 | 0.00644467632049 26 - 3 | 0.00197882934222 26 - 4 | 0.00077582942514 26 - 5 | 0.000408021393223 26 - 6 | 0.000102687052228 26 - 7 | 2.74128059635e-05 26 - 8 | 0.0 26 - 9 | 0.0 26 - 10 | 0.0 26 - 11 | 0.0 26 - 12 | 0.00585025459469 26 - 13 | 0.00693364400455 26 - 14 | 0.00679439349494 26 - 15 | 0.00297437448157 26 - 16 | 0.00179039355959 26 - 17 | 0.000880962658508 26 - 18 | 0.000438611714118 26 - 19 | 0.000248335060461 26 - 20 | 4.33547295304e-05 26 - 21 | 0.0 26 - 22 | 0.0 26 - 23 | 0.0 26 - 24 | 0.00608989016277 26 - 25 | 0.00760575239636 26 - 26 | 0.00912912592773 26 - 27 | 0.00461571658374 26 - 28 | 0.00262442229663 26 - 29 | 0.00179970694253 26 - 30 | 0.00106557289776 26 - 31 | 0.000683589497913 26 - 32 | -0.000329350485663 26 - 33 | -6.94093516622e-05 26 - 34 | 0.0 26 - 35 | 0.0 26 - 36 | 0.00627629811928 26 - 37 | 0.00666733583719 26 - 38 | 0.00714948329411 26 - 39 | 0.00542869844149 26 - 40 | 0.00344480234357 26 - 41 | 0.00238936462147 26 - 42 | 0.00173535966084 26 - 43 | 0.00141979767314 26 - 44 | 0.000307677682402 26 - 45 | -0.000446573859116 26 - 46 | 0.0 26 - 47 | 0.0 26 - 48 | 0.00616040796689 26 - 49 | 0.00584262120247 26 - 50 | 0.00734615403629 26 - 51 | 0.00584429819208 26 - 52 | 0.0047934264172 26 - 53 | 0.00367361952618 26 - 54 | 0.00200576467298 26 - 55 | 0.0110249879008 26 - 56 | 0.00121626591093 26 - 57 | 0.000282315359008 26 - 58 | 2.02323037481e-05 26 - 59 | 0.0 26 - 60 | 0.00623341094336 26 - 61 | 0.00497165180221 26 - 62 | 0.00696648601408 26 - 63 | 0.00595646323031 26 - 64 | 0.00431188120742 26 - 65 | 0.00374034717862 26 - 66 | 0.00359429939115 26 - 67 | 0.00255789667475 26 - 68 | 0.00184444616842 26 - 69 | 0.00064301367569 26 - 70 | 8.73322752933e-05 26 - 71 | 0.0 26 - 72 | 0.00510007136544 26 - 73 | 0.00540345247046 26 - 74 | 0.00609863473523 26 - 75 | 0.00635593899777 26 - 76 | 0.00495284498468 26 - 77 | 0.00408851245567 26 - 78 | 0.00344593667954 26 - 79 | 0.00300537116061 26 - 80 | 0.00240299932693 26 - 81 | 0.00178838384272 26 - 82 | 0.000646373296884 26 - 83 | 2.77701952251e-06 26 - 84 | 0.00313499064516 26 - 85 | 0.00388745069427 26 - 86 | 0.00401202302071 26 - 87 | 0.00456006139707 26 - 88 | 0.00290241720095 26 - 89 | 0.00291222420622 26 - 90 | 0.00275828026208 26 - 91 | 0.00253242433844 26 - 92 | 0.00219632869514 26 - 93 | 0.00201362120629 26 - 94 | 0.00217875843103 26 - 95 | 0.00011701564704 27 - 0 | 0.0026991733176 27 - 1 | 0.00387500625896 27 - 2 | 0.00271235453541 27 - 3 | 0.00121970948978 27 - 4 | 0.000817212753504 27 - 5 | 0.0003655187842 27 - 6 | 0.000168343840016 27 - 7 | 5.45821702377e-05 27 - 8 | 0.0 27 - 9 | 0.0 27 - 10 | 0.0 27 - 11 | 0.0 27 - 12 | 0.00223424525331 27 - 13 | 0.00247012245543 27 - 14 | 0.00352945575801 27 - 15 | 0.00245828709059 27 - 16 | 0.000785074197095 27 - 17 | 0.000739309834366 27 - 18 | 0.000456220855083 27 - 19 | 0.0002045842223 27 - 20 | 6.65486998527e-05 27 - 21 | 0.0 27 - 22 | 0.0 27 - 23 | 0.0 27 - 24 | 0.00210727927853 27 - 25 | 0.00298844297282 27 - 26 | 0.00461571658374 27 - 27 | 0.00419101524706 27 - 28 | 0.00167587543258 27 - 29 | 0.000912806607692 27 - 30 | 0.000957945084463 27 - 31 | 0.000578964935551 27 - 32 | 0.000258527923105 27 - 33 | 2.14136071323e-05 27 - 34 | 0.0 27 - 35 | 0.0 27 - 36 | 0.00166888397388 27 - 37 | 0.00160686549549 27 - 38 | 0.00319330775819 27 - 39 | 0.00206451980661 27 - 40 | 0.00200905244036 27 - 41 | 0.00131491226072 27 - 42 | 0.00126125989923 27 - 43 | 0.00114534514759 27 - 44 | 0.000594694811818 27 - 45 | 5.5982477922e-05 27 - 46 | 0.0 27 - 47 | 0.0 27 - 48 | 0.00173088269162 27 - 49 | 0.00296084728878 27 - 50 | 0.00383526333889 27 - 51 | 0.00350555952283 27 - 52 | 0.00293112019088 27 - 53 | 0.00106804168908 27 - 54 | 0.00170520279429 27 - 55 | -0.00199123790933 27 - 56 | 0.000935233597516 27 - 57 | 0.000370185507542 27 - 58 | 2.83156294026e-05 27 - 59 | 0.0 27 - 60 | 0.00218998996792 27 - 61 | 0.00393677201943 27 - 62 | 0.00739786265274 27 - 63 | 0.00774330541944 27 - 64 | 0.00574474616179 27 - 65 | 0.00176254355628 27 - 66 | 0.00131521937917 27 - 67 | 0.00178865142473 27 - 68 | 0.00152166699876 27 - 69 | 0.000815734232727 27 - 70 | 0.000130253774663 27 - 71 | 0.0 27 - 72 | 0.00179072228228 27 - 73 | 3.19389769004e-06 27 - 74 | -0.00202378982812 27 - 75 | -0.00294066301648 27 - 76 | -0.00279767509985 27 - 77 | 0.00327536998039 27 - 78 | 0.00200293195813 27 - 79 | 0.001938408544 27 - 80 | 0.0019135685728 27 - 81 | 0.00131184811079 27 - 82 | 0.000525557191366 27 - 83 | 3.11271678503e-06 27 - 84 | 0.00211502538038 27 - 85 | 0.00137255433566 27 - 86 | 0.00168500215025 27 - 87 | 0.00130287870412 27 - 88 | 0.000678996195219 27 - 89 | 0.00267780535844 27 - 90 | 0.00168891327966 27 - 91 | 0.00131254238258 27 - 92 | 0.00149644983631 27 - 93 | 0.00158165513924 27 - 94 | 0.00185350063204 27 - 95 | 0.000113928782886 28 - 0 | 0.00258441597314 28 - 1 | 0.00326007668979 28 - 2 | 0.00236091168401 28 - 3 | 0.000843317007876 28 - 4 | 0.000384012135093 28 - 5 | 0.00017242654804 28 - 6 | 6.01472316231e-05 28 - 7 | 2.15887008284e-05 28 - 8 | 0.0 28 - 9 | 0.0 28 - 10 | 0.0 28 - 11 | 0.0 28 - 12 | 0.00205357802755 28 - 13 | 0.00260291532728 28 - 14 | 0.00243841750601 28 - 15 | 0.00118273570724 28 - 16 | 0.000788082568938 28 - 17 | 0.000426480075966 28 - 18 | 0.00020437947403 28 - 19 | 0.000118029980445 28 - 20 | 3.33745038867e-05 28 - 21 | 0.0 28 - 22 | 0.0 28 - 23 | 0.0 28 - 24 | 0.00209807883343 28 - 25 | 0.00271559589209 28 - 26 | 0.00262442229663 28 - 27 | 0.00167587543258 28 - 28 | 0.00140271077936 28 - 29 | 0.000840528160725 28 - 30 | 0.000504637176848 28 - 31 | 0.000317988720264 28 - 32 | -4.41286064579e-05 28 - 33 | -1.40088207756e-05 28 - 34 | 0.0 28 - 35 | 0.0 28 - 36 | 0.00211677181495 28 - 37 | 0.00258737795599 28 - 38 | 0.00284689002829 28 - 39 | 0.00212049548456 28 - 40 | 0.00135516032904 28 - 41 | 0.00104134994144 28 - 42 | 0.000766654919972 28 - 43 | 0.000578786229829 28 - 44 | 0.000184290996642 28 - 45 | -0.000127524854933 28 - 46 | 0.0 28 - 47 | 0.0 28 - 48 | 0.00197702145696 28 - 49 | 0.00211100726326 28 - 50 | 0.00256857270766 28 - 51 | 0.00198205561347 28 - 52 | 0.00155920004025 28 - 53 | 0.00151639728232 28 - 54 | 0.000938401814195 28 - 55 | 0.00414836188845 28 - 56 | 0.000494304230148 28 - 57 | 0.000143548257117 28 - 58 | 1.66332817784e-05 28 - 59 | 0.0 28 - 60 | 0.00199338274204 28 - 61 | 0.00165395031853 28 - 62 | 0.00197057251432 28 - 63 | 0.00146699451764 28 - 64 | 0.00111672963381 28 - 65 | 0.00144750580265 28 - 66 | 0.00140498086904 28 - 67 | 0.00103028574033 28 - 68 | 0.000772368487625 28 - 69 | 0.000316822016546 28 - 70 | 5.31718298747e-05 28 - 71 | 0.0 28 - 72 | 0.00171189611704 28 - 73 | 0.00224823246981 28 - 74 | 0.00294201167529 28 - 75 | 0.00308916438366 28 - 76 | 0.00246526250017 28 - 77 | 0.0012938461477 28 - 78 | 0.00130385311959 28 - 79 | 0.00122273697649 28 - 80 | 0.00100065552715 28 - 81 | 0.000729015845285 28 - 82 | 0.000273335832261 28 - 83 | 1.55210987606e-06 28 - 84 | 0.00110833014491 28 - 85 | 0.00139319956358 28 - 86 | 0.00156618271153 28 - 87 | 0.0016577514821 28 - 88 | 0.00123320805488 28 - 89 | 0.000912198147294 28 - 90 | 0.00100183057441 28 - 91 | 0.00101620731331 28 - 92 | 0.000947599204277 28 - 93 | 0.000869129294622 28 - 94 | 0.000908943336008 28 - 95 | 4.97486446007e-05 29 - 0 | 0.00197362259173 29 - 1 | 0.00238345177095 29 - 2 | 0.00184081754738 29 - 3 | 0.00059534887138 29 - 4 | 0.000223459274496 29 - 5 | 9.39231315333e-05 29 - 6 | 2.1109969309e-05 29 - 7 | 1.06714275681e-05 29 - 8 | 0.0 29 - 9 | 0.0 29 - 10 | 0.0 29 - 11 | 0.0 29 - 12 | 0.00153585521953 29 - 13 | 0.00198494640747 29 - 14 | 0.00177169458615 29 - 15 | 0.000717857843064 29 - 16 | 0.000589406984104 29 - 17 | 0.000273725261666 29 - 18 | 0.000112319186085 29 - 19 | 7.49281420187e-05 29 - 20 | 1.80412646569e-05 29 - 21 | 0.0 29 - 22 | 0.0 29 - 23 | 0.0 29 - 24 | 0.00159608206625 29 - 25 | 0.00199529930882 29 - 26 | 0.00179970694253 29 - 27 | 0.000912806607692 29 - 28 | 0.000840528160725 29 - 29 | 0.000732522002876 29 - 30 | 0.000325255541278 29 - 31 | 0.000192132051094 29 - 32 | -9.90285980754e-05 29 - 33 | -1.70776483328e-05 29 - 34 | 0.0 29 - 35 | 0.0 29 - 36 | 0.00169570773837 29 - 37 | 0.00206632022272 29 - 38 | 0.00214329867909 29 - 39 | 0.0016861748336 29 - 40 | 0.000921252548766 29 - 41 | 0.000777158833097 29 - 42 | 0.000520687587993 29 - 43 | 0.000348856876085 29 - 44 | 7.01417881537e-05 29 - 45 | -0.000125572678542 29 - 46 | 0.0 29 - 47 | 0.0 29 - 48 | 0.0015783021701 29 - 49 | 0.00140932997765 29 - 50 | 0.00176709567481 29 - 51 | 0.00130712883033 29 - 52 | 0.00101956627165 29 - 53 | 0.00126029756412 29 - 54 | 0.000617258093929 29 - 55 | 0.00421675439121 29 - 56 | 0.000320763519877 29 - 57 | 8.18057665784e-05 29 - 58 | 1.12694249311e-05 29 - 59 | 0.0 29 - 60 | 0.00151137338115 29 - 61 | 0.000842937753824 29 - 62 | 0.000605292928019 29 - 63 | 0.000114836321969 29 - 64 | 0.000110781982703 29 - 65 | 0.00106522034274 29 - 66 | 0.00114317294939 29 - 67 | 0.000677767813543 29 - 68 | 0.000464870373812 29 - 69 | 0.000167158220761 29 - 70 | 3.19929726815e-05 29 - 71 | 0.0 29 - 72 | 0.0013119833308 29 - 73 | 0.00203108668658 29 - 74 | 0.00303632557127 29 - 75 | 0.00336431850207 29 - 76 | 0.00274098993567 29 - 77 | 0.000682728730098 29 - 78 | 0.000911100663424 29 - 79 | 0.000824427116347 29 - 80 | 0.000637737656166 29 - 81 | 0.000489206880442 29 - 82 | 0.000190281141298 29 - 83 | 9.40384724127e-07 29 - 84 | 0.000690464046554 29 - 85 | 0.00102451072911 29 - 86 | 0.00111582089007 29 - 87 | 0.00133660263441 29 - 88 | 0.000985542481251 29 - 89 | 0.000385590407844 29 - 90 | 0.000658110775842 29 - 91 | 0.000738565197947 29 - 92 | 0.000615723664124 29 - 93 | 0.000554233737807 29 - 94 | 0.000615212051141 29 - 95 | 3.19750611457e-05 30 - 0 | 0.000473234066476 30 - 1 | 0.00092106383001 30 - 2 | 0.000690646784464 30 - 3 | 0.000419210778702 30 - 4 | 0.000343436329951 30 - 5 | 0.00014462304496 30 - 6 | 8.63346615764e-05 30 - 7 | 3.04477764098e-05 30 - 8 | 0.0 30 - 9 | 0.0 30 - 10 | 0.0 30 - 11 | 0.0 30 - 12 | 0.00040081750912 30 - 13 | 0.00058804226409 30 - 14 | 0.00103193975038 30 - 15 | 0.000764163390249 30 - 16 | 0.000244104035441 30 - 17 | 0.000327115550824 30 - 18 | 0.00020716554096 30 - 19 | 9.55578749366e-05 30 - 20 | 4.20237346431e-05 30 - 21 | 0.0 30 - 22 | 0.0 30 - 23 | 0.0 30 - 24 | 0.00029091502533 30 - 25 | 0.000566831445952 30 - 26 | 0.00106557289776 30 - 27 | 0.000957945084463 30 - 28 | 0.000504637176848 30 - 29 | 0.000325255541278 30 - 30 | 0.000505632348728 30 - 31 | 0.000310160129695 30 - 32 | 0.000252122226901 30 - 33 | 3.13916013659e-05 30 - 34 | 0.0 30 - 35 | 0.0 30 - 36 | 3.32515768712e-05 30 - 37 | 0.000268573270373 30 - 38 | 0.00112265557118 30 - 39 | 0.000500593797738 30 - 40 | 0.000568975196432 30 - 41 | 0.000457415566825 30 - 42 | 0.000490971915212 30 - 43 | 0.000468996432652 30 - 44 | 0.000307377278613 30 - 45 | 8.61862768006e-05 30 - 46 | 0.0 30 - 47 | 0.0 30 - 48 | -1.4427280065e-05 30 - 49 | 0.000688475553274 30 - 50 | 0.000901328148954 30 - 51 | 0.000786704986754 30 - 52 | 0.00061532303134 30 - 53 | 0.000232799241565 30 - 54 | 0.000585617360746 30 - 55 | -0.00147308614275 30 - 56 | 0.000350335886882 30 - 57 | 0.000168397180391 30 - 58 | 1.70697036234e-05 30 - 59 | 0.0 30 - 60 | 0.000110915336468 30 - 61 | 0.000949906258714 30 - 62 | 0.00178253926521 30 - 63 | 0.00184868349374 30 - 64 | 0.00141399520879 30 - 65 | 0.000442134138904 30 - 66 | 0.000205718779263 30 - 67 | 0.000634021963648 30 - 68 | 0.000594871676923 30 - 69 | 0.000366106348718 30 - 70 | 6.14883117152e-05 30 - 71 | 0.0 30 - 72 | 0.000171619352244 30 - 73 | -0.00017330022147 30 - 74 | -0.000525170946974 30 - 75 | -0.000835851317142 30 - 76 | -0.000823626527325 30 - 77 | 0.000739462460819 30 - 78 | 0.000510600841081 30 - 79 | 0.000654514321471 30 - 80 | 0.000761509042741 30 - 81 | 0.000517809327331 30 - 82 | 0.00019112767067 30 - 83 | 1.38396531643e-06 30 - 84 | 0.000573289869797 30 - 85 | 0.000219285836917 30 - 86 | 0.000467994612776 30 - 87 | 0.000204639912467 30 - 88 | 0.000187526079493 30 - 89 | 0.000653357894256 30 - 90 | 0.000405189186024 30 - 91 | 0.000360810616355 30 - 92 | 0.000601341935868 30 - 93 | 0.000693877978744 30 - 94 | 0.000704262709621 30 - 95 | 4.39476962669e-05 31 - 0 | 0.000320513316156 31 - 1 | 0.000569742762073 31 - 2 | 0.000464324733051 31 - 3 | 0.000259564367011 31 - 4 | 0.000199899733383 31 - 5 | 9.79357544531e-05 31 - 6 | 6.83658005248e-05 31 - 7 | 2.12055178535e-05 31 - 8 | 0.0 31 - 9 | 0.0 31 - 10 | 0.0 31 - 11 | 0.0 31 - 12 | 0.000277482673197 31 - 13 | 0.000377258778082 31 - 14 | 0.000665932518666 31 - 15 | 0.000474206398427 31 - 16 | 0.000159495856988 31 - 17 | 0.000212556957804 31 - 18 | 0.00013215393449 31 - 19 | 7.67817358921e-05 31 - 20 | 3.78711291129e-05 31 - 21 | 0.0 31 - 22 | 0.0 31 - 23 | 0.0 31 - 24 | 0.000194577871844 31 - 25 | 0.000343599179279 31 - 26 | 0.000683589497913 31 - 27 | 0.000578964935551 31 - 28 | 0.000317988720264 31 - 29 | 0.000192132051094 31 - 30 | 0.000310160129695 31 - 31 | 0.000258770579243 31 - 32 | 0.000234254536108 31 - 33 | 2.99585116313e-05 31 - 34 | 0.0 31 - 35 | 0.0 31 - 36 | 6.72313015437e-05 31 - 37 | 0.000157600477608 31 - 38 | 0.000641937165596 31 - 39 | 0.00033690667897 31 - 40 | 0.000375312749493 31 - 41 | 0.000279044841481 31 - 42 | 0.000301819975502 31 - 43 | 0.000304512032442 31 - 44 | 0.000218912583913 31 - 45 | 5.21707192214e-05 31 - 46 | 0.0 31 - 47 | 0.0 31 - 48 | 1.46730263453e-05 31 - 49 | 0.000393291565512 31 - 50 | 0.000535698090484 31 - 51 | 0.000498119658785 31 - 52 | 0.000401100373485 31 - 53 | 0.000133926991836 31 - 54 | 0.00032181242896 31 - 55 | -0.000245401019214 31 - 56 | 0.000209604881269 31 - 57 | 0.000104244274448 31 - 58 | 1.25856917693e-05 31 - 59 | 0.0 31 - 60 | 7.51455392689e-05 31 - 61 | 0.000491147475248 31 - 62 | 0.0010607568035 31 - 63 | 0.00110468130646 31 - 64 | 0.000842499704481 31 - 65 | 0.000269310049077 31 - 66 | 0.000112879116065 31 - 67 | 0.000358219726882 31 - 68 | 0.000363871502896 31 - 69 | 0.000225620689243 31 - 70 | 3.60086612603e-05 31 - 71 | 0.0 31 - 72 | 0.000110991755569 31 - 73 | -0.000169129734917 31 - 74 | -0.000296736401608 31 - 75 | -0.000405671246594 31 - 76 | -0.000426106826324 31 - 77 | 0.0004331348559 31 - 78 | 0.000316093335137 31 - 79 | 0.000401435306291 31 - 80 | 0.000462053482566 31 - 81 | 0.000333562509097 31 - 82 | 0.000119844634491 31 - 83 | 8.38271750971e-07 31 - 84 | 0.000314285388898 31 - 85 | 0.000113316734522 31 - 86 | 0.00026932175237 31 - 87 | 0.000137419417974 31 - 88 | 0.000113010155223 31 - 89 | 0.000372825844427 31 - 90 | 0.000223426726393 31 - 91 | 0.000199064051663 31 - 92 | 0.000374808850978 31 - 93 | 0.000437865997598 31 - 94 | 0.00044708681201 31 - 95 | 2.65819294049e-05 32 - 0 | -0.000948168810462 32 - 1 | -0.000936303030456 32 - 2 | -0.000712200603335 32 - 3 | -3.32514558697e-05 32 - 4 | 0.000191016664303 32 - 5 | 8.33617929122e-05 32 - 6 | 9.48107921386e-05 32 - 7 | 2.9923955519e-05 32 - 8 | 0.0 32 - 9 | 0.0 32 - 10 | 0.0 32 - 11 | 0.0 32 - 12 | -0.000687643833987 32 - 13 | -0.00108238817391 32 - 14 | -0.000316859362331 32 - 15 | 0.000253320168408 32 - 16 | -0.00017249651998 32 - 17 | 0.000170606587726 32 - 18 | 0.000115466517649 32 - 19 | 5.94129962513e-05 32 - 20 | 5.16528142834e-05 32 - 21 | 0.0 32 - 22 | 0.0 32 - 23 | 0.0 32 - 24 | -0.000886706082562 32 - 25 | -0.00110475782172 32 - 26 | -0.000329350485663 32 - 27 | 0.000258527923105 32 - 28 | -4.41286064579e-05 32 - 29 | -9.90285980754e-05 32 - 30 | 0.000252122226901 32 - 31 | 0.000234254536108 32 - 32 | 0.000550048390552 32 - 33 | 7.70837489852e-05 32 - 34 | 0.0 32 - 35 | 0.0 32 - 36 | -0.00119787389601 32 - 37 | -0.00145517590031 32 - 38 | -0.000490096758428 32 - 39 | -0.000755695225157 32 - 40 | -7.6668864861e-05 32 - 41 | -3.18598186512e-05 32 - 42 | 0.000144588434093 32 - 43 | 0.000182050128336 32 - 44 | 0.000330365187927 32 - 45 | 0.000228341259604 32 - 46 | 0.0 32 - 47 | 0.0 32 - 48 | -0.0011951623085 32 - 49 | -0.000485138929411 32 - 50 | -0.0005090469053 32 - 51 | -0.000248968041716 32 - 52 | -0.00015371469662 32 - 53 | -0.000752241771848 32 - 54 | 0.000165665376914 32 - 55 | -0.00487201093289 32 - 56 | 6.7445783596e-05 32 - 57 | 0.000117055477159 32 - 58 | 1.37036932826e-05 32 - 59 | 0.0 32 - 60 | -0.00101344043603 32 - 61 | 0.0001351161015 32 - 62 | 0.00121258537004 32 - 63 | 0.00164505783309 32 - 64 | 0.00125938642516 32 - 65 | -0.000358503420315 32 - 66 | -0.000626787890604 32 - 67 | 8.12793120031e-05 32 - 68 | 0.000163848936147 32 - 69 | 0.00023508756848 32 - 70 | 4.02436702149e-05 32 - 71 | 0.0 32 - 72 | -0.000808184572311 32 - 73 | -0.00187978319275 32 - 74 | -0.0028341706174 32 - 75 | -0.00320960454145 32 - 76 | -0.00282674381445 32 - 77 | 0.000168312873489 32 - 78 | -8.93139618917e-05 32 - 79 | 5.82381680456e-05 32 - 80 | 0.000207882086715 32 - 81 | 0.000102922264732 32 - 82 | 6.96562387585e-05 32 - 83 | 6.86427964683e-07 32 - 84 | 2.34648556168e-05 32 - 85 | -0.000637116842714 32 - 86 | -0.000495006207797 32 - 87 | -0.000838779205982 32 - 88 | -0.000529996833275 32 - 89 | 0.000339623731327 32 - 90 | -7.47101510213e-05 32 - 91 | -0.00018578268629 32 - 92 | 6.45877652854e-05 32 - 93 | 0.0001555350427 32 - 94 | 0.00027630682444 32 - 95 | 2.03492963186e-05 33 - 0 | -0.000136434280686 33 - 1 | -0.00014345730992 33 - 2 | -0.000114446249989 33 - 3 | -1.08416158182e-05 33 - 4 | 2.62315045872e-05 33 - 5 | 1.07316257138e-05 33 - 6 | 1.35166091493e-05 33 - 7 | 5.28732911025e-06 33 - 8 | 0.0 33 - 9 | 0.0 33 - 10 | 0.0 33 - 11 | 0.0 33 - 12 | -0.000102258307301 33 - 13 | -0.000172769880751 33 - 14 | -6.34546487023e-05 33 - 15 | 2.68237387248e-05 33 - 16 | -2.80073801755e-05 33 - 17 | 2.17930555629e-05 33 - 18 | 1.55564698471e-05 33 - 19 | 9.13439165198e-06 33 - 20 | 7.58773888664e-06 33 - 21 | 0.0 33 - 22 | 0.0 33 - 23 | 0.0 33 - 24 | -0.000131635247536 33 - 25 | -0.000173525012203 33 - 26 | -6.94093516622e-05 33 - 27 | 2.14136071323e-05 33 - 28 | -1.40088207756e-05 33 - 29 | -1.70776483328e-05 33 - 30 | 3.13916013659e-05 33 - 31 | 2.99585116313e-05 33 - 32 | 7.70837489852e-05 33 - 33 | 1.29175136201e-05 33 - 34 | 0.0 33 - 35 | 0.0 33 - 36 | -0.000174715067324 33 - 37 | -0.000222743993913 33 - 38 | -8.75424510862e-05 33 - 39 | -0.000123438202865 33 - 40 | -2.05768046819e-05 33 - 41 | -1.06496823173e-05 33 - 42 | 1.61587856943e-05 33 - 43 | 2.24754645637e-05 33 - 44 | 4.62985642429e-05 33 - 45 | 3.77849902505e-05 33 - 46 | 0.0 33 - 47 | 0.0 33 - 48 | -0.000175698677424 33 - 49 | -8.70821442176e-05 33 - 50 | -9.2426136444e-05 33 - 51 | -5.36320652813e-05 33 - 52 | -3.45486733531e-05 33 - 53 | -0.000115103091371 33 - 54 | 2.33401248731e-05 33 - 55 | -0.000732936655203 33 - 56 | 7.96079590145e-06 33 - 57 | 1.79776270205e-05 33 - 58 | 2.27999790486e-06 33 - 59 | 0.0 33 - 60 | -0.000146936873385 33 - 61 | 4.57132816249e-06 33 - 62 | 0.000147372158534 33 - 63 | 0.000208997719726 33 - 64 | 0.00016022612122 33 - 65 | -6.1154089559e-05 33 - 66 | -9.36554917869e-05 33 - 67 | 6.38775250146e-06 33 - 68 | 1.53843324703e-05 33 - 69 | 3.18520708358e-05 33 - 70 | 6.44077665803e-06 33 - 71 | 0.0 33 - 72 | -0.000117559207513 33 - 73 | -0.000276039194183 33 - 74 | -0.000413776381231 33 - 75 | -0.000461995989945 33 - 76 | -0.000407566055335 33 - 77 | 1.08610004513e-05 33 - 78 | -2.05893394024e-05 33 - 79 | -2.56076910477e-06 33 - 80 | 2.27029422912e-05 33 - 81 | 9.00114750981e-06 33 - 82 | 8.87981568853e-06 33 - 83 | 8.8129000637e-08 33 - 84 | -6.93547785704e-07 33 - 85 | -0.000100189384624 33 - 86 | -8.09397403979e-05 33 - 87 | -0.000127059269758 33 - 88 | -7.88366513816e-05 33 - 89 | 4.17341213253e-05 33 - 90 | -1.56305786449e-05 33 - 91 | -3.16622437516e-05 33 - 92 | 1.99952353142e-06 33 - 93 | 1.58422154463e-05 33 - 94 | 3.78507445547e-05 33 - 95 | 2.88367659891e-06 34 - 0 | 0.0 34 - 1 | 0.0 34 - 2 | 0.0 34 - 3 | 0.0 34 - 4 | 0.0 34 - 5 | 0.0 34 - 6 | 0.0 34 - 7 | 0.0 34 - 8 | 0.0 34 - 9 | 0.0 34 - 10 | 0.0 34 - 11 | 0.0 34 - 12 | 0.0 34 - 13 | 0.0 34 - 14 | 0.0 34 - 15 | 0.0 34 - 16 | 0.0 34 - 17 | 0.0 34 - 18 | 0.0 34 - 19 | 0.0 34 - 20 | 0.0 34 - 21 | 0.0 34 - 22 | 0.0 34 - 23 | 0.0 34 - 24 | 0.0 34 - 25 | 0.0 34 - 26 | 0.0 34 - 27 | 0.0 34 - 28 | 0.0 34 - 29 | 0.0 34 - 30 | 0.0 34 - 31 | 0.0 34 - 32 | 0.0 34 - 33 | 0.0 34 - 34 | 0.0 34 - 35 | 0.0 34 - 36 | 0.0 34 - 37 | 0.0 34 - 38 | 0.0 34 - 39 | 0.0 34 - 40 | 0.0 34 - 41 | 0.0 34 - 42 | 0.0 34 - 43 | 0.0 34 - 44 | 0.0 34 - 45 | 0.0 34 - 46 | 0.0 34 - 47 | 0.0 34 - 48 | 0.0 34 - 49 | 0.0 34 - 50 | 0.0 34 - 51 | 0.0 34 - 52 | 0.0 34 - 53 | 0.0 34 - 54 | 0.0 34 - 55 | 0.0 34 - 56 | 0.0 34 - 57 | 0.0 34 - 58 | 0.0 34 - 59 | 0.0 34 - 60 | 0.0 34 - 61 | 0.0 34 - 62 | 0.0 34 - 63 | 0.0 34 - 64 | 0.0 34 - 65 | 0.0 34 - 66 | 0.0 34 - 67 | 0.0 34 - 68 | 0.0 34 - 69 | 0.0 34 - 70 | 0.0 34 - 71 | 0.0 34 - 72 | 0.0 34 - 73 | 0.0 34 - 74 | 0.0 34 - 75 | 0.0 34 - 76 | 0.0 34 - 77 | 0.0 34 - 78 | 0.0 34 - 79 | 0.0 34 - 80 | 0.0 34 - 81 | 0.0 34 - 82 | 0.0 34 - 83 | 0.0 34 - 84 | 0.0 34 - 85 | 0.0 34 - 86 | 0.0 34 - 87 | 0.0 34 - 88 | 0.0 34 - 89 | 0.0 34 - 90 | 0.0 34 - 91 | 0.0 34 - 92 | 0.0 34 - 93 | 0.0 34 - 94 | 0.0 34 - 95 | 0.0 35 - 0 | 0.0 35 - 1 | 0.0 35 - 2 | 0.0 35 - 3 | 0.0 35 - 4 | 0.0 35 - 5 | 0.0 35 - 6 | 0.0 35 - 7 | 0.0 35 - 8 | 0.0 35 - 9 | 0.0 35 - 10 | 0.0 35 - 11 | 0.0 35 - 12 | 0.0 35 - 13 | 0.0 35 - 14 | 0.0 35 - 15 | 0.0 35 - 16 | 0.0 35 - 17 | 0.0 35 - 18 | 0.0 35 - 19 | 0.0 35 - 20 | 0.0 35 - 21 | 0.0 35 - 22 | 0.0 35 - 23 | 0.0 35 - 24 | 0.0 35 - 25 | 0.0 35 - 26 | 0.0 35 - 27 | 0.0 35 - 28 | 0.0 35 - 29 | 0.0 35 - 30 | 0.0 35 - 31 | 0.0 35 - 32 | 0.0 35 - 33 | 0.0 35 - 34 | 0.0 35 - 35 | 0.0 35 - 36 | 0.0 35 - 37 | 0.0 35 - 38 | 0.0 35 - 39 | 0.0 35 - 40 | 0.0 35 - 41 | 0.0 35 - 42 | 0.0 35 - 43 | 0.0 35 - 44 | 0.0 35 - 45 | 0.0 35 - 46 | 0.0 35 - 47 | 0.0 35 - 48 | 0.0 35 - 49 | 0.0 35 - 50 | 0.0 35 - 51 | 0.0 35 - 52 | 0.0 35 - 53 | 0.0 35 - 54 | 0.0 35 - 55 | 0.0 35 - 56 | 0.0 35 - 57 | 0.0 35 - 58 | 0.0 35 - 59 | 0.0 35 - 60 | 0.0 35 - 61 | 0.0 35 - 62 | 0.0 35 - 63 | 0.0 35 - 64 | 0.0 35 - 65 | 0.0 35 - 66 | 0.0 35 - 67 | 0.0 35 - 68 | 0.0 35 - 69 | 0.0 35 - 70 | 0.0 35 - 71 | 0.0 35 - 72 | 0.0 35 - 73 | 0.0 35 - 74 | 0.0 35 - 75 | 0.0 35 - 76 | 0.0 35 - 77 | 0.0 35 - 78 | 0.0 35 - 79 | 0.0 35 - 80 | 0.0 35 - 81 | 0.0 35 - 82 | 0.0 35 - 83 | 0.0 35 - 84 | 0.0 35 - 85 | 0.0 35 - 86 | 0.0 35 - 87 | 0.0 35 - 88 | 0.0 35 - 89 | 0.0 35 - 90 | 0.0 35 - 91 | 0.0 35 - 92 | 0.0 35 - 93 | 0.0 35 - 94 | 0.0 35 - 95 | 0.0 36 - 0 | 0.00857885443639 36 - 1 | 0.00957049485976 36 - 2 | 0.00715442083662 36 - 3 | 0.00151055940987 36 - 4 | -0.000180212461121 36 - 5 | 3.01691097574e-05 36 - 6 | -0.000140884840801 36 - 7 | -5.22782096483e-05 36 - 8 | 0.0 36 - 9 | 0.0 36 - 10 | 0.0 36 - 11 | 0.0 36 - 12 | 0.00662083718748 36 - 13 | 0.00886881081 36 - 14 | 0.00599458040769 36 - 15 | 0.00114177150848 36 - 16 | 0.00198971091558 36 - 17 | 0.000179418662233 36 - 18 | -0.000107960636928 36 - 19 | 5.7944923863e-05 36 - 20 | -4.81483884194e-05 36 - 21 | 0.0 36 - 22 | 0.0 36 - 23 | 0.0 36 - 24 | 0.00755836828425 36 - 25 | 0.00897007402567 36 - 26 | 0.00627629811928 36 - 27 | 0.00166888397388 36 - 28 | 0.00211677181495 36 - 29 | 0.00169570773837 36 - 30 | 3.32515768712e-05 36 - 31 | 6.72313015437e-05 36 - 32 | -0.00119787389601 36 - 33 | -0.000174715067324 36 - 34 | 0.0 36 - 35 | 0.0 36 - 36 | 0.00939306605785 36 - 37 | 0.0102335976747 36 - 38 | 0.0070571779441 36 - 39 | 0.00693322189372 36 - 40 | 0.00274174732069 36 - 41 | 0.00203809592396 36 - 42 | 0.000833543794791 36 - 43 | 0.000270433301914 36 - 44 | -0.000677259380432 36 - 45 | -0.000913142310712 36 - 46 | 0.0 36 - 47 | 0.0 36 - 48 | 0.00839942441968 36 - 49 | 0.00560401688151 36 - 50 | 0.00660441960395 36 - 51 | 0.00458641262046 36 - 52 | 0.00344835583132 36 - 53 | 0.00532102555386 36 - 54 | 0.000654047955978 36 - 55 | 0.025487664028 36 - 56 | 0.000346433047869 36 - 57 | -0.000245753489143 36 - 58 | -1.49082538347e-05 36 - 59 | 0.0 36 - 60 | 0.00742862269622 36 - 61 | 0.00171047374995 36 - 62 | -0.00143444864252 36 - 63 | -0.00402285747962 36 - 64 | -0.00315361530781 36 - 65 | 0.00389469924003 36 - 66 | 0.00467276702918 36 - 67 | 0.00123721843216 36 - 68 | 0.000427291126097 36 - 69 | -0.000488866664434 36 - 70 | -0.000102698087557 36 - 71 | 0.0 36 - 72 | 0.00609353405063 36 - 73 | 0.0106615701232 36 - 74 | 0.0162575755755 36 - 75 | 0.018712728746 36 - 76 | 0.0157810088274 36 - 77 | 0.00145930309748 36 - 78 | 0.00273291305407 36 - 79 | 0.00195413249242 36 - 80 | 0.000690524283968 36 - 81 | 0.0006601122421 36 - 82 | 0.000107550981436 36 - 83 | -8.75711502888e-07 36 - 84 | 0.00155037641603 36 - 85 | 0.0047566824517 36 - 86 | 0.0044359620233 36 - 87 | 0.006323447098 36 - 88 | 0.0043653168445 36 - 89 | 0.000164325702809 36 - 90 | 0.00198152853013 36 - 91 | 0.00235951432142 36 - 92 | 0.0012706479882 36 - 93 | 0.000598572627125 36 - 94 | 0.000237745688713 36 - 95 | -1.95088871282e-05 37 - 0 | 0.0100386068366 37 - 1 | 0.0118402794482 37 - 2 | 0.00772043448083 37 - 3 | 0.00193124783588 37 - 4 | -5.58562452363e-05 37 - 5 | 7.69947164245e-05 37 - 6 | -0.000133157292645 37 - 7 | -3.66841097292e-05 37 - 8 | 0.0 37 - 9 | 0.0 37 - 10 | 0.0 37 - 11 | 0.0 37 - 12 | 0.00785344201364 37 - 13 | 0.0113072163305 37 - 14 | 0.00640728535568 37 - 15 | 0.00118980939033 37 - 16 | 0.0024212584551 37 - 17 | 0.000356816014571 37 - 18 | -2.17784912597e-05 37 - 19 | 0.000103421977998 37 - 20 | -4.23860841996e-05 37 - 21 | 0.0 37 - 22 | 0.0 37 - 23 | 0.0 37 - 24 | 0.00880153370631 37 - 25 | 0.0116337000202 37 - 26 | 0.00666733583719 37 - 27 | 0.00160686549549 37 - 28 | 0.00258737795599 37 - 29 | 0.00206632022272 37 - 30 | 0.000268573270373 37 - 31 | 0.000157600477608 37 - 32 | -0.00145517590031 37 - 33 | -0.000222743993913 37 - 34 | 0.0 37 - 35 | 0.0 37 - 36 | 0.0102335976747 37 - 37 | 0.0146206269123 37 - 38 | 0.00883512790448 37 - 39 | 0.00809647787822 37 - 40 | 0.00321033040881 37 - 41 | 0.00256902087734 37 - 42 | 0.00130054529197 37 - 43 | 0.000508209132182 37 - 44 | -0.000702893981633 37 - 45 | -0.0011226982199 37 - 46 | 0.0 37 - 47 | 0.0 37 - 48 | 0.00941266048723 37 - 49 | 0.00804985640725 37 - 50 | 0.00791508485961 37 - 51 | 0.00519964020865 37 - 52 | 0.00373537502494 37 - 53 | 0.00657660711863 37 - 54 | 0.00108031893539 37 - 55 | 0.0302066424747 37 - 56 | 0.000574704658345 37 - 57 | -0.000195678548286 37 - 58 | -2.25014604255e-06 37 - 59 | 0.0 37 - 60 | 0.00850406345784 37 - 61 | 0.00295168249553 37 - 62 | -0.00183554549046 37 - 63 | -0.00526003540063 37 - 64 | -0.00403620006663 37 - 65 | 0.00469693180401 37 - 66 | 0.00560011760393 37 - 67 | 0.00169233142763 37 - 68 | 0.000764968450583 37 - 69 | -0.000388504939304 37 - 70 | -6.76640432508e-05 37 - 71 | 0.0 37 - 72 | 0.00721613492066 37 - 73 | 0.0142113003174 37 - 74 | 0.0203360893775 37 - 75 | 0.0224001327148 37 - 76 | 0.0193705962106 37 - 77 | 0.00186124230451 37 - 78 | 0.00335850317013 37 - 79 | 0.00277682149077 37 - 80 | 0.00115641388663 37 - 81 | 0.000922419625762 37 - 82 | 0.000149756512755 37 - 83 | 6.96393175477e-07 37 - 84 | 0.00208311591441 37 - 85 | 0.00648585747289 37 - 86 | 0.00604236320093 37 - 87 | 0.00750333201935 37 - 88 | 0.00552772674272 37 - 89 | 0.000390457627465 37 - 90 | 0.00270214346627 37 - 91 | 0.00333895167049 37 - 92 | 0.00206073150304 37 - 93 | 0.00109323262099 37 - 94 | 0.000115378271617 37 - 95 | -3.34816128694e-05 38 - 0 | 0.00823549177393 38 - 1 | 0.00962235818452 38 - 2 | 0.0070146157462 38 - 3 | 0.0022327151604 38 - 4 | 0.000918086499105 38 - 5 | 0.000379855585957 38 - 6 | 6.04375947908e-05 38 - 7 | 4.28463623168e-05 38 - 8 | 0.0 38 - 9 | 0.0 38 - 10 | 0.0 38 - 11 | 0.0 38 - 12 | 0.00639625053925 38 - 13 | 0.00783915460536 38 - 14 | 0.00690672455254 38 - 15 | 0.00262900079543 38 - 16 | 0.0021757268031 38 - 17 | 0.000997744663346 38 - 18 | 0.00045440265606 38 - 19 | 0.000250212162391 38 - 20 | 4.7707996186e-05 38 - 21 | 0.0 38 - 22 | 0.0 38 - 23 | 0.0 38 - 24 | 0.0066961231369 38 - 25 | 0.00796629301938 38 - 26 | 0.00714948329411 38 - 27 | 0.00319330775819 38 - 28 | 0.00284689002829 38 - 29 | 0.00214329867909 38 - 30 | 0.00112265557118 38 - 31 | 0.000641937165596 38 - 32 | -0.000490096758428 38 - 33 | -8.75424510862e-05 38 - 34 | 0.0 38 - 35 | 0.0 38 - 36 | 0.0070571779441 38 - 37 | 0.00883512790448 38 - 38 | 0.0105639171224 38 - 39 | 0.00681978466696 38 - 40 | 0.00338852734373 38 - 41 | 0.00286082908794 38 - 42 | 0.00186229001671 38 - 43 | 0.00142764176946 38 - 44 | 0.000207809570421 38 - 45 | -0.000514365761712 38 - 46 | 0.0 38 - 47 | 0.0 38 - 48 | 0.00656731864849 38 - 49 | 0.00595387504362 38 - 50 | 0.00761646824056 38 - 51 | 0.00495529035438 38 - 52 | 0.00372604296217 38 - 53 | 0.00466953550782 38 - 54 | 0.00213776769905 38 - 55 | 0.0150425702841 38 - 56 | 0.0012050207018 38 - 57 | 0.000252889593203 38 - 58 | 2.98677891941e-05 38 - 59 | 0.0 38 - 60 | 0.00636127687801 38 - 61 | 0.00357647906773 38 - 62 | 0.00221286665754 38 - 63 | -0.000127221370495 38 - 64 | -7.80677417435e-05 38 - 65 | 0.00407962438274 38 - 66 | 0.00409346950303 38 - 67 | 0.00283514742976 38 - 68 | 0.00177961468444 38 - 69 | 0.000566518437485 38 - 70 | 7.55643795657e-05 38 - 71 | 0.0 38 - 72 | 0.00547722456619 38 - 73 | 0.00862406317932 38 - 74 | 0.0126089595629 38 - 75 | 0.0137230832967 38 - 76 | 0.0110988089416 38 - 77 | 0.00246559470762 38 - 78 | 0.00327815003457 38 - 79 | 0.00301511146817 38 - 80 | 0.00239144190225 38 - 81 | 0.00178289449285 38 - 82 | 0.000572753375097 38 - 83 | 2.91894251315e-06 38 - 84 | 0.00306759497376 38 - 85 | 0.00435856332008 38 - 86 | 0.00472853885754 38 - 87 | 0.00542023463474 38 - 88 | 0.00422440576738 38 - 89 | 0.00161324712063 38 - 90 | 0.0026122856627 38 - 91 | 0.00274136770307 38 - 92 | 0.00237754730584 38 - 93 | 0.00214097129875 38 - 94 | 0.00196562054018 38 - 95 | 0.000107008386367 39 - 0 | 0.00725690539939 39 - 1 | 0.00812396116569 39 - 2 | 0.00589903669955 39 - 3 | 0.00159261064054 39 - 4 | 0.000249918074144 39 - 5 | 0.000173961970896 39 - 6 | -2.49774994853e-05 39 - 7 | -1.07572701676e-05 39 - 8 | 0.0 39 - 9 | 0.0 39 - 10 | 0.0 39 - 11 | 0.0 39 - 12 | 0.00567354999767 39 - 13 | 0.00715171630418 39 - 14 | 0.00515107986717 39 - 15 | 0.00152014580008 39 - 16 | 0.00179276821116 39 - 17 | 0.000479393383001 39 - 18 | 0.000127892614565 39 - 19 | 0.000136543695034 39 - 20 | -3.40933224574e-06 39 - 21 | 0.0 39 - 22 | 0.0 39 - 23 | 0.0 39 - 24 | 0.00613273433524 39 - 25 | 0.00721122553312 39 - 26 | 0.00542869844149 39 - 27 | 0.00206451980661 39 - 28 | 0.00212049548456 39 - 29 | 0.0016861748336 39 - 30 | 0.000500593797738 39 - 31 | 0.00033690667897 39 - 32 | -0.000755695225157 39 - 33 | -0.000123438202865 39 - 34 | 0.0 39 - 35 | 0.0 39 - 36 | 0.00693322189372 39 - 37 | 0.00809647787822 39 - 38 | 0.00681978466696 39 - 39 | 0.00674405141934 39 - 40 | 0.0027988427711 39 - 41 | 0.00216998951484 39 - 42 | 0.00122114475964 39 - 43 | 0.000743696683786 39 - 44 | -0.000207380030665 39 - 45 | -0.000697828295511 39 - 46 | 0.0 39 - 47 | 0.0 39 - 48 | 0.00652455019772 39 - 49 | 0.00494497866722 39 - 50 | 0.00583346729769 39 - 51 | 0.0043668220473 39 - 52 | 0.00319820551228 39 - 53 | 0.00442760229495 39 - 54 | 0.00120994989362 39 - 55 | 0.0174422622769 39 - 56 | 0.000669892673566 39 - 57 | -5.18475257082e-06 39 - 58 | 7.36869955059e-06 39 - 59 | 0.0 39 - 60 | 0.00615633065014 39 - 61 | 0.00225477115755 39 - 62 | 9.85978464838e-05 39 - 63 | -0.00195466305944 39 - 64 | -0.00149541350941 39 - 65 | 0.00345515806149 39 - 66 | 0.00386812653514 39 - 67 | 0.00164665376339 39 - 68 | 0.000921064755015 39 - 69 | 1.76648202806e-05 39 - 70 | -9.61251377888e-06 39 - 71 | 0.0 39 - 72 | 0.00514157361736 39 - 73 | 0.00865728446544 39 - 74 | 0.012635225462 39 - 75 | 0.0143105594258 39 - 76 | 0.0119515124168 39 - 77 | 0.00173220980077 39 - 78 | 0.0026363054167 39 - 79 | 0.0022143682867 39 - 80 | 0.00129078507402 39 - 81 | 0.00107186431563 39 - 82 | 0.000322883965612 39 - 83 | 1.14264518989e-06 39 - 84 | 0.00187740354299 39 - 85 | 0.00405305356061 39 - 86 | 0.00382750680341 39 - 87 | 0.00510518796563 39 - 88 | 0.00386228986029 39 - 89 | 0.000801538762 39 - 90 | 0.00207619222986 39 - 91 | 0.00232370765648 39 - 92 | 0.00159720319167 39 - 93 | 0.00114725810081 39 - 94 | 0.0009233460503 39 - 95 | 3.24910968683e-05 40 - 0 | 0.00324561803762 40 - 1 | 0.0040870865094 40 - 2 | 0.00299458976578 40 - 3 | 0.00102429384775 40 - 4 | 0.00041763955931 40 - 5 | 0.000205968717766 40 - 6 | 6.90839345334e-05 40 - 7 | 1.95205076565e-05 40 - 8 | 0.0 40 - 9 | 0.0 40 - 10 | 0.0 40 - 11 | 0.0 40 - 12 | 0.00259780826718 40 - 13 | 0.00330611360472 40 - 14 | 0.00307982045507 40 - 15 | 0.00143530746785 40 - 16 | 0.000904577230632 40 - 17 | 0.000470574381718 40 - 18 | 0.00022859945611 40 - 19 | 0.000137678018191 40 - 20 | 3.41865784696e-05 40 - 21 | 0.0 40 - 22 | 0.0 40 - 23 | 0.0 40 - 24 | 0.00268978456885 40 - 25 | 0.00344302423209 40 - 26 | 0.00344480234357 40 - 27 | 0.00200905244036 40 - 28 | 0.00135516032904 40 - 29 | 0.000921252548766 40 - 30 | 0.000568975196432 40 - 31 | 0.000375312749493 40 - 32 | -7.6668864861e-05 40 - 33 | -2.05768046819e-05 40 - 34 | 0.0 40 - 35 | 0.0 40 - 36 | 0.00274174732069 40 - 37 | 0.00321033040881 40 - 38 | 0.00338852734373 40 - 39 | 0.0027988427711 40 - 40 | 0.00203966535066 40 - 41 | 0.00133391877053 40 - 42 | 0.000943098454208 40 - 43 | 0.000699569431517 40 - 44 | 0.000200907169649 40 - 45 | -0.000183649592202 40 - 46 | 0.0 40 - 47 | 0.0 40 - 48 | 0.00256998422216 40 - 49 | 0.00267672297903 40 - 50 | 0.00327309641054 40 - 51 | 0.00269664905057 40 - 52 | 0.00225300743049 40 - 53 | 0.00194536655679 40 - 54 | 0.00110194424586 40 - 55 | 0.00504108889491 40 - 56 | 0.000594276985467 40 - 57 | 0.000161933303781 40 - 58 | 1.62209035337e-05 40 - 59 | 0.0 40 - 60 | 0.00257247154676 40 - 61 | 0.00215314310051 40 - 62 | 0.00274786275876 40 - 63 | 0.0021917539027 40 - 64 | 0.00165768326077 40 - 65 | 0.00181107874863 40 - 66 | 0.00175830469034 40 - 67 | 0.00122023337888 40 - 68 | 0.000926374484984 40 - 69 | 0.000360697426325 40 - 70 | 5.89130897988e-05 40 - 71 | 0.0 40 - 72 | 0.00217996388905 40 - 73 | 0.00271501835803 40 - 74 | 0.00339630510147 40 - 75 | 0.00359718898686 40 - 76 | 0.00286140440402 40 - 77 | 0.0017702351534 40 - 78 | 0.00165740271809 40 - 79 | 0.00152623822709 40 - 80 | 0.00122993675811 40 - 81 | 0.000894315334995 40 - 82 | 0.000332694128957 40 - 83 | 1.76242660314e-06 40 - 84 | 0.00136100384651 40 - 85 | 0.00173343459276 40 - 86 | 0.00188571065938 40 - 87 | 0.00210595392103 40 - 88 | 0.00146183733889 40 - 89 | 0.00119058595896 40 - 90 | 0.00127224339794 40 - 91 | 0.00127744319426 40 - 92 | 0.00113049630665 40 - 93 | 0.00103480172227 40 - 94 | 0.00108539539659 40 - 95 | 5.72253265754e-05 41 - 0 | 0.00246960104105 41 - 1 | 0.00309052571364 41 - 2 | 0.00224012088209 41 - 3 | 0.000799139125693 41 - 4 | 0.000334093006774 41 - 5 | 0.000151166945609 41 - 6 | 5.52116592621e-05 41 - 7 | 1.45427975584e-05 41 - 8 | 0.0 41 - 9 | 0.0 41 - 10 | 0.0 41 - 11 | 0.0 41 - 12 | 0.00198181114548 41 - 13 | 0.00252085217408 41 - 14 | 0.0023214886812 41 - 15 | 0.0010671989346 41 - 16 | 0.000755364674392 41 - 17 | 0.00038427714671 41 - 18 | 0.000161999895422 41 - 19 | 9.99595748323e-05 41 - 20 | 2.55554436084e-05 41 - 21 | 0.0 41 - 22 | 0.0 41 - 23 | 0.0 41 - 24 | 0.00205547955153 41 - 25 | 0.00257269484997 41 - 26 | 0.00238936462147 41 - 27 | 0.00131491226072 41 - 28 | 0.00104134994144 41 - 29 | 0.000777158833097 41 - 30 | 0.000457415566825 41 - 31 | 0.000279044841481 41 - 32 | -3.18598186512e-05 41 - 33 | -1.06496823173e-05 41 - 34 | 0.0 41 - 35 | 0.0 41 - 36 | 0.00203809592396 41 - 37 | 0.00256902087734 41 - 38 | 0.00286082908794 41 - 39 | 0.00216998951484 41 - 40 | 0.00133391877053 41 - 41 | 0.00131707319726 41 - 42 | 0.000843389007583 41 - 43 | 0.000536832625472 41 - 44 | 0.000172518190088 41 - 45 | -0.0001169122616 41 - 46 | 0.0 41 - 47 | 0.0 41 - 48 | 0.00187259154873 41 - 49 | 0.00201056731361 41 - 50 | 0.0024445868615 41 - 51 | 0.00182433955549 41 - 52 | 0.00144167946959 41 - 53 | 0.00167456398609 41 - 54 | 0.000997555791299 41 - 55 | 0.00254420666571 41 - 56 | 0.000439139177924 41 - 57 | 0.000126926695588 41 - 58 | 1.36436765312e-05 41 - 59 | 0.0 41 - 60 | 0.00190094280623 41 - 61 | 0.00139740457346 41 - 62 | 0.00132790129604 41 - 63 | 0.000715434668755 41 - 64 | 0.000583643428323 41 - 65 | 0.00146954160256 41 - 66 | 0.00144587137061 41 - 67 | 0.000955659792815 41 - 68 | 0.000688034098448 41 - 69 | 0.00027739214235 41 - 70 | 5.01564085993e-05 41 - 71 | 0.0 41 - 72 | 0.00162812963636 41 - 73 | 0.00249537249464 41 - 74 | 0.00347485813825 41 - 75 | 0.00374971546797 41 - 76 | 0.00302363464691 41 - 77 | 0.00108647336346 41 - 78 | 0.00131882284914 41 - 79 | 0.00119795211147 41 - 80 | 0.000910601576514 41 - 81 | 0.000650222692327 41 - 82 | 0.000255435992611 41 - 83 | 1.41019215883e-06 41 - 84 | 0.000993445639154 41 - 85 | 0.00134716167815 41 - 86 | 0.00150057586419 41 - 87 | 0.00169020583847 41 - 88 | 0.00142522919834 41 - 89 | 0.000768761519323 41 - 90 | 0.00101095493968 41 - 91 | 0.00104542168909 41 - 92 | 0.000863604367057 41 - 93 | 0.000749514181074 41 - 94 | 0.000831442890983 41 - 95 | 4.35407012771e-05 42 - 0 | 0.00128498202076 42 - 1 | 0.0019290717455 42 - 2 | 0.00134154280523 42 - 3 | 0.000632916439185 42 - 4 | 0.00036978475863 42 - 5 | 0.000159229890968 42 - 6 | 8.36419915312e-05 42 - 7 | 2.6243894944e-05 42 - 8 | 0.0 42 - 9 | 0.0 42 - 10 | 0.0 42 - 11 | 0.0 42 - 12 | 0.0010828073938 42 - 13 | 0.00149711589378 42 - 14 | 0.00162313512132 42 - 15 | 0.000982553879127 42 - 16 | 0.000480111245934 42 - 17 | 0.000375872603941 42 - 18 | 0.000197814703892 42 - 19 | 0.00010440808527 42 - 20 | 3.71890124568e-05 42 - 21 | 0.0 42 - 22 | 0.0 42 - 23 | 0.0 42 - 24 | 0.00104474748091 42 - 25 | 0.00153550789296 42 - 26 | 0.00173535966084 42 - 27 | 0.00126125989923 42 - 28 | 0.000766654919972 42 - 29 | 0.000520687587993 42 - 30 | 0.000490971915212 42 - 31 | 0.000301819975502 42 - 32 | 0.000144588434093 42 - 33 | 1.61587856943e-05 42 - 34 | 0.0 42 - 35 | 0.0 42 - 36 | 0.000833543794791 42 - 37 | 0.00130054529197 42 - 38 | 0.00186229001671 42 - 39 | 0.00122114475964 42 - 40 | 0.000943098454208 42 - 41 | 0.000843389007583 42 - 42 | 0.000841341364301 42 - 43 | 0.000568370083756 42 - 44 | 0.000290678649991 42 - 45 | 1.19464647145e-05 42 - 46 | 0.0 42 - 47 | 0.0 42 - 48 | 0.000726965747479 42 - 49 | 0.00139078709296 42 - 50 | 0.00167393048676 42 - 51 | 0.00137709222649 42 - 52 | 0.00106812744962 42 - 53 | 0.00092558321258 42 - 54 | 0.000972254519082 42 - 55 | -0.000225810078898 42 - 56 | 0.000446412967438 42 - 57 | 0.000187083701713 42 - 58 | 1.84944527263e-05 42 - 59 | 0.0 42 - 60 | 0.000831182763205 42 - 61 | 0.0013900288275 42 - 62 | 0.00200509101455 42 - 63 | 0.00186010075837 42 - 64 | 0.00144608042395 42 - 65 | 0.000959722676519 42 - 66 | 0.000836136991518 42 - 67 | 0.000816825461955 42 - 68 | 0.000717235313197 42 - 69 | 0.000392297200318 42 - 70 | 7.70132790629e-05 42 - 71 | 0.0 42 - 72 | 0.000774424891418 42 - 73 | 0.000935145747357 42 - 74 | 0.000881794459541 42 - 75 | 0.000685065187283 42 - 76 | 0.000503221249956 42 - 77 | 0.00110586012482 42 - 78 | 0.000991553230868 42 - 79 | 0.00104299866314 42 - 80 | 0.000951615232403 42 - 81 | 0.000637934641909 42 - 82 | 0.000264841744946 42 - 83 | 1.79570286554e-06 42 - 84 | 0.000838008249892 42 - 85 | 0.000741509306869 42 - 86 | 0.000958574078294 42 - 87 | 0.000806972868292 42 - 88 | 0.000694207948451 42 - 89 | 0.00084934202201 42 - 90 | 0.000768844395631 42 - 91 | 0.000781397475941 42 - 92 | 0.000798424882557 42 - 93 | 0.000794164399874 42 - 94 | 0.000876016503464 42 - 95 | 4.91817638905e-05 43 - 0 | 0.00077631261023 43 - 1 | 0.00127901795903 43 - 2 | 0.00100825719067 43 - 3 | 0.000510774525678 43 - 4 | 0.000373914034192 43 - 5 | 0.000167562237335 43 - 6 | 9.04395114222e-05 43 - 7 | 3.00568240889e-05 43 - 8 | 0.0 43 - 9 | 0.0 43 - 10 | 0.0 43 - 11 | 0.0 43 - 12 | 0.000629775665814 43 - 13 | 0.000837978247683 43 - 14 | 0.0013310152611 43 - 15 | 0.00089229234333 43 - 16 | 0.000316267644237 43 - 17 | 0.00034631674949 43 - 18 | 0.000228723909561 43 - 19 | 0.000105652801889 43 - 20 | 3.55524771759e-05 43 - 21 | 0.0 43 - 22 | 0.0 43 - 23 | 0.0 43 - 24 | 0.000534505670249 43 - 25 | 0.000847833086298 43 - 26 | 0.00141979767314 43 - 27 | 0.00114534514759 43 - 28 | 0.000578786229829 43 - 29 | 0.000348856876085 43 - 30 | 0.000468996432652 43 - 31 | 0.000304512032442 43 - 32 | 0.000182050128336 43 - 33 | 2.24754645637e-05 43 - 34 | 0.0 43 - 35 | 0.0 43 - 36 | 0.000270433301914 43 - 37 | 0.000508209132182 43 - 38 | 0.00142764176946 43 - 39 | 0.000743696683786 43 - 40 | 0.000699569431517 43 - 41 | 0.000536832625472 43 - 42 | 0.000568370083756 43 - 43 | 0.000621653095795 43 - 44 | 0.000328134248768 43 - 45 | 6.51117101635e-05 43 - 46 | 0.0 43 - 47 | 0.0 43 - 48 | 0.000213505891964 43 - 49 | 0.000869005897428 43 - 50 | 0.00118974219462 43 - 51 | 0.00103356645008 43 - 52 | 0.000813071214554 43 - 53 | 0.000411629240831 43 - 54 | 0.000718802761996 43 - 55 | -0.00120061316736 43 - 56 | 0.000455283017009 43 - 57 | 0.000194219431762 43 - 58 | 1.63306433893e-05 43 - 59 | 0.0 43 - 60 | 0.000340189222828 43 - 61 | 0.00112573316698 43 - 62 | 0.00202249837842 43 - 63 | 0.00205336391392 43 - 64 | 0.00157414453918 43 - 65 | 0.00061166432422 43 - 66 | 0.000336405190723 43 - 67 | 0.000755477631188 43 - 68 | 0.000741953844916 43 - 69 | 0.000419357001121 43 - 70 | 6.87651258623e-05 43 - 71 | 0.0 43 - 72 | 0.000355163104325 43 - 73 | 4.67092521311e-06 43 - 74 | -0.000291261193471 43 - 75 | -0.00056564382434 43 - 76 | -0.000607346184206 43 - 77 | 0.000879992598728 43 - 78 | 0.000621347682783 43 - 79 | 0.00075298837977 43 - 80 | 0.000934645661402 43 - 81 | 0.000659522999171 43 - 82 | 0.000232042541714 43 - 83 | 1.52517740197e-06 43 - 84 | 0.000716585299354 43 - 85 | 0.00029963294886 43 - 86 | 0.000580057089819 43 - 87 | 0.000381343633703 43 - 88 | 0.000320493845016 43 - 89 | 0.000754791768003 43 - 90 | 0.000467887378755 43 - 91 | 0.000401012248404 43 - 92 | 0.000705463180465 43 - 93 | 0.000878361296735 43 - 94 | 0.000895214620571 43 - 95 | 5.55900666221e-05 44 - 0 | -0.000338015547979 44 - 1 | -0.000118396593961 44 - 2 | -7.67605804839e-05 44 - 3 | 0.000182104939083 44 - 4 | 0.000262366374296 44 - 5 | 0.000108581816737 44 - 6 | 8.42088535844e-05 44 - 7 | 2.78872724315e-05 44 - 8 | 0.0 44 - 9 | 0.0 44 - 10 | 0.0 44 - 11 | 0.0 44 - 12 | -0.00023055549196 44 - 13 | -0.000348165722607 44 - 14 | 0.000285762817459 44 - 15 | 0.000492474076416 44 - 16 | 1.95941590839e-05 44 - 17 | 0.000224164820638 44 - 18 | 0.000153082320126 44 - 19 | 7.05911840137e-05 44 - 20 | 3.75124163178e-05 44 - 21 | 0.0 44 - 22 | 0.0 44 - 23 | 0.0 44 - 24 | -0.0003742962925 44 - 25 | -0.000359049950103 44 - 26 | 0.000307677682402 44 - 27 | 0.000594694811818 44 - 28 | 0.000184290996642 44 - 29 | 7.01417881537e-05 44 - 30 | 0.000307377278613 44 - 31 | 0.000218912583913 44 - 32 | 0.000330365187927 44 - 33 | 4.62985642429e-05 44 - 34 | 0.0 44 - 35 | 0.0 44 - 36 | -0.000677259380432 44 - 37 | -0.000702893981633 44 - 38 | 0.000207809570421 44 - 39 | -0.000207380030665 44 - 40 | 0.000200907169649 44 - 41 | 0.000172518190088 44 - 42 | 0.000290678649991 44 - 43 | 0.000328134248768 44 - 44 | 0.00031690343314 44 - 45 | 0.00015653994134 44 - 46 | 0.0 44 - 47 | 0.0 44 - 48 | -0.000693537710871 44 - 49 | 2.96721536522e-05 44 - 50 | 0.000117213868718 44 - 51 | 0.000230129843892 44 - 52 | 0.000198752015748 44 - 53 | -0.000274926209415 44 - 54 | 0.000427105382282 44 - 55 | -0.00378104070351 44 - 56 | 0.00024630031276 44 - 57 | 0.000159683068307 44 - 58 | 1.42266871793e-05 44 - 59 | 0.0 44 - 60 | -0.00053404796892 44 - 61 | 0.000557127447274 44 - 62 | 0.00151013311077 44 - 63 | 0.00180176308599 44 - 64 | 0.00138781081825 44 - 65 | 2.32140365302e-05 44 - 66 | -0.000220404106996 44 - 67 | 0.000337826494978 44 - 68 | 0.000412877134131 44 - 69 | 0.000325415059967 44 - 70 | 5.94839447887e-05 44 - 71 | 0.0 44 - 72 | -0.000387178011868 44 - 73 | -0.00111923152962 44 - 74 | -0.00187693439754 44 - 75 | -0.00225894385604 44 - 76 | -0.00201162447749 44 - 77 | 0.000452370801938 44 - 78 | 0.000196407024421 44 - 79 | 0.000329247782569 44 - 80 | 0.000517937776382 44 - 81 | 0.000345014754063 44 - 82 | 0.000152341748451 44 - 83 | 1.14258474604e-06 44 - 84 | 0.000302805971576 44 - 85 | -0.00028678700416 44 - 86 | -7.75766601118e-05 44 - 87 | -0.000385545532223 44 - 88 | -0.000210267565886 44 - 89 | 0.000501940182567 44 - 90 | 0.000140287030672 44 - 91 | 5.90072614572e-05 44 - 92 | 0.000320367893727 44 - 93 | 0.000472395429721 44 - 94 | 0.000580169074205 44 - 95 | 3.80667280221e-05 45 - 0 | -0.000765836740289 45 - 1 | -0.000825387156266 45 - 2 | -0.000665592533033 45 - 3 | -0.000104990588284 45 - 4 | 0.000108389940064 45 - 5 | 3.25797986691e-05 45 - 6 | 4.13197604423e-05 45 - 7 | 1.61796399291e-05 45 - 8 | 0.0 45 - 9 | 0.0 45 - 10 | 0.0 45 - 11 | 0.0 45 - 12 | -0.000581470259347 45 - 13 | -0.000914450981313 45 - 14 | -0.000443158069752 45 - 15 | 6.40101536591e-05 45 - 16 | -0.000176265084179 45 - 17 | 4.89348302556e-05 45 - 18 | 5.73322176284e-05 45 - 19 | 1.81163342554e-05 45 - 20 | 1.7588916496e-05 45 - 21 | 0.0 45 - 22 | 0.0 45 - 23 | 0.0 45 - 24 | -0.000680917956586 45 - 25 | -0.000882638112287 45 - 26 | -0.000446573859116 45 - 27 | 5.5982477922e-05 45 - 28 | -0.000127524854933 45 - 29 | -0.000125572678542 45 - 30 | 8.61862768006e-05 45 - 31 | 5.21707192214e-05 45 - 32 | 0.000228341259604 45 - 33 | 3.77849902505e-05 45 - 34 | 0.0 45 - 35 | 0.0 45 - 36 | -0.000913142310712 45 - 37 | -0.0011226982199 45 - 38 | -0.000514365761712 45 - 39 | -0.000697828295511 45 - 40 | -0.000183649592202 45 - 41 | -0.0001169122616 45 - 42 | 1.19464647145e-05 45 - 43 | 6.51117101635e-05 45 - 44 | 0.00015653994134 45 - 45 | 0.000194267775233 45 - 46 | 0.0 45 - 47 | 0.0 45 - 48 | -0.0008740881439 45 - 49 | -0.000464153032839 45 - 50 | -0.00050757580356 45 - 51 | -0.000329817155572 45 - 52 | -0.000227273395901 45 - 53 | -0.000583281918334 45 - 54 | 0.00010026604238 45 - 55 | -0.00380469765374 45 - 56 | 1.85816691674e-05 45 - 57 | 6.71591548253e-05 45 - 58 | 5.2529382541e-06 45 - 59 | 0.0 45 - 60 | -0.000727954224289 45 - 61 | 6.81335278145e-05 45 - 62 | 0.00067380187597 45 - 63 | 0.000986185400937 45 - 64 | 0.000755706737247 45 - 65 | -0.000339076742612 45 - 66 | -0.000487183123217 45 - 67 | -1.25556573852e-06 45 - 68 | 4.72520131431e-05 45 - 69 | 0.000126703643428 45 - 70 | 2.65112433458e-05 45 - 71 | 0.0 45 - 72 | -0.000589579688467 45 - 73 | -0.00130373095208 45 - 74 | -0.00210800898344 45 - 75 | -0.00242188075256 45 - 76 | -0.00213150956872 45 - 77 | 2.74151768511e-05 45 - 78 | -0.000175859832823 45 - 79 | -9.82206893846e-05 45 - 80 | 5.30224164162e-05 45 - 81 | -1.90858626809e-05 45 - 82 | 1.54201090104e-05 45 - 83 | 2.6415453348e-07 45 - 84 | 3.81628566171e-05 45 - 85 | -0.00049412275492 45 - 86 | -0.00040884156645 45 - 87 | -0.000671867108283 45 - 88 | -0.000428807204756 45 - 89 | 0.000186818354332 45 - 90 | -0.000103960809337 45 - 91 | -0.000199530251545 45 - 92 | -5.59216150489e-05 45 - 93 | 2.01928692972e-05 45 - 94 | 0.000102998841976 45 - 95 | 1.12068143166e-05 46 - 0 | 0.0 46 - 1 | 0.0 46 - 2 | 0.0 46 - 3 | 0.0 46 - 4 | 0.0 46 - 5 | 0.0 46 - 6 | 0.0 46 - 7 | 0.0 46 - 8 | 0.0 46 - 9 | 0.0 46 - 10 | 0.0 46 - 11 | 0.0 46 - 12 | 0.0 46 - 13 | 0.0 46 - 14 | 0.0 46 - 15 | 0.0 46 - 16 | 0.0 46 - 17 | 0.0 46 - 18 | 0.0 46 - 19 | 0.0 46 - 20 | 0.0 46 - 21 | 0.0 46 - 22 | 0.0 46 - 23 | 0.0 46 - 24 | 0.0 46 - 25 | 0.0 46 - 26 | 0.0 46 - 27 | 0.0 46 - 28 | 0.0 46 - 29 | 0.0 46 - 30 | 0.0 46 - 31 | 0.0 46 - 32 | 0.0 46 - 33 | 0.0 46 - 34 | 0.0 46 - 35 | 0.0 46 - 36 | 0.0 46 - 37 | 0.0 46 - 38 | 0.0 46 - 39 | 0.0 46 - 40 | 0.0 46 - 41 | 0.0 46 - 42 | 0.0 46 - 43 | 0.0 46 - 44 | 0.0 46 - 45 | 0.0 46 - 46 | 0.0 46 - 47 | 0.0 46 - 48 | 0.0 46 - 49 | 0.0 46 - 50 | 0.0 46 - 51 | 0.0 46 - 52 | 0.0 46 - 53 | 0.0 46 - 54 | 0.0 46 - 55 | 0.0 46 - 56 | 0.0 46 - 57 | 0.0 46 - 58 | 0.0 46 - 59 | 0.0 46 - 60 | 0.0 46 - 61 | 0.0 46 - 62 | 0.0 46 - 63 | 0.0 46 - 64 | 0.0 46 - 65 | 0.0 46 - 66 | 0.0 46 - 67 | 0.0 46 - 68 | 0.0 46 - 69 | 0.0 46 - 70 | 0.0 46 - 71 | 0.0 46 - 72 | 0.0 46 - 73 | 0.0 46 - 74 | 0.0 46 - 75 | 0.0 46 - 76 | 0.0 46 - 77 | 0.0 46 - 78 | 0.0 46 - 79 | 0.0 46 - 80 | 0.0 46 - 81 | 0.0 46 - 82 | 0.0 46 - 83 | 0.0 46 - 84 | 0.0 46 - 85 | 0.0 46 - 86 | 0.0 46 - 87 | 0.0 46 - 88 | 0.0 46 - 89 | 0.0 46 - 90 | 0.0 46 - 91 | 0.0 46 - 92 | 0.0 46 - 93 | 0.0 46 - 94 | 0.0 46 - 95 | 0.0 47 - 0 | 0.0 47 - 1 | 0.0 47 - 2 | 0.0 47 - 3 | 0.0 47 - 4 | 0.0 47 - 5 | 0.0 47 - 6 | 0.0 47 - 7 | 0.0 47 - 8 | 0.0 47 - 9 | 0.0 47 - 10 | 0.0 47 - 11 | 0.0 47 - 12 | 0.0 47 - 13 | 0.0 47 - 14 | 0.0 47 - 15 | 0.0 47 - 16 | 0.0 47 - 17 | 0.0 47 - 18 | 0.0 47 - 19 | 0.0 47 - 20 | 0.0 47 - 21 | 0.0 47 - 22 | 0.0 47 - 23 | 0.0 47 - 24 | 0.0 47 - 25 | 0.0 47 - 26 | 0.0 47 - 27 | 0.0 47 - 28 | 0.0 47 - 29 | 0.0 47 - 30 | 0.0 47 - 31 | 0.0 47 - 32 | 0.0 47 - 33 | 0.0 47 - 34 | 0.0 47 - 35 | 0.0 47 - 36 | 0.0 47 - 37 | 0.0 47 - 38 | 0.0 47 - 39 | 0.0 47 - 40 | 0.0 47 - 41 | 0.0 47 - 42 | 0.0 47 - 43 | 0.0 47 - 44 | 0.0 47 - 45 | 0.0 47 - 46 | 0.0 47 - 47 | 0.0 47 - 48 | 0.0 47 - 49 | 0.0 47 - 50 | 0.0 47 - 51 | 0.0 47 - 52 | 0.0 47 - 53 | 0.0 47 - 54 | 0.0 47 - 55 | 0.0 47 - 56 | 0.0 47 - 57 | 0.0 47 - 58 | 0.0 47 - 59 | 0.0 47 - 60 | 0.0 47 - 61 | 0.0 47 - 62 | 0.0 47 - 63 | 0.0 47 - 64 | 0.0 47 - 65 | 0.0 47 - 66 | 0.0 47 - 67 | 0.0 47 - 68 | 0.0 47 - 69 | 0.0 47 - 70 | 0.0 47 - 71 | 0.0 47 - 72 | 0.0 47 - 73 | 0.0 47 - 74 | 0.0 47 - 75 | 0.0 47 - 76 | 0.0 47 - 77 | 0.0 47 - 78 | 0.0 47 - 79 | 0.0 47 - 80 | 0.0 47 - 81 | 0.0 47 - 82 | 0.0 47 - 83 | 0.0 47 - 84 | 0.0 47 - 85 | 0.0 47 - 86 | 0.0 47 - 87 | 0.0 47 - 88 | 0.0 47 - 89 | 0.0 47 - 90 | 0.0 47 - 91 | 0.0 47 - 92 | 0.0 47 - 93 | 0.0 47 - 94 | 0.0 47 - 95 | 0.0 48 - 0 | 0.00807993387852 48 - 1 | 0.00900812997902 48 - 2 | 0.00675823989816 48 - 3 | 0.00136106470763 48 - 4 | -0.000197638577156 48 - 5 | -1.52919636222e-06 48 - 6 | -0.000168026965167 48 - 7 | -5.75558116344e-05 48 - 8 | 0.0 48 - 9 | 0.0 48 - 10 | 0.0 48 - 11 | 0.0 48 - 12 | 0.00622202559637 48 - 13 | 0.00833886450612 48 - 14 | 0.00570775261146 48 - 15 | 0.00106435414763 48 - 16 | 0.00183512876058 48 - 17 | 0.000113177975731 48 - 18 | -0.000126753831304 48 - 19 | 2.80094317198e-05 48 - 20 | -5.35637847066e-05 48 - 21 | 0.0 48 - 22 | 0.0 48 - 23 | 0.0 48 - 24 | 0.00694031726491 48 - 25 | 0.00855285250618 48 - 26 | 0.00616040796689 48 - 27 | 0.00173088269162 48 - 28 | 0.00197702145696 48 - 29 | 0.0015783021701 48 - 30 | -1.4427280065e-05 48 - 31 | 1.46730263453e-05 48 - 32 | -0.0011951623085 48 - 33 | -0.000175698677424 48 - 34 | 0.0 48 - 35 | 0.0 48 - 36 | 0.00839942441968 48 - 37 | 0.00941266048723 48 - 38 | 0.00656731864849 48 - 39 | 0.00652455019772 48 - 40 | 0.00256998422216 48 - 41 | 0.00187259154873 48 - 42 | 0.000726965747479 48 - 43 | 0.000213505891964 48 - 44 | -0.000693537710871 48 - 45 | -0.0008740881439 48 - 46 | 0.0 48 - 47 | 0.0 48 - 48 | 0.00877300599794 48 - 49 | 0.00538505881856 48 - 50 | 0.00643570615952 48 - 51 | 0.00448809220466 48 - 52 | 0.00342140299549 48 - 53 | 0.0049533866451 48 - 54 | 0.000491403002619 48 - 55 | 0.0253040481783 48 - 56 | 0.000283729047965 48 - 57 | -0.000257735072909 48 - 58 | -1.83716828416e-05 48 - 59 | 0.0 48 - 60 | 0.00754080248541 48 - 61 | 0.00189466745593 48 - 62 | -0.000743699243445 48 - 63 | -0.00307761947079 48 - 64 | -0.00248184674885 48 - 65 | 0.00365911006603 48 - 66 | 0.00444551637936 48 - 67 | 0.0011928039447 48 - 68 | 0.000336955683598 48 - 69 | -0.000509130221683 48 - 70 | -0.000112139645564 48 - 71 | 0.0 48 - 72 | 0.00589078464534 48 - 73 | 0.00982275984449 48 - 74 | 0.0147418798316 48 - 75 | 0.0170077209115 48 - 76 | 0.0143998188119 48 - 77 | 0.00159027584814 48 - 78 | 0.00258206915989 48 - 79 | 0.00179405468613 48 - 80 | 0.000540082232242 48 - 81 | 0.000555166378628 48 - 82 | 7.51360982311e-05 48 - 83 | -1.07908824119e-06 48 - 84 | 0.00156525449067 48 - 85 | 0.00454000202874 48 - 86 | 0.00415348546791 48 - 87 | 0.00593993953069 48 - 88 | 0.00386887541147 48 - 89 | 0.000298708594685 48 - 90 | 0.00189500973967 48 - 91 | 0.00218736670617 48 - 92 | 0.00109221137644 48 - 93 | 0.000443347835033 48 - 94 | 0.000118122186153 48 - 95 | -2.08572846028e-05 49 - 0 | 0.00616382006363 49 - 1 | 0.00818637462594 49 - 2 | 0.00500914823664 49 - 3 | 0.00155705910607 49 - 4 | 0.000382213092023 49 - 5 | 0.000237527652783 49 - 6 | 4.74579450367e-05 49 - 7 | 1.14183110248e-05 49 - 8 | 0.0 49 - 9 | 0.0 49 - 10 | 0.0 49 - 11 | 0.0 49 - 12 | 0.00497287466506 49 - 13 | 0.00734454532743 49 - 14 | 0.00502489598376 49 - 15 | 0.00193304240255 49 - 16 | 0.00154436568096 49 - 17 | 0.000589691477253 49 - 18 | 0.00022718221415 49 - 19 | 0.000146789880318 49 - 20 | 1.37290431604e-05 49 - 21 | 0.0 49 - 22 | 0.0 49 - 23 | 0.0 49 - 24 | 0.00539465070426 49 - 25 | 0.00770945440432 49 - 26 | 0.00584262120247 49 - 27 | 0.00296084728878 49 - 28 | 0.00211100726326 49 - 29 | 0.00140932997765 49 - 30 | 0.000688475553274 49 - 31 | 0.000393291565512 49 - 32 | -0.000485138929411 49 - 33 | -8.70821442176e-05 49 - 34 | 0.0 49 - 35 | 0.0 49 - 36 | 0.00560401688151 49 - 37 | 0.00804985640725 49 - 38 | 0.00595387504362 49 - 39 | 0.00494497866722 49 - 40 | 0.00267672297903 49 - 41 | 0.00201056731361 49 - 42 | 0.00139078709296 49 - 43 | 0.000869005897428 49 - 44 | 2.96721536522e-05 49 - 45 | -0.000464153032839 49 - 46 | 0.0 49 - 47 | 0.0 49 - 48 | 0.00538505881856 49 - 49 | 0.00772401499103 49 - 50 | 0.00661880361489 49 - 51 | 0.0048140739607 49 - 52 | 0.00360089425601 49 - 53 | 0.00376483108298 49 - 54 | 0.00155190176796 49 - 55 | 0.00910497547538 49 - 56 | 0.000755465427326 49 - 57 | 0.000104160353081 49 - 58 | 9.99278971275e-06 49 - 59 | 0.0 49 - 60 | 0.00522793384355 49 - 61 | 0.00488188643854 49 - 62 | 0.00433450777717 49 - 63 | 0.00287726075887 49 - 64 | 0.00203495180918 49 - 65 | 0.00336454776891 49 - 66 | 0.00344823813218 49 - 67 | 0.00180610553231 49 - 68 | 0.00122590124378 49 - 69 | 0.00026477536036 49 - 70 | 4.2742021741e-05 49 - 71 | 0.0 49 - 72 | 0.00428532726931 49 - 73 | 0.00707674088381 49 - 74 | 0.0081929557795 49 - 75 | 0.00828650782033 49 - 76 | 0.00720615445663 49 - 77 | 0.00314258133358 49 - 78 | 0.00295576460096 49 - 79 | 0.00267530619424 49 - 80 | 0.00165824967645 49 - 81 | 0.00106799154659 49 - 82 | 0.000307280396424 49 - 83 | 2.21981435786e-06 49 - 84 | 0.00218414471405 49 - 85 | 0.00419781598097 49 - 86 | 0.0041772803798 49 - 87 | 0.00441881640039 49 - 88 | 0.00316682210261 49 - 89 | 0.00209408931648 49 - 90 | 0.00247404063373 49 - 91 | 0.00254885214633 49 - 92 | 0.00200533744508 49 - 93 | 0.00136825614883 49 - 94 | 0.000873529426231 49 - 95 | 3.17250783299e-05 50 - 0 | 0.00742085943667 50 - 1 | 0.00926080489665 50 - 2 | 0.00628367329594 50 - 3 | 0.00191522426907 50 - 4 | 0.000609352257668 50 - 5 | 0.000337701802197 50 - 6 | 6.69002930528e-05 50 - 7 | 1.53458676961e-05 50 - 8 | 0.0 50 - 9 | 0.0 50 - 10 | 0.0 50 - 11 | 0.0 50 - 12 | 0.0058818087985 50 - 13 | 0.00774135969966 50 - 14 | 0.00637613507715 50 - 15 | 0.00256734858771 50 - 16 | 0.00181362146222 50 - 17 | 0.00075928791182 50 - 18 | 0.000343846015831 50 - 19 | 0.000201626024913 50 - 20 | 2.5347759359e-05 50 - 21 | 0.0 50 - 22 | 0.0 50 - 23 | 0.0 50 - 24 | 0.00630980660677 50 - 25 | 0.00817052640204 50 - 26 | 0.00734615403629 50 - 27 | 0.00383526333889 50 - 28 | 0.00256857270766 50 - 29 | 0.00176709567481 50 - 30 | 0.000901328148954 50 - 31 | 0.000535698090484 50 - 32 | -0.0005090469053 50 - 33 | -9.2426136444e-05 50 - 34 | 0.0 50 - 35 | 0.0 50 - 36 | 0.00660441960395 50 - 37 | 0.00791508485961 50 - 38 | 0.00761646824056 50 - 39 | 0.00583346729769 50 - 40 | 0.00327309641054 50 - 41 | 0.0024445868615 50 - 42 | 0.00167393048676 50 - 43 | 0.00118974219462 50 - 44 | 0.000117213868718 50 - 45 | -0.00050757580356 50 - 46 | 0.0 50 - 47 | 0.0 50 - 48 | 0.00643570615952 50 - 49 | 0.00661880361489 50 - 50 | 0.00936245958304 50 - 51 | 0.00596969312801 50 - 52 | 0.00444383349236 50 - 53 | 0.00416298873975 50 - 54 | 0.00190083859619 50 - 55 | 0.012600972912 50 - 56 | 0.00100484502244 50 - 57 | 0.000170942786605 50 - 58 | 1.56344718706e-05 50 - 59 | 0.0 50 - 60 | 0.00638091036453 50 - 61 | 0.00486913991303 50 - 62 | 0.00616481642949 50 - 63 | 0.00411149428239 50 - 64 | 0.00286548202006 50 - 65 | 0.00391058519822 50 - 66 | 0.00388795552371 50 - 67 | 0.00231426835419 50 - 68 | 0.00157657452373 50 - 69 | 0.000423401133418 50 - 70 | 5.23127893412e-05 50 - 71 | 0.0 50 - 72 | 0.00523774992377 50 - 73 | 0.00706745994842 50 - 74 | 0.00859272367228 50 - 75 | 0.0089185701976 50 - 76 | 0.00740379744899 50 - 77 | 0.00374274851018 50 - 78 | 0.0034312635716 50 - 79 | 0.00296135429929 50 - 80 | 0.00203692045172 50 - 81 | 0.00144602768244 50 - 82 | 0.000466931788235 50 - 83 | 2.5150826409e-06 50 - 84 | 0.00288020090249 50 - 85 | 0.0043764939403 50 - 86 | 0.00453398826449 50 - 87 | 0.00500416398825 50 - 88 | 0.00348999262289 50 - 89 | 0.00257687850064 50 - 90 | 0.00283783316799 50 - 91 | 0.00274308966498 50 - 92 | 0.00217654584111 50 - 93 | 0.00172104185797 50 - 94 | 0.00149075546094 50 - 95 | 7.2409123562e-05 51 - 0 | 0.00531037922662 51 - 1 | 0.00671978297538 51 - 2 | 0.00462982918735 51 - 3 | 0.00150883349691 51 - 4 | 0.000561058814602 51 - 5 | 0.000304965188473 51 - 6 | 8.99280809456e-05 51 - 7 | 2.12696496771e-05 51 - 8 | 0.0 51 - 9 | 0.0 51 - 10 | 0.0 51 - 11 | 0.0 51 - 12 | 0.00428122003691 51 - 13 | 0.0054135330859 51 - 14 | 0.00483738655846 51 - 15 | 0.00226320580332 51 - 16 | 0.00130405376537 51 - 17 | 0.000639699370921 51 - 18 | 0.000321467919741 51 - 19 | 0.000184142707965 51 - 20 | 3.37305146644e-05 51 - 21 | 0.0 51 - 22 | 0.0 51 - 23 | 0.0 51 - 24 | 0.00449708235683 51 - 25 | 0.00588643102091 51 - 26 | 0.00584429819208 51 - 27 | 0.00350555952283 51 - 28 | 0.00198205561347 51 - 29 | 0.00130712883033 51 - 30 | 0.000786704986754 51 - 31 | 0.000498119658785 51 - 32 | -0.000248968041716 51 - 33 | -5.36320652813e-05 51 - 34 | 0.0 51 - 35 | 0.0 51 - 36 | 0.00458641262046 51 - 37 | 0.00519964020865 51 - 38 | 0.00495529035438 51 - 39 | 0.0043668220473 51 - 40 | 0.00269664905057 51 - 41 | 0.00182433955549 51 - 42 | 0.00137709222649 51 - 43 | 0.00103356645008 51 - 44 | 0.000230129843892 51 - 45 | -0.000329817155572 51 - 46 | 0.0 51 - 47 | 0.0 51 - 48 | 0.00448809220466 51 - 49 | 0.0048140739607 51 - 50 | 0.00596969312801 51 - 51 | 0.00594354950101 51 - 52 | 0.00405052131058 51 - 53 | 0.00290643718007 51 - 54 | 0.00160938875238 51 - 55 | 0.00748160074787 51 - 56 | 0.00087852530567 51 - 57 | 0.000206550713022 51 - 58 | 1.71197760779e-05 51 - 59 | 0.0 51 - 60 | 0.00459756415608 51 - 61 | 0.00420289410185 51 - 62 | 0.00605167484563 51 - 63 | 0.00567158584842 51 - 64 | 0.00393783046143 51 - 65 | 0.00293627555658 51 - 66 | 0.00282690956739 51 - 67 | 0.00186618117413 51 - 68 | 0.00138403741479 51 - 69 | 0.00048126473843 51 - 70 | 7.08049197958e-05 51 - 71 | 0.0 51 - 72 | 0.00375375454797 51 - 73 | 0.00414304931846 51 - 74 | 0.00417118525832 51 - 75 | 0.00423743721694 51 - 76 | 0.00341625089806 51 - 77 | 0.00345417361462 51 - 78 | 0.00272876785082 51 - 79 | 0.00240311034145 51 - 80 | 0.00180137065199 51 - 81 | 0.0012814746373 51 - 82 | 0.000458971028748 51 - 83 | 2.49252719886e-06 51 - 84 | 0.00232562516546 51 - 85 | 0.00305317994636 51 - 86 | 0.00314638031445 51 - 87 | 0.00345182370005 51 - 88 | 0.00223080676966 51 - 89 | 0.00245485571918 51 - 90 | 0.0022739312612 51 - 91 | 0.00210464484668 51 - 92 | 0.00175475577818 51 - 93 | 0.00146780644326 51 - 94 | 0.00146521144907 51 - 95 | 7.52757130931e-05 52 - 0 | 0.00404220571018 52 - 1 | 0.00515235250991 52 - 2 | 0.00367652404787 52 - 3 | 0.00115379863261 52 - 4 | 0.000439272290678 52 - 5 | 0.000239784195442 52 - 6 | 6.96032963994e-05 52 - 7 | 1.59656984486e-05 52 - 8 | 0.0 52 - 9 | 0.0 52 - 10 | 0.0 52 - 11 | 0.0 52 - 12 | 0.00327056153943 52 - 13 | 0.00406653233867 52 - 14 | 0.00388355976446 52 - 15 | 0.00185228828746 52 - 16 | 0.00100226010705 52 - 17 | 0.000496190399231 52 - 18 | 0.000254322273049 52 - 19 | 0.000148617608606 52 - 20 | 3.08939395807e-05 52 - 21 | 0.0 52 - 22 | 0.0 52 - 23 | 0.0 52 - 24 | 0.00339591774762 52 - 25 | 0.00447184852875 52 - 26 | 0.0047934264172 52 - 27 | 0.00293112019088 52 - 28 | 0.00155920004025 52 - 29 | 0.00101956627165 52 - 30 | 0.00061532303134 52 - 31 | 0.000401100373485 52 - 32 | -0.00015371469662 52 - 33 | -3.45486733531e-05 52 - 34 | 0.0 52 - 35 | 0.0 52 - 36 | 0.00344835583132 52 - 37 | 0.00373537502494 52 - 38 | 0.00372604296217 52 - 39 | 0.00319820551228 52 - 40 | 0.00225300743049 52 - 41 | 0.00144167946959 52 - 42 | 0.00106812744962 52 - 43 | 0.000813071214554 52 - 44 | 0.000198752015748 52 - 45 | -0.000227273395901 52 - 46 | 0.0 52 - 47 | 0.0 52 - 48 | 0.00342140299549 52 - 49 | 0.00360089425601 52 - 50 | 0.00444383349236 52 - 51 | 0.00405052131058 52 - 52 | 0.00384384116874 52 - 53 | 0.00241197993405 52 - 54 | 0.00131093490458 52 - 55 | 0.00634673852116 52 - 56 | 0.000706253282387 52 - 57 | 0.000172108641323 52 - 58 | 1.36659942062e-05 52 - 59 | 0.0 52 - 60 | 0.00354457880245 52 - 61 | 0.00333795977306 52 - 62 | 0.0051962732805 52 - 63 | 0.00493921249139 52 - 64 | 0.00377269551038 52 - 65 | 0.00238000212112 52 - 66 | 0.00221834961006 52 - 67 | 0.00149727372786 52 - 68 | 0.00110273648045 52 - 69 | 0.000392104780351 52 - 70 | 5.63510370797e-05 52 - 71 | 0.0 52 - 72 | 0.00286368855752 52 - 73 | 0.0026851107441 52 - 74 | 0.00248822410171 52 - 75 | 0.00243027828466 52 - 76 | 0.00194470881929 52 - 77 | 0.00285790792894 52 - 78 | 0.00214315242908 52 - 79 | 0.00185372979664 52 - 80 | 0.00141041386179 52 - 81 | 0.00102363528212 52 - 82 | 0.000382314448626 52 - 83 | 1.78662802616e-06 52 - 84 | 0.00184577312017 52 - 85 | 0.00223681511455 52 - 86 | 0.00231042627079 52 - 87 | 0.00253828832723 52 - 88 | 0.0014695481714 52 - 89 | 0.00200079085404 52 - 90 | 0.00172375099838 52 - 91 | 0.00156491176814 52 - 92 | 0.00130450379217 52 - 93 | 0.00113135249663 52 - 94 | 0.0012475885112 52 - 95 | 6.6851230661e-05 53 - 0 | 0.00535248707498 53 - 1 | 0.00617448367916 53 - 2 | 0.00434811509019 53 - 3 | 0.00117043449644 53 - 4 | 5.64844797571e-05 53 - 5 | 7.15054489408e-05 53 - 6 | -4.96572096858e-05 53 - 7 | -1.94680732731e-05 53 - 8 | 0.0 53 - 9 | 0.0 53 - 10 | 0.0 53 - 11 | 0.0 53 - 12 | 0.00419873690242 53 - 13 | 0.00573979536839 53 - 14 | 0.00358550985961 53 - 15 | 0.000853798858056 53 - 16 | 0.00138257528972 53 - 17 | 0.00027132793234 53 - 18 | 2.58825771672e-05 53 - 19 | 8.08150320655e-05 53 - 20 | -1.89073511327e-05 53 - 21 | 0.0 53 - 22 | 0.0 53 - 23 | 0.0 53 - 24 | 0.0046292147363 53 - 25 | 0.00574108048127 53 - 26 | 0.00367361952618 53 - 27 | 0.00106804168908 53 - 28 | 0.00151639728232 53 - 29 | 0.00126029756412 53 - 30 | 0.000232799241565 53 - 31 | 0.000133926991836 53 - 32 | -0.000752241771848 53 - 33 | -0.000115103091371 53 - 34 | 0.0 53 - 35 | 0.0 53 - 36 | 0.00532102555386 53 - 37 | 0.00657660711863 53 - 38 | 0.00466953550782 53 - 39 | 0.00442760229495 53 - 40 | 0.00194536655679 53 - 41 | 0.00167456398609 53 - 42 | 0.00092558321258 53 - 43 | 0.000411629240831 53 - 44 | -0.000274926209415 53 - 45 | -0.000583281918334 53 - 46 | 0.0 53 - 47 | 0.0 53 - 48 | 0.0049533866451 53 - 49 | 0.00376483108298 53 - 50 | 0.00416298873975 53 - 51 | 0.00290643718007 53 - 52 | 0.00241197993405 53 - 53 | 0.00456542700649 53 - 54 | 0.00114327120949 53 - 55 | 0.014770402047 53 - 56 | 0.000480089301746 53 - 57 | -2.20278143579e-05 53 - 58 | 3.73181943848e-06 53 - 59 | 0.0 53 - 60 | 0.00451015215004 53 - 61 | 0.00146177566846 53 - 62 | -0.000951131530717 53 - 63 | -0.00271434231766 53 - 64 | -0.00188109231459 53 - 65 | 0.00292395941898 53 - 66 | 0.003286800244 53 - 67 | 0.00110712436973 53 - 68 | 0.000636333716814 53 - 69 | -4.98344481006e-05 53 - 70 | 2.30364428491e-06 53 - 71 | 0.0 53 - 72 | 0.00381234204753 53 - 73 | 0.00736563660353 53 - 74 | 0.0108367468982 53 - 75 | 0.0119929333201 53 - 76 | 0.0102690622912 53 - 77 | 0.00107347071794 53 - 78 | 0.00202820079535 53 - 79 | 0.00170489639967 53 - 80 | 0.000903553063038 53 - 81 | 0.000727012850355 53 - 82 | 0.000231023659742 53 - 83 | 1.00760765114e-06 53 - 84 | 0.00120727804121 53 - 85 | 0.00319787646152 53 - 86 | 0.00308004404624 53 - 87 | 0.00398226482258 53 - 88 | 0.00301874488316 53 - 89 | 0.000248514044695 53 - 90 | 0.00152388361718 53 - 91 | 0.0019120972783 53 - 92 | 0.00119373125294 53 - 93 | 0.000788104408505 53 - 94 | 0.000553158525452 53 - 95 | 1.10099684471e-05 54 - 0 | 0.00131424253197 54 - 1 | 0.00206233946089 54 - 2 | 0.0014494710316 54 - 3 | 0.000801322164357 54 - 4 | 0.000543039959911 54 - 5 | 0.000221979217055 54 - 6 | 0.000122284618367 54 - 7 | 3.46321147719e-05 54 - 8 | 0.0 54 - 9 | 0.0 54 - 10 | 0.0 54 - 11 | 0.0 54 - 12 | 0.0011083932876 54 - 13 | 0.00142716913038 54 - 14 | 0.00189580232369 54 - 15 | 0.00138104554655 54 - 16 | 0.000572799003831 54 - 17 | 0.000503181435557 54 - 18 | 0.000271759331398 54 - 19 | 0.000133614217643 54 - 20 | 3.82638709817e-05 54 - 21 | 0.0 54 - 22 | 0.0 54 - 23 | 0.0 54 - 24 | 0.00103330268225 54 - 25 | 0.0015155368849 54 - 26 | 0.00200576467298 54 - 27 | 0.00170520279429 54 - 28 | 0.000938401814195 54 - 29 | 0.000617258093929 54 - 30 | 0.000585617360746 54 - 31 | 0.00032181242896 54 - 32 | 0.000165665376914 54 - 33 | 2.33401248731e-05 54 - 34 | 0.0 54 - 35 | 0.0 54 - 36 | 0.000654047955978 54 - 37 | 0.00108031893539 54 - 38 | 0.00213776769905 54 - 39 | 0.00120994989362 54 - 40 | 0.00110194424586 54 - 41 | 0.000997555791299 54 - 42 | 0.000972254519082 54 - 43 | 0.000718802761996 54 - 44 | 0.000427105382282 54 - 45 | 0.00010026604238 54 - 46 | 0.0 54 - 47 | 0.0 54 - 48 | 0.000491403002619 54 - 49 | 0.00155190176796 54 - 50 | 0.00190083859619 54 - 51 | 0.00160938875238 54 - 52 | 0.00131093490458 54 - 53 | 0.00114327120949 54 - 54 | 0.00182967878275 54 - 55 | -0.00310780196751 54 - 56 | 0.000656454190879 54 - 57 | 0.000298906680853 54 - 58 | 2.39778024616e-05 54 - 59 | 0.0 54 - 60 | 0.000744630446791 54 - 61 | 0.00190298895924 54 - 62 | 0.00291264089523 54 - 63 | 0.00288337948991 54 - 64 | 0.00229703386877 54 - 65 | 0.00123628865058 54 - 66 | 0.00109338530555 54 - 67 | 0.0010969357319 54 - 68 | 0.0010232379267 54 - 69 | 0.000612268324772 54 - 70 | 0.000131116633699 54 - 71 | 0.0 54 - 72 | 0.000733378762406 54 - 73 | 0.000637095983184 54 - 74 | 0.000156371624314 54 - 75 | -0.000278039975152 54 - 76 | -0.000417152752093 54 - 77 | 0.00146412012998 54 - 78 | 0.00130223325036 54 - 79 | 0.00130156713459 54 - 80 | 0.00131639913881 54 - 81 | 0.000858559296093 54 - 82 | 0.000404017887192 54 - 83 | 2.52259423777e-06 54 - 84 | 0.00118207840804 54 - 85 | 0.000636146903544 54 - 86 | 0.00103164693417 54 - 87 | 0.000758942524178 54 - 88 | 0.000826119729231 54 - 89 | 0.00124668415306 54 - 90 | 0.000982153008946 54 - 91 | 0.000953252603925 54 - 92 | 0.000998605661241 54 - 93 | 0.00108978352022 54 - 94 | 0.00141972179062 54 - 95 | 8.2126045507e-05 55 - 0 | 0.0222488557125 55 - 1 | 0.021253284664 55 - 2 | 0.0176846269943 55 - 3 | 0.00267370840868 55 - 4 | -0.00135874604582 55 - 5 | -0.000790630088618 55 - 6 | -0.00115975427219 55 - 7 | -0.000240758628149 55 - 8 | 0.0 55 - 9 | 0.0 55 - 10 | 0.0 55 - 11 | 0.0 55 - 12 | 0.0161297584957 55 - 13 | 0.022812038697 55 - 14 | 0.0114599489359 55 - 15 | -0.00207581435516 55 - 16 | 0.00500045706079 55 - 17 | -0.00107016892116 55 - 18 | -0.000892914944398 55 - 19 | 5.93505482591e-05 55 - 20 | -2.07310790605e-05 55 - 21 | 0.0 55 - 22 | 0.0 55 - 23 | 0.0 55 - 24 | 0.0187622608484 55 - 25 | 0.0237299833546 55 - 26 | 0.0110249879008 55 - 27 | -0.00199123790933 55 - 28 | 0.00414836188845 55 - 29 | 0.00421675439121 55 - 30 | -0.00147308614275 55 - 31 | -0.000245401019214 55 - 32 | -0.00487201093289 55 - 33 | -0.000732936655203 55 - 34 | 0.0 55 - 35 | 0.0 55 - 36 | 0.025487664028 55 - 37 | 0.0302066424747 55 - 38 | 0.0150425702841 55 - 39 | 0.0174422622769 55 - 40 | 0.00504108889491 55 - 41 | 0.00254420666571 55 - 42 | -0.000225810078898 55 - 43 | -0.00120061316736 55 - 44 | -0.00378104070351 55 - 45 | -0.00380469765374 55 - 46 | 0.0 55 - 47 | 0.0 55 - 48 | 0.0253040481783 55 - 49 | 0.00910497547538 55 - 50 | 0.012600972912 55 - 51 | 0.00748160074787 55 - 52 | 0.00634673852116 55 - 53 | 0.014770402047 55 - 54 | -0.00310780196751 -55 - 55 | 0.199799641011 +55 - 55 | 0.00199799641011 55 - 56 | -0.000250528663347 55 - 57 | -0.00145844699218 55 - 58 | 1.3631107631e-05 55 - 59 | 0.0 55 - 60 | 0.0205370737983 55 - 61 | -0.00386487634173 55 - 62 | -0.0175180739289 55 - 63 | -0.0260101937038 55 - 64 | -0.0202929663998 55 - 65 | 0.00830990458068 55 - 66 | 0.0130934358169 55 - 67 | 0.00109051154256 55 - 68 | -0.00117322628756 55 - 69 | -0.00299380689126 55 - 70 | -0.000574909860233 55 - 71 | 0.0 55 - 72 | 0.0177275343634 55 - 73 | 0.0322016986822 55 - 74 | 0.0539829983723 55 - 75 | 0.061282913844 55 - 76 | 0.0531982663682 55 - 77 | -0.00173387862878 55 - 78 | 0.00358688607228 55 - 79 | 0.00155019634365 55 - 80 | -0.00196277554689 55 - 81 | -6.52773806881e-06 55 - 82 | -0.000524955513131 55 - 83 | -4.86912722922e-06 55 - 84 | 0.00385012599935 55 - 85 | 0.0134964952211 55 - 86 | 0.0125579004817 55 - 87 | 0.0172645482177 55 - 88 | 0.00702022233212 55 - 89 | -0.00640866791546 55 - 90 | 0.00213734773968 55 - 91 | 0.00482530078534 55 - 92 | 0.00116171868728 55 - 93 | -0.000850467479292 55 - 94 | -0.00311272327584 55 - 95 | -0.000243078458657 56 - 0 | 0.000743196781925 56 - 1 | 0.0011473662762 56 - 2 | 0.000926893691946 56 - 3 | 0.000460328203253 56 - 4 | 0.000306489784752 56 - 5 | 0.000128859324727 56 - 6 | 6.03488582007e-05 56 - 7 | 2.16508583258e-05 56 - 8 | 0.0 56 - 9 | 0.0 56 - 10 | 0.0 56 - 11 | 0.0 56 - 12 | 0.000578627256413 56 - 13 | 0.000796782741658 56 - 14 | 0.00115008526045 56 - 15 | 0.000727017592617 56 - 16 | 0.000304551110857 56 - 17 | 0.000277732048766 56 - 18 | 0.000177501886089 56 - 19 | 8.39324347371e-05 56 - 20 | 2.2494140942e-05 56 - 21 | 0.0 56 - 22 | 0.0 56 - 23 | 0.0 56 - 24 | 0.000517571552276 56 - 25 | 0.000798862439156 56 - 26 | 0.00121626591093 56 - 27 | 0.000935233597516 56 - 28 | 0.000494304230148 56 - 29 | 0.000320763519877 56 - 30 | 0.000350335886882 56 - 31 | 0.000209604881269 56 - 32 | 6.7445783596e-05 56 - 33 | 7.96079590145e-06 56 - 34 | 0.0 56 - 35 | 0.0 56 - 36 | 0.000346433047869 56 - 37 | 0.000574704658345 56 - 38 | 0.0012050207018 56 - 39 | 0.000669892673566 56 - 40 | 0.000594276985467 56 - 41 | 0.000439139177924 56 - 42 | 0.000446412967438 56 - 43 | 0.000455283017009 56 - 44 | 0.00024630031276 56 - 45 | 1.85816691674e-05 56 - 46 | 0.0 56 - 47 | 0.0 56 - 48 | 0.000283729047965 56 - 49 | 0.000755465427326 56 - 50 | 0.00100484502244 56 - 51 | 0.00087852530567 56 - 52 | 0.000706253282387 56 - 53 | 0.000480089301746 56 - 54 | 0.000656454190879 56 - 55 | -0.000250528663347 56 - 56 | 0.000479988249767 56 - 57 | 0.000184697781543 56 - 58 | 1.44612178812e-05 56 - 59 | 0.0 56 - 60 | 0.000347054492605 56 - 61 | 0.000950769093508 56 - 62 | 0.00155833810994 56 - 63 | 0.0015554311413 56 - 64 | 0.00120731798436 56 - 65 | 0.000567957383057 56 - 66 | 0.000425144470654 56 - 67 | 0.000662998412529 56 - 68 | 0.000694001116479 56 - 69 | 0.00037364804416 56 - 70 | 6.81061284885e-05 56 - 71 | 0.0 56 - 72 | 0.00036628225244 56 - 73 | 0.000206250192601 56 - 74 | 4.33041267195e-05 56 - 75 | -0.000194616996678 56 - 76 | -0.000248196210536 56 - 77 | 0.000741551804652 56 - 78 | 0.000583227041541 56 - 79 | 0.000677118457738 56 - 80 | 0.000845524117824 56 - 81 | 0.000617641894182 56 - 82 | 0.000239702913147 56 - 83 | 1.49711528522e-06 56 - 84 | 0.000624461100099 56 - 85 | 0.000293537268032 56 - 86 | 0.000530677276973 56 - 87 | 0.00039449145764 56 - 88 | 0.000282593664144 56 - 89 | 0.000584849206474 56 - 90 | 0.000408601200677 56 - 91 | 0.000395141642494 56 - 92 | 0.000618441387253 56 - 93 | 0.000801660480984 56 - 94 | 0.000881124870652 56 - 95 | 5.3057782944e-05 57 - 0 | -4.39992678139e-05 57 - 1 | 0.000102529425147 57 - 2 | 9.57296915295e-05 57 - 3 | 0.000154930915758 57 - 4 | 0.000162141765686 57 - 5 | 5.90153066843e-05 57 - 6 | 3.83435327592e-05 57 - 7 | 1.61931611827e-05 57 - 8 | 0.0 57 - 9 | 0.0 57 - 10 | 0.0 57 - 11 | 0.0 57 - 12 | -3.25891042718e-05 57 - 13 | -2.52284661e-05 57 - 14 | 0.000266294772333 57 - 15 | 0.000296309625168 57 - 16 | 5.62479500469e-05 57 - 17 | 0.000129403592883 57 - 18 | 8.70027487742e-05 57 - 19 | 4.13566034186e-05 57 - 20 | 1.77877963647e-05 57 - 21 | 0.0 57 - 22 | 0.0 57 - 23 | 0.0 57 - 24 | -9.66817171023e-05 57 - 25 | -3.01559583416e-05 57 - 26 | 0.000282315359008 57 - 27 | 0.000370185507542 57 - 28 | 0.000143548257117 57 - 29 | 8.18057665784e-05 57 - 30 | 0.000168397180391 57 - 31 | 0.000104244274448 57 - 32 | 0.000117055477159 57 - 33 | 1.79776270205e-05 57 - 34 | 0.0 57 - 35 | 0.0 57 - 36 | -0.000245753489143 57 - 37 | -0.000195678548286 57 - 38 | 0.000252889593203 57 - 39 | -5.18475257082e-06 57 - 40 | 0.000161933303781 57 - 41 | 0.000126926695588 57 - 42 | 0.000187083701713 57 - 43 | 0.000194219431762 57 - 44 | 0.000159683068307 57 - 45 | 6.71591548253e-05 57 - 46 | 0.0 57 - 47 | 0.0 57 - 48 | -0.000257735072909 57 - 49 | 0.000104160353081 57 - 50 | 0.000170942786605 57 - 51 | 0.000206550713022 57 - 52 | 0.000172108641323 57 - 53 | -2.20278143579e-05 57 - 54 | 0.000298906680853 57 - 55 | -0.00145844699218 57 - 56 | 0.000184697781543 57 - 57 | 0.000110045257113 57 - 58 | 9.5177506474e-06 57 - 59 | 0.0 57 - 60 | -0.00019571448735 57 - 61 | 0.000371439609278 57 - 62 | 0.000823507066159 57 - 63 | 0.000951038145605 57 - 64 | 0.000741425489908 57 - 65 | 9.99192931789e-05 57 - 66 | 9.66437085622e-06 57 - 67 | 0.000245188904554 57 - 68 | 0.000282636731789 57 - 69 | 0.000207880863165 57 - 70 | 4.23832974688e-05 57 - 71 | 0.0 57 - 72 | -0.00011656876654 57 - 73 | -0.000409486681244 57 - 74 | -0.0007631289914 57 - 75 | -0.000987571829748 57 - 76 | -0.000866577248138 57 - 77 | 0.000299489552606 57 - 78 | 0.000182588158672 57 - 79 | 0.000251150994069 57 - 80 | 0.000360043380684 57 - 81 | 0.000253083533779 57 - 82 | 0.000113871785394 57 - 83 | 8.17984764515e-07 57 - 84 | 0.000233030707166 57 - 85 | -7.78773980159e-05 57 - 86 | 5.14418517417e-05 57 - 87 | -0.000111395032687 57 - 88 | -7.32822142575e-05 57 - 89 | 0.000279324138048 57 - 90 | 0.000124782018724 57 - 91 | 0.000110383544327 57 - 92 | 0.000233178703388 57 - 93 | 0.000331774090554 57 - 94 | 0.000407932083797 57 - 95 | 2.59247868768e-05 58 - 0 | 1.67500068122e-07 58 - 1 | 1.54693203685e-05 58 - 2 | 1.24033586313e-05 58 - 3 | 1.67220244601e-05 58 - 4 | 1.57925803469e-05 58 - 5 | 5.01149593197e-06 58 - 6 | 4.0870035457e-06 58 - 7 | 2.44744938937e-06 58 - 8 | 0.0 58 - 9 | 0.0 58 - 10 | 0.0 58 - 11 | 0.0 58 - 12 | -3.38202019192e-07 58 - 13 | 7.82857988645e-06 58 - 14 | 2.5164888014e-05 58 - 15 | 2.5799445536e-05 58 - 16 | 7.78661210308e-06 58 - 17 | 1.37137609581e-05 58 - 18 | 8.70154414347e-06 58 - 19 | 5.46413482885e-06 58 - 20 | 3.07679505237e-06 58 - 21 | 0.0 58 - 22 | 0.0 58 - 23 | 0.0 58 - 24 | -7.7627228912e-06 58 - 25 | 5.81518808194e-06 58 - 26 | 2.02323037481e-05 58 - 27 | 2.83156294026e-05 58 - 28 | 1.66332817784e-05 58 - 29 | 1.12694249311e-05 58 - 30 | 1.70697036234e-05 58 - 31 | 1.25856917693e-05 58 - 32 | 1.37036932826e-05 58 - 33 | 2.27999790486e-06 58 - 34 | 0.0 58 - 35 | 0.0 58 - 36 | -1.49082538347e-05 58 - 37 | -2.25014604255e-06 58 - 38 | 2.98677891941e-05 58 - 39 | 7.36869955059e-06 58 - 40 | 1.62209035337e-05 58 - 41 | 1.36436765312e-05 58 - 42 | 1.84944527263e-05 58 - 43 | 1.63306433893e-05 58 - 44 | 1.42266871793e-05 58 - 45 | 5.2529382541e-06 58 - 46 | 0.0 58 - 47 | 0.0 58 - 48 | -1.83716828416e-05 58 - 49 | 9.99278971275e-06 58 - 50 | 1.56344718706e-05 58 - 51 | 1.71197760779e-05 58 - 52 | 1.36659942062e-05 58 - 53 | 3.73181943848e-06 58 - 54 | 2.39778024616e-05 58 - 55 | 1.3631107631e-05 58 - 56 | 1.44612178812e-05 58 - 57 | 9.5177506474e-06 58 - 58 | 1.90429016123e-06 58 - 59 | 0.0 58 - 60 | -1.37348894853e-05 58 - 61 | 2.21017299083e-05 58 - 62 | 5.59238818778e-05 58 - 63 | 6.1731782385e-05 58 - 64 | 4.97608943624e-05 58 - 65 | 1.11304139402e-05 58 - 66 | 9.72220485957e-06 58 - 67 | 2.4189054511e-05 58 - 68 | 2.18382963451e-05 58 - 69 | 1.76498412291e-05 58 - 70 | 4.16197074335e-06 58 - 71 | 0.0 58 - 72 | -5.62793736036e-06 58 - 73 | -2.29681914419e-05 58 - 74 | -3.5956183329e-05 58 - 75 | -5.27332174877e-05 58 - 76 | -4.2724929941e-05 58 - 77 | 2.26977695915e-05 58 - 78 | 1.6675102759e-05 58 - 79 | 2.42296574181e-05 58 - 80 | 3.08102175483e-05 58 - 81 | 2.28131208475e-05 58 - 82 | 1.07080597476e-05 58 - 83 | 9.54422611231e-08 58 - 84 | 1.32675750164e-05 58 - 85 | 2.47010216988e-07 58 - 86 | 1.32535453625e-05 58 - 87 | -2.8586964508e-06 58 - 88 | -2.9797857025e-06 58 - 89 | 1.91772362702e-05 58 - 90 | 1.26930589581e-05 58 - 91 | 1.54025557393e-05 58 - 92 | 2.66166500743e-05 58 - 93 | 3.10531257546e-05 58 - 94 | 3.62496441724e-05 58 - 95 | 2.24079843343e-06 59 - 0 | 0.0 59 - 1 | 0.0 59 - 2 | 0.0 59 - 3 | 0.0 59 - 4 | 0.0 59 - 5 | 0.0 59 - 6 | 0.0 59 - 7 | 0.0 59 - 8 | 0.0 59 - 9 | 0.0 59 - 10 | 0.0 59 - 11 | 0.0 59 - 12 | 0.0 59 - 13 | 0.0 59 - 14 | 0.0 59 - 15 | 0.0 59 - 16 | 0.0 59 - 17 | 0.0 59 - 18 | 0.0 59 - 19 | 0.0 59 - 20 | 0.0 59 - 21 | 0.0 59 - 22 | 0.0 59 - 23 | 0.0 59 - 24 | 0.0 59 - 25 | 0.0 59 - 26 | 0.0 59 - 27 | 0.0 59 - 28 | 0.0 59 - 29 | 0.0 59 - 30 | 0.0 59 - 31 | 0.0 59 - 32 | 0.0 59 - 33 | 0.0 59 - 34 | 0.0 59 - 35 | 0.0 59 - 36 | 0.0 59 - 37 | 0.0 59 - 38 | 0.0 59 - 39 | 0.0 59 - 40 | 0.0 59 - 41 | 0.0 59 - 42 | 0.0 59 - 43 | 0.0 59 - 44 | 0.0 59 - 45 | 0.0 59 - 46 | 0.0 59 - 47 | 0.0 59 - 48 | 0.0 59 - 49 | 0.0 59 - 50 | 0.0 59 - 51 | 0.0 59 - 52 | 0.0 59 - 53 | 0.0 59 - 54 | 0.0 59 - 55 | 0.0 59 - 56 | 0.0 59 - 57 | 0.0 59 - 58 | 0.0 59 - 59 | 0.0 59 - 60 | 0.0 59 - 61 | 0.0 59 - 62 | 0.0 59 - 63 | 0.0 59 - 64 | 0.0 59 - 65 | 0.0 59 - 66 | 0.0 59 - 67 | 0.0 59 - 68 | 0.0 59 - 69 | 0.0 59 - 70 | 0.0 59 - 71 | 0.0 59 - 72 | 0.0 59 - 73 | 0.0 59 - 74 | 0.0 59 - 75 | 0.0 59 - 76 | 0.0 59 - 77 | 0.0 59 - 78 | 0.0 59 - 79 | 0.0 59 - 80 | 0.0 59 - 81 | 0.0 59 - 82 | 0.0 59 - 83 | 0.0 59 - 84 | 0.0 59 - 85 | 0.0 59 - 86 | 0.0 59 - 87 | 0.0 59 - 88 | 0.0 59 - 89 | 0.0 59 - 90 | 0.0 59 - 91 | 0.0 59 - 92 | 0.0 59 - 93 | 0.0 59 - 94 | 0.0 59 - 95 | 0.0 60 - 0 | 0.00757011500512 60 - 1 | 0.00864535454908 60 - 2 | 0.006444257335 60 - 3 | 0.00136616902433 60 - 4 | -6.39926182246e-05 60 - 5 | 5.7182887464e-05 60 - 6 | -0.000113259837316 60 - 7 | -4.18760117072e-05 60 - 8 | 0.0 60 - 9 | 0.0 60 - 10 | 0.0 60 - 11 | 0.0 60 - 12 | 0.00586223927756 60 - 13 | 0.00776009528636 60 - 14 | 0.00566537069901 60 - 15 | 0.00138429345514 60 - 16 | 0.00173019344471 60 - 17 | 0.00020342009987 60 - 18 | -4.97111545211e-05 60 - 19 | 5.08897636169e-05 60 - 20 | -4.22519148636e-05 60 - 21 | 0.0 60 - 22 | 0.0 60 - 23 | 0.0 60 - 24 | 0.00645039998304 60 - 25 | 0.00809675711598 60 - 26 | 0.00623341094336 60 - 27 | 0.00218998996792 60 - 28 | 0.00199338274204 60 - 29 | 0.00151137338115 60 - 30 | 0.000110915336468 60 - 31 | 7.51455392689e-05 60 - 32 | -0.00101344043603 60 - 33 | -0.000146936873385 60 - 34 | 0.0 60 - 35 | 0.0 60 - 36 | 0.00742862269622 60 - 37 | 0.00850406345784 60 - 38 | 0.00636127687801 60 - 39 | 0.00615633065014 60 - 40 | 0.00257247154676 60 - 41 | 0.00190094280623 60 - 42 | 0.000831182763205 60 - 43 | 0.000340189222828 60 - 44 | -0.00053404796892 60 - 45 | -0.000727954224289 60 - 46 | 0.0 60 - 47 | 0.0 60 - 48 | 0.00754080248541 60 - 49 | 0.00522793384355 60 - 50 | 0.00638091036453 60 - 51 | 0.00459756415608 60 - 52 | 0.00354457880245 60 - 53 | 0.00451015215004 60 - 54 | 0.000744630446791 60 - 55 | 0.0205370737983 60 - 56 | 0.000347054492605 60 - 57 | -0.00019571448735 60 - 58 | -1.37348894853e-05 60 - 59 | 0.0 60 - 60 | 0.00758491032547 60 - 61 | 0.00243494486115 60 - 62 | 0.000778656205127 60 - 63 | -0.00129673679933 60 - 64 | -0.00113863311786 60 - 65 | 0.00353230979529 60 - 66 | 0.00410647127162 60 - 67 | 0.00129613826308 60 - 68 | 0.000478642791112 60 - 69 | -0.00036760196437 60 - 70 | -9.02275899044e-05 60 - 71 | 0.0 60 - 72 | 0.00585271211769 60 - 73 | 0.00862822073673 60 - 74 | 0.0126324790129 60 - 75 | 0.0145293659935 60 - 76 | 0.0122427127701 60 - 77 | 0.00198192449019 60 - 78 | 0.00259520572198 60 - 79 | 0.00182065570363 60 - 80 | 0.000691498785305 60 - 81 | 0.000617904188621 60 - 82 | 0.000114212254076 60 - 83 | -8.25699798032e-07 60 - 84 | 0.00170643293054 60 - 85 | 0.00416985982068 60 - 86 | 0.00387558657611 60 - 87 | 0.00543629563815 60 - 88 | 0.00364753098913 60 - 89 | 0.00078870401906 60 - 90 | 0.00196699524177 60 - 91 | 0.00208210748403 60 - 92 | 0.00113121488664 60 - 93 | 0.00055118518981 60 - 94 | 0.000339073273829 60 - 95 | -3.82050956291e-06 61 - 0 | 0.00279485588595 61 - 1 | 0.00491304299721 61 - 2 | 0.00276724267823 61 - 3 | 0.00128001458474 61 - 4 | 0.000786602340772 61 - 5 | 0.000338105588959 61 - 6 | 0.000151065724463 61 - 7 | 5.19360115654e-05 61 - 8 | 0.0 61 - 9 | 0.0 61 - 10 | 0.0 61 - 11 | 0.0 61 - 12 | 0.00241778445179 61 - 13 | 0.00387687637469 61 - 14 | 0.00380732772459 61 - 15 | 0.00245555603155 61 - 16 | 0.000813041627697 61 - 17 | 0.000715207796175 61 - 18 | 0.000430338589326 61 - 19 | 0.000165219514515 61 - 20 | 4.63719738142e-05 61 - 21 | 0.0 61 - 22 | 0.0 61 - 23 | 0.0 61 - 24 | 0.00242598737111 61 - 25 | 0.00438794258518 61 - 26 | 0.00497165180221 61 - 27 | 0.00393677201943 61 - 28 | 0.00165395031853 61 - 29 | 0.000842937753824 61 - 30 | 0.000949906258714 61 - 31 | 0.000491147475248 61 - 32 | 0.0001351161015 61 - 33 | 4.57132816249e-06 61 - 34 | 0.0 61 - 35 | 0.0 61 - 36 | 0.00171047374995 61 - 37 | 0.00295168249553 61 - 38 | 0.00357647906773 61 - 39 | 0.00225477115755 61 - 40 | 0.00215314310051 61 - 41 | 0.00139740457346 61 - 42 | 0.0013900288275 61 - 43 | 0.00112573316698 61 - 44 | 0.000557127447274 61 - 45 | 6.81335278145e-05 61 - 46 | 0.0 61 - 47 | 0.0 61 - 48 | 0.00189466745593 61 - 49 | 0.00488188643854 61 - 50 | 0.00486913991303 61 - 51 | 0.00420289410185 61 - 52 | 0.00333795977306 61 - 53 | 0.00146177566846 61 - 54 | 0.00190298895924 61 - 55 | -0.00386487634173 61 - 56 | 0.000950769093508 61 - 57 | 0.000371439609278 61 - 58 | 2.21017299083e-05 61 - 59 | 0.0 61 - 60 | 0.00243494486115 61 - 61 | 0.00671463548574 61 - 62 | 0.00942462583398 61 - 63 | 0.00950453114683 61 - 64 | 0.0069748757305 61 - 65 | 0.0021701341529 61 - 66 | 0.00168859062455 61 - 67 | 0.00189228132047 61 - 68 | 0.00161058908722 61 - 69 | 0.000807215122942 61 - 70 | 0.000140775088983 61 - 71 | 0.0 61 - 72 | 0.00192753195438 61 - 73 | 0.00142270009935 61 - 74 | -0.00197442900414 61 - 75 | -0.00363767184795 61 - 76 | -0.00297659865149 61 - 77 | 0.0042091334379 61 - 78 | 0.00243143747271 61 - 79 | 0.00241905463871 61 - 80 | 0.0020942410631 61 - 81 | 0.00123861257766 61 - 82 | 0.000464023823156 61 - 83 | 3.42369889374e-06 61 - 84 | 0.00242743396348 61 - 85 | 0.00212696550922 61 - 86 | 0.00242723675889 61 - 87 | 0.00157376561136 61 - 88 | 0.000688220940308 61 - 89 | 0.00328698040997 61 - 90 | 0.00212836512837 61 - 91 | 0.00178180525499 61 - 92 | 0.00183208194213 61 - 93 | 0.00168878454951 61 - 94 | 0.00157388008063 61 - 95 | 9.36902058897e-05 62 - 0 | 0.000574069419969 62 - 1 | 0.00334721030457 62 - 2 | 0.00163662686412 62 - 3 | 0.00149751768415 62 - 4 | 0.00161636009138 62 - 5 | 0.000692538090623 62 - 6 | 0.00040703243719 62 - 7 | 0.000127838845475 62 - 8 | 0.0 62 - 9 | 0.0 62 - 10 | 0.0 62 - 11 | 0.0 62 - 12 | 0.000907709559216 62 - 13 | 0.00116495942012 62 - 14 | 0.00441958185205 62 - 15 | 0.00441542057133 62 - 16 | 0.0002888252758 62 - 17 | 0.00125674533621 62 - 18 | 0.000918187833653 62 - 19 | 0.000346606361882 62 - 20 | 0.00015907842925 62 - 21 | 0.0 62 - 22 | 0.0 62 - 23 | 0.0 62 - 24 | 0.000382946569996 62 - 25 | 0.00231753952056 62 - 26 | 0.00696648601408 62 - 27 | 0.00739786265274 62 - 28 | 0.00197057251432 62 - 29 | 0.000605292928019 62 - 30 | 0.00178253926521 62 - 31 | 0.0010607568035 62 - 32 | 0.00121258537004 62 - 33 | 0.000147372158534 62 - 34 | 0.0 62 - 35 | 0.0 62 - 36 | -0.00143444864252 62 - 37 | -0.00183554549046 62 - 38 | 0.00221286665754 62 - 39 | 9.85978464838e-05 62 - 40 | 0.00274786275876 62 - 41 | 0.00132790129604 62 - 42 | 0.00200509101455 62 - 43 | 0.00202249837842 62 - 44 | 0.00151013311077 62 - 45 | 0.00067380187597 62 - 46 | 0.0 62 - 47 | 0.0 62 - 48 | -0.000743699243445 62 - 49 | 0.00433450777717 62 - 50 | 0.00616481642949 62 - 51 | 0.00605167484563 62 - 52 | 0.0051962732805 62 - 53 | -0.000951131530717 62 - 54 | 0.00291264089523 62 - 55 | -0.0175180739289 62 - 56 | 0.00155833810994 62 - 57 | 0.000823507066159 62 - 58 | 5.59238818778e-05 62 - 59 | 0.0 62 - 60 | 0.000778656205127 62 - 61 | 0.00942462583398 62 - 62 | 0.0225906564745 62 - 63 | 0.0239785611906 62 - 64 | 0.017360418093 62 - 65 | 0.00173172162843 62 - 66 | 0.000241166054685 62 - 67 | 0.00285704891438 62 - 68 | 0.00275859961759 62 - 69 | 0.00180880775515 62 - 70 | 0.000296144465212 62 - 71 | 0.0 62 - 72 | 0.000391593840343 62 - 73 | -0.00722668566219 62 - 74 | -0.0165015307943 62 - 75 | -0.0209296303636 62 - 76 | -0.0178546503961 62 - 77 | 0.0078638009214 62 - 78 | 0.00304977707762 62 - 79 | 0.0030987505493 62 - 80 | 0.00336454653888 62 - 81 | 0.00204536547517 62 - 82 | 0.000883100820192 62 - 83 | 6.44181149194e-06 62 - 84 | 0.00379353324342 62 - 85 | 0.000561683374476 62 - 86 | 0.00150451454536 62 - 87 | -0.000874099225694 62 - 88 | -0.00196270734373 62 - 89 | 0.00687541587309 62 - 90 | 0.00288001110313 62 - 91 | 0.00163931811828 62 - 92 | 0.00244044478898 62 - 93 | 0.00267353801516 62 - 94 | 0.00322362212748 62 - 95 | 0.000214110947224 63 - 0 | -0.00186754485194 63 - 1 | 0.000647558077231 63 - 2 | -0.000248290501065 63 - 3 | 0.00114388535449 63 - 4 | 0.00173938442693 63 - 5 | 0.000711002559225 63 - 6 | 0.000466815651379 63 - 7 | 0.000146396246169 63 - 8 | 0.0 63 - 9 | 0.0 63 - 10 | 0.0 63 - 11 | 0.0 63 - 12 | -0.000948990255407 63 - 13 | -0.00152441868254 63 - 14 | 0.00308019427296 63 - 15 | 0.00449648515342 63 - 16 | -0.000305437872496 63 - 17 | 0.00124497643652 63 - 18 | 0.000988218387516 63 - 19 | 0.000349766233691 63 - 20 | 0.000182299400462 63 - 21 | 0.0 63 - 22 | 0.0 63 - 23 | 0.0 63 - 24 | -0.00172310430856 63 - 25 | -0.000149151044963 63 - 26 | 0.00595646323031 63 - 27 | 0.00774330541944 63 - 28 | 0.00146699451764 63 - 29 | 0.000114836321969 63 - 30 | 0.00184868349374 63 - 31 | 0.00110468130646 63 - 32 | 0.00164505783309 63 - 33 | 0.000208997719726 63 - 34 | 0.0 63 - 35 | 0.0 63 - 36 | -0.00402285747962 63 - 37 | -0.00526003540063 63 - 38 | -0.000127221370495 63 - 39 | -0.00195466305944 63 - 40 | 0.0021917539027 63 - 41 | 0.000715434668755 63 - 42 | 0.00186010075837 63 - 43 | 0.00205336391392 63 - 44 | 0.00180176308599 63 - 45 | 0.000986185400937 63 - 46 | 0.0 63 - 47 | 0.0 63 - 48 | -0.00307761947079 63 - 49 | 0.00287726075887 63 - 50 | 0.00411149428239 63 - 51 | 0.00567158584842 63 - 52 | 0.00493921249139 63 - 53 | -0.00271434231766 63 - 54 | 0.00288337948991 63 - 55 | -0.0260101937038 63 - 56 | 0.0015554311413 63 - 57 | 0.000951038145605 63 - 58 | 6.1731782385e-05 63 - 59 | 0.0 63 - 60 | -0.00129673679933 63 - 61 | 0.00950453114683 63 - 62 | 0.0239785611906 63 - 63 | 0.0284601965592 63 - 64 | 0.0203701005528 63 - 65 | 0.000701815648515 63 - 66 | -0.00106054395663 63 - 67 | 0.00266320374512 63 - 68 | 0.0028153706578 63 - 69 | 0.00206579621199 63 - 70 | 0.000347090835974 63 - 71 | 0.0 63 - 72 | -0.00132786665215 63 - 73 | -0.0114907839967 63 - 74 | -0.0239259887123 63 - 75 | -0.0285518121129 63 - 76 | -0.024536381833 63 - 77 | 0.00821874699578 63 - 78 | 0.00251291612773 63 - 79 | 0.00274148506171 63 - 80 | 0.00338583402701 63 - 81 | 0.00199336999344 63 - 82 | 0.000942300837206 63 - 83 | 6.83388880725e-06 63 - 84 | 0.00363734106339 63 - 85 | -0.000929284438909 63 - 86 | 2.35087558817e-05 63 - 87 | -0.0028470409574 63 - 88 | -0.00365957388022 63 - 89 | 0.00737714858241 63 - 90 | 0.0024726917542 63 - 91 | 0.000998396911584 63 - 92 | 0.00212139802718 63 - 93 | 0.00259887921018 63 - 94 | 0.0034887232502 63 - 95 | 0.000240328677094 64 - 0 | -0.0015099728354 64 - 1 | 0.000368887789053 64 - 2 | -0.000222544588559 64 - 3 | 0.000875378910179 64 - 4 | 0.00133635502195 64 - 5 | 0.000548917207044 64 - 6 | 0.000361205727599 64 - 7 | 0.000114892405 64 - 8 | 0.0 64 - 9 | 0.0 64 - 10 | 0.0 64 - 11 | 0.0 64 - 12 | -0.000781369902774 64 - 13 | -0.00125313628052 64 - 14 | 0.00225721712128 64 - 15 | 0.00338717098102 64 - 16 | -0.00021352928326 64 - 17 | 0.000971030730058 64 - 18 | 0.00075810328622 64 - 19 | 0.000269643786557 64 - 20 | 0.000139081471277 64 - 21 | 0.0 64 - 22 | 0.0 64 - 23 | 0.0 64 - 24 | -0.00140575675297 64 - 25 | -0.000247025029155 64 - 26 | 0.00431188120742 64 - 27 | 0.00574474616179 64 - 28 | 0.00111672963381 64 - 29 | 0.000110781982703 64 - 30 | 0.00141399520879 64 - 31 | 0.000842499704481 64 - 32 | 0.00125938642516 64 - 33 | 0.00016022612122 64 - 34 | 0.0 64 - 35 | 0.0 64 - 36 | -0.00315361530781 64 - 37 | -0.00403620006663 64 - 38 | -7.80677417435e-05 64 - 39 | -0.00149541350941 64 - 40 | 0.00165768326077 64 - 41 | 0.000583643428323 64 - 42 | 0.00144608042395 64 - 43 | 0.00157414453918 64 - 44 | 0.00138781081825 64 - 45 | 0.000755706737247 64 - 46 | 0.0 64 - 47 | 0.0 64 - 48 | -0.00248184674885 64 - 49 | 0.00203495180918 64 - 50 | 0.00286548202006 64 - 51 | 0.00393783046143 64 - 52 | 0.00377269551038 64 - 53 | -0.00188109231459 64 - 54 | 0.00229703386877 64 - 55 | -0.0202929663998 64 - 56 | 0.00120731798436 64 - 57 | 0.000741425489908 64 - 58 | 4.97608943624e-05 64 - 59 | 0.0 64 - 60 | -0.00113863311786 64 - 61 | 0.0069748757305 64 - 62 | 0.017360418093 64 - 63 | 0.0203701005528 64 - 64 | 0.0155317800616 64 - 65 | 0.000759194976302 64 - 66 | -0.000721591872736 64 - 67 | 0.00204799427309 64 - 68 | 0.00216527673137 64 - 69 | 0.00159734363391 64 - 70 | 0.000271624182904 64 - 71 | 0.0 64 - 72 | -0.00109956828712 64 - 73 | -0.00859158609086 64 - 74 | -0.0177874463596 64 - 75 | -0.0214458468271 64 - 76 | -0.0180200219001 64 - 77 | 0.00612060031145 64 - 78 | 0.00190603655245 64 - 79 | 0.00212327790683 64 - 80 | 0.00262107074274 64 - 81 | 0.00155201117628 64 - 82 | 0.000733633534603 64 - 83 | 5.26983264225e-06 64 - 84 | 0.0026609257339 64 - 85 | -0.000780506617123 64 - 86 | -9.3812511713e-05 64 - 87 | -0.0022309825147 64 - 88 | -0.00267554987546 64 - 89 | 0.00541208330441 64 - 90 | 0.00180793832866 64 - 91 | 0.000763033649515 64 - 92 | 0.00161647897628 64 - 93 | 0.00200933380962 64 - 94 | 0.00269395083441 64 - 95 | 0.000184679655452 65 - 0 | 0.00424116677819 65 - 1 | 0.00514142752885 65 - 2 | 0.00364362981625 65 - 3 | 0.00112257351049 65 - 4 | 0.000291068648789 65 - 5 | 0.000161408812184 65 - 6 | 2.06965286956e-05 65 - 7 | 9.66668904312e-07 65 - 8 | 0.0 65 - 9 | 0.0 65 - 10 | 0.0 65 - 11 | 0.0 65 - 12 | 0.00335553192477 65 - 13 | 0.00444434119722 65 - 14 | 0.00346360539975 65 - 15 | 0.00129225538067 65 - 16 | 0.00114429563474 65 - 17 | 0.000415420310237 65 - 18 | 0.000143738665592 65 - 19 | 0.000106983093251 65 - 20 | 8.38247095585e-06 65 - 21 | 0.0 65 - 22 | 0.0 65 - 23 | 0.0 65 - 24 | 0.00364381801342 65 - 25 | 0.00456765444483 65 - 26 | 0.00374034717862 65 - 27 | 0.00176254355628 65 - 28 | 0.00144750580265 65 - 29 | 0.00106522034274 65 - 30 | 0.000442134138904 65 - 31 | 0.000269310049077 65 - 32 | -0.000358503420315 65 - 33 | -6.1154089559e-05 65 - 34 | 0.0 65 - 35 | 0.0 65 - 36 | 0.00389469924003 65 - 37 | 0.00469693180401 65 - 38 | 0.00407962438274 65 - 39 | 0.00345515806149 65 - 40 | 0.00181107874863 65 - 41 | 0.00146954160256 65 - 42 | 0.000959722676519 65 - 43 | 0.00061166432422 65 - 44 | 2.32140365302e-05 65 - 45 | -0.000339076742612 65 - 46 | 0.0 65 - 47 | 0.0 65 - 48 | 0.00365911006603 65 - 49 | 0.00336454776891 65 - 50 | 0.00391058519822 65 - 51 | 0.00293627555658 65 - 52 | 0.00238000212112 65 - 53 | 0.00292395941898 65 - 54 | 0.00123628865058 65 - 55 | 0.00830990458068 65 - 56 | 0.000567957383057 65 - 57 | 9.99192931789e-05 65 - 58 | 1.11304139402e-05 65 - 59 | 0.0 65 - 60 | 0.00353230979529 65 - 61 | 0.0021701341529 65 - 62 | 0.00173172162843 65 - 63 | 0.000701815648515 65 - 64 | 0.000759194976302 65 - 65 | 0.0030133003638 65 - 66 | 0.00271521737607 65 - 67 | 0.00129670598236 65 - 68 | 0.000890194275664 65 - 69 | 0.000225870019308 65 - 70 | 4.2936506768e-05 65 - 71 | 0.0 65 - 72 | 0.00295477808505 65 - 73 | 0.0046301825027 65 - 74 | 0.00626962244157 65 - 75 | 0.00685582744072 65 - 76 | 0.00591327521895 65 - 77 | 0.00190315306447 65 - 78 | 0.00209472262991 65 - 79 | 0.00173235466295 65 - 80 | 0.00113088349424 65 - 81 | 0.000845927837808 65 - 82 | 0.000312078990912 65 - 83 | 1.5891411152e-06 65 - 84 | 0.00143625808776 65 - 85 | 0.00248584915971 65 - 86 | 0.00253140472204 65 - 87 | 0.00299514554491 65 - 88 | 0.0022339682502 65 - 89 | 0.00105292097719 65 - 90 | 0.00153831612333 65 - 91 | 0.00167001136749 65 - 92 | 0.00122301901006 65 - 93 | 0.000955794453202 65 - 94 | 0.000939222709975 65 - 95 | 4.26977848969e-05 66 - 0 | 0.00470429596863 66 - 1 | 0.00546268144522 66 - 2 | 0.00389739988712 66 - 3 | 0.0010579681949 66 - 4 | 0.00010201213672 66 - 5 | 4.51845208554e-05 66 - 6 | -5.92069490779e-05 66 - 7 | -1.10230634106e-05 66 - 8 | 0.0 66 - 9 | 0.0 66 - 10 | 0.0 66 - 11 | 0.0 66 - 12 | 0.00367801008527 66 - 13 | 0.00496931783339 66 - 14 | 0.00339469880782 66 - 15 | 0.000929632546129 66 - 16 | 0.00122802165952 66 - 17 | 0.000254464817321 66 - 18 | 3.23893263978e-06 66 - 19 | 6.59527573768e-05 66 - 20 | -7.98247970154e-06 66 - 21 | 0.0 66 - 22 | 0.0 66 - 23 | 0.0 66 - 24 | 0.00406659717659 66 - 25 | 0.00505836523059 66 - 26 | 0.00359429939115 66 - 27 | 0.00131521937917 66 - 28 | 0.00140498086904 66 - 29 | 0.00114317294939 66 - 30 | 0.000205718779263 66 - 31 | 0.000112879116065 66 - 32 | -0.000626787890604 66 - 33 | -9.36554917869e-05 66 - 34 | 0.0 66 - 35 | 0.0 66 - 36 | 0.00467276702918 66 - 37 | 0.00560011760393 66 - 38 | 0.00409346950303 66 - 39 | 0.00386812653514 66 - 40 | 0.00175830469034 66 - 41 | 0.00144587137061 66 - 42 | 0.000836136991518 66 - 43 | 0.000336405190723 66 - 44 | -0.000220404106996 66 - 45 | -0.000487183123217 66 - 46 | 0.0 66 - 47 | 0.0 66 - 48 | 0.00444551637936 66 - 49 | 0.00344823813218 66 - 50 | 0.00388795552371 66 - 51 | 0.00282690956739 66 - 52 | 0.00221834961006 66 - 53 | 0.003286800244 66 - 54 | 0.00109338530555 66 - 55 | 0.0130934358169 66 - 56 | 0.000425144470654 66 - 57 | 9.66437085622e-06 66 - 58 | 9.72220485957e-06 66 - 59 | 0.0 66 - 60 | 0.00410647127162 66 - 61 | 0.00168859062455 66 - 62 | 0.000241166054685 66 - 63 | -0.00106054395663 66 - 64 | -0.000721591872736 66 - 65 | 0.00271521737607 66 - 66 | 0.00376217247876 66 - 67 | 0.0012695595666 66 - 68 | 0.000557638879161 66 - 69 | -1.46405692852e-05 66 - 70 | 1.75199006652e-05 66 - 71 | 0.0 66 - 72 | 0.00340606317709 66 - 73 | 0.0059476243286 66 - 74 | 0.00842220052558 66 - 75 | 0.00941801536428 66 - 76 | 0.00812692322047 66 - 77 | 0.00149431531575 66 - 78 | 0.00222818754621 66 - 79 | 0.00171378647009 66 - 80 | 0.000824186668443 66 - 81 | 0.000657317132246 66 - 82 | 0.000278327406863 66 - 83 | 1.21370940083e-06 66 - 84 | 0.00122404087308 66 - 85 | 0.00283787438472 66 - 86 | 0.00266929217476 66 - 87 | 0.0034676322207 66 - 88 | 0.00242138043398 66 - 89 | 0.000556312290323 66 - 90 | 0.0015547313461 66 - 91 | 0.00186680550049 66 - 92 | 0.0010546637585 66 - 93 | 0.000605477429009 66 - 94 | 0.00066383662683 66 - 95 | 2.14313544983e-05 67 - 0 | 0.00197113830862 67 - 1 | 0.00274657032443 67 - 2 | 0.00207876795473 67 - 3 | 0.000877961358449 67 - 4 | 0.000570420418135 67 - 5 | 0.000209680830718 67 - 6 | 7.99040437523e-05 67 - 7 | 4.58583651109e-05 67 - 8 | 0.0 67 - 9 | 0.0 67 - 10 | 0.0 67 - 11 | 0.0 67 - 12 | 0.00153309269583 67 - 13 | 0.00197112086859 67 - 14 | 0.0024543081437 67 - 15 | 0.00134748613721 67 - 16 | 0.000612757465804 67 - 17 | 0.000505384846876 67 - 18 | 0.000297532888634 67 - 19 | 0.000134282100757 67 - 20 | 4.57717953188e-05 67 - 21 | 0.0 67 - 22 | 0.0 67 - 23 | 0.0 67 - 24 | 0.00143905724683 67 - 25 | 0.00203679209119 67 - 26 | 0.00255789667475 67 - 27 | 0.00178865142473 67 - 28 | 0.00103028574033 67 - 29 | 0.000677767813543 67 - 30 | 0.000634021963648 67 - 31 | 0.000358219726882 67 - 32 | 8.12793120031e-05 67 - 33 | 6.38775250146e-06 67 - 34 | 0.0 67 - 35 | 0.0 67 - 36 | 0.00123721843216 67 - 37 | 0.00169233142763 67 - 38 | 0.00283514742976 67 - 39 | 0.00164665376339 67 - 40 | 0.00122023337888 67 - 41 | 0.000955659792815 67 - 42 | 0.000816825461955 67 - 43 | 0.000755477631188 67 - 44 | 0.000337826494978 67 - 45 | -1.25556573852e-06 67 - 46 | 0.0 67 - 47 | 0.0 67 - 48 | 0.0011928039447 67 - 49 | 0.00180610553231 67 - 50 | 0.00231426835419 67 - 51 | 0.00186618117413 67 - 52 | 0.00149727372786 67 - 53 | 0.00110712436973 67 - 54 | 0.0010969357319 67 - 55 | 0.00109051154256 67 - 56 | 0.000662998412529 67 - 57 | 0.000245188904554 67 - 58 | 2.4189054511e-05 67 - 59 | 0.0 67 - 60 | 0.00129613826308 67 - 61 | 0.00189228132047 67 - 62 | 0.00285704891438 67 - 63 | 0.00266320374512 67 - 64 | 0.00204799427309 67 - 65 | 0.00129670598236 67 - 66 | 0.0012695595666 67 - 67 | 0.00167424914489 67 - 68 | 0.00111258732224 67 - 69 | 0.000526977841578 67 - 70 | 8.56266451794e-05 67 - 71 | 0.0 67 - 72 | 0.00117016889074 67 - 73 | 0.00102842441167 67 - 74 | 0.00106093007554 67 - 75 | 0.000804171966556 67 - 76 | 0.000554402133968 67 - 77 | 0.00149929132801 67 - 78 | 0.00127137477031 67 - 79 | 0.00142069712792 67 - 80 | 0.00138184567023 67 - 81 | 0.000956728250895 67 - 82 | 0.000348671820544 67 - 83 | 2.18206169782e-06 67 - 84 | 0.00121371050085 67 - 85 | 0.000941895203773 67 - 86 | 0.00123733197854 67 - 87 | 0.00110451030622 67 - 88 | 0.000757172756667 67 - 89 | 0.00113510191546 67 - 90 | 0.000947360525271 67 - 91 | 0.000893521478249 67 - 92 | 0.00108822194291 67 - 93 | 0.00118786984669 67 - 94 | 0.00125043671444 67 - 95 | 7.7160007243e-05 68 - 0 | 0.00102743617456 68 - 1 | 0.00167395868741 68 - 2 | 0.00131082601607 68 - 3 | 0.000725116090676 68 - 4 | 0.000500800928101 68 - 5 | 0.000226336595278 68 - 6 | 0.000116319765078 68 - 7 | 3.29882402491e-05 68 - 8 | 0.0 68 - 9 | 0.0 68 - 10 | 0.0 68 - 11 | 0.0 68 - 12 | 0.00085399823275 68 - 13 | 0.00115729945144 68 - 14 | 0.0017129684139 68 - 15 | 0.00117281906948 68 - 16 | 0.000444335656066 68 - 17 | 0.000458106186948 68 - 18 | 0.000301947094339 68 - 19 | 0.000137187147623 68 - 20 | 3.9275845623e-05 68 - 21 | 0.0 68 - 22 | 0.0 68 - 23 | 0.0 68 - 24 | 0.000770523457419 68 - 25 | 0.00120708955503 68 - 26 | 0.00184444616842 68 - 27 | 0.00152166699876 68 - 28 | 0.000772368487625 68 - 29 | 0.000464870373812 68 - 30 | 0.000594871676923 68 - 31 | 0.000363871502896 68 - 32 | 0.000163848936147 68 - 33 | 1.53843324703e-05 68 - 34 | 0.0 68 - 35 | 0.0 68 - 36 | 0.000427291126097 68 - 37 | 0.000764968450583 68 - 38 | 0.00177961468444 68 - 39 | 0.000921064755015 68 - 40 | 0.000926374484984 68 - 41 | 0.000688034098448 68 - 42 | 0.000717235313197 68 - 43 | 0.000741953844916 68 - 44 | 0.000412877134131 68 - 45 | 4.72520131431e-05 68 - 46 | 0.0 68 - 47 | 0.0 68 - 48 | 0.000336955683598 68 - 49 | 0.00122590124378 68 - 50 | 0.00157657452373 68 - 51 | 0.00138403741479 68 - 52 | 0.00110273648045 68 - 53 | 0.000636333716814 68 - 54 | 0.0010232379267 68 - 55 | -0.00117322628756 68 - 56 | 0.000694001116479 68 - 57 | 0.000282636731789 68 - 58 | 2.18382963451e-05 68 - 59 | 0.0 68 - 60 | 0.000478642791112 68 - 61 | 0.00161058908722 68 - 62 | 0.00275859961759 68 - 63 | 0.0028153706578 68 - 64 | 0.00216527673137 68 - 65 | 0.000890194275664 68 - 66 | 0.000557638879161 68 - 67 | 0.00111258732224 68 - 68 | 0.00125820594542 68 - 69 | 0.000633252049384 68 - 70 | 0.000107350450022 68 - 71 | 0.0 68 - 72 | 0.000520989167479 68 - 73 | 0.000134561714228 68 - 74 | -0.000366082714015 68 - 75 | -0.000814719632766 68 - 76 | -0.000833744152229 68 - 77 | 0.00124653199946 68 - 78 | 0.000921765633333 68 - 79 | 0.00111949233155 68 - 80 | 0.00139823690449 68 - 81 | 0.000984401324373 68 - 82 | 0.000361808001432 68 - 83 | 2.45896680444e-06 68 - 84 | 0.00101137055311 68 - 85 | 0.000462643593258 68 - 86 | 0.000856490037463 68 - 87 | 0.000548161214367 68 - 88 | 0.000465270028719 68 - 89 | 0.00105425878655 68 - 90 | 0.000680021685053 68 - 91 | 0.000622625559897 68 - 92 | 0.00103221086394 68 - 93 | 0.00129041281345 68 - 94 | 0.00133702049963 68 - 95 | 8.06542236069e-05 69 - 0 | -8.9502972186e-05 69 - 1 | 0.000224982899631 69 - 2 | 0.000235969443513 69 - 3 | 0.000329864720182 69 - 4 | 0.000337638614512 69 - 5 | 0.000132307409299 69 - 6 | 8.39825861541e-05 69 - 7 | 2.87264297197e-05 69 - 8 | 0.0 69 - 9 | 0.0 69 - 10 | 0.0 69 - 11 | 0.0 69 - 12 | -4.76236568959e-05 69 - 13 | -2.46169387136e-05 69 - 14 | 0.000599681228219 69 - 15 | 0.000655366110081 69 - 16 | 0.000122529289649 69 - 17 | 0.000276049729958 69 - 18 | 0.000189295620218 69 - 19 | 8.40667288962e-05 69 - 20 | 3.45003388756e-05 69 - 21 | 0.0 69 - 22 | 0.0 69 - 23 | 0.0 69 - 24 | -0.000168287948648 69 - 25 | -2.66448207759e-05 69 - 26 | 0.00064301367569 69 - 27 | 0.000815734232727 69 - 28 | 0.000316822016546 69 - 29 | 0.000167158220761 69 - 30 | 0.000366106348718 69 - 31 | 0.000225620689243 69 - 32 | 0.00023508756848 69 - 33 | 3.18520708358e-05 69 - 34 | 0.0 69 - 35 | 0.0 69 - 36 | -0.000488866664434 69 - 37 | -0.000388504939304 69 - 38 | 0.000566518437485 69 - 39 | 1.76648202806e-05 69 - 40 | 0.000360697426325 69 - 41 | 0.00027739214235 69 - 42 | 0.000392297200318 69 - 43 | 0.000419357001121 69 - 44 | 0.000325415059967 69 - 45 | 0.000126703643428 69 - 46 | 0.0 69 - 47 | 0.0 69 - 48 | -0.000509130221683 69 - 49 | 0.00026477536036 69 - 50 | 0.000423401133418 69 - 51 | 0.00048126473843 69 - 52 | 0.000392104780351 69 - 53 | -4.98344481006e-05 69 - 54 | 0.000612268324772 69 - 55 | -0.00299380689126 69 - 56 | 0.00037364804416 69 - 57 | 0.000207880863165 69 - 58 | 1.76498412291e-05 69 - 59 | 0.0 69 - 60 | -0.00036760196437 69 - 61 | 0.000807215122942 69 - 62 | 0.00180880775515 69 - 63 | 0.00206579621199 69 - 64 | 0.00159734363391 69 - 65 | 0.000225870019308 69 - 66 | -1.46405692852e-05 69 - 67 | 0.000526977841578 69 - 68 | 0.000633252049384 69 - 69 | 0.000454040841609 69 - 70 | 8.41447107571e-05 69 - 71 | 0.0 69 - 72 | -0.000219448454972 69 - 73 | -0.000858233607717 69 - 74 | -0.00158576524429 69 - 75 | -0.00206058062069 69 - 76 | -0.00183651842218 69 - 77 | 0.000646000257073 69 - 78 | 0.000371237168868 69 - 79 | 0.000525489198697 69 - 80 | 0.000767405315516 69 - 81 | 0.000555421252938 69 - 82 | 0.000230101139144 69 - 83 | 1.67597332644e-06 69 - 84 | 0.000489644746527 69 - 85 | -0.000139107776366 69 - 86 | 0.000151733942884 69 - 87 | -0.00020176599345 69 - 88 | -0.000103296474937 69 - 89 | 0.000624448932057 69 - 90 | 0.000269467672118 69 - 91 | 0.000222148395448 69 - 92 | 0.000512216769971 69 - 93 | 0.000727406052429 69 - 94 | 0.000842849843311 69 - 95 | 5.36014107145e-05 70 - 0 | -3.87039978083e-05 70 - 1 | 2.47553656086e-05 70 - 2 | 2.02931363556e-05 70 - 3 | 5.74852684985e-05 70 - 4 | 5.87501901555e-05 70 - 5 | 2.02323147279e-05 70 - 6 | 1.42877260508e-05 70 - 7 | 5.50040780745e-06 70 - 8 | 0.0 70 - 9 | 0.0 70 - 10 | 0.0 70 - 11 | 0.0 70 - 12 | -2.42311296725e-05 70 - 13 | -2.47618794125e-06 70 - 14 | 8.2245791309e-05 70 - 15 | 0.000107273132427 70 - 16 | 2.34930635979e-05 70 - 17 | 4.75902457336e-05 70 - 18 | 2.99804612078e-05 70 - 19 | 1.52189210677e-05 70 - 20 | 6.50266772165e-06 70 - 21 | 0.0 70 - 22 | 0.0 70 - 23 | 0.0 70 - 24 | -4.32218518861e-05 70 - 25 | -1.02737750169e-05 70 - 26 | 8.73322752933e-05 70 - 27 | 0.000130253774663 70 - 28 | 5.31718298747e-05 70 - 29 | 3.19929726815e-05 70 - 30 | 6.14883117152e-05 70 - 31 | 3.60086612603e-05 70 - 32 | 4.02436702149e-05 70 - 33 | 6.44077665803e-06 70 - 34 | 0.0 70 - 35 | 0.0 70 - 36 | -0.000102698087557 70 - 37 | -6.76640432508e-05 70 - 38 | 7.55643795657e-05 70 - 39 | -9.61251377888e-06 70 - 40 | 5.89130897988e-05 70 - 41 | 5.01564085993e-05 70 - 42 | 7.70132790629e-05 70 - 43 | 6.87651258623e-05 70 - 44 | 5.94839447887e-05 70 - 45 | 2.65112433458e-05 70 - 46 | 0.0 70 - 47 | 0.0 70 - 48 | -0.000112139645564 70 - 49 | 4.2742021741e-05 70 - 50 | 5.23127893412e-05 70 - 51 | 7.08049197958e-05 70 - 52 | 5.63510370797e-05 70 - 53 | 2.30364428491e-06 70 - 54 | 0.000131116633699 70 - 55 | -0.000574909860233 70 - 56 | 6.81061284885e-05 70 - 57 | 4.23832974688e-05 70 - 58 | 4.16197074335e-06 70 - 59 | 0.0 70 - 60 | -9.02275899044e-05 70 - 61 | 0.000140775088983 70 - 62 | 0.000296144465212 70 - 63 | 0.000347090835974 70 - 64 | 0.000271624182904 70 - 65 | 4.2936506768e-05 70 - 66 | 1.75199006652e-05 70 - 67 | 8.56266451794e-05 70 - 68 | 0.000107350450022 70 - 69 | 8.41447107571e-05 70 - 70 | 2.09882916131e-05 70 - 71 | 0.0 70 - 72 | -5.37205925901e-05 70 - 73 | -0.000140167211958 70 - 74 | -0.000279235531771 70 - 75 | -0.000370171116193 70 - 76 | -0.000321158472791 70 - 77 | 0.000113229234704 70 - 78 | 8.17620072035e-05 70 - 79 | 0.000108726524404 70 - 80 | 0.000139835046114 70 - 81 | 9.48945914303e-05 70 - 82 | 5.11863706285e-05 70 - 83 | 3.67156112782e-07 70 - 84 | 8.24068080452e-05 70 - 85 | -2.48204798738e-05 70 - 86 | 3.03636819369e-05 70 - 87 | -4.1145186925e-05 70 - 88 | -2.08138186349e-05 70 - 89 | 0.000106720041846 70 - 90 | 5.71678554134e-05 70 - 91 | 6.39271131927e-05 70 - 92 | 9.89229262796e-05 70 - 93 | 0.000123323489987 70 - 94 | 0.000170938024389 70 - 95 | 1.02698110922e-05 71 - 0 | 0.0 71 - 1 | 0.0 71 - 2 | 0.0 71 - 3 | 0.0 71 - 4 | 0.0 71 - 5 | 0.0 71 - 6 | 0.0 71 - 7 | 0.0 71 - 8 | 0.0 71 - 9 | 0.0 71 - 10 | 0.0 71 - 11 | 0.0 71 - 12 | 0.0 71 - 13 | 0.0 71 - 14 | 0.0 71 - 15 | 0.0 71 - 16 | 0.0 71 - 17 | 0.0 71 - 18 | 0.0 71 - 19 | 0.0 71 - 20 | 0.0 71 - 21 | 0.0 71 - 22 | 0.0 71 - 23 | 0.0 71 - 24 | 0.0 71 - 25 | 0.0 71 - 26 | 0.0 71 - 27 | 0.0 71 - 28 | 0.0 71 - 29 | 0.0 71 - 30 | 0.0 71 - 31 | 0.0 71 - 32 | 0.0 71 - 33 | 0.0 71 - 34 | 0.0 71 - 35 | 0.0 71 - 36 | 0.0 71 - 37 | 0.0 71 - 38 | 0.0 71 - 39 | 0.0 71 - 40 | 0.0 71 - 41 | 0.0 71 - 42 | 0.0 71 - 43 | 0.0 71 - 44 | 0.0 71 - 45 | 0.0 71 - 46 | 0.0 71 - 47 | 0.0 71 - 48 | 0.0 71 - 49 | 0.0 71 - 50 | 0.0 71 - 51 | 0.0 71 - 52 | 0.0 71 - 53 | 0.0 71 - 54 | 0.0 71 - 55 | 0.0 71 - 56 | 0.0 71 - 57 | 0.0 71 - 58 | 0.0 71 - 59 | 0.0 71 - 60 | 0.0 71 - 61 | 0.0 71 - 62 | 0.0 71 - 63 | 0.0 71 - 64 | 0.0 71 - 65 | 0.0 71 - 66 | 0.0 71 - 67 | 0.0 71 - 68 | 0.0 71 - 69 | 0.0 71 - 70 | 0.0 71 - 71 | 0.0 71 - 72 | 0.0 71 - 73 | 0.0 71 - 74 | 0.0 71 - 75 | 0.0 71 - 76 | 0.0 71 - 77 | 0.0 71 - 78 | 0.0 71 - 79 | 0.0 71 - 80 | 0.0 71 - 81 | 0.0 71 - 82 | 0.0 71 - 83 | 0.0 71 - 84 | 0.0 71 - 85 | 0.0 71 - 86 | 0.0 71 - 87 | 0.0 71 - 88 | 0.0 71 - 89 | 0.0 71 - 90 | 0.0 71 - 91 | 0.0 71 - 92 | 0.0 71 - 93 | 0.0 71 - 94 | 0.0 71 - 95 | 0.0 72 - 0 | 0.00626571121633 72 - 1 | 0.0072260698718 72 - 2 | 0.00539105506912 72 - 3 | 0.00124882198415 72 - 4 | 4.92409478168e-05 72 - 5 | 7.72217396064e-05 72 - 6 | -7.98452315403e-05 72 - 7 | -2.67635989695e-05 72 - 8 | 0.0 72 - 9 | 0.0 72 - 10 | 0.0 72 - 11 | 0.0 72 - 12 | 0.00487704524262 72 - 13 | 0.0065018232222 72 - 14 | 0.00472039946108 72 - 15 | 0.00118541635665 72 - 16 | 0.00148924121463 72 - 17 | 0.000225923684571 72 - 18 | 2.54032809827e-07 72 - 19 | 6.61736154919e-05 72 - 20 | -2.45729459774e-05 72 - 21 | 0.0 72 - 22 | 0.0 72 - 23 | 0.0 72 - 24 | 0.00536284652328 72 - 25 | 0.00670938259616 72 - 26 | 0.00510007136544 72 - 27 | 0.00179072228228 72 - 28 | 0.00171189611704 72 - 29 | 0.0013119833308 72 - 30 | 0.000171619352244 72 - 31 | 0.000110991755569 72 - 32 | -0.000808184572311 72 - 33 | -0.000117559207513 72 - 34 | 0.0 72 - 35 | 0.0 72 - 36 | 0.00609353405063 72 - 37 | 0.00721613492066 72 - 38 | 0.00547722456619 72 - 39 | 0.00514157361736 72 - 40 | 0.00217996388905 72 - 41 | 0.00162812963636 72 - 42 | 0.000774424891418 72 - 43 | 0.000355163104325 72 - 44 | -0.000387178011868 72 - 45 | -0.000589579688467 72 - 46 | 0.0 72 - 47 | 0.0 72 - 48 | 0.00589078464534 72 - 49 | 0.00428532726931 72 - 50 | 0.00523774992377 72 - 51 | 0.00375375454797 72 - 52 | 0.00286368855752 72 - 53 | 0.00381234204753 72 - 54 | 0.000733378762406 72 - 55 | 0.0177275343634 72 - 56 | 0.00036628225244 72 - 57 | -0.00011656876654 72 - 58 | -5.62793736036e-06 72 - 59 | 0.0 72 - 60 | 0.00585271211769 72 - 61 | 0.00192753195438 72 - 62 | 0.000391593840343 72 - 63 | -0.00132786665215 72 - 64 | -0.00109956828712 72 - 65 | 0.00295477808505 72 - 66 | 0.00340606317709 72 - 67 | 0.00117016889074 72 - 68 | 0.000520989167479 72 - 69 | -0.000219448454972 72 - 70 | -5.37205925901e-05 72 - 71 | 0.0 72 - 72 | 0.0056805512793 72 - 73 | 0.00741999381774 72 - 74 | 0.010771223381 72 - 75 | 0.0122737931352 72 - 76 | 0.0103744416197 72 - 77 | 0.00160842136432 72 - 78 | 0.00217983183062 72 - 79 | 0.00162282186473 72 - 80 | 0.000732242260028 72 - 81 | 0.000616790853347 72 - 82 | 0.000134311253876 72 - 83 | -2.0360838175e-07 72 - 84 | 0.00169785025473 72 - 85 | 0.00349864887802 72 - 86 | 0.00331718304516 72 - 87 | 0.0045141311168 72 - 88 | 0.00306116023132 72 - 89 | 0.000553804803988 72 - 90 | 0.0016293211689 72 - 91 | 0.00180151048192 72 - 92 | 0.00106102659703 72 - 93 | 0.000612862833712 72 - 94 | 0.000400298026835 72 - 95 | 3.84341481566e-06 73 - 0 | 0.0101652144923 73 - 1 | 0.0117721993042 73 - 2 | 0.0078430203291 73 - 3 | 0.00169482139509 73 - 4 | -0.000503782089994 73 - 5 | -0.000106372894504 73 - 6 | -0.00023907852461 73 - 7 | -8.01185969771e-05 73 - 8 | 0.0 73 - 9 | 0.0 73 - 10 | 0.0 73 - 11 | 0.0 73 - 12 | 0.00792026484135 73 - 13 | 0.01179131568 73 - 14 | 0.00584939830844 73 - 15 | 0.000245606738472 73 - 16 | 0.0024729878623 73 - 17 | 1.95830830867e-05 73 - 18 | -0.000284718068091 73 - 19 | -1.48177106728e-05 73 - 20 | -0.00010968945764 73 - 21 | 0.0 73 - 22 | 0.0 73 - 23 | 0.0 73 - 24 | 0.00897916824969 73 - 25 | 0.0114337627827 73 - 26 | 0.00540345247046 73 - 27 | 3.19389769004e-06 73 - 28 | 0.00224823246981 73 - 29 | 0.00203108668658 73 - 30 | -0.00017330022147 73 - 31 | -0.000169129734917 73 - 32 | -0.00187978319275 73 - 33 | -0.000276039194183 73 - 34 | 0.0 73 - 35 | 0.0 73 - 36 | 0.0106615701232 73 - 37 | 0.0142113003174 73 - 38 | 0.00862406317932 73 - 39 | 0.00865728446544 73 - 40 | 0.00271501835803 73 - 41 | 0.00249537249464 73 - 42 | 0.000935145747357 73 - 43 | 4.67092521311e-06 73 - 44 | -0.00111923152962 73 - 45 | -0.00130373095208 73 - 46 | 0.0 73 - 47 | 0.0 73 - 48 | 0.00982275984449 73 - 49 | 0.00707674088381 73 - 50 | 0.00706745994842 73 - 51 | 0.00414304931846 73 - 52 | 0.0026851107441 73 - 53 | 0.00736563660353 73 - 54 | 0.000637095983184 73 - 55 | 0.0322016986822 73 - 56 | 0.000206250192601 73 - 57 | -0.000409486681244 73 - 58 | -2.29681914419e-05 73 - 59 | 0.0 73 - 60 | 0.00862822073673 73 - 61 | 0.00142270009935 73 - 62 | -0.00722668566219 73 - 63 | -0.0114907839967 73 - 64 | -0.00859158609086 73 - 65 | 0.0046301825027 73 - 66 | 0.0059476243286 73 - 67 | 0.00102842441167 73 - 68 | 0.000134561714228 73 - 69 | -0.000858233607717 73 - 70 | -0.000140167211958 73 - 71 | 0.0 73 - 72 | 0.00741999381774 73 - 73 | 0.0193322237794 73 - 74 | 0.0266140343396 73 - 75 | 0.02940879846 73 - 76 | 0.0252630478892 73 - 77 | 2.4732896027e-05 73 - 78 | 0.00289807972841 73 - 79 | 0.0022828726389 73 - 80 | 0.000416093999982 73 - 81 | 0.000389199593574 73 - 82 | -0.000100973121465 73 - 83 | -1.01847724426e-06 73 - 84 | 0.00124222419999 73 - 85 | 0.00696216655176 73 - 86 | 0.00613660149341 73 - 87 | 0.00824149596629 73 - 88 | 0.00659139841017 73 - 89 | -0.00132552173796 73 - 90 | 0.00220695533806 73 - 91 | 0.00322283228356 73 - 92 | 0.00158857004813 73 - 93 | 0.000498653324171 73 - 94 | -0.000761429556298 73 - 95 | -9.37306132021e-05 74 - 0 | 0.0152565774931 74 - 1 | 0.0159759563853 74 - 2 | 0.011521647503 74 - 3 | 0.00223287970077 74 - 4 | -0.000943792813395 74 - 5 | -0.000235822701035 74 - 6 | -0.000412343847133 74 - 7 | -0.000136149276658 74 - 8 | 0.0 74 - 9 | 0.0 74 - 10 | 0.0 74 - 11 | 0.0 74 - 12 | 0.0115725607421 74 - 13 | 0.0159902367356 74 - 14 | 0.00775106688838 74 - 15 | -0.000504895891191 74 - 16 | 0.00368848486164 74 - 17 | -5.22980886156e-05 74 - 18 | -0.000520231807983 74 - 19 | -2.37502394493e-05 74 - 20 | -0.000155939817195 74 - 21 | 0.0 74 - 22 | 0.0 74 - 23 | 0.0 74 - 24 | 0.0130895589273 74 - 25 | 0.0149634697841 74 - 26 | 0.00609863473523 74 - 27 | -0.00202378982812 74 - 28 | 0.00294201167529 74 - 29 | 0.00303632557127 74 - 30 | -0.000525170946974 74 - 31 | -0.000296736401608 74 - 32 | -0.0028341706174 74 - 33 | -0.000413776381231 74 - 34 | 0.0 74 - 35 | 0.0 74 - 36 | 0.0162575755755 74 - 37 | 0.0203360893775 74 - 38 | 0.0126089595629 74 - 39 | 0.012635225462 74 - 40 | 0.00339630510147 74 - 41 | 0.00347485813825 74 - 42 | 0.000881794459541 74 - 43 | -0.000291261193471 74 - 44 | -0.00187693439754 74 - 45 | -0.00210800898344 74 - 46 | 0.0 74 - 47 | 0.0 74 - 48 | 0.0147418798316 74 - 49 | 0.0081929557795 74 - 50 | 0.00859272367228 74 - 51 | 0.00417118525832 74 - 52 | 0.00248822410171 74 - 53 | 0.0108367468982 74 - 54 | 0.000156371624314 74 - 55 | 0.0539829983723 74 - 56 | 4.33041267195e-05 74 - 57 | -0.0007631289914 74 - 58 | -3.5956183329e-05 74 - 59 | 0.0 74 - 60 | 0.0126324790129 74 - 61 | -0.00197442900414 74 - 62 | -0.0165015307943 74 - 63 | -0.0239259887123 74 - 64 | -0.0177874463596 74 - 65 | 0.00626962244157 74 - 66 | 0.00842220052558 74 - 67 | 0.00106093007554 74 - 68 | -0.000366082714015 74 - 69 | -0.00158576524429 74 - 70 | -0.000279235531771 74 - 71 | 0.0 74 - 72 | 0.010771223381 74 - 73 | 0.0266140343396 74 - 74 | 0.0466330070978 74 - 75 | 0.0500641974246 74 - 76 | 0.0420312254645 74 - 77 | -0.00249346671467 74 - 78 | 0.00330973523733 74 - 79 | 0.00235798100535 74 - 80 | -8.58399007285e-05 74 - 81 | 0.000400193942256 74 - 82 | -0.000200081776948 74 - 83 | -2.90094588939e-06 74 - 84 | 0.000797857214882 74 - 85 | 0.00900481828519 74 - 86 | 0.00854756829251 74 - 87 | 0.0122995670969 74 - 88 | 0.0102147193549 74 - 89 | -0.00393285657545 74 - 90 | 0.00224849645584 74 - 91 | 0.00395430462266 74 - 92 | 0.00167506462568 74 - 93 | 0.000267434469281 74 - 94 | -0.00128395102197 74 - 95 | -0.00014860086963 75 - 0 | 0.0172984228592 75 - 1 | 0.0172867507994 75 - 2 | 0.0130743357289 75 - 3 | 0.00222718945288 75 - 4 | -0.0013427413171 75 - 5 | -0.000348267705941 75 - 6 | -0.000497528867014 75 - 7 | -0.000180496763689 75 - 8 | 0.0 75 - 9 | 0.0 75 - 10 | 0.0 75 - 11 | 0.0 75 - 12 | 0.0130757894272 75 - 13 | 0.0172882263506 75 - 14 | 0.00843159185614 75 - 15 | -0.000982872860752 75 - 16 | 0.00405457911648 75 - 17 | -0.000248339030904 75 - 18 | -0.000729508200303 75 - 19 | -6.06279056594e-05 75 - 20 | -0.000192317449157 75 - 21 | 0.0 75 - 22 | 0.0 75 - 23 | 0.0 75 - 24 | 0.0148591021385 75 - 25 | 0.0161143823176 75 - 26 | 0.00635593899777 75 - 27 | -0.00294066301648 75 - 28 | 0.00308916438366 75 - 29 | 0.00336431850207 75 - 30 | -0.000835851317142 75 - 31 | -0.000405671246594 75 - 32 | -0.00320960454145 75 - 33 | -0.000461995989945 75 - 34 | 0.0 75 - 35 | 0.0 75 - 36 | 0.018712728746 75 - 37 | 0.0224001327148 75 - 38 | 0.0137230832967 75 - 39 | 0.0143105594258 75 - 40 | 0.00359718898686 75 - 41 | 0.00374971546797 75 - 42 | 0.000685065187283 75 - 43 | -0.00056564382434 75 - 44 | -0.00225894385604 75 - 45 | -0.00242188075256 75 - 46 | 0.0 75 - 47 | 0.0 75 - 48 | 0.0170077209115 75 - 49 | 0.00828650782033 75 - 50 | 0.0089185701976 75 - 51 | 0.00423743721694 75 - 52 | 0.00243027828466 75 - 53 | 0.0119929333201 75 - 54 | -0.000278039975152 75 - 55 | 0.061282913844 75 - 56 | -0.000194616996678 75 - 57 | -0.000987571829748 75 - 58 | -5.27332174877e-05 75 - 59 | 0.0 75 - 60 | 0.0145293659935 75 - 61 | -0.00363767184795 75 - 62 | -0.0209296303636 75 - 63 | -0.0285518121129 75 - 64 | -0.0214458468271 75 - 65 | 0.00685582744072 75 - 66 | 0.00941801536428 75 - 67 | 0.000804171966556 75 - 68 | -0.000814719632766 75 - 69 | -0.00206058062069 75 - 70 | -0.000370171116193 75 - 71 | 0.0 75 - 72 | 0.0122737931352 75 - 73 | 0.02940879846 75 - 74 | 0.0500641974246 75 - 75 | 0.0604062009105 75 - 76 | 0.0492121180262 75 - 77 | -0.00357249347749 75 - 78 | 0.00346444463453 75 - 79 | 0.00219131205001 75 - 80 | -0.000599776478552 75 - 81 | 0.000199896218513 75 - 82 | -0.000280601270664 75 - 83 | -4.68307860076e-06 75 - 84 | 0.000402130294557 75 - 85 | 0.00969687251288 75 - 86 | 0.00855128546781 75 - 87 | 0.0141782452236 75 - 88 | 0.0116681183181 75 - 89 | -0.00504269532857 75 - 90 | 0.00214149162062 75 - 91 | 0.00405267212056 75 - 92 | 0.00133676282235 75 - 93 | -0.000226020786708 75 - 94 | -0.00159121157672 75 - 95 | -0.000180062640131 76 - 0 | 0.0144494146074 76 - 1 | 0.0145989538982 76 - 2 | 0.0106054649129 76 - 3 | 0.00177599801539 76 - 4 | -0.00124704708138 76 - 5 | -0.000344403790757 76 - 6 | -0.000450559410052 76 - 7 | -0.000150684387764 76 - 8 | 0.0 76 - 9 | 0.0 76 - 10 | 0.0 76 - 11 | 0.0 76 - 12 | 0.0109553075376 76 - 13 | 0.0149191673677 76 - 14 | 0.00661537307958 76 - 15 | -0.0011857648411 76 - 16 | 0.00334597335519 76 - 17 | -0.000317472482531 76 - 18 | -0.000685125607051 76 - 19 | -8.12783090711e-05 76 - 20 | -0.000170189089934 76 - 21 | 0.0 76 - 22 | 0.0 76 - 23 | 0.0 76 - 24 | 0.0124876138553 76 - 25 | 0.0139461131887 76 - 26 | 0.00495284498468 76 - 27 | -0.00279767509985 76 - 28 | 0.00246526250017 76 - 29 | 0.00274098993567 76 - 30 | -0.000823626527325 76 - 31 | -0.000426106826324 76 - 32 | -0.00282674381445 76 - 33 | -0.000407566055335 76 - 34 | 0.0 76 - 35 | 0.0 76 - 36 | 0.0157810088274 76 - 37 | 0.0193705962106 76 - 38 | 0.0110988089416 76 - 39 | 0.0119515124168 76 - 40 | 0.00286140440402 76 - 41 | 0.00302363464691 76 - 42 | 0.000503221249956 76 - 43 | -0.000607346184206 76 - 44 | -0.00201162447749 76 - 45 | -0.00213150956872 76 - 46 | 0.0 76 - 47 | 0.0 76 - 48 | 0.0143998188119 76 - 49 | 0.00720615445663 76 - 50 | 0.00740379744899 76 - 51 | 0.00341625089806 76 - 52 | 0.00194470881929 76 - 53 | 0.0102690622912 76 - 54 | -0.000417152752093 76 - 55 | 0.0531982663682 76 - 56 | -0.000248196210536 76 - 57 | -0.000866577248138 76 - 58 | -4.2724929941e-05 76 - 59 | 0.0 76 - 60 | 0.0122427127701 76 - 61 | -0.00297659865149 76 - 62 | -0.0178546503961 76 - 63 | -0.024536381833 76 - 64 | -0.0180200219001 76 - 65 | 0.00591327521895 76 - 66 | 0.00812692322047 76 - 67 | 0.000554402133968 76 - 68 | -0.000833744152229 76 - 69 | -0.00183651842218 76 - 70 | -0.000321158472791 76 - 71 | 0.0 76 - 72 | 0.0103744416197 76 - 73 | 0.0252630478892 76 - 74 | 0.0420312254645 76 - 75 | 0.0492121180262 76 - 76 | 0.0437453967515 76 - 77 | -0.00256631227729 76 - 78 | 0.00295827038624 76 - 79 | 0.00187170968451 76 - 80 | -0.000667579494999 76 - 81 | 4.97946488979e-05 76 - 82 | -0.000305158397639 76 - 83 | -3.79161446182e-06 76 - 84 | 0.000135641548062 76 - 85 | 0.00844969623569 76 - 86 | 0.0072315213723 76 - 87 | 0.0116354255117 76 - 88 | 0.00994868076869 76 - 89 | -0.00424458335019 76 - 90 | 0.00187365492116 76 - 91 | 0.00359014977811 76 - 92 | 0.00114541471285 76 - 93 | -0.000317697831417 76 - 94 | -0.00174344513663 76 - 95 | -0.00017732341192 77 - 0 | 0.00215971301558 77 - 1 | 0.00359663809602 77 - 2 | 0.00220009254348 77 - 3 | 0.00100356713005 77 - 4 | 0.000602874364142 77 - 5 | 0.000266216918922 77 - 6 | 0.000128463521603 77 - 7 | 4.05840905305e-05 77 - 8 | 0.0 77 - 9 | 0.0 77 - 10 | 0.0 77 - 11 | 0.0 77 - 12 | 0.00189865826564 77 - 13 | 0.00269097012582 77 - 14 | 0.0030025074562 77 - 15 | 0.00200845327509 77 - 16 | 0.00061476565534 77 - 17 | 0.000553121291578 77 - 18 | 0.000333050070988 77 - 19 | 0.000146680209447 77 - 20 | 4.90186141977e-05 77 - 21 | 0.0 77 - 22 | 0.0 77 - 23 | 0.0 77 - 24 | 0.00190324824599 77 - 25 | 0.00317332584799 77 - 26 | 0.00408851245567 77 - 27 | 0.00327536998039 77 - 28 | 0.0012938461477 77 - 29 | 0.000682728730098 77 - 30 | 0.000739462460819 77 - 31 | 0.0004331348559 77 - 32 | 0.000168312873489 77 - 33 | 1.08610004513e-05 77 - 34 | 0.0 77 - 35 | 0.0 77 - 36 | 0.00145930309748 77 - 37 | 0.00186124230451 77 - 38 | 0.00246559470762 77 - 39 | 0.00173220980077 77 - 40 | 0.0017702351534 77 - 41 | 0.00108647336346 77 - 42 | 0.00110586012482 77 - 43 | 0.000879992598728 77 - 44 | 0.000452370801938 77 - 45 | 2.74151768511e-05 77 - 46 | 0.0 77 - 47 | 0.0 77 - 48 | 0.00159027584814 77 - 49 | 0.00314258133358 77 - 50 | 0.00374274851018 77 - 51 | 0.00345417361462 77 - 52 | 0.00285790792894 77 - 53 | 0.00107347071794 77 - 54 | 0.00146412012998 77 - 55 | -0.00173387862878 77 - 56 | 0.000741551804652 77 - 57 | 0.000299489552606 77 - 58 | 2.26977695915e-05 77 - 59 | 0.0 77 - 60 | 0.00198192449019 77 - 61 | 0.0042091334379 77 - 62 | 0.0078638009214 77 - 63 | 0.00821874699578 77 - 64 | 0.00612060031145 77 - 65 | 0.00190315306447 77 - 66 | 0.00149431531575 77 - 67 | 0.00149929132801 77 - 68 | 0.00124653199946 77 - 69 | 0.000646000257073 77 - 70 | 0.000113229234704 77 - 71 | 0.0 77 - 72 | 0.00160842136432 77 - 73 | 2.4732896027e-05 77 - 74 | -0.00249346671467 77 - 75 | -0.00357249347749 77 - 76 | -0.00256631227729 77 - 77 | 0.0043972543228 77 - 78 | 0.00226440302339 77 - 79 | 0.00199879570783 77 - 80 | 0.00164079315202 77 - 81 | 0.00102129164812 77 - 82 | 0.000418529617141 77 - 83 | 2.844933536e-06 77 - 84 | 0.00188765572699 77 - 85 | 0.00150488401248 77 - 86 | 0.0016043457359 77 - 87 | 0.00110889606704 77 - 88 | 0.000369960683209 77 - 89 | 0.00284380494998 77 - 90 | 0.00179213456218 77 - 91 | 0.00145817505759 77 - 92 | 0.0013714991528 77 - 93 | 0.00123177567614 77 - 94 | 0.00133821314031 77 - 95 | 7.9135858054e-05 78 - 0 | 0.00320018389697 78 - 1 | 0.00414500797315 78 - 2 | 0.00289380096499 78 - 3 | 0.0010353344609 78 - 4 | 0.000379165340937 78 - 5 | 0.000173807091395 78 - 6 | 5.5585256659e-05 78 - 7 | 1.3124126616e-05 78 - 8 | 0.0 78 - 9 | 0.0 78 - 10 | 0.0 78 - 11 | 0.0 78 - 12 | 0.00259303108222 78 - 13 | 0.0034752072758 78 - 14 | 0.00305616445496 78 - 15 | 0.00142311490492 78 - 16 | 0.000935539233953 78 - 17 | 0.000452947975198 78 - 18 | 0.000165703767009 78 - 19 | 0.000112005450232 78 - 20 | 2.57108335718e-05 78 - 21 | 0.0 78 - 22 | 0.0 78 - 23 | 0.0 78 - 24 | 0.00274120816438 78 - 25 | 0.0036282822218 78 - 26 | 0.00344593667954 78 - 27 | 0.00200293195813 78 - 28 | 0.00130385311959 78 - 29 | 0.000911100663424 78 - 30 | 0.000510600841081 78 - 31 | 0.000316093335137 78 - 32 | -8.93139618917e-05 78 - 33 | -2.05893394024e-05 78 - 34 | 0.0 78 - 35 | 0.0 78 - 36 | 0.00273291305407 78 - 37 | 0.00335850317013 78 - 38 | 0.00327815003457 78 - 39 | 0.0026363054167 78 - 40 | 0.00165740271809 78 - 41 | 0.00131882284914 78 - 42 | 0.000991553230868 78 - 43 | 0.000621347682783 78 - 44 | 0.000196407024421 78 - 45 | -0.000175859832823 78 - 46 | 0.0 78 - 47 | 0.0 78 - 48 | 0.00258206915989 78 - 49 | 0.00295576460096 78 - 50 | 0.0034312635716 78 - 51 | 0.00272876785082 78 - 52 | 0.00214315242908 78 - 53 | 0.00202820079535 78 - 54 | 0.00130223325036 78 - 55 | 0.00358688607228 78 - 56 | 0.000583227041541 78 - 57 | 0.000182588158672 78 - 58 | 1.6675102759e-05 78 - 59 | 0.0 78 - 60 | 0.00259520572198 78 - 61 | 0.00243143747271 78 - 62 | 0.00304977707762 78 - 63 | 0.00251291612773 78 - 64 | 0.00190603655245 78 - 65 | 0.00209472262991 78 - 66 | 0.00222818754621 78 - 67 | 0.00127137477031 78 - 68 | 0.000921765633333 78 - 69 | 0.000371237168868 78 - 70 | 8.17620072035e-05 78 - 71 | 0.0 78 - 72 | 0.00217983183062 78 - 73 | 0.00289807972841 78 - 74 | 0.00330973523733 78 - 75 | 0.00346444463453 78 - 76 | 0.00295827038624 78 - 77 | 0.00226440302339 78 - 78 | 0.00260058092233 78 - 79 | 0.00194781099143 78 - 80 | 0.00125714047666 78 - 81 | 0.000849587527344 78 - 82 | 0.000384097895015 78 - 83 | 2.22436691491e-06 78 - 84 | 0.00142304508323 78 - 85 | 0.00191211014751 78 - 86 | 0.0020595625067 78 - 87 | 0.00221210550952 78 - 88 | 0.00158834500666 78 - 89 | 0.00144502601826 78 - 90 | 0.00161535602795 78 - 91 | 0.00162761277983 78 - 92 | 0.00122755428667 78 - 93 | 0.000959860207579 78 - 94 | 0.00116198289286 78 - 95 | 5.8224799959e-05 79 - 0 | 0.00252287353601 79 - 1 | 0.00357508857343 79 - 2 | 0.00241431422527 79 - 3 | 0.001018738971 79 - 4 | 0.000473813815811 79 - 5 | 0.000206155713091 79 - 6 | 8.92787871023e-05 79 - 7 | 3.05281452225e-05 79 - 8 | 0.0 79 - 9 | 0.0 79 - 10 | 0.0 79 - 11 | 0.0 79 - 12 | 0.0020872322784 79 - 13 | 0.00301101701349 79 - 14 | 0.00270688323905 79 - 15 | 0.00141916840516 79 - 16 | 0.000803881014436 79 - 17 | 0.000516885160013 79 - 18 | 0.000251117032279 79 - 19 | 0.000137721970303 79 - 20 | 4.1157705062e-05 79 - 21 | 0.0 79 - 22 | 0.0 79 - 23 | 0.0 79 - 24 | 0.00213002684137 79 - 25 | 0.0030502665183 79 - 26 | 0.00300537116061 79 - 27 | 0.001938408544 79 - 28 | 0.00122273697649 79 - 29 | 0.000824427116347 79 - 30 | 0.000654514321471 79 - 31 | 0.000401435306291 79 - 32 | 5.82381680456e-05 79 - 33 | -2.56076910477e-06 79 - 34 | 0.0 79 - 35 | 0.0 79 - 36 | 0.00195413249242 79 - 37 | 0.00277682149077 79 - 38 | 0.00301511146817 79 - 39 | 0.0022143682867 79 - 40 | 0.00152623822709 79 - 41 | 0.00119795211147 79 - 42 | 0.00104299866314 79 - 43 | 0.00075298837977 79 - 44 | 0.000329247782569 79 - 45 | -9.82206893846e-05 79 - 46 | 0.0 79 - 47 | 0.0 79 - 48 | 0.00179405468613 79 - 49 | 0.00267530619424 79 - 50 | 0.00296135429929 79 - 51 | 0.00240311034145 79 - 52 | 0.00185372979664 79 - 53 | 0.00170489639967 79 - 54 | 0.00130156713459 79 - 55 | 0.00155019634365 79 - 56 | 0.000677118457738 79 - 57 | 0.000251150994069 79 - 58 | 2.42296574181e-05 79 - 59 | 0.0 79 - 60 | 0.00182065570363 79 - 61 | 0.00241905463871 79 - 62 | 0.0030987505493 79 - 63 | 0.00274148506171 79 - 64 | 0.00212327790683 79 - 65 | 0.00173235466295 79 - 66 | 0.00171378647009 79 - 67 | 0.00142069712792 79 - 68 | 0.00111949233155 79 - 69 | 0.000525489198697 79 - 70 | 0.000108726524404 79 - 71 | 0.0 79 - 72 | 0.00162282186473 79 - 73 | 0.0022828726389 79 - 74 | 0.00235798100535 79 - 75 | 0.00219131205001 79 - 76 | 0.00187170968451 79 - 77 | 0.00199879570783 79 - 78 | 0.00194781099143 79 - 79 | 0.00225350116753 79 - 80 | 0.0016027292394 79 - 81 | 0.00100262364948 79 - 82 | 0.000408404974466 79 - 83 | 2.75656970794e-06 79 - 84 | 0.00133826290998 79 - 85 | 0.00158418743546 79 - 86 | 0.00175880872097 79 - 87 | 0.00164713538765 79 - 88 | 0.0012071940221 79 - 89 | 0.0013543241749 79 - 90 | 0.00141782477416 79 - 91 | 0.00154630141345 79 - 92 | 0.00140917638492 79 - 93 | 0.00124514853943 79 - 94 | 0.00126404410174 79 - 95 | 6.70456790903e-05 80 - 0 | 0.00146432512511 80 - 1 | 0.00235942944117 80 - 2 | 0.00177146812115 80 - 3 | 0.000929684276775 80 - 4 | 0.000629598515159 80 - 5 | 0.000268253859488 80 - 6 | 0.000137137446817 80 - 7 | 5.00890612776e-05 80 - 8 | 0.0 80 - 9 | 0.0 80 - 10 | 0.0 80 - 11 | 0.0 80 - 12 | 0.00118978582366 80 - 13 | 0.00165282341897 80 - 14 | 0.00224743975742 80 - 15 | 0.00149507292872 80 - 16 | 0.000577699353159 80 - 17 | 0.000589336346224 80 - 18 | 0.000375949846666 80 - 19 | 0.000175380348059 80 - 20 | 5.09745409787e-05 80 - 21 | 0.0 80 - 22 | 0.0 80 - 23 | 0.0 80 - 24 | 0.00105173884526 80 - 25 | 0.00162966087037 80 - 26 | 0.00240299932693 80 - 27 | 0.0019135685728 80 - 28 | 0.00100065552715 80 - 29 | 0.000637737656166 80 - 30 | 0.000761509042741 80 - 31 | 0.000462053482566 80 - 32 | 0.000207882086715 80 - 33 | 2.27029422912e-05 80 - 34 | 0.0 80 - 35 | 0.0 80 - 36 | 0.000690524283968 80 - 37 | 0.00115641388663 80 - 38 | 0.00239144190225 80 - 39 | 0.00129078507402 80 - 40 | 0.00122993675811 80 - 41 | 0.000910601576514 80 - 42 | 0.000951615232403 80 - 43 | 0.000934645661402 80 - 44 | 0.000517937776382 80 - 45 | 5.30224164162e-05 80 - 46 | 0.0 80 - 47 | 0.0 80 - 48 | 0.000540082232242 80 - 49 | 0.00165824967645 80 - 50 | 0.00203692045172 80 - 51 | 0.00180137065199 80 - 52 | 0.00141041386179 80 - 53 | 0.000903553063038 80 - 54 | 0.00131639913881 80 - 55 | -0.00196277554689 80 - 56 | 0.000845524117824 80 - 57 | 0.000360043380684 80 - 58 | 3.08102175483e-05 80 - 59 | 0.0 80 - 60 | 0.000691498785305 80 - 61 | 0.0020942410631 80 - 62 | 0.00336454653888 80 - 63 | 0.00338583402701 80 - 64 | 0.00262107074274 80 - 65 | 0.00113088349424 80 - 66 | 0.000824186668443 80 - 67 | 0.00138184567023 80 - 68 | 0.00139823690449 80 - 69 | 0.000767405315516 80 - 70 | 0.000139835046114 80 - 71 | 0.0 80 - 72 | 0.000732242260028 80 - 73 | 0.000416093999982 80 - 74 | -8.58399007285e-05 80 - 75 | -0.000599776478552 80 - 76 | -0.000667579494999 80 - 77 | 0.00164079315202 80 - 78 | 0.00125714047666 80 - 79 | 0.0016027292394 80 - 80 | 0.00203341782395 80 - 81 | 0.00130126119606 80 - 82 | 0.000484593019138 80 - 83 | 3.18317178819e-06 80 - 84 | 0.00124192477627 80 - 85 | 0.000645432226946 80 - 86 | 0.00107228235071 80 - 87 | 0.000726397934778 80 - 88 | 0.000566211758855 80 - 89 | 0.00129589423203 80 - 90 | 0.000923051648972 80 - 91 | 0.000929736120878 80 - 92 | 0.0014438099182 80 - 93 | 0.00169551408459 80 - 94 | 0.00176732663603 80 - 95 | 0.00010529013493 81 - 0 | 0.00118290409502 81 - 1 | 0.0017191806711 81 - 2 | 0.00148459386456 81 - 3 | 0.00069622915753 81 - 4 | 0.000427348324794 81 - 5 | 0.000188414524185 81 - 6 | 8.96498946338e-05 81 - 7 | 3.36005224848e-05 81 - 8 | 0.0 81 - 9 | 0.0 81 - 10 | 0.0 81 - 11 | 0.0 81 - 12 | 0.000915710296527 81 - 13 | 0.00121538522833 81 - 14 | 0.00172922063907 81 - 15 | 0.00104136940636 81 - 16 | 0.0004631048629 81 - 17 | 0.000412633775641 81 - 18 | 0.00025827099998 81 - 19 | 0.000131123728824 81 - 20 | 3.63230475461e-05 81 - 21 | 0.0 81 - 22 | 0.0 81 - 23 | 0.0 81 - 24 | 0.000822529079113 81 - 25 | 0.00116695924817 81 - 26 | 0.00178838384272 81 - 27 | 0.00131184811079 81 - 28 | 0.000729015845285 81 - 29 | 0.000489206880442 81 - 30 | 0.000517809327331 81 - 31 | 0.000333562509097 81 - 32 | 0.000102922264732 81 - 33 | 9.00114750981e-06 81 - 34 | 0.0 81 - 35 | 0.0 81 - 36 | 0.0006601122421 81 - 37 | 0.000922419625762 81 - 38 | 0.00178289449285 81 - 39 | 0.00107186431563 81 - 40 | 0.000894315334995 81 - 41 | 0.000650222692327 81 - 42 | 0.000637934641909 81 - 43 | 0.000659522999171 81 - 44 | 0.000345014754063 81 - 45 | -1.90858626809e-05 81 - 46 | 0.0 81 - 47 | 0.0 81 - 48 | 0.000555166378628 81 - 49 | 0.00106799154659 81 - 50 | 0.00144602768244 81 - 51 | 0.0012814746373 81 - 52 | 0.00102363528212 81 - 53 | 0.000727012850355 81 - 54 | 0.000858559296093 81 - 55 | -6.52773806881e-06 81 - 56 | 0.000617641894182 81 - 57 | 0.000253083533779 81 - 58 | 2.28131208475e-05 81 - 59 | 0.0 81 - 60 | 0.000617904188621 81 - 61 | 0.00123861257766 81 - 62 | 0.00204536547517 81 - 63 | 0.00199336999344 81 - 64 | 0.00155201117628 81 - 65 | 0.000845927837808 81 - 66 | 0.000657317132246 81 - 67 | 0.000956728250895 81 - 68 | 0.000984401324373 81 - 69 | 0.000555421252938 81 - 70 | 9.48945914303e-05 81 - 71 | 0.0 81 - 72 | 0.000616790853347 81 - 73 | 0.000389199593574 81 - 74 | 0.000400193942256 81 - 75 | 0.000199896218513 81 - 76 | 4.97946488979e-05 81 - 77 | 0.00102129164812 81 - 78 | 0.000849587527344 81 - 79 | 0.00100262364948 81 - 80 | 0.00130126119606 81 - 81 | 0.00110008172504 81 - 82 | 0.00038395535876 81 - 83 | 2.40850685825e-06 81 - 84 | 0.000786509761147 81 - 85 | 0.000442091929595 81 - 86 | 0.000763146728206 81 - 87 | 0.000645414879648 81 - 88 | 0.000470301876154 81 - 89 | 0.000790684856785 81 - 90 | 0.000570338695268 81 - 91 | 0.000583802102687 81 - 92 | 0.00097360909815 81 - 93 | 0.00133051535539 81 - 94 | 0.00137412959425 81 - 95 | 8.19292811922e-05 82 - 0 | 0.000308989244786 82 - 1 | 0.000490638824414 82 - 2 | 0.000490915534417 82 - 3 | 0.000257543082579 82 - 4 | 0.000174753055025 82 - 5 | 6.49758934587e-05 82 - 6 | 3.1628135217e-05 82 - 7 | 1.11758289942e-05 82 - 8 | 0.0 82 - 9 | 0.0 82 - 10 | 0.0 82 - 11 | 0.0 82 - 12 | 0.000243458629137 82 - 13 | 0.000305680951194 82 - 14 | 0.00061572695175 82 - 15 | 0.000416557801807 82 - 16 | 0.000173152704311 82 - 17 | 0.000163146031535 82 - 18 | 8.64062360184e-05 82 - 19 | 4.68615979227e-05 82 - 20 | 1.55979660256e-05 82 - 21 | 0.0 82 - 22 | 0.0 82 - 23 | 0.0 82 - 24 | 0.000192442202741 82 - 25 | 0.000287824351026 82 - 26 | 0.000646373296884 82 - 27 | 0.000525557191366 82 - 28 | 0.000273335832261 82 - 29 | 0.000190281141298 82 - 30 | 0.00019112767067 82 - 31 | 0.000119844634491 82 - 32 | 6.96562387585e-05 82 - 33 | 8.87981568853e-06 82 - 34 | 0.0 82 - 35 | 0.0 82 - 36 | 0.000107550981436 82 - 37 | 0.000149756512755 82 - 38 | 0.000572753375097 82 - 39 | 0.000322883965612 82 - 40 | 0.000332694128957 82 - 41 | 0.000255435992611 82 - 42 | 0.000264841744946 82 - 43 | 0.000232042541714 82 - 44 | 0.000152341748451 82 - 45 | 1.54201090104e-05 82 - 46 | 0.0 82 - 47 | 0.0 82 - 48 | 7.51360982311e-05 82 - 49 | 0.000307280396424 82 - 50 | 0.000466931788235 82 - 51 | 0.000458971028748 82 - 52 | 0.000382314448626 82 - 53 | 0.000231023659742 82 - 54 | 0.000404017887192 82 - 55 | -0.000524955513131 82 - 56 | 0.000239702913147 82 - 57 | 0.000113871785394 82 - 58 | 1.07080597476e-05 82 - 59 | 0.0 82 - 60 | 0.000114212254076 82 - 61 | 0.000464023823156 82 - 62 | 0.000883100820192 82 - 63 | 0.000942300837206 82 - 64 | 0.000733633534603 82 - 65 | 0.000312078990912 82 - 66 | 0.000278327406863 82 - 67 | 0.000348671820544 82 - 68 | 0.000361808001432 82 - 69 | 0.000230101139144 82 - 70 | 5.11863706285e-05 82 - 71 | 0.0 82 - 72 | 0.000134311253876 82 - 73 | -0.000100973121465 82 - 74 | -0.000200081776948 82 - 75 | -0.000280601270664 82 - 76 | -0.000305158397639 82 - 77 | 0.000418529617141 82 - 78 | 0.000384097895015 82 - 79 | 0.000408404974466 82 - 80 | 0.000484593019138 82 - 81 | 0.00038395535876 82 - 82 | 0.0002057037827 82 - 83 | 1.15625578536e-06 82 - 84 | 0.00030110001104 82 - 85 | 6.98996166943e-05 82 - 86 | 0.000212911540168 82 - 87 | 0.000150457229668 82 - 88 | 0.000103428111814 82 - 89 | 0.000331845414732 82 - 90 | 0.000232532843623 82 - 91 | 0.000258354367377 82 - 92 | 0.000346391840682 82 - 93 | 0.000439373555806 82 - 94 | 0.000661878050894 82 - 95 | 3.81995800147e-05 83 - 0 | 3.13326041213e-07 83 - 1 | 2.12561622041e-06 83 - 2 | 1.63135619153e-06 83 - 3 | 1.63567939637e-06 83 - 4 | 1.26661479731e-06 83 - 5 | 4.52720100477e-07 83 - 6 | 2.77319257244e-07 83 - 7 | 1.18150047906e-07 83 - 8 | 0.0 83 - 9 | 0.0 83 - 10 | 0.0 83 - 11 | 0.0 83 - 12 | 4.15413622361e-07 83 - 13 | 1.60413405321e-06 83 - 14 | 2.79634930964e-06 83 - 15 | 2.46376449701e-06 83 - 16 | 8.48383212098e-07 83 - 17 | 1.10571143935e-06 83 - 18 | 6.65127775293e-07 83 - 19 | 3.35187150971e-07 83 - 20 | 1.4905664864e-07 83 - 21 | 0.0 83 - 22 | 0.0 83 - 23 | 0.0 83 - 24 | 9.7427520798e-08 83 - 25 | 1.49451239487e-06 83 - 26 | 2.77701952251e-06 83 - 27 | 3.11271678503e-06 83 - 28 | 1.55210987606e-06 83 - 29 | 9.40384724127e-07 83 - 30 | 1.38396531643e-06 83 - 31 | 8.38271750971e-07 83 - 32 | 6.86427964683e-07 83 - 33 | 8.8129000637e-08 83 - 34 | 0.0 83 - 35 | 0.0 83 - 36 | -8.75711502888e-07 83 - 37 | 6.96393175477e-07 83 - 38 | 2.91894251315e-06 83 - 39 | 1.14264518989e-06 83 - 40 | 1.76242660314e-06 83 - 41 | 1.41019215883e-06 83 - 42 | 1.79570286554e-06 83 - 43 | 1.52517740197e-06 83 - 44 | 1.14258474604e-06 83 - 45 | 2.6415453348e-07 83 - 46 | 0.0 83 - 47 | 0.0 83 - 48 | -1.07908824119e-06 83 - 49 | 2.21981435786e-06 83 - 50 | 2.5150826409e-06 83 - 51 | 2.49252719886e-06 83 - 52 | 1.78662802616e-06 83 - 53 | 1.00760765114e-06 83 - 54 | 2.52259423777e-06 83 - 55 | -4.86912722922e-06 83 - 56 | 1.49711528522e-06 83 - 57 | 8.17984764515e-07 83 - 58 | 9.54422611231e-08 83 - 59 | 0.0 83 - 60 | -8.25699798032e-07 83 - 61 | 3.42369889374e-06 83 - 62 | 6.44181149194e-06 83 - 63 | 6.83388880725e-06 83 - 64 | 5.26983264225e-06 83 - 65 | 1.5891411152e-06 83 - 66 | 1.21370940083e-06 83 - 67 | 2.18206169782e-06 83 - 68 | 2.45896680444e-06 83 - 69 | 1.67597332644e-06 83 - 70 | 3.67156112782e-07 83 - 71 | 0.0 83 - 72 | -2.0360838175e-07 83 - 73 | -1.01847724426e-06 83 - 74 | -2.90094588939e-06 83 - 75 | -4.68307860076e-06 83 - 76 | -3.79161446182e-06 83 - 77 | 2.844933536e-06 83 - 78 | 2.22436691491e-06 83 - 79 | 2.75656970794e-06 83 - 80 | 3.18317178819e-06 83 - 81 | 2.40850685825e-06 83 - 82 | 1.15625578536e-06 83 - 83 | 1.27047675652e-08 83 - 84 | 1.75498194395e-06 83 - 85 | 5.23087799626e-07 83 - 86 | 1.72691876617e-06 83 - 87 | 1.94473702701e-07 83 - 88 | 2.42985384714e-07 83 - 89 | 2.36134808214e-06 83 - 90 | 1.65470036039e-06 83 - 91 | 1.92351347909e-06 83 - 92 | 2.65734139959e-06 83 - 93 | 3.21446142587e-06 83 - 94 | 3.53821159875e-06 83 - 95 | 2.15735747227e-07 84 - 0 | 0.00229149359019 84 - 1 | 0.0030850025486 84 - 2 | 0.00225565245924 84 - 3 | 0.000863059894371 84 - 4 | 0.000565403371192 84 - 5 | 0.000204476650376 84 - 6 | 5.318355987e-05 84 - 7 | 1.98300169732e-05 84 - 8 | 0.0 84 - 9 | 0.0 84 - 10 | 0.0 84 - 11 | 0.0 84 - 12 | 0.00182808096654 84 - 13 | 0.00237824954516 84 - 14 | 0.00273757625198 84 - 15 | 0.00146355093023 84 - 16 | 0.000695460851309 84 - 17 | 0.000437981784059 84 - 18 | 0.000262161218164 84 - 19 | 0.000110580685534 84 - 20 | 3.20642187595e-05 84 - 21 | 0.0 84 - 22 | 0.0 84 - 23 | 0.0 84 - 24 | 0.00186741783405 84 - 25 | 0.00270325082135 84 - 26 | 0.00313499064516 84 - 27 | 0.00211502538038 84 - 28 | 0.00110833014491 84 - 29 | 0.000690464046554 84 - 30 | 0.000573289869797 84 - 31 | 0.000314285388898 84 - 32 | 2.34648556168e-05 84 - 33 | -6.93547785704e-07 84 - 34 | 0.0 84 - 35 | 0.0 84 - 36 | 0.00155037641603 84 - 37 | 0.00208311591441 84 - 38 | 0.00306759497376 84 - 39 | 0.00187740354299 84 - 40 | 0.00136100384651 84 - 41 | 0.000993445639154 84 - 42 | 0.000838008249892 84 - 43 | 0.000716585299354 84 - 44 | 0.000302805971576 84 - 45 | 3.81628566171e-05 84 - 46 | 0.0 84 - 47 | 0.0 84 - 48 | 0.00156525449067 84 - 49 | 0.00218414471405 84 - 50 | 0.00288020090249 84 - 51 | 0.00232562516546 84 - 52 | 0.00184577312017 84 - 53 | 0.00120727804121 84 - 54 | 0.00118207840804 84 - 55 | 0.00385012599935 84 - 56 | 0.000624461100099 84 - 57 | 0.000233030707166 84 - 58 | 1.32675750164e-05 84 - 59 | 0.0 84 - 60 | 0.00170643293054 84 - 61 | 0.00242743396348 84 - 62 | 0.00379353324342 84 - 63 | 0.00363734106339 84 - 64 | 0.0026609257339 84 - 65 | 0.00143625808776 84 - 66 | 0.00122404087308 84 - 67 | 0.00121371050085 84 - 68 | 0.00101137055311 84 - 69 | 0.000489644746527 84 - 70 | 8.24068080452e-05 84 - 71 | 0.0 84 - 72 | 0.00169785025473 84 - 73 | 0.00124222419999 84 - 74 | 0.000797857214882 84 - 75 | 0.000402130294557 84 - 76 | 0.000135641548062 84 - 77 | 0.00188765572699 84 - 78 | 0.00142304508323 84 - 79 | 0.00133826290998 84 - 80 | 0.00124192477627 84 - 81 | 0.000786509761147 84 - 82 | 0.00030110001104 84 - 83 | 1.75498194395e-06 84 - 84 | 0.00265388494501 84 - 85 | 0.0013503676251 84 - 86 | 0.00159254968893 84 - 87 | 0.00133638204761 84 - 88 | 0.000702091728817 84 - 89 | 0.00139218217535 84 - 90 | 0.00113469610763 84 - 91 | 0.000991880077418 84 - 92 | 0.000948254707334 84 - 93 | 0.00100143435978 84 - 94 | 0.00110388322809 84 - 95 | 6.93986850936e-05 85 - 0 | 0.00481620895723 85 - 1 | 0.00612857737993 85 - 2 | 0.00392170889588 85 - 3 | 0.00100607580953 85 - 4 | 1.43071257275e-05 85 - 5 | 4.65672016148e-05 85 - 6 | -5.26235267137e-05 85 - 7 | -1.5980348131e-05 85 - 8 | 0.0 85 - 9 | 0.0 85 - 10 | 0.0 85 - 11 | 0.0 85 - 12 | 0.00382907425086 85 - 13 | 0.00588916360739 85 - 14 | 0.00353325445569 85 - 15 | 0.000854561638168 85 - 16 | 0.00121277162448 85 - 17 | 0.000211379757869 85 - 18 | 7.88450726967e-06 85 - 19 | 5.05537189692e-05 85 - 20 | -1.43980051954e-05 85 - 21 | 0.0 85 - 22 | 0.0 85 - 23 | 0.0 85 - 24 | 0.00424264303091 85 - 25 | 0.00599294118269 85 - 26 | 0.00388745069427 85 - 27 | 0.00137255433566 85 - 28 | 0.00139319956358 85 - 29 | 0.00102451072911 85 - 30 | 0.000219285836917 85 - 31 | 0.000113316734522 85 - 32 | -0.000637116842714 85 - 33 | -0.000100189384624 85 - 34 | 0.0 85 - 35 | 0.0 85 - 36 | 0.0047566824517 85 - 37 | 0.00648585747289 85 - 38 | 0.00435856332008 85 - 39 | 0.00405305356061 85 - 40 | 0.00173343459276 85 - 41 | 0.00134716167815 85 - 42 | 0.000741509306869 85 - 43 | 0.00029963294886 85 - 44 | -0.00028678700416 85 - 45 | -0.00049412275492 85 - 46 | 0.0 85 - 47 | 0.0 85 - 48 | 0.00454000202874 85 - 49 | 0.00419781598097 85 - 50 | 0.0043764939403 85 - 51 | 0.00305317994636 85 - 52 | 0.00223681511455 85 - 53 | 0.00319787646152 85 - 54 | 0.000636146903544 85 - 55 | 0.0134964952211 85 - 56 | 0.000293537268032 85 - 57 | -7.78773980159e-05 85 - 58 | 2.47010216988e-07 85 - 59 | 0.0 85 - 60 | 0.00416985982068 85 - 61 | 0.00212696550922 85 - 62 | 0.000561683374476 85 - 63 | -0.000929284438909 85 - 64 | -0.000780506617123 85 - 65 | 0.00248584915971 85 - 66 | 0.00283787438472 85 - 67 | 0.000941895203773 85 - 68 | 0.000462643593258 85 - 69 | -0.000139107776366 85 - 70 | -2.48204798738e-05 85 - 71 | 0.0 85 - 72 | 0.00349864887802 85 - 73 | 0.00696216655176 85 - 74 | 0.00900481828519 85 - 75 | 0.00969687251288 85 - 76 | 0.00844969623569 85 - 77 | 0.00150488401248 85 - 78 | 0.00191211014751 85 - 79 | 0.00158418743546 85 - 80 | 0.000645432226946 85 - 81 | 0.000442091929595 85 - 82 | 6.98996166943e-05 85 - 83 | 5.23087799626e-07 85 - 84 | 0.0013503676251 85 - 85 | 0.00466164430598 85 - 86 | 0.00347439688538 85 - 87 | 0.00382537661359 85 - 88 | 0.00264988053091 85 - 89 | 0.000690050012279 85 - 90 | 0.00158398335296 85 - 91 | 0.00180007284793 85 - 92 | 0.00114136022863 85 - 93 | 0.000567742346902 85 - 94 | 4.06087835724e-05 85 - 95 | -1.52063722868e-05 86 - 0 | 0.00473625865517 86 - 1 | 0.00601995008058 86 - 2 | 0.00392191373561 86 - 3 | 0.00120711818272 86 - 4 | 0.000284634008729 86 - 5 | 0.000154200077751 86 - 6 | 8.56562044085e-06 86 - 7 | 1.91110975354e-06 86 - 8 | 0.0 86 - 9 | 0.0 86 - 10 | 0.0 86 - 11 | 0.0 86 - 12 | 0.00377818077254 86 - 13 | 0.00556987585579 86 - 14 | 0.00375891588839 86 - 15 | 0.00124364125129 86 - 16 | 0.00129029355397 86 - 17 | 0.000428015846882 86 - 18 | 0.000158470331452 86 - 19 | 0.0001160567703 86 - 20 | 1.40870933455e-05 86 - 21 | 0.0 86 - 22 | 0.0 86 - 23 | 0.0 86 - 24 | 0.0041739835671 86 - 25 | 0.00571920787824 86 - 26 | 0.00401202302071 86 - 27 | 0.00168500215025 86 - 28 | 0.00156618271153 86 - 29 | 0.00111582089007 86 - 30 | 0.000467994612776 86 - 31 | 0.00026932175237 86 - 32 | -0.000495006207797 86 - 33 | -8.09397403979e-05 86 - 34 | 0.0 86 - 35 | 0.0 86 - 36 | 0.0044359620233 86 - 37 | 0.00604236320093 86 - 38 | 0.00472853885754 86 - 39 | 0.00382750680341 86 - 40 | 0.00188571065938 86 - 41 | 0.00150057586419 86 - 42 | 0.000958574078294 86 - 43 | 0.000580057089819 86 - 44 | -7.75766601118e-05 86 - 45 | -0.00040884156645 86 - 46 | 0.0 86 - 47 | 0.0 86 - 48 | 0.00415348546791 86 - 49 | 0.0041772803798 86 - 50 | 0.00453398826449 86 - 51 | 0.00314638031445 86 - 52 | 0.00231042627079 86 - 53 | 0.00308004404624 86 - 54 | 0.00103164693417 86 - 55 | 0.0125579004817 86 - 56 | 0.000530677276973 86 - 57 | 5.14418517417e-05 86 - 58 | 1.32535453625e-05 86 - 59 | 0.0 86 - 60 | 0.00387558657611 86 - 61 | 0.00242723675889 86 - 62 | 0.00150451454536 86 - 63 | 2.35087558817e-05 86 - 64 | -9.3812511713e-05 86 - 65 | 0.00253140472204 86 - 66 | 0.00266929217476 86 - 67 | 0.00123733197854 86 - 68 | 0.000856490037463 86 - 69 | 0.000151733942884 86 - 70 | 3.03636819369e-05 86 - 71 | 0.0 86 - 72 | 0.00331718304516 86 - 73 | 0.00613660149341 86 - 74 | 0.00854756829251 86 - 75 | 0.00855128546781 86 - 76 | 0.0072315213723 86 - 77 | 0.0016043457359 86 - 78 | 0.0020595625067 86 - 79 | 0.00175880872097 86 - 80 | 0.00107228235071 86 - 81 | 0.000763146728206 86 - 82 | 0.000212911540168 86 - 83 | 1.72691876617e-06 86 - 84 | 0.00159254968893 86 - 85 | 0.00347439688538 86 - 86 | 0.00530714543756 86 - 87 | 0.00408741716804 86 - 88 | 0.00271080520039 86 - 89 | 0.000990211418649 86 - 90 | 0.00172367767987 86 - 91 | 0.00190689455255 86 - 92 | 0.0015107006842 86 - 93 | 0.00107678199482 86 - 94 | 0.000589615762782 86 - 95 | 2.01089179579e-05 87 - 0 | 0.006340450537 87 - 1 | 0.00723738364666 87 - 2 | 0.00523790953475 87 - 3 | 0.00124032600841 87 - 4 | -1.50388179219e-05 87 - 5 | 7.30548558005e-05 87 - 6 | -6.59927900925e-05 87 - 7 | -2.86507010327e-05 87 - 8 | 0.0 87 - 9 | 0.0 87 - 10 | 0.0 87 - 11 | 0.0 87 - 12 | 0.00491378017153 87 - 13 | 0.00661225539675 87 - 14 | 0.00436477753721 87 - 15 | 0.000971873789125 87 - 16 | 0.00153099793592 87 - 17 | 0.000261547816219 87 - 18 | -5.22247884546e-06 87 - 19 | 7.30396151324e-05 87 - 20 | -2.51672187618e-05 87 - 21 | 0.0 87 - 22 | 0.0 87 - 23 | 0.0 87 - 24 | 0.00548545479525 87 - 25 | 0.00668410753825 87 - 26 | 0.00456006139707 87 - 27 | 0.00130287870412 87 - 28 | 0.0016577514821 87 - 29 | 0.00133660263441 87 - 30 | 0.000204639912467 87 - 31 | 0.000137419417974 87 - 32 | -0.000838779205982 87 - 33 | -0.000127059269758 87 - 34 | 0.0 87 - 35 | 0.0 87 - 36 | 0.006323447098 87 - 37 | 0.00750333201935 87 - 38 | 0.00542023463474 87 - 39 | 0.00510518796563 87 - 40 | 0.00210595392103 87 - 41 | 0.00169020583847 87 - 42 | 0.000806972868292 87 - 43 | 0.000381343633703 87 - 44 | -0.000385545532223 87 - 45 | -0.000671867108283 87 - 46 | 0.0 87 - 47 | 0.0 87 - 48 | 0.00593993953069 87 - 49 | 0.00441881640039 87 - 50 | 0.00500416398825 87 - 51 | 0.00345182370005 87 - 52 | 0.00253828832723 87 - 53 | 0.00398226482258 87 - 54 | 0.000758942524178 87 - 55 | 0.0172645482177 87 - 56 | 0.00039449145764 87 - 57 | -0.000111395032687 87 - 58 | -2.8586964508e-06 87 - 59 | 0.0 87 - 60 | 0.00543629563815 87 - 61 | 0.00157376561136 87 - 62 | -0.000874099225694 87 - 63 | -0.0028470409574 87 - 64 | -0.0022309825147 87 - 65 | 0.00299514554491 87 - 66 | 0.0034676322207 87 - 67 | 0.00110451030622 87 - 68 | 0.000548161214367 87 - 69 | -0.00020176599345 87 - 70 | -4.1145186925e-05 87 - 71 | 0.0 87 - 72 | 0.0045141311168 87 - 73 | 0.00824149596629 87 - 74 | 0.0122995670969 87 - 75 | 0.0141782452236 87 - 76 | 0.0116354255117 87 - 77 | 0.00110889606704 87 - 78 | 0.00221210550952 87 - 79 | 0.00164713538765 87 - 80 | 0.000726397934778 87 - 81 | 0.000645414879648 87 - 82 | 0.000150457229668 87 - 83 | 1.94473702701e-07 87 - 84 | 0.00133638204761 87 - 85 | 0.00382537661359 87 - 86 | 0.00408741716804 87 - 87 | 0.00651390815241 87 - 88 | 0.00392297535579 87 - 89 | 0.000407038299956 87 - 90 | 0.00172149496332 87 - 91 | 0.00202186147061 87 - 92 | 0.00127056664446 87 - 93 | 0.000718904353003 87 - 94 | 0.000365864037683 87 - 95 | -2.488585058e-06 88 - 0 | 0.00447960875436 88 - 1 | 0.00515742562265 88 - 2 | 0.00362181112298 88 - 3 | 0.000943896580766 88 - 4 | -2.57015360191e-06 88 - 5 | 0.000103389716695 88 - 6 | 1.20847867903e-05 88 - 7 | -1.97616394945e-05 88 - 8 | 0.0 88 - 9 | 0.0 88 - 10 | 0.0 88 - 11 | 0.0 88 - 12 | 0.0035295522578 88 - 13 | 0.00474861922987 88 - 14 | 0.00306126325257 88 - 15 | 0.000769119500356 88 - 16 | 0.00118168873857 88 - 17 | 0.0002646666016 88 - 18 | 1.37374421694e-05 88 - 19 | 5.99261380982e-05 88 - 20 | -2.54958755208e-05 88 - 21 | 0.0 88 - 22 | 0.0 88 - 23 | 0.0 88 - 24 | 0.00391019543057 88 - 25 | 0.00469749088513 88 - 26 | 0.00290241720095 88 - 27 | 0.000678996195219 88 - 28 | 0.00123320805488 88 - 29 | 0.000985542481251 88 - 30 | 0.000187526079493 88 - 31 | 0.000113010155223 88 - 32 | -0.000529996833275 88 - 33 | -7.88366513816e-05 88 - 34 | 0.0 88 - 35 | 0.0 88 - 36 | 0.0043653168445 88 - 37 | 0.00552772674272 88 - 38 | 0.00422440576738 88 - 39 | 0.00386228986029 88 - 40 | 0.00146183733889 88 - 41 | 0.00142522919834 88 - 42 | 0.000694207948451 88 - 43 | 0.000320493845016 88 - 44 | -0.000210267565886 88 - 45 | -0.000428807204756 88 - 46 | 0.0 88 - 47 | 0.0 88 - 48 | 0.00386887541147 88 - 49 | 0.00316682210261 88 - 50 | 0.00348999262289 88 - 51 | 0.00223080676966 88 - 52 | 0.0014695481714 88 - 53 | 0.00301874488316 88 - 54 | 0.000826119729231 88 - 55 | 0.00702022233212 88 - 56 | 0.000282593664144 88 - 57 | -7.32822142575e-05 88 - 58 | -2.9797857025e-06 88 - 59 | 0.0 88 - 60 | 0.00364753098913 88 - 61 | 0.000688220940308 88 - 62 | -0.00196270734373 88 - 63 | -0.00365957388022 88 - 64 | -0.00267554987546 88 - 65 | 0.0022339682502 88 - 66 | 0.00242138043398 88 - 67 | 0.000757172756667 88 - 68 | 0.000465270028719 88 - 69 | -0.000103296474937 88 - 70 | -2.08138186349e-05 88 - 71 | 0.0 88 - 72 | 0.00306116023132 88 - 73 | 0.00659139841017 88 - 74 | 0.0102147193549 88 - 75 | 0.0116681183181 88 - 76 | 0.00994868076869 88 - 77 | 0.000369960683209 88 - 78 | 0.00158834500666 88 - 79 | 0.0012071940221 88 - 80 | 0.000566211758855 88 - 81 | 0.000470301876154 88 - 82 | 0.000103428111814 88 - 83 | 2.42985384714e-07 88 - 84 | 0.000702091728817 88 - 85 | 0.00264988053091 88 - 86 | 0.00271080520039 88 - 87 | 0.00392297535579 88 - 88 | 0.00433980201904 88 - 89 | 0.000333998701578 88 - 90 | 0.0012851264202 88 - 91 | 0.00144171521242 88 - 92 | 0.000986406176529 88 - 93 | 0.000609756138317 88 - 94 | 0.000345270204795 88 - 95 | -7.77351387876e-07 89 - 0 | 0.000906874287803 89 - 1 | 0.00203672925602 89 - 2 | 0.00120977448322 89 - 3 | 0.000706469933582 89 - 4 | 0.000563578772703 89 - 5 | 0.000257229679212 89 - 6 | 0.000150554797854 89 - 7 | 4.04630644302e-05 89 - 8 | 0.0 89 - 9 | 0.0 89 - 10 | 0.0 89 - 11 | 0.0 89 - 12 | 0.000895026295766 89 - 13 | 0.00126859444928 89 - 14 | 0.00209407270783 89 - 15 | 0.00170173650989 89 - 16 | 0.000341391218293 89 - 17 | 0.000493147438129 89 - 18 | 0.000311852553481 89 - 19 | 0.000125523068849 89 - 20 | 4.71610461667e-05 89 - 21 | 0.0 89 - 22 | 0.0 89 - 23 | 0.0 89 - 24 | 0.000801479969185 89 - 25 | 0.00168895146958 89 - 26 | 0.00291222420622 89 - 27 | 0.00267780535844 89 - 28 | 0.000912198147294 89 - 29 | 0.000385590407844 89 - 30 | 0.000653357894256 89 - 31 | 0.000372825844427 89 - 32 | 0.000339623731327 89 - 33 | 4.17341213253e-05 89 - 34 | 0.0 89 - 35 | 0.0 89 - 36 | 0.000164325702809 89 - 37 | 0.000390457627465 89 - 38 | 0.00161324712063 89 - 39 | 0.000801538762 89 - 40 | 0.00119058595896 89 - 41 | 0.000768761519323 89 - 42 | 0.00084934202201 89 - 43 | 0.000754791768003 89 - 44 | 0.000501940182567 89 - 45 | 0.000186818354332 89 - 46 | 0.0 89 - 47 | 0.0 89 - 48 | 0.000298708594685 89 - 49 | 0.00209408931648 89 - 50 | 0.00257687850064 89 - 51 | 0.00245485571918 89 - 52 | 0.00200079085404 89 - 53 | 0.000248514044695 89 - 54 | 0.00124668415306 89 - 55 | -0.00640866791546 89 - 56 | 0.000584849206474 89 - 57 | 0.000279324138048 89 - 58 | 1.91772362702e-05 89 - 59 | 0.0 89 - 60 | 0.00078870401906 89 - 61 | 0.00328698040997 89 - 62 | 0.00687541587309 89 - 63 | 0.00737714858241 89 - 64 | 0.00541208330441 89 - 65 | 0.00105292097719 89 - 66 | 0.000556312290323 89 - 67 | 0.00113510191546 89 - 68 | 0.00105425878655 89 - 69 | 0.000624448932057 89 - 70 | 0.000106720041846 89 - 71 | 0.0 89 - 72 | 0.000553804803988 89 - 73 | -0.00132552173796 89 - 74 | -0.00393285657545 89 - 75 | -0.00504269532857 89 - 76 | -0.00424458335019 89 - 77 | 0.00284380494998 89 - 78 | 0.00144502601826 89 - 79 | 0.0013543241749 89 - 80 | 0.00129589423203 89 - 81 | 0.000790684856785 89 - 82 | 0.000331845414732 89 - 83 | 2.36134808214e-06 89 - 84 | 0.00139218217535 89 - 85 | 0.000690050012279 89 - 86 | 0.000990211418649 89 - 87 | 0.000407038299956 89 - 88 | 0.000333998701578 89 - 89 | 0.00286742252349 89 - 90 | 0.00145627037084 89 - 91 | 0.000924206879197 89 - 92 | 0.00108557839059 89 - 93 | 0.00105247872342 89 - 94 | 0.00122335890534 89 - 95 | 7.62483772376e-05 90 - 0 | 0.00230199524518 90 - 1 | 0.00321652691664 90 - 2 | 0.00212668159646 90 - 3 | 0.000773755756163 90 - 4 | 0.000297770109144 90 - 5 | 0.000133880645795 90 - 6 | 4.87922470406e-05 90 - 7 | 1.23884958941e-05 90 - 8 | 0.0 90 - 9 | 0.0 90 - 10 | 0.0 90 - 11 | 0.0 90 - 12 | 0.00192917468639 90 - 13 | 0.00281213761845 90 - 14 | 0.00236924922463 90 - 15 | 0.00114216252521 90 - 16 | 0.000682595428772 90 - 17 | 0.000333912779089 90 - 18 | 0.000138656988571 90 - 19 | 7.94130473013e-05 90 - 20 | 1.91389252777e-05 90 - 21 | 0.0 90 - 22 | 0.0 90 - 23 | 0.0 90 - 24 | 0.00206899683556 90 - 25 | 0.00300495683681 90 - 26 | 0.00275828026208 90 - 27 | 0.00168891327966 90 - 28 | 0.00100183057441 90 - 29 | 0.000658110775842 90 - 30 | 0.000405189186024 90 - 31 | 0.000223426726393 90 - 32 | -7.47101510213e-05 90 - 33 | -1.56305786449e-05 90 - 34 | 0.0 90 - 35 | 0.0 90 - 36 | 0.00198152853013 90 - 37 | 0.00270214346627 90 - 38 | 0.0026122856627 90 - 39 | 0.00207619222986 90 - 40 | 0.00127224339794 90 - 41 | 0.00101095493968 90 - 42 | 0.000768844395631 90 - 43 | 0.000467887378755 90 - 44 | 0.000140287030672 90 - 45 | -0.000103960809337 90 - 46 | 0.0 90 - 47 | 0.0 90 - 48 | 0.00189500973967 90 - 49 | 0.00247404063373 90 - 50 | 0.00283783316799 90 - 51 | 0.0022739312612 90 - 52 | 0.00172375099838 90 - 53 | 0.00152388361718 90 - 54 | 0.000982153008946 90 - 55 | 0.00213734773968 90 - 56 | 0.000408601200677 90 - 57 | 0.000124782018724 90 - 58 | 1.26930589581e-05 90 - 59 | 0.0 90 - 60 | 0.00196699524177 90 - 61 | 0.00212836512837 90 - 62 | 0.00288001110313 90 - 63 | 0.0024726917542 90 - 64 | 0.00180793832866 90 - 65 | 0.00153831612333 90 - 66 | 0.0015547313461 90 - 67 | 0.000947360525271 90 - 68 | 0.000680021685053 90 - 69 | 0.000269467672118 90 - 70 | 5.71678554134e-05 90 - 71 | 0.0 90 - 72 | 0.0016293211689 90 - 73 | 0.00220695533806 90 - 74 | 0.00224849645584 90 - 75 | 0.00214149162062 90 - 76 | 0.00187365492116 90 - 77 | 0.00179213456218 90 - 78 | 0.00161535602795 90 - 79 | 0.00141782477416 90 - 80 | 0.000923051648972 90 - 81 | 0.000570338695268 90 - 82 | 0.000232532843623 90 - 83 | 1.65470036039e-06 90 - 84 | 0.00113469610763 90 - 85 | 0.00158398335296 90 - 86 | 0.00172367767987 90 - 87 | 0.00172149496332 90 - 88 | 0.0012851264202 90 - 89 | 0.00145627037084 90 - 90 | 0.00169366601558 90 - 91 | 0.00146613995431 90 - 92 | 0.00102347931509 90 - 93 | 0.00071127327106 90 - 94 | 0.000700904318335 90 - 95 | 3.48611441228e-05 91 - 0 | 0.00254598026848 91 - 1 | 0.00343058166403 91 - 2 | 0.00228214810817 91 - 3 | 0.000817446352964 91 - 4 | 0.000226650311371 91 - 5 | 9.09902446366e-05 91 - 6 | 1.83575947219e-05 91 - 7 | 7.85667780722e-06 91 - 8 | 0.0 91 - 9 | 0.0 91 - 10 | 0.0 91 - 11 | 0.0 91 - 12 | 0.00210458821759 91 - 13 | 0.00325402630619 91 - 14 | 0.00231578421108 91 - 15 | 0.000919177964981 91 - 16 | 0.000776493963073 91 - 17 | 0.000304624593477 91 - 18 | 8.9954803605e-05 91 - 19 | 7.24978995631e-05 91 - 20 | 1.56237009275e-05 91 - 21 | 0.0 91 - 22 | 0.0 91 - 23 | 0.0 91 - 24 | 0.00229698066262 91 - 25 | 0.00328006657358 91 - 26 | 0.00253242433844 91 - 27 | 0.00131254238258 91 - 28 | 0.00101620731331 91 - 29 | 0.000738565197947 91 - 30 | 0.000360810616355 91 - 31 | 0.000199064051663 91 - 32 | -0.00018578268629 91 - 33 | -3.16622437516e-05 91 - 34 | 0.0 91 - 35 | 0.0 91 - 36 | 0.00235951432142 91 - 37 | 0.00333895167049 91 - 38 | 0.00274136770307 91 - 39 | 0.00232370765648 91 - 40 | 0.00127744319426 91 - 41 | 0.00104542168909 91 - 42 | 0.000781397475941 91 - 43 | 0.000401012248404 91 - 44 | 5.90072614572e-05 91 - 45 | -0.000199530251545 91 - 46 | 0.0 91 - 47 | 0.0 91 - 48 | 0.00218736670617 91 - 49 | 0.00254885214633 91 - 50 | 0.00274308966498 91 - 51 | 0.00210464484668 91 - 52 | 0.00156491176814 91 - 53 | 0.0019120972783 91 - 54 | 0.000953252603925 91 - 55 | 0.00482530078534 91 - 56 | 0.000395141642494 91 - 57 | 0.000110383544327 91 - 58 | 1.54025557393e-05 91 - 59 | 0.0 91 - 60 | 0.00208210748403 91 - 61 | 0.00178180525499 91 - 62 | 0.00163931811828 91 - 63 | 0.000998396911584 91 - 64 | 0.000763033649515 91 - 65 | 0.00167001136749 91 - 66 | 0.00186680550049 91 - 67 | 0.000893521478249 91 - 68 | 0.000622625559897 91 - 69 | 0.000222148395448 91 - 70 | 6.39271131927e-05 91 - 71 | 0.0 91 - 72 | 0.00180151048192 91 - 73 | 0.00322283228356 91 - 74 | 0.00395430462266 91 - 75 | 0.00405267212056 91 - 76 | 0.00359014977811 91 - 77 | 0.00145817505759 91 - 78 | 0.00162761277983 91 - 79 | 0.00154630141345 91 - 80 | 0.000929736120878 91 - 81 | 0.000583802102687 91 - 82 | 0.000258354367377 91 - 83 | 1.92351347909e-06 91 - 84 | 0.000991880077418 91 - 85 | 0.00180007284793 91 - 86 | 0.00190689455255 91 - 87 | 0.00202186147061 91 - 88 | 0.00144171521242 91 - 89 | 0.000924206879197 91 - 90 | 0.00146613995431 91 - 91 | 0.0018912373623 91 - 92 | 0.00118528019888 91 - 93 | 0.000728665480497 91 - 94 | 0.000675980928462 91 - 95 | 2.84236057841e-05 92 - 0 | 0.00172735378144 92 - 1 | 0.00265928243105 92 - 2 | 0.00183276394893 92 - 3 | 0.00082894342513 92 - 4 | 0.000422975814312 92 - 5 | 0.000194423582576 92 - 6 | 0.000101225251295 92 - 7 | 3.60963477671e-05 92 - 8 | 0.0 92 - 9 | 0.0 92 - 10 | 0.0 92 - 11 | 0.0 92 - 12 | 0.00143325653292 92 - 13 | 0.00227960773679 92 - 14 | 0.00209437098026 92 - 15 | 0.00114713495716 92 - 16 | 0.000609938712503 92 - 17 | 0.00046343161874 92 - 18 | 0.000268952010863 92 - 19 | 0.000141128674853 92 - 20 | 4.07713416332e-05 92 - 21 | 0.0 92 - 22 | 0.0 92 - 23 | 0.0 92 - 24 | 0.00143258194655 92 - 25 | 0.00223103317178 92 - 26 | 0.00219632869514 92 - 27 | 0.00149644983631 92 - 28 | 0.000947599204277 92 - 29 | 0.000615723664124 92 - 30 | 0.000601341935868 92 - 31 | 0.000374808850978 92 - 32 | 6.45877652854e-05 92 - 33 | 1.99952353142e-06 92 - 34 | 0.0 92 - 35 | 0.0 92 - 36 | 0.0012706479882 92 - 37 | 0.00206073150304 92 - 38 | 0.00237754730584 92 - 39 | 0.00159720319167 92 - 40 | 0.00113049630665 92 - 41 | 0.000863604367057 92 - 42 | 0.000798424882557 92 - 43 | 0.000705463180465 92 - 44 | 0.000320367893727 92 - 45 | -5.59216150489e-05 92 - 46 | 0.0 92 - 47 | 0.0 92 - 48 | 0.00109221137644 92 - 49 | 0.00200533744508 92 - 50 | 0.00217654584111 92 - 51 | 0.00175475577818 92 - 52 | 0.00130450379217 92 - 53 | 0.00119373125294 92 - 54 | 0.000998605661241 92 - 55 | 0.00116171868728 92 - 56 | 0.000618441387253 92 - 57 | 0.000233178703388 92 - 58 | 2.66166500743e-05 92 - 59 | 0.0 92 - 60 | 0.00113121488664 92 - 61 | 0.00183208194213 92 - 62 | 0.00244044478898 92 - 63 | 0.00212139802718 92 - 64 | 0.00161647897628 92 - 65 | 0.00122301901006 92 - 66 | 0.0010546637585 92 - 67 | 0.00108822194291 92 - 68 | 0.00103221086394 92 - 69 | 0.000512216769971 92 - 70 | 9.89229262796e-05 92 - 71 | 0.0 92 - 72 | 0.00106102659703 92 - 73 | 0.00158857004813 92 - 74 | 0.00167506462568 92 - 75 | 0.00133676282235 92 - 76 | 0.00114541471285 92 - 77 | 0.0013714991528 92 - 78 | 0.00122755428667 92 - 79 | 0.00140917638492 92 - 80 | 0.0014438099182 92 - 81 | 0.00097360909815 92 - 82 | 0.000346391840682 92 - 83 | 2.65734139959e-06 92 - 84 | 0.000948254707334 92 - 85 | 0.00114136022863 92 - 86 | 0.0015107006842 92 - 87 | 0.00127056664446 92 - 88 | 0.000986406176529 92 - 89 | 0.00108557839059 92 - 90 | 0.00102347931509 92 - 91 | 0.00118528019888 92 - 92 | 0.00162360841 92 - 93 | 0.00145258716639 92 - 94 | 0.00125639065257 92 - 95 | 6.94114570798e-05 93 - 0 | 0.00125301107251 93 - 1 | 0.00203462625572 93 - 2 | 0.00162944691279 93 - 3 | 0.000840404153384 93 - 4 | 0.000556359168046 93 - 5 | 0.000253656072122 93 - 6 | 0.000135693731911 93 - 7 | 4.9725636217e-05 93 - 8 | 0.0 93 - 9 | 0.0 93 - 10 | 0.0 93 - 11 | 0.0 93 - 12 | 0.000998206255637 93 - 13 | 0.00145762081629 93 - 14 | 0.00200695946297 93 - 15 | 0.0012920445037 93 - 16 | 0.000529318406691 93 - 17 | 0.000541785124794 93 - 18 | 0.000366127891345 93 - 19 | 0.000177015282715 93 - 20 | 4.77818388183e-05 93 - 21 | 0.0 93 - 22 | 0.0 93 - 23 | 0.0 93 - 24 | 0.000883526579267 93 - 25 | 0.00138503696596 93 - 26 | 0.00201362120629 93 - 27 | 0.00158165513924 93 - 28 | 0.000869129294622 93 - 29 | 0.000554233737807 93 - 30 | 0.000693877978744 93 - 31 | 0.000437865997598 93 - 32 | 0.0001555350427 93 - 33 | 1.58422154463e-05 93 - 34 | 0.0 93 - 35 | 0.0 93 - 36 | 0.000598572627125 93 - 37 | 0.00109323262099 93 - 38 | 0.00214097129875 93 - 39 | 0.00114725810081 93 - 40 | 0.00103480172227 93 - 41 | 0.000749514181074 93 - 42 | 0.000794164399874 93 - 43 | 0.000878361296735 93 - 44 | 0.000472395429721 93 - 45 | 2.01928692972e-05 93 - 46 | 0.0 93 - 47 | 0.0 93 - 48 | 0.000443347835033 93 - 49 | 0.00136825614883 93 - 50 | 0.00172104185797 93 - 51 | 0.00146780644326 93 - 52 | 0.00113135249663 93 - 53 | 0.000788104408505 93 - 54 | 0.00108978352022 93 - 55 | -0.000850467479292 93 - 56 | 0.000801660480984 93 - 57 | 0.000331774090554 93 - 58 | 3.10531257546e-05 93 - 59 | 0.0 93 - 60 | 0.00055118518981 93 - 61 | 0.00168878454951 93 - 62 | 0.00267353801516 93 - 63 | 0.00259887921018 93 - 64 | 0.00200933380962 93 - 65 | 0.000955794453202 93 - 66 | 0.000605477429009 93 - 67 | 0.00118786984669 93 - 68 | 0.00129041281345 93 - 69 | 0.000727406052429 93 - 70 | 0.000123323489987 93 - 71 | 0.0 93 - 72 | 0.000612862833712 93 - 73 | 0.000498653324171 93 - 74 | 0.000267434469281 93 - 75 | -0.000226020786708 93 - 76 | -0.000317697831417 93 - 77 | 0.00123177567614 93 - 78 | 0.000959860207579 93 - 79 | 0.00124514853943 93 - 80 | 0.00169551408459 93 - 81 | 0.00133051535539 93 - 82 | 0.000439373555806 93 - 83 | 3.21446142587e-06 93 - 84 | 0.00100143435978 93 - 85 | 0.000567742346902 93 - 86 | 0.00107678199482 93 - 87 | 0.000718904353003 93 - 88 | 0.000609756138317 93 - 89 | 0.00105247872342 93 - 90 | 0.00071127327106 93 - 91 | 0.000728665480497 93 - 92 | 0.00145258716639 93 - 93 | 0.00205312152822 93 - 94 | 0.00176932988696 93 - 95 | 0.000105596750406 94 - 0 | 0.00104598311201 94 - 1 | 0.00152840995187 94 - 2 | 0.00162098262583 94 - 3 | 0.000850018588175 94 - 4 | 0.00065373773787 94 - 5 | 0.000259836281434 94 - 6 | 0.000134885606349 94 - 7 | 4.53272707252e-05 94 - 8 | 0.0 94 - 9 | 0.0 94 - 10 | 0.0 94 - 11 | 0.0 94 - 12 | 0.000783566757454 94 - 13 | 0.000709777532503 94 - 14 | 0.00211488788243 94 - 15 | 0.00152627568981 94 - 16 | 0.00054356606817 94 - 17 | 0.000597738487733 94 - 18 | 0.000354646350379 94 - 19 | 0.000182400427173 94 - 20 | 5.50023108642e-05 94 - 21 | 0.0 94 - 22 | 0.0 94 - 23 | 0.0 94 - 24 | 0.000567729207548 94 - 25 | 0.000688713978931 94 - 26 | 0.00217875843103 94 - 27 | 0.00185350063204 94 - 28 | 0.000908943336008 94 - 29 | 0.000615212051141 94 - 30 | 0.000704262709621 94 - 31 | 0.00044708681201 94 - 32 | 0.00027630682444 94 - 33 | 3.78507445547e-05 94 - 34 | 0.0 94 - 35 | 0.0 94 - 36 | 0.000237745688713 94 - 37 | 0.000115378271617 94 - 38 | 0.00196562054018 94 - 39 | 0.0009233460503 94 - 40 | 0.00108539539659 94 - 41 | 0.000831442890983 94 - 42 | 0.000876016503464 94 - 43 | 0.000895214620571 94 - 44 | 0.000580169074205 94 - 45 | 0.000102998841976 94 - 46 | 0.0 94 - 47 | 0.0 94 - 48 | 0.000118122186153 94 - 49 | 0.000873529426231 94 - 50 | 0.00149075546094 94 - 51 | 0.00146521144907 94 - 52 | 0.0012475885112 94 - 53 | 0.000553158525452 94 - 54 | 0.00141972179062 94 - 55 | -0.00311272327584 94 - 56 | 0.000881124870652 94 - 57 | 0.000407932083797 94 - 58 | 3.62496441724e-05 94 - 59 | 0.0 94 - 60 | 0.000339073273829 94 - 61 | 0.00157388008063 94 - 62 | 0.00322362212748 94 - 63 | 0.0034887232502 94 - 64 | 0.00269395083441 94 - 65 | 0.000939222709975 94 - 66 | 0.00066383662683 94 - 67 | 0.00125043671444 94 - 68 | 0.00133702049963 94 - 69 | 0.000842849843311 94 - 70 | 0.000170938024389 94 - 71 | 0.0 94 - 72 | 0.000400298026835 94 - 73 | -0.000761429556298 94 - 74 | -0.00128395102197 94 - 75 | -0.00159121157672 94 - 76 | -0.00174344513663 94 - 77 | 0.00133821314031 94 - 78 | 0.00116198289286 94 - 79 | 0.00126404410174 94 - 80 | 0.00176732663603 94 - 81 | 0.00137412959425 94 - 82 | 0.000661878050894 94 - 83 | 3.53821159875e-06 94 - 84 | 0.00110388322809 94 - 85 | 4.06087835724e-05 94 - 86 | 0.000589615762782 94 - 87 | 0.000365864037683 94 - 88 | 0.000345270204795 94 - 89 | 0.00122335890534 94 - 90 | 0.000700904318335 94 - 91 | 0.000675980928462 94 - 92 | 0.00125639065257 94 - 93 | 0.00176932988696 94 - 94 | 0.00255703378682 94 - 95 | 0.000148832702583 95 - 0 | 3.60236316688e-05 95 - 1 | 6.10118531234e-05 95 - 2 | 7.7193312075e-05 95 - 3 | 4.75029801892e-05 95 - 4 | 4.39538659098e-05 95 - 5 | 1.60833419184e-05 95 - 6 | 8.06396721e-06 95 - 7 | 3.24060679452e-06 95 - 8 | 0.0 95 - 9 | 0.0 95 - 10 | 0.0 95 - 11 | 0.0 95 - 12 | 2.40824546492e-05 95 - 13 | 8.00226061321e-06 95 - 14 | 0.000114160740723 95 - 15 | 9.22706509619e-05 95 - 16 | 2.53156969404e-05 95 - 17 | 3.60881149899e-05 95 - 18 | 2.310816281e-05 95 - 19 | 1.06503082887e-05 95 - 20 | 3.52111379177e-06 95 - 21 | 0.0 95 - 22 | 0.0 95 - 23 | 0.0 95 - 24 | 7.49168332211e-06 95 - 25 | 9.46763661834e-06 95 - 26 | 0.00011701564704 95 - 27 | 0.000113928782886 95 - 28 | 4.97486446007e-05 95 - 29 | 3.19750611457e-05 95 - 30 | 4.39476962669e-05 95 - 31 | 2.65819294049e-05 95 - 32 | 2.03492963186e-05 95 - 33 | 2.88367659891e-06 95 - 34 | 0.0 95 - 35 | 0.0 95 - 36 | -1.95088871282e-05 95 - 37 | -3.34816128694e-05 95 - 38 | 0.000107008386367 95 - 39 | 3.24910968683e-05 95 - 40 | 5.72253265754e-05 95 - 41 | 4.35407012771e-05 95 - 42 | 4.91817638905e-05 95 - 43 | 5.55900666221e-05 95 - 44 | 3.80667280221e-05 95 - 45 | 1.12068143166e-05 95 - 46 | 0.0 95 - 47 | 0.0 95 - 48 | -2.08572846028e-05 95 - 49 | 3.17250783299e-05 95 - 50 | 7.2409123562e-05 95 - 51 | 7.52757130931e-05 95 - 52 | 6.6851230661e-05 95 - 53 | 1.10099684471e-05 95 - 54 | 8.2126045507e-05 95 - 55 | -0.000243078458657 95 - 56 | 5.3057782944e-05 95 - 57 | 2.59247868768e-05 95 - 58 | 2.24079843343e-06 95 - 59 | 0.0 95 - 60 | -3.82050956291e-06 95 - 61 | 9.36902058897e-05 95 - 62 | 0.000214110947224 95 - 63 | 0.000240328677094 95 - 64 | 0.000184679655452 95 - 65 | 4.26977848969e-05 95 - 66 | 2.14313544983e-05 95 - 67 | 7.7160007243e-05 95 - 68 | 8.06542236069e-05 95 - 69 | 5.36014107145e-05 95 - 70 | 1.02698110922e-05 95 - 71 | 0.0 95 - 72 | 3.84341481566e-06 95 - 73 | -9.37306132021e-05 95 - 74 | -0.00014860086963 95 - 75 | -0.000180062640131 95 - 76 | -0.00017732341192 95 - 77 | 7.9135858054e-05 95 - 78 | 5.8224799959e-05 95 - 79 | 6.70456790903e-05 95 - 80 | 0.00010529013493 95 - 81 | 8.19292811922e-05 95 - 82 | 3.81995800147e-05 95 - 83 | 2.15735747227e-07 95 - 84 | 6.93986850936e-05 95 - 85 | -1.52063722868e-05 95 - 86 | 2.01089179579e-05 95 - 87 | -2.488585058e-06 95 - 88 | -7.77351387876e-07 95 - 89 | 7.62483772376e-05 95 - 90 | 3.48611441228e-05 95 - 91 | 2.84236057841e-05 95 - 92 | 6.94114570798e-05 95 - 93 | 0.000105596750406 95 - 94 | 0.000148832702583 95 - 95 | 9.53334376027e-06 diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index d199d0e..56901f3 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -1,1519 +1,1519 @@ # Doxyfile 1.6.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = "NUISANCE" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = "@NUISANCE_VERSION_STRING@" # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. -INHERIT_DOCS = YES +INHERIT_DOCS = NO # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. -TAB_SIZE = 8 +TAB_SIZE = 4 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it parses. # With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this tag. # The format is ext=language, where ext is a file extension, and language is one of # the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, # Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat # .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penality. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will rougly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. -EXTRACT_PRIVATE = YES +EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. -EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_CLASSES = NO # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = YES # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = YES # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. -SHOW_INCLUDE_FILES = YES +SHOW_INCLUDE_FILES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by # doxygen. The layout file controls the global structure of the generated output files # in an output format independent way. The create the layout file that represents # doxygen's defaults, run doxygen with the -l option. You can optionally specify a # file name after the option, if omitted DoxygenLayout.xml will be used as the name # of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @CMAKE_SOURCE_DIR@/src/ @CMAKE_SOURCE_DIR@/doc/ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 -FILE_PATTERNS = *.dox *.cxx *.h +FILE_PATTERNS = *.dox *.cxx *.h *.md # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. -EXCLUDE = ANL BEBC BNL Devel FNAL GGM K2K MCStudies MINERvA MiniBooNE T2K +EXCLUDE = src/ANL src/ArgoNeuT src/BEBC src/BNL src/Devel src/Electron src/FNAL src/GGM src/K2K src/MCStudies src/MINERvA src/MiniBooNE src/SciBooNE src/T2K # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = *ROOT_DICT* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. -SOURCE_BROWSER = YES +SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # If the HTML_TIMESTAMP tag is set to YES then the generated HTML # documentation will contain the timesstamp. HTML_TIMESTAMP = NO # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER # are set, an additional index file will be generated that can be used as input for # Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated # HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. # For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's # filter section matches. # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # When the SEARCHENGINE tag is enable doxygen will generate a search box for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP) or Qt help (GENERATE_QHP) # there is already a search function so this one should typically # be disabled. SEARCHENGINE = YES #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. -COMPACT_LATEX = NO +COMPACT_LATEX = YES # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = ./ # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES 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/parameters/dial_conversion.card b/parameters/dial_conversion.card index 64b2531..b34a7d9 100644 --- a/parameters/dial_conversion.card +++ b/parameters/dial_conversion.card @@ -1,5 +1,23 @@ # par Name Units Nominal FracErr ConvFunc -neut_parameter MaCCQE GeV 1.21*(1.0+x*0.16) +neut_parameter MaCCQE GeV 1.21*(1.0+x*0.16) niwg_parameter NIWGMEC_Norm_C12 % 100.0*(1.0+x) niwg_parameter VecFFCCQE MDLQE x -niwg_parameter CCQEFermiSurfMom MeV 217*(1.0+x*0.15) \ No newline at end of file +niwg_parameter CCQEFermiSurfMom MeV 217*(1.0+x*0.15) + + +t2k_parameter NIWG2014a_pF_C12 MeV 217*(1.0+x*0.073733) +t2k_parameter NIWG2014a_pF_O16 MeV 225*(1.0+x*0.071111) +t2k_parameter NIWGMEC_PDDWeight_C12 x 0.5*(1.0+x*1.0) +t2k_parameter NIWGMEC_PDDWeight_O16 x 0.5*(1.0+x*1.0) + +t2k_parameter NXSec_MaCCQE GeV 1.21*(1.0+x*0.165289256) + +t2k_parameter NXSec_MaNFFRES GeV 0.95*(1.0+x*0.157894737) +t2k_parameter NXSec_CA5RES x 1.01*(1.0+x*0.247524752) +t2k_parameter NXSec_BgSclCCRES x 1.30*(1.0+x*0.153846154) + +t2k_parameter NIWG_Effective_rpaCCQE_A x 1.0*(1.0 + x*0.1) +t2k_parameter NIWG_Effective_rpaCCQE_B x 1.0*(1.0 + x*0.1) +t2k_parameter NIWG_Effective_rpaCCQE_C x 1.0*(1.0 + x*0.1) +t2k_parameter NIWG_Effective_rpaCCQE_D x 1.0*(1.0 + x*0.1) +t2k_parameter NIWG_Effective_rpaCCQE_U x 1.0*(1.0 + x*0.1) 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/ANL/ANL_CC1ppip_Evt_1DcosthAdler_nu.cxx b/src/ANL/ANL_CC1ppip_Evt_1DcosthAdler_nu.cxx index 06be048..6e52217 100644 --- a/src/ANL/ANL_CC1ppip_Evt_1DcosthAdler_nu.cxx +++ b/src/ANL/ANL_CC1ppip_Evt_1DcosthAdler_nu.cxx @@ -1,135 +1,118 @@ // 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 . *******************************************************************************/ /** * Radecky et al. Phys Rev D, 3rd series, Vol 25, No 5, 1 March 1982, p 1161-1173 */ #include "ANL_CC1ppip_Evt_1DcosthAdler_nu.h" //******************************************************************** ANL_CC1ppip_Evt_1DcosthAdler_nu::ANL_CC1ppip_Evt_1DcosthAdler_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "ANL CC1ppip Event Rate 1DcosmuStar nu sample. \n" \ "Target: D2 \n" \ "Flux: \n" \ "Signal: \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("cos#theta_{Adler}"); fSettings.SetYTitle("Number of events"); fSettings.SetAllowedTypes("EVT/SHAPE/DIAG", "EVT/SHAPE/DIAG"); fSettings.SetEnuRange(0.0, 6.0); fSettings.DefineAllowedTargets("D,H"); // CCQELike plot information fSettings.SetTitle("ANL #nu_mu CC1n#pi^{+}"); fSettings.SetDataInput( FitPar::GetDataBase() + "/ANL/CC1pip_on_p/ANL_CC1pip_on_p_noEvents_costhAdler_1982.csv" ); fSettings.DefineAllowedSpecies("numu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = GetEventHistogram()->Integral("width") / (fNEvents + 0.) * 2. / 1.; // Plot Setup ------------------------------------------------------- SetDataFromTextFile( fSettings.GetDataInput() ); SetPoissonErrors(); SetCovarFromDiagonal(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void ANL_CC1ppip_Evt_1DcosthAdler_nu::FillEventVariables(FitEvent *event) { + fXVar = -999.99; + if (event->NumFSParticle(2212) == 0 || event->NumFSParticle(211) == 0 || event->NumFSParticle(13) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Pp = event->GetHMFSParticle(2212)->fP; TLorentzVector Ppip = event->GetHMFSParticle(211)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; // Get the hadronic mass double hadMass = FitUtils::MpPi(Pp, Ppip); - // Need to boost pion and muon into resonance rest-frame to get phi (e.g. see F. Sanchez arxiv 1511.00501v2) - // - // Get the resonance 4-vector - TLorentzVector Pres = Ppip + Pp; - // Boost in/outgoing particles into rest frame - Ppip.Boost(-Pres.BoostVector()); - Pmu.Boost(-Pres.BoostVector()); - Pnu.Boost(Pres.BoostVector()); - // Define the vectors - TVector3 PpipVect = Ppip.Vect(); - TVector3 PnuVect = Pnu.Vect(); - TVector3 PmuVect = Pmu.Vect(); - // Define the z-direction; should be same as Pres - TVector3 zVect = (PnuVect - PmuVect); - zVect *= 1 / double(zVect.Mag()); - - // Then finally construct phi as the angle between pion projection and x axis - double cosThAdler = -999; - // ANL has a M(pi, p) < 1.4 GeV cut imposed - if (hadMass < 1400) cosThAdler = cos(PpipVect.Angle(zVect)); + if (hadMass > 1400) return; + // Get Adler cos theta + double cosThAdler = FitUtils::CosThAdler(Pnu, Pmu, Ppip, Pp); fXVar = cosThAdler; - - return; }; bool ANL_CC1ppip_Evt_1DcosthAdler_nu::isSignal(FitEvent *event) { return SignalDef::isCC1pi3Prong(event, 14, 211, 2212, EnuMin, EnuMax); } /* void ANL_CC1ppip_Evt_1DcosthAdler_nu::FillHistograms() { if (makeHadronicMassHist) { hadMassHist->Fill(hadMass); } Measurement1D::FillHistograms(); } void ANL_CC1ppip_Evt_1DcosthAdler_nu::ScaleEvents() { PlotUtils::FluxUnfoldedScaling(fMCHist, GetFluxHistogram()); PlotUtils::FluxUnfoldedScaling(fMCFine, GetFluxHistogram()); fMCHist->Scale(fScaleFactor); fMCFine->Scale(fScaleFactor); return; } */ diff --git a/src/ANL/ANL_CC1ppip_Evt_1Dphi_nu.cxx b/src/ANL/ANL_CC1ppip_Evt_1Dphi_nu.cxx index 1a41fb5..c4a27c7 100644 --- a/src/ANL/ANL_CC1ppip_Evt_1Dphi_nu.cxx +++ b/src/ANL/ANL_CC1ppip_Evt_1Dphi_nu.cxx @@ -1,164 +1,117 @@ // 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 . *******************************************************************************/ /** * Radecky et al. Phys Rev D, 3rd series, Vol 25, No 5, 1 March 1982, p 1161-1173 */ #include "ANL_CC1ppip_Evt_1Dphi_nu.h" //******************************************************************** ANL_CC1ppip_Evt_1Dphi_nu::ANL_CC1ppip_Evt_1Dphi_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "ANL CC1npip Event Rate 1DcosmuStar nu sample. \n" \ "Target: D2 \n" \ "Flux: \n" \ "Signal: \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle(" #phi_{Adler}"); fSettings.SetYTitle("Number of events"); fSettings.SetAllowedTypes("EVT/SHAPE/DIAG", "EVT/SHAPE/DIAG"); fSettings.SetEnuRange(0.0, 6.0); fSettings.DefineAllowedTargets("D,H"); // CCQELike plot information fSettings.SetTitle("ANL #nu_mu CC1n#pi^{+}"); fSettings.SetDataInput( FitPar::GetDataBase() + "/ANL/CC1pip_on_p/ANL_CC1pip_on_p_noEvents_phiAdler_1982.csv" ); fSettings.DefineAllowedSpecies("numu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = GetEventHistogram()->Integral("width")/(fNEvents+0.)*2./1.; // Plot Setup ------------------------------------------------------- SetDataFromTextFile( fSettings.GetDataInput() ); SetPoissonErrors(); SetCovarFromDiagonal(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void ANL_CC1ppip_Evt_1Dphi_nu::FillEventVariables(FitEvent *event) { + fXVar = -999.99; + if (event->NumFSParticle(2212) == 0 || event->NumFSParticle(211) == 0 || event->NumFSParticle(13) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Pp = event->GetHMFSParticle(2212)->fP; TLorentzVector Ppip = event->GetHMFSParticle(211)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; // Get the hadronic mass double hadMass = FitUtils::MpPi(Pp, Ppip); - // Need to boost pion and muon into resonance rest-frame to get phi (e.g. see F. Sanchez arxiv 1511.00501v2) - // - // Get the resonance 4-vector - TLorentzVector Pres = Ppip + Pp; - // Boost the outgoing and incoming particles into the resonance frame - Pnu.Boost(Pres.BoostVector()); - Pmu.Boost(-Pres.BoostVector()); - Ppip.Boost(-Pres.BoostVector()); - - // Get the vectors from the 4-vector - TVector3 PmuVect = Pmu.Vect(); - TVector3 PnuVect = Pnu.Vect(); - TVector3 PresVect = Pres.Vect(); - TVector3 PpipVect = Ppip.Vect(); - - // Define the z-direction - TVector3 zVect = (PnuVect-PmuVect); - zVect *= 1/double(zVect.Mag()); - // Define y direction as being z (resonance direction) x pmu* - TVector3 yVect = zVect.Cross(PmuVect); - // Normalise yVector - yVect *= 1/double(yVect.Mag()); - // define x direction as being y X z - TVector3 xVect = yVect.Cross(zVect); - // Normalise zVector - xVect *= 1/double(xVect.Mag()); - - // Project pion onto z axis - TVector3 PpipVectZ = zVect * PpipVect.Dot(zVect); - // Then subtract this vector off the pion vector - TVector3 PpipVectPlane = PpipVect - PpipVectZ; - - // Then finally construct phi as the angle between pion projection and x axis - double phi = -999; - - // ANL has a M(pi, p) < 1.4 GeV cut imposed - if (hadMass < 1400) { - if (PpipVectPlane.Y() > 0) { - phi = (180./M_PI)*PpipVectPlane.Angle(xVect); - } else if (PpipVectPlane.Y() < 0) { - phi = (180./M_PI)*(2*M_PI-PpipVectPlane.Angle(xVect)); - } else if (PpipVectPlane.Y() == 0) { - double randNo = rand.Rndm(); - if (randNo > 0.5) { - phi = (180./M_PI)*PpipVectPlane.Angle(xVect); - } else { - phi = (180./M_PI)*(2*M_PI-PpipVectPlane.Angle(xVect)); - } - } - } + if (hadMass > 1400) return; + // Get phi Adler + double phi = FitUtils::PhiAdler(Pnu, Pmu, Ppip, Pp); fXVar = phi; - - return; }; bool ANL_CC1ppip_Evt_1Dphi_nu::isSignal(FitEvent *event) { return SignalDef::isCC1pi3Prong(event, 14, 211, 2212, EnuMin, EnuMax); } /* void ANL_CC1ppip_Evt_1Dphi_nu::FillHistograms() { if (makeHadronicMassHist) { hadMassHist->Fill(hadMass); } Measurement1D::FillHistograms(); } void ANL_CC1ppip_Evt_1Dphi_nu::ScaleEvents() { PlotUtils::FluxUnfoldedScaling(fMCHist, GetFluxHistogram()); PlotUtils::FluxUnfoldedScaling(fMCFine, GetFluxHistogram()); fMCHist->Scale(fScaleFactor); fMCFine->Scale(fScaleFactor); return; } */ diff --git a/src/ANL/ANL_CCQE_Evt_1DQ2_nu.cxx b/src/ANL/ANL_CCQE_Evt_1DQ2_nu.cxx index b6bc1de..53b5b17 100755 --- a/src/ANL/ANL_CCQE_Evt_1DQ2_nu.cxx +++ b/src/ANL/ANL_CCQE_Evt_1DQ2_nu.cxx @@ -1,160 +1,160 @@ // 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 "ANL_CCQE_Evt_1DQ2_nu.h" //******************************************************************** ANL_CCQE_Evt_1DQ2_nu::ANL_CCQE_Evt_1DQ2_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "ANL CCQ2 Event Rate 1DQ2 nu sample. \n" \ "Target: D2 \n" \ "Flux: \n" \ "Signal: \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("Q^{2}_{CCQE} (GeV^{2})"); fSettings.SetYTitle("Number of events"); fSettings.SetAllowedTypes("EVT/SHAPE/DIAG", "EVT/SHAPE/DIAG/Q2CORR/MASK"); fSettings.SetEnuRange(0.0, 6.0); fSettings.DefineAllowedTargets("D,H"); // plot information fSettings.SetTitle("ANL #nu_mu CCQE"); fSettings.DefineAllowedSpecies("numu"); // Hadronic Cut Info if (fSettings.Found("name", "PRL31")) { fSettings.SetDataInput( FitPar::GetDataBase() + "ANL/ANL_CCQE_Data_PRL31_844.root;ANL_1DQ2_Data" ); fSettings.SetEnuRange(0.0, 3.0); } else if (fSettings.Found("name", "PRD16")) { fSettings.SetDataInput( FitPar::GetDataBase() + "ANL/ANL_CCQE_Data_PRD16_3103.root;ANL_1DQ2_Data" ); } else { fSettings.SetDataInput( FitPar::GetDataBase() + "ANL/ANL_Data_PRD26_537.root;ANL_1DQ2_Data" ); } // is Q2 Correction applied applyQ2correction = fSettings.Found("type", "Q2CORR"); if (applyQ2correction) { fSettings.SetS("q2correction_file", FitPar::GetDataBase() + "/ANL/ANL_CCQE_Data_PRL31_844.root"); - fSettings.SetS("q2correction_hist", "ANL_XSec_1DQ2_Correction"); + fSettings.SetS("q2correction_hist", "ANL_1DQ2_Correction"); } FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor for shape fScaleFactor = 1.0; // Plot Setup ------------------------------------------------------- SetDataFromRootFile( fSettings.GetDataInput() ); SetPoissonErrors(); SetCovarFromDiagonal(); // Correction Histogram if (applyQ2correction) { // Correction Hist CorrectionHist = PlotUtils::GetTH1DFromFile( fSettings.GetS("q2correction_file"), fSettings.GetS("q2correction_hist") ); SetAutoProcessTH1(CorrectionHist, kCMD_Write); // Make uncorrected MC hist fMCHist_NoCorr = (TH1D*) fDataHist->Clone(); fMCHist_NoCorr->Reset(); fMCHist_NoCorr->SetNameTitle( (fName + "_NOCORR").c_str(), (fName + "_NOCORR").c_str()); SetAutoProcessTH1(fMCHist_NoCorr); } // Final setup --------------------------------------------------- FinaliseMeasurement(); } //******************************************************************** void ANL_CCQE_Evt_1DQ2_nu::FillEventVariables(FitEvent * event) { //******************************************************************** if (event->NumFSParticle(13) == 0) return; // Fill histogram with reconstructed Q2 Distribution fXVar = -999.9; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; ThetaMu = Pnu.Vect().Angle(Pmu.Vect()); fXVar = FitUtils::Q2QErec(Pmu, cos(ThetaMu), 0., true); GetQ2Box()->fQ2 = fXVar; return; }; //******************************************************************** bool ANL_CCQE_Evt_1DQ2_nu::isSignal(FitEvent * event) { //******************************************************************** if (!SignalDef::isCCQE(event, 14, EnuMin, EnuMax)) return false; // Q2 cut if (GetQ2Box()->fQ2 <= 0) return false; return true; }; //******************************************************************** void ANL_CCQE_Evt_1DQ2_nu::FillHistograms() { //******************************************************************** if (applyQ2correction) { fMCHist_NoCorr->Fill( GetQ2Box()->fQ2, Weight); if (GetQ2Box()->fQ2 < CorrectionHist->GetXaxis()->GetXmax() && GetQ2Box()->fQ2 > CorrectionHist->GetXaxis()->GetXmin()) Weight *= CorrectionHist->Interpolate(GetQ2Box()->fQ2); } Measurement1D::FillHistograms(); } //******************************************************************** void ANL_CCQE_Evt_1DQ2_nu::ScaleEvents() { //******************************************************************** Measurement1D::ScaleEvents(); // Flux unfold our extra histogram if (applyQ2correction) { if (fMCHist_NoCorr->Integral()) { fMCHist_NoCorr->Scale(fDataHist->Integral() / fMCHist_NoCorr->Integral()); } } } diff --git a/src/ANL/ANL_CCQE_XSec_1DEnu_nu.cxx b/src/ANL/ANL_CCQE_XSec_1DEnu_nu.cxx index 563487c..aca2998 100644 --- a/src/ANL/ANL_CCQE_XSec_1DEnu_nu.cxx +++ b/src/ANL/ANL_CCQE_XSec_1DEnu_nu.cxx @@ -1,154 +1,152 @@ // 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 "ANL_CCQE_XSec_1DEnu_nu.h" //******************************************************************** ANL_CCQE_XSec_1DEnu_nu::ANL_CCQE_XSec_1DEnu_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "ANL CCQ2 XSec 1DEnu nu sample. \n" \ "Target: D2 \n" \ "Flux: \n" \ "Signal: \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("E_{#nu} (GeV)"); fSettings.SetYTitle("#sigma(#E_{#nu}) (cm^{2}/neutron)"); fSettings.SetAllowedTypes("EVT/SHAPE/DIAG", "EVT/SHAPE/DIAG/Q2CORR/MASK"); fSettings.SetEnuRange(0.0, 6.0); fSettings.DefineAllowedTargets("D,H"); // plot information fSettings.SetTitle("ANL #nu_mu CCQE"); fSettings.DefineAllowedSpecies("numu"); // Hadronic Cut Info if (fSettings.Found("name", "PRL31")) { fSettings.SetDataInput( FitPar::GetDataBase() + "ANL/ANL_CCQE_Data_PRL31_844.root;ANL_1DEnu_Data" ); fSettings.SetEnuRange(0.0, 3.0); } else { fSettings.SetDataInput( FitPar::GetDataBase() + "ANL/ANL_CCQE_Data_PRD16_3103.root;ANL_1DEnu_fluxtuned_Data" ); } // is Q2 Correction applied applyQ2correction = fSettings.Found("type", "Q2CORR"); - if (applyQ2correction) { - fSettings.SetS("q2correction_file", FitPar::GetDataBase() + "/ANL/ANL_CCQE_Data_PRL31_844.root"); - fSettings.SetS("q2correction_hist", "ANL_XSec_1DQ2_Correction"); - } + fSettings.SetS("q2correction_file", FitPar::GetDataBase() + "/ANL/ANL_CCQE_Data_PRL31_844.root"); + fSettings.SetS("q2correction_hist", "ANL_1DQ2_Correction"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor for shape fScaleFactor = (GetEventHistogram()->Integral("width") * 2.0 / 1.0 * 1E-38 / (fNEvents + 0.)); // Plot Setup ------------------------------------------------------- SetDataFromRootFile( fSettings.GetDataInput() ); SetCovarFromDiagonal(); // Correction Histogram if (applyQ2correction) { // Correction Hist CorrectionHist = PlotUtils::GetTH1DFromFile( fSettings.GetS("q2correction_file"), fSettings.GetS("q2correction_hist") ); SetAutoProcessTH1(CorrectionHist, kCMD_Write); // Make uncorrected MC hist fMCHist_NoCorr = (TH1D*) fDataHist->Clone(); fMCHist_NoCorr->Reset(); fMCHist_NoCorr->SetNameTitle( (fName + "_NOCORR").c_str(), (fName + "_NOCORR").c_str()); SetAutoProcessTH1(fMCHist_NoCorr); } // Final setup --------------------------------------------------- FinaliseMeasurement(); } //******************************************************************** void ANL_CCQE_XSec_1DEnu_nu::FillEventVariables(FitEvent *event) { //******************************************************************** if (event->NumFSParticle(13) == 0) return; // Get Q2 double q2qe = 0.0; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; ThetaMu = Pnu.Vect().Angle(Pmu.Vect()); q2qe = FitUtils::Q2QErec(Pmu, cos(ThetaMu), 0., true); Enu_rec = FitUtils::EnuQErec(Pmu, cos(ThetaMu), 0., true); fXVar = Enu_rec; GetQ2Box()->fQ2 = q2qe; return; }; //******************************************************************** bool ANL_CCQE_XSec_1DEnu_nu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCCQE(event, 14, EnuMin, EnuMax); }; //******************************************************************** void ANL_CCQE_XSec_1DEnu_nu::FillHistograms() { //******************************************************************** if (applyQ2correction) { fMCHist_NoCorr->Fill( GetQ2Box()->fQ2, Weight); if (GetQ2Box()->fQ2 < CorrectionHist->GetXaxis()->GetXmax() && GetQ2Box()->fQ2 > CorrectionHist->GetXaxis()->GetXmin()) Weight *= CorrectionHist->Interpolate(GetQ2Box()->fQ2); } Measurement1D::FillHistograms(); } //******************************************************************** void ANL_CCQE_XSec_1DEnu_nu::ScaleEvents() { //******************************************************************** Measurement1D::ScaleEvents(); // Flux unfold our extra histogram if (applyQ2correction) { PlotUtils::FluxUnfoldedScaling(fMCHist_NoCorr, GetFluxHistogram(), GetEventHistogram(), fScaleFactor, fNEvents); } } diff --git a/src/BNL/BNL_CC1ppip_Evt_1DcosthAdler_nu.cxx b/src/BNL/BNL_CC1ppip_Evt_1DcosthAdler_nu.cxx index 0d2f6eb..306cc6a 100644 --- a/src/BNL/BNL_CC1ppip_Evt_1DcosthAdler_nu.cxx +++ b/src/BNL/BNL_CC1ppip_Evt_1DcosthAdler_nu.cxx @@ -1,109 +1,90 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "BNL_CC1ppip_Evt_1DcosthAdler_nu.h" //******************************************************************** BNL_CC1ppip_Evt_1DcosthAdler_nu::BNL_CC1ppip_Evt_1DcosthAdler_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "BNL_CC1ppip_Evt_1DcosthAdler_nu sample. \n" \ "Target: D2 \n" \ "Flux: \n" \ "Signal: \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("cos#theta_{Adler}"); fSettings.SetYTitle("Number of events"); fSettings.SetAllowedTypes("EVT/SHAPE/DIAG", "EVT/SHAPE/DIAG"); fSettings.SetEnuRange(0.5, 6.0); fSettings.DefineAllowedTargets("D,H"); // CCQELike plot information fSettings.SetTitle("BNL_CC1ppip_Evt_1DcosthAdler_nu"); fSettings.SetDataInput( FitPar::GetDataBase() + "/BNL/CC1pip_on_p/BNL_CC1ppip_W14_cosThAdler.csv" ); fSettings.DefineAllowedSpecies("numu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor =GetEventHistogram()->Integral("width")/(fNEvents+0.)*2./1.; // Plot Setup ------------------------------------------------------- SetDataFromTextFile( fSettings.GetDataInput() ); SetPoissonErrors(); SetCovarFromDiagonal(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void BNL_CC1ppip_Evt_1DcosthAdler_nu::FillEventVariables(FitEvent *event) { + fXVar = -999.99; + if (event->NumFSParticle(2212) == 0 || event->NumFSParticle(211) == 0 || event->NumFSParticle(13) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Pp = event->GetHMFSParticle(2212)->fP; TLorentzVector Ppip = event->GetHMFSParticle(211)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; // Get the hadronic mass double hadMass = FitUtils::MpPi(Pp, Ppip); - // Need to boost pion and muon into resonance rest-frame to get phi (e.g. see F. Sanchez arxiv 1511.00501v2) - // - // Get the resonance 4-vector - TLorentzVector Pres = Ppip + Pp; - Ppip.Boost(-Pres.BoostVector()); - Pmu.Boost(-Pres.BoostVector()); - Pnu.Boost(Pres.BoostVector()); - // Define the vectors - TVector3 PpipVect = Ppip.Vect(); - TVector3 PnuVect = Pnu.Vect(); - TVector3 PmuVect = Pmu.Vect(); - // Define the z-direction; should be same as Pres - TVector3 zVect = (PnuVect-PmuVect); - zVect *= 1/double(zVect.Mag()); - - // Then finally construct phi as the angle between pion projection and x axis - double cosThAdler = -999; - - // BNL has a M(pi, p) < 1.4 GeV cut imposed - if (hadMass < 1400) { - cosThAdler = cos(PpipVect.Angle(zVect)); - } + if (hadMass > 1400) return; + // Get Adler cos theta + double cosThAdler = FitUtils::CosThAdler(Pnu, Pmu, Ppip, Pp); fXVar = cosThAdler; - - return; }; bool BNL_CC1ppip_Evt_1DcosthAdler_nu::isSignal(FitEvent *event) { return SignalDef::isCC1pi3Prong(event, 14, 211, 2212,EnuMin,EnuMax); } diff --git a/src/BNL/BNL_CC1ppip_Evt_1Dphi_nu.cxx b/src/BNL/BNL_CC1ppip_Evt_1Dphi_nu.cxx index 977e295..03b4826 100644 --- a/src/BNL/BNL_CC1ppip_Evt_1Dphi_nu.cxx +++ b/src/BNL/BNL_CC1ppip_Evt_1Dphi_nu.cxx @@ -1,159 +1,113 @@ // 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 "BNL_CC1ppip_Evt_1Dphi_nu.h" //******************************************************************** BNL_CC1ppip_Evt_1Dphi_nu::BNL_CC1ppip_Evt_1Dphi_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "BNL_CC1ppip_Evt_1Dphi_nu sample. \n" \ "Target: D2 \n" \ "Flux: \n" \ "Signal: \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("#phi_{Adler}"); fSettings.SetYTitle("Number of events"); fSettings.SetAllowedTypes("EVT/SHAPE/DIAG", "EVT/SHAPE/DIAG"); fSettings.SetEnuRange(0.0, 6.0); fSettings.DefineAllowedTargets("D,H"); // CCQELike plot information fSettings.SetTitle("BNL_CC1ppip_Evt_1Dphi_nu"); fSettings.SetDataInput( FitPar::GetDataBase() + "/BNL/CC1pip_on_p/BNL_CC1ppip_W14_phiAdler.csv" ); fSettings.DefineAllowedSpecies("numu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor =GetEventHistogram()->Integral("width")/(fNEvents+0.)*2./1.; // Plot Setup ------------------------------------------------------- SetDataFromTextFile( fSettings.GetDataInput() ); SetPoissonErrors(); SetCovarFromDiagonal(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void BNL_CC1ppip_Evt_1Dphi_nu::FillEventVariables(FitEvent *event) { + fXVar = -999.99; + if (event->NumFSParticle(2212) == 0 || event->NumFSParticle(211) == 0 || event->NumFSParticle(13) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Pp = event->GetHMFSParticle(2212)->fP; TLorentzVector Ppip = event->GetHMFSParticle(211)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; // Get the hadronic mass double hadMass = FitUtils::MpPi(Pp, Ppip); - // Need to boost pion and muon into resonance rest-frame to get phi (e.g. see F. Sanchez arxiv 1511.00501v2) - // - // Get the resonance 4-vector - TLorentzVector Pres = Ppip + Pp; - // Boost the pion 4-vector into the resonance 4-vector rest-frame - Ppip.Boost(Pres.BoostVector()); - Pmu.Boost(-Pres.BoostVector()); - Pp.Boost(-Pres.BoostVector()); - - // Get the vectors from the 4-vector - TVector3 PmuVect = Pmu.Vect(); - TVector3 PnuVect = Pnu.Vect(); - TVector3 PresVect = Pres.Vect(); - TVector3 PpipVect = Ppip.Vect(); - - // Define y direction as being z (resonance direction) x pmu* - TVector3 zVect = (PnuVect-PmuVect); - zVect *= 1/double(zVect.Mag()); - TVector3 yVect = zVect.Cross(PmuVect); - // Normalise yVector - yVect *= 1/double(yVect.Mag()); - // define x direction as being y X z - TVector3 xVect = yVect.Cross(zVect); - // Normalise zVector - xVect *= 1/double(xVect.Mag()); - - // Project pion onto z axis - TVector3 PpipVectZ = zVect * PpipVect.Dot(zVect); - // Then subtract this vector off the pion vector - TVector3 PpipVectPlane = PpipVect - PpipVectZ; - - // Then finally construct phi as the angle between pion projection and x axis - double phi = -999; - - // BNL has a M(pi, p) < 1.4 GeV cut imposed - if (hadMass < 1400) { - if (PpipVectPlane.Y() > 0) { - phi = (180./M_PI)*PpipVectPlane.Angle(xVect); - } else if (PpipVectPlane.Y() < 0) { - phi = (180./M_PI)*(2*M_PI-PpipVectPlane.Angle(xVect)); - } else if (PpipVectPlane.Y() == 0) { - double randNo = rand.Rndm(); - if (randNo > 0.5) { - phi = (180./M_PI)*PpipVectPlane.Angle(xVect); - } else { - phi = (180./M_PI)*(2*M_PI-PpipVectPlane.Angle(xVect)); - } - } - } + if (hadMass > 1400) return; + // Get phi Adler + double phi = FitUtils::PhiAdler(Pnu, Pmu, Ppip, Pp); fXVar = phi; - - return; }; bool BNL_CC1ppip_Evt_1Dphi_nu::isSignal(FitEvent *event) { return SignalDef::isCC1pi3Prong(event, 14, 211, 2212,EnuMin,EnuMax); } /* void BNL_CC1ppip_Evt_1Dphi_nu::FillHistograms() { if (makeHadronicMassHist) { hadMassHist->Fill(hadMass); } Measurement1D::FillHistograms(); } void BNL_CC1ppip_Evt_1Dphi_nu::ScaleEvents() { PlotUtils::FluxUnfoldedScaling(fMCHist, GetFluxHistogram()); PlotUtils::FluxUnfoldedScaling(fMCFine, GetFluxHistogram()); fMCHist->Scale(fScaleFactor); fMCFine->Scale(fScaleFactor); return; } */ diff --git a/src/BNL/BNL_CCQE_Evt_1DQ2_nu.cxx b/src/BNL/BNL_CCQE_Evt_1DQ2_nu.cxx index 9dfb637..6e91ddb 100755 --- a/src/BNL/BNL_CCQE_Evt_1DQ2_nu.cxx +++ b/src/BNL/BNL_CCQE_Evt_1DQ2_nu.cxx @@ -1,148 +1,148 @@ // 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 "BNL_CCQE_Evt_1DQ2_nu.h" //******************************************************************** BNL_CCQE_Evt_1DQ2_nu::BNL_CCQE_Evt_1DQ2_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "BNL_CCQE_Evt_1DQ2_nu sample. \n" \ "Target: D2 \n" \ "Flux: \n" \ "Signal: \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("Q^{2}_{CCQE} (GeV^{2})"); fSettings.SetYTitle("Number of events"); fSettings.SetAllowedTypes("EVT/SHAPE/DIAG", "EVT/SHAPE/DIAG/Q2CORR/MASK"); fSettings.SetEnuRange(0.0, 6.0); fSettings.DefineAllowedTargets("D,H"); // plot information fSettings.SetTitle("BNL #nu_mu CCQE"); fSettings.DefineAllowedSpecies("numu"); fSettings.SetDataInput( FitPar::GetDataBase() + "BNL/BNL_Data_PRD23_2499.root;BNL_1DQ2_Data"); // is Q2 Correction applied applyQ2correction = fSettings.Found("type", "Q2CORR"); if (applyQ2correction) { fSettings.SetS("q2correction_file", FitPar::GetDataBase() + "ANL/ANL_CCQE_Data_PRL31_844.root"); - fSettings.SetS("q2correction_hist", "ANL_XSec_1DQ2_Correction"); + fSettings.SetS("q2correction_hist", "ANL_1DQ2_Correction"); } FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor for shape fScaleFactor = 1.0; // Plot Setup ------------------------------------------------------- SetDataFromRootFile( fSettings.GetDataInput() ); SetPoissonErrors(); SetCovarFromDiagonal(); // Correction Histogram if (applyQ2correction) { // Correction Hist CorrectionHist = PlotUtils::GetTH1DFromFile( fSettings.GetS("q2correction_file"), fSettings.GetS("q2correction_hist") ); SetAutoProcessTH1(CorrectionHist, kCMD_Write); // Make uncorrected MC hist fMCHist_NoCorr = (TH1D*) fDataHist->Clone(); fMCHist_NoCorr->Reset(); fMCHist_NoCorr->SetNameTitle( (fName + "_NOCORR").c_str(), (fName + "_NOCORR").c_str()); SetAutoProcessTH1(fMCHist_NoCorr); } // Final setup --------------------------------------------------- FinaliseMeasurement(); } //******************************************************************** void BNL_CCQE_Evt_1DQ2_nu::FillEventVariables(FitEvent * event) { //******************************************************************** if (event->NumFSParticle(13) == 0) return; // Fill histogram with reconstructed Q2 Distribution fXVar = -999.9; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; ThetaMu = Pnu.Vect().Angle(Pmu.Vect()); fXVar = FitUtils::Q2QErec(Pmu, cos(ThetaMu), 0., true); GetQ2Box()->fQ2 = fXVar; return; }; //******************************************************************** bool BNL_CCQE_Evt_1DQ2_nu::isSignal(FitEvent * event) { //******************************************************************** if (!SignalDef::isCCQE(event, 14, EnuMin, EnuMax)) return false; // Q2 cut if (GetQ2Box()->fQ2 <= 0) return false; return true; }; //******************************************************************** void BNL_CCQE_Evt_1DQ2_nu::FillHistograms() { //******************************************************************** if (applyQ2correction) { fMCHist_NoCorr->Fill( GetQ2Box()->fQ2, Weight); if (GetQ2Box()->fQ2 < CorrectionHist->GetXaxis()->GetXmax() && GetQ2Box()->fQ2 > CorrectionHist->GetXaxis()->GetXmin()) Weight *= CorrectionHist->Interpolate(GetQ2Box()->fQ2); } Measurement1D::FillHistograms(); } //******************************************************************** void BNL_CCQE_Evt_1DQ2_nu::ScaleEvents() { //******************************************************************** Measurement1D::ScaleEvents(); // Flux unfold our extra histogram if (applyQ2correction) { if (fMCHist_NoCorr->Integral()) { fMCHist_NoCorr->Scale(fDataHist->Integral() / fMCHist_NoCorr->Integral()); } } } diff --git a/src/BNL/BNL_CCQE_XSec_1DEnu_nu.cxx b/src/BNL/BNL_CCQE_XSec_1DEnu_nu.cxx index f337515..fad5e99 100644 --- a/src/BNL/BNL_CCQE_XSec_1DEnu_nu.cxx +++ b/src/BNL/BNL_CCQE_XSec_1DEnu_nu.cxx @@ -1,147 +1,147 @@ // 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 "BNL_CCQE_XSec_1DEnu_nu.h" //******************************************************************** BNL_CCQE_XSec_1DEnu_nu::BNL_CCQE_XSec_1DEnu_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "BNL CCQ2 XSec 1DEnu nu sample. \n" \ "Target: D2 \n" \ "Flux: \n" \ "Signal: \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("E_{#nu} (GeV)"); fSettings.SetYTitle("#sigma(#E_{#nu}) (cm^{2}/neutron)"); fSettings.SetAllowedTypes("EVT/SHAPE/DIAG", "EVT/SHAPE/DIAG/Q2CORR/MASK"); fSettings.SetEnuRange(0.0, 6.0); fSettings.DefineAllowedTargets("D,H"); // plot information fSettings.SetTitle("BNL #nu_mu CCQE"); fSettings.DefineAllowedSpecies("numu"); fSettings.SetDataInput( FitPar::GetDataBase() + "BNL/BNL_Data_PRD23_2499.root;BNL_1DEnu_Data"); // is Q2 Correction applied applyQ2correction = fSettings.Found("type", "Q2CORR"); if (applyQ2correction) { fSettings.SetS("q2correction_file", FitPar::GetDataBase() + "/ANL/ANL_CCQE_Data_PRL31_844.root"); - fSettings.SetS("q2correction_hist", "ANL_XSec_1DQ2_Correction"); + fSettings.SetS("q2correction_hist", "ANL_1DQ2_Correction"); } FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor for shape fScaleFactor = (GetEventHistogram()->Integral("width") * (2.0 / 1.0) * 1E-38 / (fNEvents + 0.)); // Plot Setup ------------------------------------------------------- SetDataFromRootFile( fSettings.GetDataInput() ); SetCovarFromDiagonal(); // Correction Histogram if (applyQ2correction) { // Correction Hist CorrectionHist = PlotUtils::GetTH1DFromFile( fSettings.GetS("q2correction_file"), fSettings.GetS("q2correction_hist") ); SetAutoProcessTH1(CorrectionHist, kCMD_Write); // Make uncorrected MC hist fMCHist_NoCorr = (TH1D*) fDataHist->Clone(); fMCHist_NoCorr->Reset(); fMCHist_NoCorr->SetNameTitle( (fName + "_NOCORR").c_str(), (fName + "_NOCORR").c_str()); SetAutoProcessTH1(fMCHist_NoCorr); } // Final setup --------------------------------------------------- FinaliseMeasurement(); } //******************************************************************** void BNL_CCQE_XSec_1DEnu_nu::FillEventVariables(FitEvent *event) { //******************************************************************** if (event->NumFSParticle(13) == 0) return; // Get Q2 double q2qe = 0.0; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; ThetaMu = Pnu.Vect().Angle(Pmu.Vect()); q2qe = FitUtils::Q2QErec(Pmu, cos(ThetaMu), 0., true); Enu_rec = FitUtils::EnuQErec(Pmu, cos(ThetaMu), 0., true); fXVar = Enu_rec; GetQ2Box()->fQ2 = q2qe; return; }; //******************************************************************** bool BNL_CCQE_XSec_1DEnu_nu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCCQE(event, 14, EnuMin, EnuMax); }; //******************************************************************** void BNL_CCQE_XSec_1DEnu_nu::FillHistograms() { //******************************************************************** if (applyQ2correction) { fMCHist_NoCorr->Fill( GetQ2Box()->fQ2, Weight); if (GetQ2Box()->fQ2 < CorrectionHist->GetXaxis()->GetXmax() && GetQ2Box()->fQ2 > CorrectionHist->GetXaxis()->GetXmin()) Weight *= CorrectionHist->Interpolate(GetQ2Box()->fQ2); } Measurement1D::FillHistograms(); } //******************************************************************** void BNL_CCQE_XSec_1DEnu_nu::ScaleEvents() { //******************************************************************** Measurement1D::ScaleEvents(); // Flux unfold our extra histogram if (applyQ2correction) { PlotUtils::FluxUnfoldedScaling(fMCHist_NoCorr, GetFluxHistogram(), GetEventHistogram(), fScaleFactor, fNEvents); } } diff --git a/src/Smearceptance/CMakeLists.txt b/src/Config/CMakeLists.txt similarity index 92% copy from src/Smearceptance/CMakeLists.txt copy to src/Config/CMakeLists.txt index a0f7251..7577b9d 100644 --- a/src/Smearceptance/CMakeLists.txt +++ b/src/Config/CMakeLists.txt @@ -1,54 +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(HEADERFILES -ISmearcepter.h -Smearcepterton.h - -ThresholdAccepter.h +NuisConfig.h +NuisKey.h ) set(IMPLFILES -ISmearcepter.cxx -Smearcepterton.cxx - -ThresholdAccepter.cxx +NuisConfig.cxx +NuisKey.cxx ) -set(LIBNAME Smearceptance) +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(${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/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/Electron/CLAS6-EG2_Accepter.cxx b/src/Electron/CLAS6-EG2_Accepter.cxx new file mode 100644 index 0000000..d2c4307 --- /dev/null +++ b/src/Electron/CLAS6-EG2_Accepter.cxx @@ -0,0 +1,177 @@ +#include "ISmearcepter.h" + +#include "TH3D.h" +#include "TRandom3.h" + +#include + +#define DEBUG_CLASACCEPT + +class CLASAccepter : public ISmearcepter { + TRandom3 rand; + // Maps a particle PDG to the relevant generated and accepted histograms from + // the input map. + std::map > Acceptance; + + public: + CLASAccepter() { ElementName = "CLASAccepter"; } + + void SpecifcSetup(nuiskey &nk) { + rand.~TRandom3(); + new (&rand) TRandom3(); + + InstanceName = nk.GetS("name"); + + std::string const &mapfile = nk.GetS("map"); + + if (!mapfile.length()) { + std::cout << "[ERROR]: No input file specified by \"map\" attribute." + << std::endl; + exit(1); + } + + TFile *f = new TFile(mapfile.c_str()); + + if (!f || !f->IsOpen()) { + std::cout << "[ERROR]: Could not open root file specified by \"map\" " + "attribute: \"" + << mapfile << "\"" << std::endl; + exit(1); + } + + std::vector accepts = nk.GetListOfChildNodes("accept"); + for (auto &acc : accepts) { + std::string const &genStr = acc.GetS("generated"); + std::string const &accStr = acc.GetS("accepted"); + + if (!genStr.length() || !accStr.length()) { + std::cout << "[ERROR]: expected accept node to contain both " + "\"generated\" and \"accepted\" attributes." + << std::endl; + exit(1); + } + + std::string const &pdgs_s = acc.GetS("PDG"); + std::vector pdgs_i = GeneralUtils::ParseToInt(pdgs_s, ","); + + if (!pdgs_i.size()) { + std::cout + << "[ERROR]: Could not find any applicable particle PDG codes." + << std::endl; + exit(1); + } + + std::pair genacc; + + genacc.first = dynamic_cast(f->Get(accStr.c_str())); + genacc.second = dynamic_cast(f->Get(genStr.c_str())); + + if (!genacc.first) { + std::cout << "[ERROR]: Could not retrieve \"accepted\" histogram: \"" + << accStr << "\" from file: \"" << mapfile << "\"." + << std::endl; + exit(1); + } + if (!genacc.second) { + std::cout << "[ERROR]: Could not retrieve \"accepted\" histogram: \"" + << genStr << "\" from file: \"" << mapfile << "\"." + << std::endl; + exit(1); + } + + genacc.first = static_cast(genacc.first->Clone()); + genacc.first->SetDirectory(NULL); + genacc.second = static_cast(genacc.second->Clone()); + genacc.second->SetDirectory(NULL); + + for (size_t pdg_it = 0; pdg_it < pdgs_i.size(); ++pdg_it) { + if (Acceptance.count(pdgs_i[pdg_it])) { + std::cout + << "[WARN]: Acceptance map already contains acceptance for PDG: " + << pdgs_i[pdg_it] << ". Overwriting..." << std::endl; + } + Acceptance[pdgs_i[pdg_it]] = genacc; + } + } + + std::cout << "Loaded " << Acceptance.size() + << " particle acceptance definitions." << std::endl; + f->Close(); + delete f; + } + + RecoInfo *Smearcept(FitEvent *fe) { + RecoInfo *ri = new RecoInfo(); + + for (size_t p_it = 0; p_it < fe->NParticles(); ++p_it) { + FitParticle *fp = fe->GetParticle(p_it); + + int PDG = fp->PDG(); + double p = fp->P3().Mag(); + double cost = fp->P3().CosTheta(); + double phi = fp->P3().Phi(); + +#ifdef DEBUG_CLASACCEPT + std::cout << std::endl; + std::cout << "[" << p_it << "]: " << PDG << ", " << fp->Status() << ", " + << fp->E() << " -- KE:" << fp->KE() << " Mom: " << p + << std::flush; +#endif + + if (fp->Status() != kFinalState) { +#ifdef DEBUG_CLASACCEPT + std::cout << " -- Not final state." << std::flush; +#endif + continue; + } + + if (!Acceptance.count(PDG)) { +#ifdef DEBUG_CLASACCEPT + std::cout << " -- Unknown acceptance." << std::flush; +#endif + + continue; + } + + std::pair acc = Acceptance[PDG]; + + // For a bin in phase space defined by p, cost, phi: + // Find number of generated events + Int_t pbin = acc.second->GetXaxis()->FindBin(p); + Int_t tbin = acc.second->GetYaxis()->FindBin(cost); + Int_t phibin = acc.second->GetZaxis()->FindBin(phi); + double num_gen = acc.second->GetBinContent(pbin, tbin, phibin); + // Find number of accepted events + pbin = acc.first->GetXaxis()->FindBin(p); + tbin = acc.first->GetYaxis()->FindBin(cost); + phibin = acc.first->GetZaxis()->FindBin(phi); + double num_acc = acc.first->GetBinContent(pbin, tbin, phibin); + double acc_ratio = double(num_acc) / double(num_gen); + + bool accepted = (rand.Uniform() < acc_ratio); + if (accepted) { +#ifdef DEBUG_CLASACCEPT + std::cout << " -- Reconstructed with probability: " << acc_ratio + << std::flush; +#endif + ri->RecObjMom.push_back(fp->P3()); + ri->RecObjClass.push_back(fp->PDG()); + + continue; + } + +#ifdef DEBUG_CLASACCEPT + std::cout << " -- Rejected with probability: " << acc_ratio << std::flush; +#endif +#ifdef DEBUG_CLASACCEPT + std::cout << std::endl; +#endif + } + +#ifdef DEBUG_CLASACCEPT + std::cout << "Reconstructed " << ri->RecObjMom.size() << " particles. " + << std::endl; +#endif + return ri; + } +}; diff --git a/src/Electron/ElectronScattering_DurhamData.cxx b/src/Electron/ElectronScattering_DurhamData.cxx index 6a52007..c171df5 100644 --- a/src/Electron/ElectronScattering_DurhamData.cxx +++ b/src/Electron/ElectronScattering_DurhamData.cxx @@ -1,485 +1,486 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "ElectronScattering_DurhamData.h" //******************************************************************** ElectronScattering_DurhamData::ElectronScattering_DurhamData( nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "Electron Scattering Durham Data sample. \n" "Target: Multiple \n" "Flux: Energy should match data being handled \n" "Signal: Any event with an electron in the final state \n"; fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.DefineAllowedSpecies("electron"); fSettings.SetTitle("Electron"); fSettings.SetAllowedTypes("FIX/DIAG", "FIX,FREE,SHAPE/DIAG/NORM/MASK"); fSettings.SetXTitle("q0"); fSettings.SetYTitle("#sigma"); fIsNoWidth = true; FinaliseSampleSettings(); // Plot Setup ------------------------------------------------------- SetDataFromName(fSettings.GetS("originalname")); SetCovarFromDiagonal(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon // fScaleFactor = ((GetEventHistogram()->Integral("width") * 1E-38 / (fNEvents // + 0.)) / TotalIntegratedFlux()); EnuMin = fZLowLim; EnuMax = fZHighLim; double sigscale = GetEventHistogram()->Integral() * 1E-38 / double(fNEvents) / TotalIntegratedFlux(); // double dangle = 2 * M_PI * fabs((1. - cos(fYLowLim * M_PI / 180.)) - (1. - // cos(fYHighLim * M_PI / 180.))); // fScaleFactor = sigscale / dangle / fZCenter; fScaleFactor = sigscale; std::cout << "Event Integral = " << GetEventHistogram()->Integral() << std::endl; std::cout << "Flux Integral = " << TotalIntegratedFlux() << std::endl; std::cout << "FNEvents = " << fNEvents << std::endl; std::cout << "Z Limits = " << fZLowLim << " " << fZHighLim << std::endl; std::cout << "sigscale = " << sigscale << std::endl; std::cout << "fZCenter = " << fZCenter << std::endl; std::cout << "ScaleFactor = " << fScaleFactor << std::endl; // Finish up FinaliseMeasurement(); }; //******************************************************************** void ElectronScattering_DurhamData::SetDataFromName(std::string name) { //******************************************************************** // Data Should be given in the format // Electron_Z_A_Energy_Theta_Source std::vector splitstring = GeneralUtils::ParseToStr(name, "_"); std::string zstring = splitstring[1]; std::string astring = splitstring[2]; std::string estring = splitstring[3]; std::string tstring = splitstring[4]; std::string sstring = splitstring[5]; fYCenter = GeneralUtils::StrToDbl(tstring); fZCenter = GeneralUtils::StrToDbl(estring); // Create effective E and Theta bin Edges std::vector thetabinedges; std::vector ebinedges; int nthetabins = FitPar::Config().GetParI("Electron_NThetaBins"); int nebins = FitPar::Config().GetParI("Electron_NEnergyBins"); double thetawidth = FitPar::Config().GetParD("Electron_ThetaWidth"); double ewidth = FitPar::Config().GetParD("Electron_EnergyWidth"); for (int i = -nthetabins; i <= nthetabins; i++) { thetabinedges.push_back(fYCenter + thetawidth * (double(i))); } for (int i = -nebins; i <= nebins; i++) { double newval = fZCenter + ewidth * (double(i)); if (newval < 0.0) newval = 0.0; if (newval < GetEventHistogram()->GetXaxis()->GetXmin()) newval = GetEventHistogram()->GetXaxis()->GetXmin(); if (newval > GetEventHistogram()->GetXaxis()->GetXmax()) newval = GetEventHistogram()->GetXaxis()->GetXmax(); if (std::find(ebinedges.begin(), ebinedges.end(), newval) != ebinedges.end()) continue; ebinedges.push_back(newval); } // Determine target std::string target = ""; if (!zstring.compare("6") && !astring.compare("12")) target = "12C.dat"; else if (!zstring.compare("8") && !astring.compare("16")) target = "16O.dat"; else { ERR(FTL) << "Target not supported in electron scattering module!" << std::endl; throw; } // Fill Data Points std::string line; std::ifstream mask((FitPar::GetDataBase() + "/Electron/" + target).c_str(), ifstream::in); if (!mask.good()) { ERR(FTL) << "Failed to open e-scattering database file: " << (FitPar::GetDataBase() + "/Electron/" + target) << std::endl; throw; } int i = 0; std::vector pointx; std::vector errorx; std::vector pointy; std::vector errory; double scalef = 1.E-38 * 1.E5; while (std::getline(mask >> std::ws, line, '\n')) { // std::cout << "Line = " << line << std::endl; if (line.empty()) continue; std::vector lineentries = GeneralUtils::ParseToStr(line, " "); // std::cout << "Checking : " << line << std::endl; if (zstring.compare(lineentries[0])) continue; if (astring.compare(lineentries[1])) continue; if (estring.compare(lineentries[2])) continue; if (tstring.compare(lineentries[3])) continue; if (sstring.compare(lineentries[7])) continue; // std::cout << "Registering data point : " << line << std::endl; // std::cout << "Adding Graph Point : " << // GeneralUtils::StrToDbl(lineentries[4]) << " " << // GeneralUtils::StrToDbl(lineentries[5]) << std::endl; // Loop through x and y points and find a place to insert if (pointx.empty()) { pointx.push_back(GeneralUtils::StrToDbl(lineentries[4])); errorx.push_back(0.0); pointy.push_back(GeneralUtils::StrToDbl(lineentries[5]) * scalef); errory.push_back(GeneralUtils::StrToDbl(lineentries[6]) * scalef); } else { for (size_t j = 0; j < pointx.size(); j++) { if (GeneralUtils::StrToDbl(lineentries[4]) < pointx[j] && j == 0) { // std::cout << "Inserting at start point iterator " << std::endl; pointx.insert(pointx.begin() + j, GeneralUtils::StrToDbl(lineentries[4])); errorx.insert(errorx.begin() + j, 0.0); pointy.insert(pointy.begin() + j, GeneralUtils::StrToDbl(lineentries[5]) * scalef); errory.insert(errory.begin() + j, GeneralUtils::StrToDbl(lineentries[6]) * scalef); break; } else if (GeneralUtils::StrToDbl(lineentries[4]) > pointx[j] && j == pointx.size() - 1) { // std::cout << "Pushing back data point " << std::endl; pointx.push_back(GeneralUtils::StrToDbl(lineentries[4])); errorx.push_back(0.0); pointy.push_back(GeneralUtils::StrToDbl(lineentries[5]) * scalef); errory.push_back(GeneralUtils::StrToDbl(lineentries[6]) * scalef); break; } else if (GeneralUtils::StrToDbl(lineentries[4]) > pointx[j - 1] && GeneralUtils::StrToDbl(lineentries[4]) < pointx[j]) { // std::cout << "Inserting at point iterator = " << j << std::endl; pointx.insert(pointx.begin() + j, GeneralUtils::StrToDbl(lineentries[4])); errorx.insert(errorx.begin() + j, 0.0); pointy.insert(pointy.begin() + j, GeneralUtils::StrToDbl(lineentries[5]) * scalef); errory.insert(errory.begin() + j, GeneralUtils::StrToDbl(lineentries[6]) * scalef); break; } } } // pointx.push_back(GeneralUtils::StrToDbl(lineentries[4])); // errorx.push_back(0.0); // pointy.push_back(GeneralUtils::StrToDbl(lineentries[5])); // errory.push_back(GeneralUtils::StrToDbl(lineentries[6])); i++; } if (!pointx.size() || (pointx.size() != errorx.size()) || !pointy.size() || (pointy.size() != errory.size())) { ERR(FTL) << "Failed to find dataset: " << name << "{" << "Z: " << zstring << ", A: " << astring << ", E: " << estring << ", CTheta: " << tstring << ", PubID: " << sstring << " } in file: " << (FitPar::GetDataBase() + "/Electron/" + target) << std::endl; throw; } // for (uint i = 0; i < pointx.size(); i++) { // std::cout << "Q0 Point " << i << " = " << pointx[i] << std::endl; // } fDataGraph = new TGraphErrors(pointx.size(), &pointx[0], &pointy[0], &errorx[0], &errory[0]); fDataGraph->SetNameTitle((fName + "_data_GRAPH").c_str(), (fName + "_data_GRAPH").c_str()); // Now form an effective data and mc histogram std::vector q0binedges; const double* x = fDataGraph->GetX(); // Loop over graph and get mid way point between each data point. for (int i = 0; i < fDataGraph->GetN(); i++) { // std::cout << "X Point = " << x[i] << std::endl; if (i == 0) { // First point set lower width as half distance to point above q0binedges.push_back(x[0] - ((x[1] - x[0]) / 2.0)); } else if (i == fDataGraph->GetN() - 1) { // Last point set upper width as half distance to point above. q0binedges.push_back(x[i] - ((x[i] - x[i - 1]) / 2.0)); q0binedges.push_back(x[i] + ((x[i] - x[i - 1]) / 2.0)); } else { // Set half distance to point below q0binedges.push_back(x[i] - ((x[i] - x[i - 1]) / 2.0)); } } // Bubble Sort // for (uint i = 0; i < q0binedges.size(); i++) { // std::cout << "Q0 Edge " << i << " = " << q0binedges[i] << std::endl; // } // for (uint i = 0; i < ebinedges.size(); i++) { // std::cout << "e Edge " << i << " = " << ebinedges[i] << std::endl; // } // for (uint i = 0; i < thetabinedges.size(); i++) { // std::cout << "theta Edge " << i << " = " << thetabinedges[i] << // std::endl; // } // Form the data hist, mchist, etc fDataHist = new TH1D((fName + "_data").c_str(), (fName + "_data").c_str(), q0binedges.size() - 1, &q0binedges[0]); fMCHist = (TH1D*)fDataHist->Clone("MC"); const double* y = fDataGraph->GetY(); const double* ey = fDataGraph->GetEY(); for (int i = 0; i < fDataGraph->GetN(); i++) { // std::cout << "Setting Data Bin " << i + 1 << " to " << y[i] << " +- " << // ey[i] << std::endl; fDataHist->SetBinContent(i + 1, y[i]); fDataHist->SetBinError(i + 1, ey[i]); fMCHist->SetBinContent(i + 1, 0.0); fMCHist->SetBinError(i + 1, 0.0); } fMCScan_Q0vsThetavsE = new TH3D((fName + "_MC_q0vsthetavse").c_str(), "MC_q0vsthetavse", q0binedges.size() - 1, &q0binedges[0], thetabinedges.size() - 1, &thetabinedges[0], ebinedges.size() - 1, &ebinedges[0]); fMCScan_Q0vsThetavsE->Reset(); fMCScan_Q0vsTheta = new TH2D( (fName + "_MC_q0vstheta").c_str(), "MC_q0vstheta", q0binedges.size() - 1, &q0binedges[0], thetabinedges.size() - 1, &thetabinedges[0]); fMCScan_Q0vsTheta->Reset(); fMCScan_Q0vsE = new TH2D((fName + "_MC_q0vse").c_str(), "MC_q0vse", q0binedges.size() - 1, &q0binedges[0], ebinedges.size() - 1, &ebinedges[0]); fMCScan_Q0vsE->Reset(); fXLowLim = fMCScan_Q0vsThetavsE->GetXaxis()->GetBinLowEdge(1); fXHighLim = fMCScan_Q0vsThetavsE->GetXaxis()->GetBinLowEdge( fMCScan_Q0vsThetavsE->GetNbinsX() + 2); fYLowLim = fMCScan_Q0vsThetavsE->GetYaxis()->GetBinLowEdge(1); fYHighLim = fMCScan_Q0vsThetavsE->GetYaxis()->GetBinLowEdge( fMCScan_Q0vsThetavsE->GetNbinsY() + 2); fZLowLim = fMCScan_Q0vsThetavsE->GetZaxis()->GetBinLowEdge(1); fZHighLim = fMCScan_Q0vsThetavsE->GetZaxis()->GetBinLowEdge( fMCScan_Q0vsThetavsE->GetNbinsZ() + 2); std::cout << "Sample " << name << "initialised: " << "{" << fXLowLim << "--" << fXHighLim << ", " << fYLowLim << "--" << fYHighLim << ", " << fZLowLim << "--" << fZHighLim << "}" << std::endl; } //******************************************************************** void ElectronScattering_DurhamData::FillEventVariables(FitEvent* event) { //******************************************************************** if (event->NumFSParticle(11) == 0) return; FitParticle* ein = event->PartInfo(0); FitParticle* eout = event->GetHMFSParticle(11); double q0 = fabs(ein->fP.E() - eout->fP.E()) / 1000.0; double E = ein->fP.E() / 1000.0; double theta = ein->fP.Vect().Angle(eout->fP.Vect()) * 180. / M_PI; fXVar = q0; fYVar = theta; fZVar = E; return; }; //******************************************************************** bool ElectronScattering_DurhamData::isSignal(FitEvent* event) { //******************************************************************** if (event->NumFSParticle(11) == 0) { std::cout << "Ev Cut due to no FS electron." << std::endl; return false; } // std::cout << "fXVar = " << fXVar << " " << fXLowLim << " " << fXHighLim << // std::endl; // std::cout << "fYVar = " << fYVar << " " << fYLowLim << " " << fYHighLim << // std::endl; // std::cout << "fZVar = " << fZVar << " " << fZLowLim << " " << fZHighLim << // std::endl; + // std::cout << "iWeight: " << event->InputWeight << std::endl; if (fXVar < fXLowLim or fXVar > fXHighLim) { - // std::cout << "Ev Cut due to X lims: " << fYLowLim << " -- " << fXHighLim - // << " !<> " << fXVar << std::endl; + // std::cout << "Ev Cut due to X lims: " << fXLowLim << " -- " << fXHighLim + // << " !<> " << fXVar << std::endl; return false; } if (fYVar < fYLowLim or fYVar > fYHighLim) { - // std::cout << "Ev Cut due to Y lims: " << fYLowLim << " -- " << fXHighLim - // << " !<> " << fXVar << std::endl; + // std::cout << "Ev Cut due to Y lims: " << fYLowLim << " -- " << fYHighLim + // << " !<> " << fXVar << std::endl; return false; } if (fZVar < fZLowLim or fZVar > fZHighLim) { - // std::cout << "Ev Cut due to Z lims: " << fYLowLim << " -- " << fXHighLim - // << " !<> " << fXVar << std::endl; + // std::cout << "Ev Cut due to Z lims: " << fZLowLim << " -- " << fZHighLim + // << " !<> " << fXVar << std::endl; return false; } return true; }; //******************************************************************** void ElectronScattering_DurhamData::FillHistograms() { //******************************************************************** Measurement1D::FillHistograms(); if (Signal) { fMCScan_Q0vsThetavsE->Fill(fXVar, fYVar, fZVar); fMCScan_Q0vsTheta->Fill(fXVar, fYVar); fMCScan_Q0vsE->Fill(fXVar, fZVar); } } // Weight = 1.0; // if (Signal) { // fMCHist->Fill(fXVar, Weight); // fMCFine->Fill(fXVar, Weight); // fMCStat->Fill(fXVar, 1.0); // if (fMCHist_Modes) fMCHist_Modes->Fill(Mode, fXVar, Weight); // } // } void ElectronScattering_DurhamData::ResetAll() { Measurement1D::ResetAll(); fMCScan_Q0vsThetavsE->Reset(); fMCScan_Q0vsTheta->Reset(); fMCScan_Q0vsE->Reset(); } void ElectronScattering_DurhamData::ApplyNormScale(double norm) { Measurement1D::ApplyNormScale(norm); fMCScan_Q0vsThetavsE->Scale(1.0 / norm); fMCScan_Q0vsTheta->Scale(1.0 / norm); fMCScan_Q0vsE->Scale(1.0 / norm); } //******************************************************************** void ElectronScattering_DurhamData::ScaleEvents() { //******************************************************************** Measurement1D::ScaleEvents(); /* fMCScan_Q0vsThetavsE->Scale(fScaleFactor, "width"); // Project into fMCScan_Q0vsTheta for (int x = 0; x < fMCScan_Q0vsThetavsE->GetNbinsX(); x++) { for (int y = 0; y < fMCScan_Q0vsThetavsE->GetNbinsY(); y++) { double total = 0.; for (int z = 0; z < fMCScan_Q0vsThetavsE->GetNbinsZ(); z++) { double zwidth = fMCScan_Q0vsThetavsE->GetZaxis()->GetBinWidth(z + 1); total += fMCScan_Q0vsThetavsE->GetBinContent(x + 1, y + 1, z + 1) * zwidth; } fMCScan_Q0vsTheta->SetBinContent(x + 1, y + 1, total); } } // Project into fMCScan_Q0vsE for (int x = 0; x < fMCScan_Q0vsThetavsE->GetNbinsX(); x++) { for (int z = 0; z < fMCScan_Q0vsThetavsE->GetNbinsZ(); z++) { double total = 0.; for (int y = 0; y < fMCScan_Q0vsThetavsE->GetNbinsY(); y++) { double ywidth = fMCScan_Q0vsThetavsE->GetYaxis()->GetBinWidth(y + 1); total += fMCScan_Q0vsThetavsE->GetBinContent(x + 1, y + 1, z + 1) * ywidth; } fMCScan_Q0vsE->SetBinContent(x + 1, z + 1, total); } } // Project fMCScan_Q0vsTheta into MC Hist for (int x = 0; x < fMCScan_Q0vsTheta->GetNbinsX(); x++) { double total = 0.; for (int y = 0; y < fMCScan_Q0vsTheta->GetNbinsY(); y++) { double ywidth = fMCScan_Q0vsTheta->GetYaxis()->GetBinWidth(y + 1); total += fMCScan_Q0vsTheta->GetBinContent(x + 1, y + 1); } double xwidth = fMCScan_Q0vsTheta->GetXaxis()->GetBinWidth(x + 1); fMCHist->SetBinContent(x + 1, total * xwidth); } fMCHist->Scale(fDataHist->Integral() / fMCHist->Integral()); */ } //******************************************************************** int ElectronScattering_DurhamData::GetNDOF() { //******************************************************************** return fDataGraph->GetN(); } void ElectronScattering_DurhamData::Write(std::string drawOpts) { Measurement1D::Write(drawOpts); fMCScan_Q0vsThetavsE->Write(); fMCScan_Q0vsTheta->Write(); fMCScan_Q0vsE->Write(); fDataGraph->Write(); } double ElectronScattering_DurhamData::GetLikelihood() { return 0.0; } void ElectronScattering_DurhamData::SetFitOptions(std::string opt) { return; } TH1D* ElectronScattering_DurhamData::GetMCHistogram(void) { return fMCHist; } TH1D* ElectronScattering_DurhamData::GetDataHistogram(void) { return fDataHist; } diff --git a/src/FCN/JointFCN.cxx b/src/FCN/#JointFCN.cxx# similarity index 99% copy from src/FCN/JointFCN.cxx copy to src/FCN/#JointFCN.cxx# index 54593b9..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 fSampleN = fSamples.size() + fPulls.size(); fSampleLikes = new double[fSampleN]; fSampleNDOF = new int[fSampleN]; // Add Dials std::vector dials = rw->GetDialNames(); for (size_t i = 0; i < dials.size(); i++){ fNameValues.push_back( dials[i] ); fCurrentValues.push_back( 0.0 ); } fNDials = dials.size(); fDialVals = new double[fNDials]; // Set IterationTree Flag fIterationTree = true; } //*************************************************** void JointFCN::DestroyIterationTree() { //*************************************************** fIterationCount.clear(); fCurrentValues.clear(); fNameValues.clear(); fIterationValues.clear(); } //*************************************************** void JointFCN::WriteIterationTree() { //*************************************************** LOG(FIT) << "Writing iteration tree" << std::endl; // Make a new TTree TTree* itree = new TTree(fIterationTreeName.c_str(), fIterationTreeName.c_str()); double* vals = new double[fNameValues.size()]; int count = 0; itree->Branch("iteration",&count,"Iteration/I"); for (int i = 0; i < fNameValues.size(); i++) { itree->Branch( fNameValues[i].c_str(), &vals[i], (fNameValues[i] + "/D").c_str() ); } // Fill Iterations for (size_t i = 0; i < fIterationValues.size(); i++){ std::vector itervals = fIterationValues[i]; // Fill iteration state count = fIterationCount[i]; for (size_t j = 0; j < itervals.size(); j++){ vals[j] = itervals[j]; } // Save to TTree itree->Fill(); } // Write to file + 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 (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 54593b9..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 + // 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]; + 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 (splinecount % countwidth == 0) { + 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 b7fe07c..857b9fb 100644 --- a/src/FCN/SampleList.cxx +++ b/src/FCN/SampleList.cxx @@ -1,1015 +1,1307 @@ #include "SampleList.h" #ifndef __NO_ANL__ #include "ANL_CCQE_Evt_1DQ2_nu.h" #include "ANL_CCQE_XSec_1DEnu_nu.h" // ANL CC1ppip #include "ANL_CC1ppip_Evt_1DQ2_nu.h" #include "ANL_CC1ppip_Evt_1DcosmuStar_nu.h" #include "ANL_CC1ppip_Evt_1DcosmuStar_nu.h" #include "ANL_CC1ppip_Evt_1DcosthAdler_nu.h" #include "ANL_CC1ppip_Evt_1Dphi_nu.h" #include "ANL_CC1ppip_Evt_1Dppi_nu.h" #include "ANL_CC1ppip_Evt_1Dthpr_nu.h" #include "ANL_CC1ppip_XSec_1DEnu_nu.h" #include "ANL_CC1ppip_XSec_1DQ2_nu.h" // ANL CC1npip #include "ANL_CC1npip_Evt_1DQ2_nu.h" #include "ANL_CC1npip_Evt_1DcosmuStar_nu.h" #include "ANL_CC1npip_Evt_1Dppi_nu.h" #include "ANL_CC1npip_XSec_1DEnu_nu.h" // ANL CC1pi0 #include "ANL_CC1pi0_Evt_1DQ2_nu.h" #include "ANL_CC1pi0_Evt_1DcosmuStar_nu.h" #include "ANL_CC1pi0_XSec_1DEnu_nu.h" // ANL NC1npip (mm, exotic!) #include "ANL_NC1npip_Evt_1Dppi_nu.h" // ANL NC1ppim (mm, exotic!) #include "ANL_NC1ppim_Evt_1DcosmuStar_nu.h" #include "ANL_NC1ppim_XSec_1DEnu_nu.h" // ANL CC2pi 1pim1pip (mm, even more exotic!) #include "ANL_CC2pi_1pim1pip_Evt_1Dpmu_nu.h" #include "ANL_CC2pi_1pim1pip_Evt_1Dppim_nu.h" #include "ANL_CC2pi_1pim1pip_Evt_1Dppip_nu.h" #include "ANL_CC2pi_1pim1pip_Evt_1Dpprot_nu.h" #include "ANL_CC2pi_1pim1pip_XSec_1DEnu_nu.h" // ANL CC2pi 1pip1pip (mm, even more exotic!) #include "ANL_CC2pi_1pip1pip_Evt_1Dpmu_nu.h" #include "ANL_CC2pi_1pip1pip_Evt_1Dpneut_nu.h" #include "ANL_CC2pi_1pip1pip_Evt_1DppipHigh_nu.h" #include "ANL_CC2pi_1pip1pip_Evt_1DppipLow_nu.h" #include "ANL_CC2pi_1pip1pip_XSec_1DEnu_nu.h" // ANL CC2pi 1pip1pi0 (mm, even more exotic!) #include "ANL_CC2pi_1pip1pi0_Evt_1Dpmu_nu.h" #include "ANL_CC2pi_1pip1pi0_Evt_1Dppi0_nu.h" #include "ANL_CC2pi_1pip1pi0_Evt_1Dppip_nu.h" #include "ANL_CC2pi_1pip1pi0_Evt_1Dpprot_nu.h" #include "ANL_CC2pi_1pip1pi0_XSec_1DEnu_nu.h" #endif #ifndef __NO_ArgoNeuT__ // ArgoNeuT CC-inclusive #include "ArgoNeuT_CCInc_XSec_1Dpmu_antinu.h" #include "ArgoNeuT_CCInc_XSec_1Dpmu_nu.h" #include "ArgoNeuT_CCInc_XSec_1Dthetamu_antinu.h" #include "ArgoNeuT_CCInc_XSec_1Dthetamu_nu.h" #endif #ifndef __NO_BNL__ // BNL CCQE #include "BNL_CCQE_Evt_1DQ2_nu.h" #include "BNL_CCQE_XSec_1DEnu_nu.h" // BNL CC1ppip #include "BNL_CC1ppip_Evt_1DQ2_nu.h" #include "BNL_CC1ppip_Evt_1DQ2_nu.h" #include "BNL_CC1ppip_Evt_1DcosthAdler_nu.h" #include "BNL_CC1ppip_Evt_1Dphi_nu.h" #include "BNL_CC1ppip_XSec_1DEnu_nu.h" // BNL CC1npip #include "BNL_CC1npip_Evt_1DQ2_nu.h" #include "BNL_CC1npip_XSec_1DEnu_nu.h" // BNL CC1pi0 #include "BNL_CC1pi0_Evt_1DQ2_nu.h" #include "BNL_CC1pi0_XSec_1DEnu_nu.h" #endif #ifndef __NO_FNAL__ // FNAL CCQE #include "FNAL_CCQE_Evt_1DQ2_nu.h" // FNAL CC1ppip #include "FNAL_CC1ppip_Evt_1DQ2_nu.h" #include "FNAL_CC1ppip_XSec_1DEnu_nu.h" #include "FNAL_CC1ppip_XSec_1DQ2_nu.h" // FNAL CC1ppim #include "FNAL_CC1ppim_XSec_1DEnu_antinu.h" #endif #ifndef __NO_BEBC__ // BEBC CCQE #include "BEBC_CCQE_XSec_1DQ2_nu.h" // BEBC CC1ppip #include "BEBC_CC1ppip_XSec_1DEnu_nu.h" #include "BEBC_CC1ppip_XSec_1DQ2_nu.h" // BEBC CC1npip #include "BEBC_CC1npip_XSec_1DEnu_nu.h" #include "BEBC_CC1npip_XSec_1DQ2_nu.h" // BEBC CC1pi0 #include "BEBC_CC1pi0_XSec_1DEnu_nu.h" #include "BEBC_CC1pi0_XSec_1DQ2_nu.h" // BEBC CC1npim #include "BEBC_CC1npim_XSec_1DEnu_antinu.h" #include "BEBC_CC1npim_XSec_1DQ2_antinu.h" // BEBC CC1ppim #include "BEBC_CC1ppim_XSec_1DEnu_antinu.h" #include "BEBC_CC1ppim_XSec_1DQ2_antinu.h" #endif #ifndef __NO_GGM__ // GGM CC1ppip #include "GGM_CC1ppip_Evt_1DQ2_nu.h" #include "GGM_CC1ppip_XSec_1DEnu_nu.h" #endif #ifndef __NO_MiniBooNE__ // MiniBooNE CCQE #include "MiniBooNE_CCQE_XSec_1DQ2_antinu.h" #include "MiniBooNE_CCQE_XSec_1DQ2_nu.h" #include "MiniBooNE_CCQE_XSec_2DTcos_antinu.h" #include "MiniBooNE_CCQE_XSec_2DTcos_antinu.h" #include "MiniBooNE_CCQE_XSec_2DTcos_nu.h" // MiniBooNE CC1pi+ 1D #include "MiniBooNE_CC1pip_XSec_1DEnu_nu.h" #include "MiniBooNE_CC1pip_XSec_1DQ2_nu.h" #include "MiniBooNE_CC1pip_XSec_1DTpi_nu.h" #include "MiniBooNE_CC1pip_XSec_1DTu_nu.h" // MiniBooNE CC1pi+ 2D #include "MiniBooNE_CC1pip_XSec_2DQ2Enu_nu.h" #include "MiniBooNE_CC1pip_XSec_2DTpiCospi_nu.h" #include "MiniBooNE_CC1pip_XSec_2DTpiEnu_nu.h" #include "MiniBooNE_CC1pip_XSec_2DTuCosmu_nu.h" #include "MiniBooNE_CC1pip_XSec_2DTuEnu_nu.h" // MiniBooNE CC1pi0 #include "MiniBooNE_CC1pi0_XSec_1DEnu_nu.h" #include "MiniBooNE_CC1pi0_XSec_1DQ2_nu.h" #include "MiniBooNE_CC1pi0_XSec_1DTu_nu.h" #include "MiniBooNE_CC1pi0_XSec_1Dcosmu_nu.h" #include "MiniBooNE_CC1pi0_XSec_1Dcospi0_nu.h" #include "MiniBooNE_CC1pi0_XSec_1Dppi0_nu.h" #include "MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu.h" #include "MiniBooNE_NC1pi0_XSec_1Dcospi0_nu.h" #include "MiniBooNE_NC1pi0_XSec_1Dppi0_antinu.h" #include "MiniBooNE_NC1pi0_XSec_1Dppi0_nu.h" // MiniBooNE NC1pi0 //#include "MiniBooNE_NCpi0_XSec_1Dppi0_nu.h" // MiniBooNE NCEL #include "MiniBooNE_NCEL_XSec_Treco_nu.h" #endif #ifndef __NO_MINERvA__ // MINERvA CCQE #include "MINERvA_CCQE_XSec_1DQ2_antinu.h" #include "MINERvA_CCQE_XSec_1DQ2_joint.h" #include "MINERvA_CCQE_XSec_1DQ2_nu.h" // MINERvA CC0pi #include "MINERvA_CC0pi_XSec_1DEe_nue.h" #include "MINERvA_CC0pi_XSec_1DQ2_nu_proton.h" #include "MINERvA_CC0pi_XSec_1DQ2_nue.h" #include "MINERvA_CC0pi_XSec_1DThetae_nue.h" // MINERvA CC1pi+ #include "MINERvA_CC1pip_XSec_1DTpi_20deg_nu.h" #include "MINERvA_CC1pip_XSec_1DTpi_nu.h" #include "MINERvA_CC1pip_XSec_1Dth_20deg_nu.h" #include "MINERvA_CC1pip_XSec_1Dth_nu.h" +// 2017 data update +#include "MINERvA_CC1pip_XSec_1D_2017Update.h" // MINERvA CCNpi+ #include "MINERvA_CCNpip_XSec_1DEnu_nu.h" #include "MINERvA_CCNpip_XSec_1DQ2_nu.h" #include "MINERvA_CCNpip_XSec_1DTpi_nu.h" #include "MINERvA_CCNpip_XSec_1Dpmu_nu.h" #include "MINERvA_CCNpip_XSec_1Dth_nu.h" #include "MINERvA_CCNpip_XSec_1Dthmu_nu.h" // MINERvA CC1pi0 #include "MINERvA_CC1pi0_XSec_1DEnu_antinu.h" #include "MINERvA_CC1pi0_XSec_1DQ2_antinu.h" #include "MINERvA_CC1pi0_XSec_1DTpi0_antinu.h" #include "MINERvA_CC1pi0_XSec_1Dpmu_antinu.h" #include "MINERvA_CC1pi0_XSec_1Dppi0_antinu.h" #include "MINERvA_CC1pi0_XSec_1Dth_antinu.h" #include "MINERvA_CC1pi0_XSec_1Dthmu_antinu.h" +// MINERvA CC1pi0 neutrino +#include "MINERvA_CC1pi0_XSec_1D_nu.h" + // MINERvA CCINC #include "MINERvA_CCinc_XSec_1DEnu_ratio.h" #include "MINERvA_CCinc_XSec_1Dx_ratio.h" #include "MINERvA_CCinc_XSec_2DEavq3_nu.h" // MINERvA CCDIS #include "MINERvA_CCDIS_XSec_1DEnu_ratio.h" #include "MINERvA_CCDIS_XSec_1Dx_ratio.h" // MINERvA CCCOH pion #include "MINERvA_CCCOHPI_XSec_1DEnu_antinu.h" -#include "MINERvA_CCCOHPI_XSec_1DEnu_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_1DQ2_nu.h" +#include "MINERvA_CCCOHPI_XSec_1Dth_nu.h" +#include "MINERvA_CCCOHPI_XSec_1Dth_nu.h" + +#include "MINERvA_CCCOHPI_XSec_joint.h" #include "MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu.h" #include "MINERvA_CC0pi_XSec_1DQ2_Tgt_nu.h" -#include "MINERvA_CC1pip_XSec_1D_2017Update.h" - +#include "MINERvA_CC0pi_XSec_2Dptpx_antinu.h" +#include "MINERvA_CC0pi_XSec_2Dptpx_nu.h" #endif #ifndef __NO_T2K__ // T2K CC0pi #include "T2K_CC0pi_XSec_2DPcos_nu.h" // T2K CC1pi+ on CH #include "T2K_CC1pip_CH_XSec_1DQ2_nu.h" #include "T2K_CC1pip_CH_XSec_1DWrec_nu.h" #include "T2K_CC1pip_CH_XSec_1Dpmu_nu.h" #include "T2K_CC1pip_CH_XSec_1Dppi_nu.h" #include "T2K_CC1pip_CH_XSec_1Dq3_nu.h" #include "T2K_CC1pip_CH_XSec_1Dthmupi_nu.h" #include "T2K_CC1pip_CH_XSec_1Dthpi_nu.h" #include "T2K_CC1pip_CH_XSec_1Dthq3pi_nu.h" // T2K CC1pi+ on H2O #include "T2K_CC1pip_H2O_XSec_1DEnuDelta_nu.h" #include "T2K_CC1pip_H2O_XSec_1DEnuMB_nu.h" #include "T2K_CC1pip_H2O_XSec_1Dcosmu_nu.h" #include "T2K_CC1pip_H2O_XSec_1Dcosmupi_nu.h" #include "T2K_CC1pip_H2O_XSec_1Dcospi_nu.h" #include "T2K_CC1pip_H2O_XSec_1Dpmu_nu.h" #include "T2K_CC1pip_H2O_XSec_1Dppi_nu.h" // T2K STV CC0pi #include "T2K_CC0pinp_STV_XSec_1Ddpt_nu.h" #include "T2K_CC0pi_XSec_2DPcos_nu_nonuniform.h" #endif #ifndef __NO_SciBooNE__ // SciBooNE COH studies #include "SciBooNE_CCCOH_1TRK_1DQ2_nu.h" #include "SciBooNE_CCCOH_MuPiNoVA_1DQ2_nu.h" #include "SciBooNE_CCCOH_MuPiNoVA_1Dthetapi_nu.h" #include "SciBooNE_CCCOH_MuPiNoVA_1Dthetapr_nu.h" #include "SciBooNE_CCCOH_MuPiVA_1DQ2_nu.h" #include "SciBooNE_CCCOH_MuPr_1DQ2_nu.h" #include "SciBooNE_CCCOH_STOPFINAL_1DQ2_nu.h" #include "SciBooNE_CCCOH_STOP_NTrks_nu.h" #endif #ifndef __NO_K2K__ // K2K NC1pi0 #include "K2K_NC1pi0_Evt_1Dppi0_nu.h" #endif // MC Studies #include "ExpMultDist_CCQE_XSec_1DVar_FakeStudy.h" #include "ExpMultDist_CCQE_XSec_2DVar_FakeStudy.h" #include "MCStudy_CCQEHistograms.h" #include "GenericFlux_Tester.h" #include "GenericFlux_Vectors.h" #include "ElectronFlux_FlatTree.h" #include "ElectronScattering_DurhamData.h" #include "MCStudy_KaonPreSelection.h" #include "MCStudy_MuonValidation.h" #include "OfficialNIWGPlots.h" #include "T2K2017_FakeData.h" #include "Simple_Osc.h" +#include "Smear_SVDUnfold_Propagation_Osc.h" #include "FitWeight.h" #include "NuisConfig.h" #include "NuisKey.h" +#ifdef __USE_DYNSAMPLES__ + +#include "TRegexp.h" + +#include + +// linux +#include + +DynamicSampleFactory::DynamicSampleFactory() : NSamples(0), NManifests(0) { + LoadPlugins(); + QLOG(FIT, "Loaded " << NSamples << " from " << NManifests + << " shared object libraries."); +} +DynamicSampleFactory* DynamicSampleFactory::glblDSF = NULL; +DynamicSampleFactory::PluginManifest::~PluginManifest() { + for (size_t i_it = 0; i_it < Instances.size(); ++i_it) { + (*(DSF_DestroySample))(Instances[i_it]); + } +} +std::string EnsureTrailingSlash(std::string const& inp) { + if (!inp.length()) { + return "/"; + } + if (inp[inp.length() - 1] == '/') { + return inp; + } + return inp + "/"; +} +void DynamicSampleFactory::LoadPlugins() { + std::vector SearchDirectories; + + if (Config::HasPar("dynamic_sample.path")) { + SearchDirectories = + GeneralUtils::ParseToStr(Config::GetParS("dynamic_sample.path"), ":"); + } + + char const* envPath = getenv("NUISANCE_DS_PATH"); + if (envPath) { + std::vector envPaths = GeneralUtils::ParseToStr(envPath, ":"); + for (size_t ep_it = 0; ep_it < envPaths.size(); ++ep_it) { + SearchDirectories.push_back(envPaths[ep_it]); + } + } + + if (!SearchDirectories.size()) { + char const* pwdPath = getenv("PWD"); + if (pwdPath) { + SearchDirectories.push_back(pwdPath); + } + } + + for (size_t sp_it = 0; sp_it < SearchDirectories.size(); ++sp_it) { + std::string dirpath = EnsureTrailingSlash(SearchDirectories[sp_it]); + + QLOG(FIT, "Searching for dynamic sample manifests in: " << dirpath); + + Ssiz_t len = 0; + DIR* dir; + struct dirent* ent; + dir = opendir(dirpath.c_str()); + if (dir != NULL) { + TRegexp matchExp("*.so", true); + while ((ent = readdir(dir)) != NULL) { + if (matchExp.Index(TString(ent->d_name), &len) != Ssiz_t(-1)) { + QLOG(FIT, "\tFound shared object: " + << ent->d_name << " checking for relevant methods..."); + + void* dlobj = + dlopen((dirpath + ent->d_name).c_str(), RTLD_NOW | RTLD_GLOBAL); + char const* dlerr_cstr = dlerror(); + std::string dlerr; + if (dlerr_cstr) { + dlerr = dlerr_cstr; + } + + if (dlerr.length()) { + ERROR(WRN, "\tDL Load Error: " << dlerr); + continue; + } + + PluginManifest plgManif; + plgManif.dllib = dlobj; + plgManif.soloc = (dirpath + ent->d_name); + + plgManif.DSF_NSamples = + reinterpret_cast(dlsym(dlobj, "DSF_NSamples")); + + dlerr = ""; + dlerr_cstr = dlerror(); + if (dlerr_cstr) { + dlerr = dlerr_cstr; + } + + if (dlerr.length()) { + ERROR(WRN, "\tFailed to load symbol \"DSF_NSamples\" from " + << (dirpath + ent->d_name) << ": " << dlerr); + dlclose(dlobj); + continue; + } + + plgManif.DSF_GetSampleName = reinterpret_cast( + dlsym(dlobj, "DSF_GetSampleName")); + + dlerr = ""; + dlerr_cstr = dlerror(); + if (dlerr_cstr) { + dlerr = dlerr_cstr; + } + + if (dlerr.length()) { + ERROR(WRN, "\tFailed to load symbol \"DSF_GetSampleName\" from " + << (dirpath + ent->d_name) << ": " << dlerr); + dlclose(dlobj); + continue; + } + + plgManif.DSF_GetSample = reinterpret_cast( + dlsym(dlobj, "DSF_GetSample")); + + dlerr = ""; + dlerr_cstr = dlerror(); + if (dlerr_cstr) { + dlerr = dlerr_cstr; + } + + if (dlerr.length()) { + ERROR(WRN, "\tFailed to load symbol \"DSF_GetSample\" from " + << (dirpath + ent->d_name) << ": " << dlerr); + dlclose(dlobj); + continue; + } + + plgManif.DSF_DestroySample = reinterpret_cast( + dlsym(dlobj, "DSF_DestroySample")); + + dlerr = ""; + dlerr_cstr = dlerror(); + if (dlerr_cstr) { + dlerr = dlerr_cstr; + } + + if (dlerr.length()) { + ERROR(WRN, "Failed to load symbol \"DSF_DestroySample\" from " + << (dirpath + ent->d_name) << ": " << dlerr); + dlclose(dlobj); + continue; + } + + plgManif.NSamples = (*(plgManif.DSF_NSamples))(); + QLOG(FIT, "\tSuccessfully loaded dynamic sample manifest: " + << plgManif.soloc << ". Contains " << plgManif.NSamples + << " samples."); + + for (size_t smp_it = 0; smp_it < plgManif.NSamples; ++smp_it) { + char const* smp_name = (*(plgManif.DSF_GetSampleName))(smp_it); + if (!smp_name) { + THROW("Could not load sample " << smp_it << " / " + << plgManif.NSamples << " from " + << plgManif.soloc); + } + + if (Samples.count(smp_name)) { + ERROR(WRN, "Already loaded a sample named: \"" + << smp_name << "\". cannot load duplciates. This " + "sample will be skipped."); + continue; + } + + plgManif.SamplesProvided.push_back(smp_name); + Samples[smp_name] = std::make_pair(plgManif.soloc, smp_it); + QLOG(FIT, "\t\t" << smp_name); + } + + if (plgManif.SamplesProvided.size()) { + Manifests[plgManif.soloc] = plgManif; + + NSamples += plgManif.SamplesProvided.size(); + NManifests++; + } else { + dlclose(dlobj); + } + } + } + closedir(dir); + } else { + ERROR(WRN, "Tried to open non-existant directory."); + } + } +} +DynamicSampleFactory& DynamicSampleFactory::Get() { + if (!glblDSF) { + glblDSF = new DynamicSampleFactory(); + } + return *glblDSF; +} +void DynamicSampleFactory::Print() { + std::map > ManifestSamples; + + for (std::map >::iterator smp_it = + Samples.begin(); + smp_it != Samples.end(); ++smp_it) { + if (!ManifestSamples.count(smp_it->second.first)) { + ManifestSamples[smp_it->second.first] = std::vector(); + } + ManifestSamples[smp_it->second.first].push_back(smp_it->first); + } + + QLOG(FIT, "Dynamic sample manifest: "); + for (std::map >::iterator m_it = + ManifestSamples.begin(); + m_it != ManifestSamples.end(); ++m_it) { + QLOG(FIT, "\tLibrary " << m_it->first << " contains: "); + for (size_t s_it = 0; s_it < m_it->second.size(); ++s_it) { + QLOG(FIT, "\t\t" << m_it->second[s_it]); + } + } +} +bool DynamicSampleFactory::HasSample(std::string const& name) { + return Samples.count(name); +} +bool DynamicSampleFactory::HasSample(nuiskey& samplekey) { + return HasSample(samplekey.GetS("name")); +} +MeasurementBase* DynamicSampleFactory::CreateSample(nuiskey& samplekey) { + if (!HasSample(samplekey)) { + ERROR(WRN, "Asked to load unknown sample: \"" << samplekey.GetS("name") + << "\"."); + return NULL; + } + + std::pair sample = Samples[samplekey.GetS("name")]; + QLOG(SAM, "\tLoading sample " << sample.second << " from " << sample.first); + return (*(Manifests[sample.first].DSF_GetSample))(sample.second, &samplekey); +} + +DynamicSampleFactory::~DynamicSampleFactory() { Manifests.clear(); } + +#endif //! Functions to make it easier for samples to be created and handled. namespace SampleUtils { //! Create a given sample given its name, file, type, fakdata(fkdt) file and the //! current rw engine and push it back into the list fChain. MeasurementBase* CreateSample(std::string name, std::string file, std::string type, std::string fkdt, FitWeight* rw) { nuiskey samplekey = Config::CreateKey("sample"); - samplekey.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) { +#ifdef __USE_DYNSAMPLES__ + if (DynamicSampleFactory::Get().HasSample(samplekey)) { + QLOG(SAM, "Instantiating dynamic sample..."); + + MeasurementBase* ds = DynamicSampleFactory::Get().CreateSample(samplekey); + if (ds) { + QLOG(SAM, "Done."); + return ds; + } + THROW("Failed to instantiate dynamic sample."); + } +#endif + FitWeight* rw = FitBase::GetRW(); std::string name = samplekey.GetS("name"); std::string file = samplekey.GetS("input"); std::string type = samplekey.GetS("type"); std::string fkdt = ""; /* ANL CCQE Samples */ #ifndef __NO_ANL__ if (!name.compare("ANL_CCQE_XSec_1DEnu_nu") || !name.compare("ANL_CCQE_XSec_1DEnu_nu_PRD26") || !name.compare("ANL_CCQE_XSec_1DEnu_nu_PRL31") || !name.compare("ANL_CCQE_XSec_1DEnu_nu_PRD16")) { return (new ANL_CCQE_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CCQE_Evt_1DQ2_nu") || !name.compare("ANL_CCQE_Evt_1DQ2_nu_PRL31") || !name.compare("ANL_CCQE_Evt_1DQ2_nu_PRD26") || !name.compare("ANL_CCQE_Evt_1DQ2_nu_PRD16")) { return (new ANL_CCQE_Evt_1DQ2_nu(samplekey)); /* ANL CC1ppip samples */ } else if (!name.compare("ANL_CC1ppip_XSec_1DEnu_nu") || !name.compare("ANL_CC1ppip_XSec_1DEnu_nu_W14Cut") || !name.compare("ANL_CC1ppip_XSec_1DEnu_nu_Uncorr") || !name.compare("ANL_CC1ppip_XSec_1DEnu_nu_W14Cut_Uncorr") || !name.compare("ANL_CC1ppip_XSec_1DEnu_nu_W16Cut_Uncorr")) { return (new ANL_CC1ppip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_XSec_1DQ2_nu")) { return (new ANL_CC1ppip_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_Evt_1DQ2_nu") || !name.compare("ANL_CC1ppip_Evt_1DQ2_nu_W14Cut")) { return (new ANL_CC1ppip_Evt_1DQ2_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_Evt_1Dppi_nu")) { return (new ANL_CC1ppip_Evt_1Dppi_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_Evt_1Dthpr_nu")) { return (new ANL_CC1ppip_Evt_1Dthpr_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_Evt_1DcosmuStar_nu")) { return (new ANL_CC1ppip_Evt_1DcosmuStar_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_Evt_1DcosthAdler_nu")) { return (new ANL_CC1ppip_Evt_1DcosthAdler_nu(samplekey)); } else if (!name.compare("ANL_CC1ppip_Evt_1Dphi_nu")) { return (new ANL_CC1ppip_Evt_1Dphi_nu(samplekey)); /* ANL CC1npip sample */ } else if (!name.compare("ANL_CC1npip_XSec_1DEnu_nu") || !name.compare("ANL_CC1npip_XSec_1DEnu_nu_W14Cut") || !name.compare("ANL_CC1npip_XSec_1DEnu_nu_Uncorr") || !name.compare("ANL_CC1npip_XSec_1DEnu_nu_W14Cut_Uncorr") || !name.compare("ANL_CC1npip_XSec_1DEnu_nu_W16Cut_Uncorr")) { return (new ANL_CC1npip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CC1npip_Evt_1DQ2_nu") || !name.compare("ANL_CC1npip_Evt_1DQ2_nu_W14Cut")) { return (new ANL_CC1npip_Evt_1DQ2_nu(samplekey)); } else if (!name.compare("ANL_CC1npip_Evt_1Dppi_nu")) { return (new ANL_CC1npip_Evt_1Dppi_nu(samplekey)); } else if (!name.compare("ANL_CC1npip_Evt_1DcosmuStar_nu")) { return (new ANL_CC1npip_Evt_1DcosmuStar_nu(samplekey)); /* ANL CC1pi0 sample */ } else if (!name.compare("ANL_CC1pi0_XSec_1DEnu_nu") || !name.compare("ANL_CC1pi0_XSec_1DEnu_nu_W14Cut") || !name.compare("ANL_CC1pi0_XSec_1DEnu_nu_Uncorr") || !name.compare("ANL_CC1pi0_XSec_1DEnu_nu_W14Cut_Uncorr") || !name.compare("ANL_CC1pi0_XSec_1DEnu_nu_W16Cut_Uncorr")) { return (new ANL_CC1pi0_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CC1pi0_Evt_1DQ2_nu") || !name.compare("ANL_CC1pi0_Evt_1DQ2_nu_W14Cut")) { return (new ANL_CC1pi0_Evt_1DQ2_nu(samplekey)); } else if (!name.compare("ANL_CC1pi0_Evt_1DcosmuStar_nu")) { return (new ANL_CC1pi0_Evt_1DcosmuStar_nu(samplekey)); /* ANL NC1npip sample */ } else if (!name.compare("ANL_NC1npip_Evt_1Dppi_nu")) { return (new ANL_NC1npip_Evt_1Dppi_nu(samplekey)); /* ANL NC1ppim sample */ } else if (!name.compare("ANL_NC1ppim_XSec_1DEnu_nu")) { return (new ANL_NC1ppim_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_NC1ppim_Evt_1DcosmuStar_nu")) { return (new ANL_NC1ppim_Evt_1DcosmuStar_nu(samplekey)); /* ANL CC2pi sample */ } else if (!name.compare("ANL_CC2pi_1pim1pip_XSec_1DEnu_nu")) { return (new ANL_CC2pi_1pim1pip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pim1pip_Evt_1Dpmu_nu")) { return (new ANL_CC2pi_1pim1pip_Evt_1Dpmu_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pim1pip_Evt_1Dppip_nu")) { return (new ANL_CC2pi_1pim1pip_Evt_1Dppip_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pim1pip_Evt_1Dppim_nu")) { return (new ANL_CC2pi_1pim1pip_Evt_1Dppim_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pim1pip_Evt_1Dpprot_nu")) { return (new ANL_CC2pi_1pim1pip_Evt_1Dpprot_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pip_XSec_1DEnu_nu")) { return (new ANL_CC2pi_1pip1pip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pip_Evt_1Dpmu_nu")) { return (new ANL_CC2pi_1pip1pip_Evt_1Dpmu_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pip_Evt_1Dpneut_nu")) { return (new ANL_CC2pi_1pip1pip_Evt_1Dpneut_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pip_Evt_1DppipHigh_nu")) { return (new ANL_CC2pi_1pip1pip_Evt_1DppipHigh_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pip_Evt_1DppipLow_nu")) { return (new ANL_CC2pi_1pip1pip_Evt_1DppipLow_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pi0_XSec_1DEnu_nu")) { return (new ANL_CC2pi_1pip1pi0_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pi0_Evt_1Dpmu_nu")) { return (new ANL_CC2pi_1pip1pi0_Evt_1Dpmu_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pi0_Evt_1Dppip_nu")) { return (new ANL_CC2pi_1pip1pi0_Evt_1Dppip_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pi0_Evt_1Dppi0_nu")) { return (new ANL_CC2pi_1pip1pi0_Evt_1Dppi0_nu(samplekey)); } else if (!name.compare("ANL_CC2pi_1pip1pi0_Evt_1Dpprot_nu")) { return (new ANL_CC2pi_1pip1pi0_Evt_1Dpprot_nu(samplekey)); /* ArgoNeut Samples */ } else #endif #ifndef __NO_ArgoNeuT__ if (!name.compare("ArgoNeuT_CCInc_XSec_1Dpmu_antinu")) { return (new ArgoNeuT_CCInc_XSec_1Dpmu_antinu(samplekey)); } else if (!name.compare("ArgoNeuT_CCInc_XSec_1Dpmu_nu")) { return (new ArgoNeuT_CCInc_XSec_1Dpmu_nu(samplekey)); } else if (!name.compare("ArgoNeuT_CCInc_XSec_1Dthetamu_antinu")) { return (new ArgoNeuT_CCInc_XSec_1Dthetamu_antinu(samplekey)); } else if (!name.compare("ArgoNeuT_CCInc_XSec_1Dthetamu_nu")) { return (new ArgoNeuT_CCInc_XSec_1Dthetamu_nu(samplekey)); /* BNL Samples */ } else #endif #ifndef __NO_BNL__ if (!name.compare("BNL_CCQE_XSec_1DEnu_nu")) { return (new BNL_CCQE_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BNL_CCQE_Evt_1DQ2_nu")) { return (new BNL_CCQE_Evt_1DQ2_nu(samplekey)); /* BNL CC1ppip samples */ } else if (!name.compare("BNL_CC1ppip_XSec_1DEnu_nu") || !name.compare("BNL_CC1ppip_XSec_1DEnu_nu_Uncorr") || !name.compare("BNL_CC1ppip_XSec_1DEnu_nu_W14Cut") || !name.compare("BNL_CC1ppip_XSec_1DEnu_nu_W14Cut_Uncorr")) { return (new BNL_CC1ppip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BNL_CC1ppip_Evt_1DQ2_nu") || !name.compare("BNL_CC1ppip_Evt_1DQ2_nu_W14Cut")) { return (new BNL_CC1ppip_Evt_1DQ2_nu(samplekey)); } else if (!name.compare("BNL_CC1ppip_Evt_1DcosthAdler_nu")) { return (new BNL_CC1ppip_Evt_1DcosthAdler_nu(samplekey)); } else if (!name.compare("BNL_CC1ppip_Evt_1Dphi_nu")) { return (new BNL_CC1ppip_Evt_1Dphi_nu(samplekey)); /* BNL CC1npip samples */ } else if (!name.compare("BNL_CC1npip_XSec_1DEnu_nu") || !name.compare("BNL_CC1npip_XSec_1DEnu_nu_Uncorr")) { return (new BNL_CC1npip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BNL_CC1npip_Evt_1DQ2_nu")) { return (new BNL_CC1npip_Evt_1DQ2_nu(samplekey)); /* BNL CC1pi0 samples */ } else if (!name.compare("BNL_CC1pi0_XSec_1DEnu_nu")) { return (new BNL_CC1pi0_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BNL_CC1pi0_Evt_1DQ2_nu")) { return (new BNL_CC1pi0_Evt_1DQ2_nu(samplekey)); /* FNAL Samples */ } else #endif #ifndef __NO_FNAL__ if (!name.compare("FNAL_CCQE_Evt_1DQ2_nu")) { return (new FNAL_CCQE_Evt_1DQ2_nu(samplekey)); /* FNAL CC1ppip */ } else if (!name.compare("FNAL_CC1ppip_XSec_1DEnu_nu")) { return (new FNAL_CC1ppip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("FNAL_CC1ppip_XSec_1DQ2_nu")) { return (new FNAL_CC1ppip_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("FNAL_CC1ppip_Evt_1DQ2_nu")) { return (new FNAL_CC1ppip_Evt_1DQ2_nu(samplekey)); /* FNAL CC1ppim */ } else if (!name.compare("FNAL_CC1ppim_XSec_1DEnu_antinu")) { return (new FNAL_CC1ppim_XSec_1DEnu_antinu(samplekey)); /* BEBC Samples */ } else #endif #ifndef __NO_BEBC__ if (!name.compare("BEBC_CCQE_XSec_1DQ2_nu")) { return (new BEBC_CCQE_XSec_1DQ2_nu(samplekey)); /* BEBC CC1ppip samples */ } else if (!name.compare("BEBC_CC1ppip_XSec_1DEnu_nu")) { return (new BEBC_CC1ppip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BEBC_CC1ppip_XSec_1DQ2_nu")) { return (new BEBC_CC1ppip_XSec_1DQ2_nu(samplekey)); /* BEBC CC1npip samples */ } else if (!name.compare("BEBC_CC1npip_XSec_1DEnu_nu")) { return (new BEBC_CC1npip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BEBC_CC1npip_XSec_1DQ2_nu")) { return (new BEBC_CC1npip_XSec_1DQ2_nu(samplekey)); /* BEBC CC1pi0 samples */ } else if (!name.compare("BEBC_CC1pi0_XSec_1DEnu_nu")) { return (new BEBC_CC1pi0_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("BEBC_CC1pi0_XSec_1DQ2_nu")) { return (new BEBC_CC1pi0_XSec_1DQ2_nu(samplekey)); /* BEBC CC1npim samples */ } else if (!name.compare("BEBC_CC1npim_XSec_1DEnu_antinu")) { return (new BEBC_CC1npim_XSec_1DEnu_antinu(samplekey)); } else if (!name.compare("BEBC_CC1npim_XSec_1DQ2_antinu")) { return (new BEBC_CC1npim_XSec_1DQ2_antinu(samplekey)); /* BEBC CC1ppim samples */ } else if (!name.compare("BEBC_CC1ppim_XSec_1DEnu_antinu")) { return (new BEBC_CC1ppim_XSec_1DEnu_antinu(samplekey)); } else if (!name.compare("BEBC_CC1ppim_XSec_1DQ2_antinu")) { return (new BEBC_CC1ppim_XSec_1DQ2_antinu(samplekey)); /* GGM CC1ppip samples */ } else #endif #ifndef __NO_GGM__ if (!name.compare("GGM_CC1ppip_XSec_1DEnu_nu")) { return (new GGM_CC1ppip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("GGM_CC1ppip_Evt_1DQ2_nu")) { return (new GGM_CC1ppip_Evt_1DQ2_nu(samplekey)); /* MiniBooNE Samples */ /* CCQE */ } else #endif #ifndef __NO_MiniBooNE__ if (!name.compare("MiniBooNE_CCQE_XSec_1DQ2_nu") || !name.compare("MiniBooNE_CCQELike_XSec_1DQ2_nu")) { return (new MiniBooNE_CCQE_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("MiniBooNE_CCQE_XSec_1DQ2_antinu") || !name.compare("MiniBooNE_CCQELike_XSec_1DQ2_antinu") || !name.compare("MiniBooNE_CCQE_CTarg_XSec_1DQ2_antinu")) { return (new MiniBooNE_CCQE_XSec_1DQ2_antinu(samplekey)); } else if (!name.compare("MiniBooNE_CCQE_XSec_2DTcos_nu") || !name.compare("MiniBooNE_CCQELike_XSec_2DTcos_nu")) { return (new MiniBooNE_CCQE_XSec_2DTcos_nu(samplekey)); } else if (!name.compare("MiniBooNE_CCQE_XSec_2DTcos_antinu") || !name.compare("MiniBooNE_CCQELike_XSec_2DTcos_antinu")) { return (new MiniBooNE_CCQE_XSec_2DTcos_antinu(samplekey)); /* MiniBooNE CC1pi+ */ // 1D } else if (!name.compare("MiniBooNE_CC1pip_XSec_1DEnu_nu")) { return (new MiniBooNE_CC1pip_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_1DQ2_nu")) { return (new MiniBooNE_CC1pip_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_1DTpi_nu")) { return (new MiniBooNE_CC1pip_XSec_1DTpi_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_1DTu_nu")) { return (new MiniBooNE_CC1pip_XSec_1DTu_nu(samplekey)); // 2D } else if (!name.compare("MiniBooNE_CC1pip_XSec_2DQ2Enu_nu")) { return (new MiniBooNE_CC1pip_XSec_2DQ2Enu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_2DTpiCospi_nu")) { return (new MiniBooNE_CC1pip_XSec_2DTpiCospi_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_2DTpiEnu_nu")) { return (new MiniBooNE_CC1pip_XSec_2DTpiEnu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_2DTuCosmu_nu")) { return (new MiniBooNE_CC1pip_XSec_2DTuCosmu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pip_XSec_2DTuEnu_nu")) { return (new MiniBooNE_CC1pip_XSec_2DTuEnu_nu(samplekey)); /* MiniBooNE CC1pi0 */ } else if (!name.compare("MiniBooNE_CC1pi0_XSec_1DEnu_nu")) { return (new MiniBooNE_CC1pi0_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pi0_XSec_1DQ2_nu")) { return (new MiniBooNE_CC1pi0_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pi0_XSec_1DTu_nu")) { return (new MiniBooNE_CC1pi0_XSec_1DTu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pi0_XSec_1Dcosmu_nu")) { return (new MiniBooNE_CC1pi0_XSec_1Dcosmu_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pi0_XSec_1Dcospi0_nu")) { return (new MiniBooNE_CC1pi0_XSec_1Dcospi0_nu(samplekey)); } else if (!name.compare("MiniBooNE_CC1pi0_XSec_1Dppi0_nu")) { return (new MiniBooNE_CC1pi0_XSec_1Dppi0_nu(samplekey)); } else if (!name.compare("MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu") || !name.compare("MiniBooNE_NC1pi0_XSec_1Dcospi0_rhc")) { return (new MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu(samplekey)); } else if (!name.compare("MiniBooNE_NC1pi0_XSec_1Dcospi0_nu") || !name.compare("MiniBooNE_NC1pi0_XSec_1Dcospi0_fhc")) { return (new MiniBooNE_NC1pi0_XSec_1Dcospi0_nu(samplekey)); } else if (!name.compare("MiniBooNE_NC1pi0_XSec_1Dppi0_antinu") || !name.compare("MiniBooNE_NC1pi0_XSec_1Dppi0_rhc")) { return (new MiniBooNE_NC1pi0_XSec_1Dppi0_antinu(samplekey)); } else if (!name.compare("MiniBooNE_NC1pi0_XSec_1Dppi0_nu") || !name.compare("MiniBooNE_NC1pi0_XSec_1Dppi0_fhc")) { return (new MiniBooNE_NC1pi0_XSec_1Dppi0_nu(samplekey)); /* MiniBooNE NCEL */ } else if (!name.compare("MiniBooNE_NCEL_XSec_Treco_nu")) { return (new MiniBooNE_NCEL_XSec_Treco_nu(samplekey)); /* MINERvA Samples */ } else #endif #ifndef __NO_MINERvA__ if (!name.compare("MINERvA_CCQE_XSec_1DQ2_nu") || !name.compare("MINERvA_CCQE_XSec_1DQ2_nu_20deg") || !name.compare("MINERvA_CCQE_XSec_1DQ2_nu_oldflux") || !name.compare("MINERvA_CCQE_XSec_1DQ2_nu_20deg_oldflux")) { return (new MINERvA_CCQE_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("MINERvA_CCQE_XSec_1DQ2_antinu") || !name.compare("MINERvA_CCQE_XSec_1DQ2_antinu_20deg") || !name.compare("MINERvA_CCQE_XSec_1DQ2_antinu_oldflux") || !name.compare("MINERvA_CCQE_XSec_1DQ2_antinu_20deg_oldflux")) { return (new MINERvA_CCQE_XSec_1DQ2_antinu(samplekey)); } else if (!name.compare("MINERvA_CCQE_XSec_1DQ2_joint_oldflux") || !name.compare("MINERvA_CCQE_XSec_1DQ2_joint_20deg_oldflux") || !name.compare("MINERvA_CCQE_XSec_1DQ2_joint") || !name.compare("MINERvA_CCQE_XSec_1DQ2_joint_20deg")) { return (new MINERvA_CCQE_XSec_1DQ2_joint(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_1DEe_nue")) { return (new MINERvA_CC0pi_XSec_1DEe_nue(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_1DQ2_nue")) { return (new MINERvA_CC0pi_XSec_1DQ2_nue(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_1DThetae_nue")) { return (new MINERvA_CC0pi_XSec_1DThetae_nue(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_1DQ2_nu_proton")) { return (new MINERvA_CC0pi_XSec_1DQ2_nu_proton(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtC_nu") || - !name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtCH_nu") || + !name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtCH_nu") || !name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtFe_nu") || !name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtPb_nu")) { return (new MINERvA_CC0pi_XSec_1DQ2_Tgt_nu(samplekey)); } else if (!name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtRatioC_nu") || !name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtRatioFe_nu") || !name.compare("MINERvA_CC0pi_XSec_1DQ2_TgtRatioPb_nu")) { return (new MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu(samplekey)); + } else if (!name.compare("MINERvA_CC0pi_XSec_2Dptpx_nu")) { + return (new MINERvA_CC0pi_XSec_2Dptpx_nu(samplekey)); + + } else if (!name.compare("MINERvA_CC0pi_XSec_2Dptpx_antinu")) { + return (new MINERvA_CC0pi_XSec_2Dptpx_antinu(samplekey)); + /* CC1pi+ */ // DONE } else if (!name.compare("MINERvA_CC1pip_XSec_1DTpi_nu") || !name.compare("MINERvA_CC1pip_XSec_1DTpi_nu_20deg") || !name.compare("MINERvA_CC1pip_XSec_1DTpi_nu_fluxcorr") || !name.compare("MINERvA_CC1pip_XSec_1DTpi_nu_20deg_fluxcorr")) { return (new MINERvA_CC1pip_XSec_1DTpi_nu(samplekey)); // DONE } else if (!name.compare("MINERvA_CC1pip_XSec_1Dth_nu") || !name.compare("MINERvA_CC1pip_XSec_1Dth_nu_20deg") || !name.compare("MINERvA_CC1pip_XSec_1Dth_nu_fluxcorr") || !name.compare("MINERvA_CC1pip_XSec_1Dth_nu_20deg_fluxcorr")) { return (new MINERvA_CC1pip_XSec_1Dth_nu(samplekey)); } else if (!name.compare("MINERvA_CC1pip_XSec_1DTpi_nu_2017") || !name.compare("MINERvA_CC1pip_XSec_1Dth_nu_2017") || !name.compare("MINERvA_CC1pip_XSec_1Dpmu_nu_2017") || !name.compare("MINERvA_CC1pip_XSec_1Dthmu_nu_2017") || !name.compare("MINERvA_CC1pip_XSec_1DQ2_nu_2017") || !name.compare("MINERvA_CC1pip_XSec_1DEnu_nu_2017")) { return (new MINERvA_CC1pip_XSec_1D_2017Update(samplekey)); /* CCNpi+ */ } else if (!name.compare("MINERvA_CCNpip_XSec_1Dth_nu") || !name.compare("MINERvA_CCNpip_XSec_1Dth_nu_2015") || !name.compare("MINERvA_CCNpip_XSec_1Dth_nu_2016") || !name.compare("MINERvA_CCNpip_XSec_1Dth_nu_2015_20deg") || !name.compare("MINERvA_CCNpip_XSec_1Dth_nu_2015_fluxcorr") || !name.compare("MINERvA_CCNpip_XSec_1Dth_nu_2015_20deg_fluxcorr")) { return (new MINERvA_CCNpip_XSec_1Dth_nu(samplekey)); } else if (!name.compare("MINERvA_CCNpip_XSec_1DTpi_nu") || !name.compare("MINERvA_CCNpip_XSec_1DTpi_nu_2015") || !name.compare("MINERvA_CCNpip_XSec_1DTpi_nu_2016") || !name.compare("MINERvA_CCNpip_XSec_1DTpi_nu_2015_20deg") || !name.compare("MINERvA_CCNpip_XSec_1DTpi_nu_2015_fluxcorr") || !name.compare( "MINERvA_CCNpip_XSec_1DTpi_nu_2015_20deg_fluxcorr")) { return (new MINERvA_CCNpip_XSec_1DTpi_nu(samplekey)); // Done } else if (!name.compare("MINERvA_CCNpip_XSec_1Dthmu_nu")) { return (new MINERvA_CCNpip_XSec_1Dthmu_nu(samplekey)); // Done } else if (!name.compare("MINERvA_CCNpip_XSec_1Dpmu_nu")) { return (new MINERvA_CCNpip_XSec_1Dpmu_nu(samplekey)); // Done } else if (!name.compare("MINERvA_CCNpip_XSec_1DQ2_nu")) { return (new MINERvA_CCNpip_XSec_1DQ2_nu(samplekey)); // Done } else if (!name.compare("MINERvA_CCNpip_XSec_1DEnu_nu")) { return (new MINERvA_CCNpip_XSec_1DEnu_nu(samplekey)); /* - CC1pi0 + 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_Fe56_CH") || !name.compare("MINERvA_CCinc_XSec_1DEnu_ratio_Pb208_CH")) { - return (new MINERvA_CCinc_XSec_1DEnu_ratio(samplekey)); + 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)); - + !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)); + !name.compare("MINERvA_CCDIS_XSec_1DEnu_ratio_Fe56_CH") || + !name.compare("MINERvA_CCDIS_XSec_1DEnu_ratio_Pb208_CH")) { + return (new MINERvA_CCDIS_XSec_1DEnu_ratio(samplekey)); /* CC-COH */ } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DEnu_nu")) { return (new MINERvA_CCCOHPI_XSec_1DEnu_nu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DEpi_nu")) { return (new MINERvA_CCCOHPI_XSec_1DEpi_nu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1Dth_nu")) { return (new MINERvA_CCCOHPI_XSec_1Dth_nu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DQ2_nu")) { return (new MINERvA_CCCOHPI_XSec_1DQ2_nu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DEnu_antinu")) { return (new MINERvA_CCCOHPI_XSec_1DEnu_antinu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DEpi_antinu")) { return (new MINERvA_CCCOHPI_XSec_1DEpi_antinu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1Dth_antinu")) { return (new MINERvA_CCCOHPI_XSec_1Dth_antinu(samplekey)); } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DQ2_antinu")) { return (new MINERvA_CCCOHPI_XSec_1DQ2_antinu(samplekey)); + } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DEnu_joint")) { + return (new MINERvA_CCCOHPI_XSec_joint(samplekey)); + } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DEpi_joint")) { + return (new MINERvA_CCCOHPI_XSec_joint(samplekey)); + } else if (!name.compare("MINERvA_CCCOHPI_XSec_1Dth_joint")) { + return (new MINERvA_CCCOHPI_XSec_joint(samplekey)); + } else if (!name.compare("MINERvA_CCCOHPI_XSec_1DQ2_joint")) { + return (new MINERvA_CCCOHPI_XSec_joint(samplekey)); + /* T2K Samples */ } else #endif #ifndef __NO_T2K__ if (!name.compare("T2K_CC0pi_XSec_2DPcos_nu") || !name.compare("T2K_CC0pi_XSec_2DPcos_nu_I") || !name.compare("T2K_CC0pi_XSec_2DPcos_nu_II")) { return (new T2K_CC0pi_XSec_2DPcos_nu(samplekey)); } else if (!name.compare("T2K_CC0pi_XSec_2DPcos_nu_nonuniform")) { return (new T2K_CC0pi_XSec_2DPcos_nu_nonuniform(samplekey)); /* T2K CC1pi+ CH samples */ // Comment these out for now because we don't have the proper data } else if (!name.compare("T2K_CC1pip_CH_XSec_1Dpmu_nu")) { return (new T2K_CC1pip_CH_XSec_1Dpmu_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1Dppi_nu")) { return (new T2K_CC1pip_CH_XSec_1Dppi_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1DQ2_nu")) { return (new T2K_CC1pip_CH_XSec_1DQ2_nu(file, rw, type, fkdt)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1Dq3_nu")) { return (new T2K_CC1pip_CH_XSec_1Dq3_nu(file, rw, type, fkdt)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1Dthmupi_nu")) { return (new T2K_CC1pip_CH_XSec_1Dthmupi_nu(file, rw, type, fkdt)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1Dthpi_nu")) { return (new T2K_CC1pip_CH_XSec_1Dthpi_nu(file, rw, type, fkdt)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1Dthq3pi_nu")) { return (new T2K_CC1pip_CH_XSec_1Dthq3pi_nu(file, rw, type, fkdt)); } else if (!name.compare("T2K_CC1pip_CH_XSec_1DWrec_nu")) { return (new T2K_CC1pip_CH_XSec_1DWrec_nu(file, rw, type, fkdt)); /* T2K CC1pi+ H2O samples */ } else if (!name.compare("T2K_CC1pip_H2O_XSec_1DEnuDelta_nu")) { return (new T2K_CC1pip_H2O_XSec_1DEnuDelta_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_H2O_XSec_1DEnuMB_nu")) { return (new T2K_CC1pip_H2O_XSec_1DEnuMB_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_H2O_XSec_1Dcosmu_nu")) { return (new T2K_CC1pip_H2O_XSec_1Dcosmu_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_H2O_XSec_1Dcosmupi_nu")) { return (new T2K_CC1pip_H2O_XSec_1Dcosmupi_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_H2O_XSec_1Dcospi_nu")) { return (new T2K_CC1pip_H2O_XSec_1Dcospi_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_H2O_XSec_1Dpmu_nu")) { return (new T2K_CC1pip_H2O_XSec_1Dpmu_nu(samplekey)); } else if (!name.compare("T2K_CC1pip_H2O_XSec_1Dppi_nu")) { return (new T2K_CC1pip_H2O_XSec_1Dppi_nu(samplekey)); /* T2K CC0pi + np CH samples */ } else if (!name.compare("T2K_CC0pinp_STV_XSec_1Ddpt_nu")) { return (new T2K_CC0pinp_STV_XSec_1Ddpt_nu(samplekey)); // SciBooNE COH studies } else #endif #ifndef __NO_SciBooNE__ if (!name.compare("SciBooNE_CCCOH_STOP_NTrks_nu")) { return (new SciBooNE_CCCOH_STOP_NTrks_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_1TRK_1DQ2_nu")) { return (new SciBooNE_CCCOH_1TRK_1DQ2_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPr_1DQ2_nu")) { return (new SciBooNE_CCCOH_MuPr_1DQ2_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPiVA_1DQ2_nu")) { return (new SciBooNE_CCCOH_MuPiVA_1DQ2_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPiNoVA_1DQ2_nu")) { return (new SciBooNE_CCCOH_MuPiNoVA_1DQ2_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPiNoVA_1Dthetapr_nu")) { return (new SciBooNE_CCCOH_MuPiNoVA_1Dthetapr_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_MuPiNoVA_1Dthetapi_nu")) { return (new SciBooNE_CCCOH_MuPiNoVA_1Dthetapi_nu(samplekey)); } else if (!name.compare("SciBooNE_CCCOH_STOPFINAL_1DQ2_nu")) { return (new SciBooNE_CCCOH_STOPFINAL_1DQ2_nu(samplekey)); /* K2K Samples */ /* NC1pi0 */ } else #endif #ifndef __NO_K2K__ if (!name.compare("K2K_NC1pi0_Evt_1Dppi0_nu")) { return (new K2K_NC1pi0_Evt_1Dppi0_nu(samplekey)); /* Fake Studies */ } else #endif if (name.find("ExpMultDist_CCQE_XSec_1D") != std::string::npos && name.find("_FakeStudy") != std::string::npos) { return ( new ExpMultDist_CCQE_XSec_1DVar_FakeStudy(name, file, rw, type, fkdt)); } else if (name.find("ExpMultDist_CCQE_XSec_2D") != std::string::npos && name.find("_FakeStudy") != std::string::npos) { return ( new ExpMultDist_CCQE_XSec_2DVar_FakeStudy(name, file, rw, type, fkdt)); } else if (name.find("GenericFlux_") != std::string::npos) { return (new GenericFlux_Tester(name, file, rw, type, fkdt)); } else if (name.find("GenericVectors_") != std::string::npos) { return (new GenericFlux_Vectors(name, file, rw, type, fkdt)); } else if (!name.compare("T2K2017_FakeData")) { return (new T2K2017_FakeData(samplekey)); } else if (!name.compare("MCStudy_CCQE")) { return (new MCStudy_CCQEHistograms(name, file, rw, type, fkdt)); } else if (!name.compare("ElectronFlux_FlatTree")) { return (new ElectronFlux_FlatTree(name, file, rw, type, fkdt)); } else if (name.find("ElectronData_") != std::string::npos) { return new ElectronScattering_DurhamData(samplekey); } else if (name.find("MuonValidation_") != std::string::npos) { return (new MCStudy_MuonValidation(name, file, rw, type, fkdt)); } else if (!name.compare("NIWGOfficialPlots")) { return (new OfficialNIWGPlots(samplekey)); - }else if (!name.compare("Simple_Osc")) { + } 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/FCN/SampleList.h b/src/FCN/SampleList.h index dbf0356..cd2db89 100644 --- a/src/FCN/SampleList.h +++ b/src/FCN/SampleList.h @@ -1,29 +1,85 @@ #ifndef _SAMPLE_LIST_H_ #define _SAMPLE_LIST_H_ /*! * \addtogroup FCN * @{ */ +#include #include +#include class FitWeight; class nuiskey; class MeasurementBase; +#ifdef __USE_DYNSAMPLES__ +/// Expect each .so containing samples to supply 4 c-style methods. +/// int DSF_NSamples(); +/// char const * DSF_GetSampleName(int); +/// MeasurementBase* DSF_GetSample(int, nuiskey *); +/// void DSF_DestroySample(MeasurementBase *); +class DynamicSampleFactory { + size_t NSamples; + size_t NManifests; + + DynamicSampleFactory(); + + static DynamicSampleFactory* glblDSF; + + typedef int (*DSF_NSamples_ptr)(void); + typedef char const* (*DSF_GetSampleName_ptr)(int); + typedef MeasurementBase* (*DSF_GetSample_ptr)(int, nuiskey *); + typedef void (*DSF_DestroySample_ptr)(MeasurementBase*); + + struct PluginManifest { + void* dllib; + + DSF_NSamples_ptr DSF_NSamples; + DSF_GetSampleName_ptr DSF_GetSampleName; + DSF_GetSample_ptr DSF_GetSample; + DSF_DestroySample_ptr DSF_DestroySample; + + std::string soloc; + std::vector Instances; + std::vector SamplesProvided; + size_t NSamples; + ~PluginManifest(); + }; + + std::map Manifests; + std::map > Samples; + + void LoadPlugins(); + + public: + static DynamicSampleFactory& Get(); + + void Print(); + + bool HasSample(std::string const& name); + bool HasSample(nuiskey& samplekey); + + MeasurementBase* CreateSample(nuiskey& samplekey); + + ~DynamicSampleFactory(); +}; + +#endif + //! Functions to make it easier for samples to be created and handled. namespace SampleUtils { //! Create a given sample given its name, file, type, fakdata(fkdt) file and the //! current rw engine and push it back into the list fChain. /*bool LoadSample(std::list* fChain, std::string name, std::string file, std::string type, std::string fkdt, FitWeight* rw);*/ MeasurementBase* CreateSample(std::string name, std::string file, std::string type, std::string fkdt, FitWeight* rw); MeasurementBase* CreateSample(nuiskey samplekey); } /*! @} */ #endif 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 70a03a5..cb2cdd3 100644 --- a/src/FitBase/Measurement1D.cxx +++ b/src/FitBase/Measurement1D.cxx @@ -1,1896 +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) && GetMCList().at(0)){ + 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 e373dfe..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. + /// 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 + /// \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.cxx b/src/FitBase/MeasurementBase.cxx index 235b470..9c8c621 100644 --- a/src/FitBase/MeasurementBase.cxx +++ b/src/FitBase/MeasurementBase.cxx @@ -1,562 +1,597 @@ // 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 "MeasurementBase.h" /* Constructor/Destructors */ //******************************************************************** // 2nd Level Constructor (Inherits From MeasurementBase.h) MeasurementBase::MeasurementBase(void) { //******************************************************************** fScaleFactor = 1.0; fMCFilled = false; fNoData = false; fInput = NULL; + NSignal = 0; // Set the default values // After-wards this gets set in SetupMeasurement EnuMin = 0.; EnuMax = 1.E5; fMeasurementSpeciesType = kSingleSpeciesMeasurement; fEventVariables = NULL; fIsJoint = false; + + fNPOT = 0xdeadbeef; + fFluxIntegralOverride = 0xdeadbeef; + fTargetVolume = 0xdeadbeef; + fTargetMaterialDensity = 0xdeadbeef; + fEvtRateScaleFactor = 0xdeadbeef; }; void MeasurementBase::FinaliseMeasurement() { - // Used to setup default data hists, covars, etc. - - - } //******************************************************************** // 2nd Level Destructor (Inherits From MeasurementBase.h) -MeasurementBase::~MeasurementBase() { - //******************************************************************** +MeasurementBase::~MeasurementBase(){ + //******************************************************************** }; //******************************************************************** double MeasurementBase::TotalIntegratedFlux(std::string intOpt, double low, - double high) { -//******************************************************************** + double high) { + //******************************************************************** // Set Energy Limits if (low == -9999.9) low = this->EnuMin; if (high == -9999.9) high = this->EnuMax; return GetInput()->TotalIntegratedFlux(low, high, intOpt); }; //******************************************************************** double MeasurementBase::PredictedEventRate(std::string intOpt, double low, - double high) { + double high) { //******************************************************************** // Set Energy Limits if (low == -9999.9) low = this->EnuMin; if (high == -9999.9) high = this->EnuMax; return GetInput()->PredictedEventRate(low, high, intOpt) * 1E-38; }; //******************************************************************** void MeasurementBase::SetupInputs(std::string inputfile) { //******************************************************************** - // Add this infile to the global manager if (FitPar::Config().GetParB("EventManager")) { fInput = FitBase::AddInput(fName, inputfile); } else { std::vector file_descriptor = - GeneralUtils::ParseToStr(inputfile, ":"); + GeneralUtils::ParseToStr(inputfile, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfile << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inpType = - InputUtils::ParseInputType(file_descriptor[0]); + InputUtils::ParseInputType(file_descriptor[0]); fInput = InputUtils::CreateInputHandler(fName, inpType, file_descriptor[1]); } - fNEvents = fInput->GetNEvents(); // Expect INPUTTYPE:FileLocation(s) std::vector file_descriptor = - GeneralUtils::ParseToStr(inputfile, ":"); + GeneralUtils::ParseToStr(inputfile, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfile << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } fInputType = InputUtils::ParseInputType(file_descriptor[0]); fInputFileName = file_descriptor[1]; if (EnuMin == 0 && EnuMax == 1.E5) { EnuMin = fInput->GetFluxHistogram()->GetBinLowEdge(1); EnuMax = fInput->GetFluxHistogram()->GetBinLowEdge( - fInput->GetFluxHistogram()->GetNbinsX() + 1); + fInput->GetFluxHistogram()->GetNbinsX() + 1); } fFluxHist = fInput->GetFluxHistogram(); fEventHist = fInput->GetEventHistogram(); } //*********************************************** int MeasurementBase::GetInputID() { -//*********************************************** + //*********************************************** return FitBase::GetInputID(fInputFileName); } //*********************************************** SampleSettings MeasurementBase::LoadSampleSettings(nuiskey samplekey) { -//*********************************************** + //*********************************************** SampleSettings setting = SampleSettings(samplekey); fName = setting.GetS("name"); // Used as an initial setup function incase we need to do anything here. LOG(SAM) << "Loading Sample : " << setting.GetName() << std::endl; - if (!fIsJoint) SetupInputs( setting.GetS("input") ); + + fEvtRateScaleFactor = 0xdeadbeef; + + if (!fIsJoint) { + SetupInputs(setting.GetS("input")); + + fNPOT = samplekey.Has("NPOT") ? samplekey.GetD("NPOT") : 1; + fFluxIntegralOverride = samplekey.Has("FluxIntegralOverride") + ? samplekey.GetD("FluxIntegralOverride") + : 0xdeadbeef; + fTargetVolume = samplekey.Has("TargetVolume") + ? samplekey.GetD("TargetVolume") + : 0xdeadbeef; + fTargetMaterialDensity = samplekey.Has("TargetMaterialDensity") + ? samplekey.GetD("TargetMaterialDensity") + : 0xdeadbeef; + if ((fTargetVolume != 0xdeadbeef) && + (fTargetMaterialDensity != 0xdeadbeef)) { + double TargetMass_kg = fTargetVolume * fTargetMaterialDensity; + double NNucleons = TargetMass_kg / PhysConst::mass_nucleon_kg; + double NNeutrinos = + ((fFluxIntegralOverride == 0xdeadbeef) ? TotalIntegratedFlux() + : fFluxIntegralOverride) * + fNPOT; + fEvtRateScaleFactor = NNeutrinos * NNucleons; + + QLOG(SAM, "\tEvent rate prediction : "); + QLOG(SAM, "\t\tTarget volume : " << fTargetVolume << " m^3"); + QLOG(SAM, "\t\tTarget density : " << fTargetMaterialDensity << " kg/m^3"); + QLOG(SAM, "\t\tTarget mass : " << TargetMass_kg << " kg"); + QLOG(SAM, "\t\tNTarget Nucleons : " << NNucleons); + if ((fNPOT != 1)) { + QLOG(SAM, "\t\tTotal POT : " << fNPOT); + } + QLOG(SAM, "\t\tNNeutrinos : " << NNeutrinos + << ((fNPOT != 1) ? " /cm^2" : " /POT /cm^2")); + QLOG(SAM, "\t\tXSec -> EvtRate scale factor : " << fEvtRateScaleFactor); + } + } return setting; } //*********************************************** -SampleSettings MeasurementBase::LoadSampleSettings(std::string name, std::string input, std::string type) { -//*********************************************** +SampleSettings MeasurementBase::LoadSampleSettings(std::string name, + std::string input, + std::string type) { + //*********************************************** nuiskey samplekey = Config::CreateKey("sample"); - samplekey.SetS("name",name); - samplekey.SetS("input",input); - samplekey.SetS("type",type); + samplekey.SetS("name", name); + samplekey.SetS("input", input); + samplekey.SetS("type", type); return LoadSampleSettings(samplekey); } void MeasurementBase::FinaliseSampleSettings() { - EnuMin = fSettings.GetD("enu_min"); EnuMax = fSettings.GetD("enu_max"); - } - //*********************************************** void MeasurementBase::Reconfigure() { -//*********************************************** - + //*********************************************** + LOG(REC) << " Reconfiguring sample " << fName << std::endl; // Reset Histograms ResetExtraHistograms(); AutoResetExtraTH1(); this->ResetAll(); // FitEvent* cust_event = fInput->GetEventPointer(); int fNEvents = fInput->GetNEvents(); int countwidth = (fNEvents / 5); - // MAIN EVENT LOOP FitEvent* cust_event = fInput->FirstNuisanceEvent(); int i = 0; int npassed = 0; - while(cust_event){ - + while (cust_event) { cust_event->RWWeight = fRW->CalcWeight(cust_event); cust_event->Weight = cust_event->RWWeight * cust_event->InputWeight; Weight = cust_event->Weight; // Initialize fXVar = -999.9; fYVar = -999.9; fZVar = -999.9; Signal = false; Mode = cust_event->Mode; // Extract Measurement Variables this->FillEventVariables(cust_event); Signal = this->isSignal(cust_event); if (Signal) npassed++; GetBox()->SetX(fXVar); GetBox()->SetY(fYVar); GetBox()->SetZ(fZVar); GetBox()->SetMode(Mode); // GetBox()->fSignal = Signal; // Fill Histogram Values GetBox()->FillBoxFromEvent(cust_event); // this->FillExtraHistograms(GetBox(), Weight); this->FillHistogramsFromBox(GetBox(), Weight); // Print Out if (LOG_LEVEL(REC) && countwidth > 0 && !(i % countwidth)) { std::stringstream ss(""); ss.unsetf(std::ios_base::fixed); ss << std::setw(7) << std::right << i << "/" << fNEvents << " events (" << std::setw(2) << double(i) / double(fNEvents) * 100. << std::left << std::setw(5) << "%) " << "[S,X,Y,Z,M,W] = [" << std::fixed << std::setprecision(2) << std::right << Signal << ", " << std::setw(5) << fXVar << ", " << std::setw(5) << fYVar << ", " << std::setw(5) << fYVar << ", " << std::setw(3) << (int)Mode << ", " << std::setw(5) << Weight << "] " << std::endl; LOG(SAM) << ss.str(); } // iterate cust_event = fInput->NextNuisanceEvent(); i++; } LOG(SAM) << npassed << "/" << fNEvents << " passed selection " << std::endl; if (npassed == 0) { LOG(SAM) << "WARNING: NO EVENTS PASSED SELECTION!" << std::endl; } - LOG(REC) << std::setw(10) << std::right << NSignal << "/" - << fNEvents << " events passed selection + binning after reweight" - << std::endl; + LOG(REC) << std::setw(10) << std::right << NSignal << "/" << fNEvents + << " events passed selection + binning after reweight" << std::endl; // Finalise Histograms fMCFilled = true; this->ConvertEventRates(); } -void MeasurementBase::FillHistogramsFromBox(MeasurementVariableBox* var, double weight) { - - fXVar = var->GetX(); - fYVar = var->GetY(); - fZVar = var->GetZ(); - // Signal = var->fSignal; - // Mode = var->fMode; +void MeasurementBase::FillHistogramsFromBox(MeasurementVariableBox* var, + double weight) { + fXVar = var->GetX(); + fYVar = var->GetY(); + fZVar = var->GetZ(); Weight = weight; fEventVariables = var; FillHistograms(); FillExtraHistograms(var, weight); - } -void MeasurementBase::FillHistograms(double weight){ +void MeasurementBase::FillHistograms(double weight) { Weight = weight * GetBox()->GetSampleWeight(); FillHistograms(); FillExtraHistograms(GetBox(), Weight); } - MeasurementVariableBox* MeasurementBase::FillVariableBox(FitEvent* event) { - GetBox()->Reset(); Mode = event->Mode; - Weight = 1.0; //event->Weight; + Weight = 1.0; // event->Weight; this->FillEventVariables(event); Signal = this->isSignal(event); GetBox()->FillBoxFromEvent(event); - + GetBox()->SetX(fXVar); GetBox()->SetY(fYVar); GetBox()->SetZ(fZVar); GetBox()->SetMode(event->Mode); GetBox()->SetSampleWeight(Weight); // GetBox()->fSignal = Signal; return GetBox(); } MeasurementVariableBox* MeasurementBase::GetBox() { if (!fEventVariables) fEventVariables = CreateBox(); return fEventVariables; } //*********************************************** void MeasurementBase::ReconfigureFast() { //*********************************************** this->Reconfigure(); } //*********************************************** void MeasurementBase::ConvertEventRates() { //*********************************************** AutoScaleExtraTH1(); ScaleExtraHistograms(GetBox()); this->ScaleEvents(); double normval = fRW->GetSampleNorm(this->fName); - if (normval < 0.01 or normval > 10.0){ - ERR(WRN) << "Norm Value inside MeasurementBase::ConvertEventRates() looks off!" << std::endl; - ERR(WRN) << "It could have become out of sync with the minimizer norm list." << std::endl; + if (normval < 0.01 or normval > 10.0) { + ERR(WRN) + << "Norm Value inside MeasurementBase::ConvertEventRates() looks off!" + << std::endl; + ERR(WRN) << "It could have become out of sync with the minimizer norm list." + << std::endl; ERR(WRN) << "Setting it to 1.0" << std::endl; normval = 1.0; } AutoNormExtraTH1(normval); NormExtraHistograms(GetBox(), normval); this->ApplyNormScale(normval); - } //*********************************************** InputHandlerBase* MeasurementBase::GetInput() { //*********************************************** if (!fInput) { ERR(FTL) << "MeasurementBase::fInput not set. Please submit your command " - "line options and input cardfile with a bug report to: " - "nuisance@projects.hepforge.org" + "line options and input cardfile with a bug report to: " + "nuisance@projects.hepforge.org" << std::endl; throw; } return fInput; }; //*********************************************** void MeasurementBase::Renormalise() { //*********************************************** // Called when the fitter has changed a measurements normalisation but not any // reweight dials // Means we don't have to call the time consuming reconfigure when this // happens. double norm = fRW->GetDialValue(this->fName + "_norm"); if ((this->fCurrentNorm == 0.0 and norm != 0.0) or not fMCFilled) { this->ReconfigureFast(); return; } if (this->fCurrentNorm == norm) return; this->ApplyNormScale(1.0 / this->fCurrentNorm); this->ApplyNormScale(norm); return; }; //*********************************************** void MeasurementBase::SetSignal(bool sig) { //*********************************************** Signal = sig; } //*********************************************** void MeasurementBase::SetSignal(FitEvent* evt) { //*********************************************** Signal = this->isSignal(evt); } //*********************************************** void MeasurementBase::SetWeight(double wght) { //*********************************************** Weight = wght; } //*********************************************** void MeasurementBase::SetMode(int md) { //*********************************************** Mode = md; } //*********************************************** std::vector MeasurementBase::GetFluxList() { //*********************************************** return GetInput()->GetFluxList(); } //*********************************************** std::vector MeasurementBase::GetEventRateList() { //*********************************************** return GetInput()->GetEventList(); } //*********************************************** std::vector MeasurementBase::GetXSecList() { //*********************************************** return GetInput()->GetXSecList(); } - void MeasurementBase::ProcessExtraHistograms(int cmd, - MeasurementVariableBox* vars, - double weight) { + MeasurementVariableBox* vars, + double weight) { // This should be overriden if we have extra histograms!!! // Add a flag to tell user this... return; } void MeasurementBase::FillExtraHistograms(MeasurementVariableBox* vars, - double weight) { + double weight) { ProcessExtraHistograms(kCMD_Fill, vars, weight); } void MeasurementBase::ScaleExtraHistograms(MeasurementVariableBox* vars) { ProcessExtraHistograms(kCMD_Scale, vars, 1.0); } void MeasurementBase::ResetExtraHistograms() { ProcessExtraHistograms(kCMD_Reset, NULL, 1.0); } void MeasurementBase::NormExtraHistograms(MeasurementVariableBox* vars, - double norm) { + double norm) { ProcessExtraHistograms(kCMD_Norm, vars, norm); } void MeasurementBase::WriteExtraHistograms() { ProcessExtraHistograms(kCMD_Write, NULL, 1.00); } -void MeasurementBase::SetAutoProcessTH1(TH1* hist, int c1, int c2, int c3, int c4, int c5) { +void MeasurementBase::SetAutoProcessTH1(TH1* hist, int c1, int c2, int c3, + int c4, int c5) { FakeStack* fake = new FakeStack(hist); - SetAutoProcessTH1(fake, c1, c2, c3, c4, c5); // Need to add a destroy command! + SetAutoProcessTH1(fake, c1, c2, c3, c4, + c5); // Need to add a destroy command! } -void MeasurementBase::SetAutoProcess(TH1* hist, int c1, int c2, int c3, int c4, int c5) { +void MeasurementBase::SetAutoProcess(TH1* hist, int c1, int c2, int c3, int c4, + int c5) { FakeStack* fake = new FakeStack(hist); - SetAutoProcessTH1(fake, c1, c2, c3, c4, c5); // Need to add a destroy command! + SetAutoProcessTH1(fake, c1, c2, c3, c4, + c5); // Need to add a destroy command! } -void MeasurementBase::SetAutoProcess(TGraph* g, int c1, int c2, int c3, int c4, int c5) { +void MeasurementBase::SetAutoProcess(TGraph* g, int c1, int c2, int c3, int c4, + int c5) { FakeStack* fake = new FakeStack(g); - SetAutoProcessTH1(fake, c1, c2, c3, c4, c5); // Need to add a destroy command! + SetAutoProcessTH1(fake, c1, c2, c3, c4, + c5); // Need to add a destroy command! } -void MeasurementBase::SetAutoProcess(TF1* f, int c1, int c2, int c3, int c4, int c5) { +void MeasurementBase::SetAutoProcess(TF1* f, int c1, int c2, int c3, int c4, + int c5) { FakeStack* fake = new FakeStack(f); - SetAutoProcessTH1(fake, c1, c2, c3, c4, c5); // Need to add a destroy command! + SetAutoProcessTH1(fake, c1, c2, c3, c4, + c5); // Need to add a destroy command! } -void MeasurementBase::SetAutoProcess(StackBase* hist, int c1, int c2, int c3, int c4, int c5){ +void MeasurementBase::SetAutoProcess(StackBase* hist, int c1, int c2, int c3, + int c4, int c5) { SetAutoProcessTH1(hist, c1, c2, c3, c4, c5); } -void MeasurementBase::SetAutoProcessTH1(StackBase* hist, int c1, int c2, int c3, int c4, int c5) { - +void MeasurementBase::SetAutoProcessTH1(StackBase* hist, int c1, int c2, int c3, + int c4, int c5) { // Set Defaults // int ncommands = kCMD_extraplotflags; bool autoflags[5]; autoflags[0] = false; autoflags[1] = false; autoflags[2] = false; autoflags[3] = false; autoflags[4] = false; int givenflags[5]; givenflags[0] = c1; givenflags[1] = c2; givenflags[2] = c3; givenflags[3] = c4; givenflags[4] = c5; - fExtraTH1s[hist] = std::vector(5,0); + fExtraTH1s[hist] = std::vector(5, 0); // Setup a default one. - if (c1 == -1 && c2 == -1 && c3 == -1 && c4 == -1 && c5 == -1){ + if (c1 == -1 && c2 == -1 && c3 == -1 && c4 == -1 && c5 == -1) { fExtraTH1s[hist][kCMD_Reset] = 1; fExtraTH1s[hist][kCMD_Scale] = 1; fExtraTH1s[hist][kCMD_Norm] = 1; fExtraTH1s[hist][kCMD_Write] = 1; } for (int i = 0; i < 5; i++) { switch (givenflags[i]) { - - // Skip over... - case -1: - break; - - case kCMD_Reset: - case kCMD_Scale: - case kCMD_Norm: - case kCMD_Write: - fExtraTH1s[hist][givenflags[i]] = 1; - break; - - case kCMD_Fill: - ERR(FTL) << "Can't auto fill yet!" << std::endl; - autoflags[givenflags[i]] = 1; - break; - - default: - break; + // Skip over... + case -1: + break; + + case kCMD_Reset: + case kCMD_Scale: + case kCMD_Norm: + case kCMD_Write: + fExtraTH1s[hist][givenflags[i]] = 1; + break; + + case kCMD_Fill: + ERR(FTL) << "Can't auto fill yet!" << std::endl; + autoflags[givenflags[i]] = 1; + break; + + default: + break; } } // LOG(SAM) << "AutoProcessing " << hist->GetName() << std::endl; }; void MeasurementBase::AutoFillExtraTH1() { ERR(FTL) << "Can't auto fill yet! it's too inefficent!" << std::endl; return; } void MeasurementBase::AutoResetExtraTH1() { - - for (std::map >::iterator iter = fExtraTH1s.begin(); + for (std::map >::iterator iter = + fExtraTH1s.begin(); iter != fExtraTH1s.end(); iter++) { - if (!((*iter).second)[kCMD_Reset]) continue; (*iter).first->Reset(); } }; void MeasurementBase::AutoScaleExtraTH1() { - for (std::map >::iterator iter = fExtraTH1s.begin(); + for (std::map >::iterator iter = + fExtraTH1s.begin(); iter != fExtraTH1s.end(); iter++) { - if (!((*iter).second)[kCMD_Scale]) continue; - if (fIsNoWidth){ + if (fIsNoWidth) { (*iter).first->Scale(fScaleFactor); } else { (*iter).first->Scale(fScaleFactor, "width"); } } }; void MeasurementBase::AutoNormExtraTH1(double norm) { double sfactor = 0.0; if (norm != 0.0) sfactor = 1.0 / norm; - for (std::map >::iterator iter = fExtraTH1s.begin(); + for (std::map >::iterator iter = + fExtraTH1s.begin(); iter != fExtraTH1s.end(); iter++) { - if (!((*iter).second)[kCMD_Norm]) continue; (*iter).first->Scale(sfactor); } }; void MeasurementBase::AutoWriteExtraTH1() { - for (std::map >::iterator iter = fExtraTH1s.begin(); + for (std::map >::iterator iter = + fExtraTH1s.begin(); iter != fExtraTH1s.end(); iter++) { - if (!(((*iter).second)[kCMD_Write])) continue; (*iter).first->Write(); } }; - - - diff --git a/src/FitBase/MeasurementBase.h b/src/FitBase/MeasurementBase.h index ea2e1e5..00dddc7 100644 --- a/src/FitBase/MeasurementBase.h +++ b/src/FitBase/MeasurementBase.h @@ -1,357 +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/ParamPull.h b/src/FitBase/ParamPull.h index 7da9eac..aa99977 100644 --- a/src/FitBase/ParamPull.h +++ b/src/FitBase/ParamPull.h @@ -1,193 +1,194 @@ // 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 PARAM_PULL_H_SEEN #define PARAM_PULL_H_SEEN /*! * \addtogroup FitBase * @{ */ #include #include #include #include #include #include #include #include // ROOT includes #include #include #include #include #include #include #include +#include "TRandom3.h" // Fit Includes #include "PlotUtils.h" #include "StatUtils.h" #include "FitWeight.h" #include "FitLogger.h" #include "EventManager.h" #include "TVector.h" using namespace std; //! Enums to allow Non Guassian Pulls in Future enum FitPullTypes { kUnknownPull = -1, kNoPull = 0, kGausPull = 1 }; enum FitThrowTypes { kUnknownThrow = -1, kNoThrow = 0, kGausThrow = 1, kFlatThrow = 2 }; //! Used to produce gaussian penalty terms in the fit. class ParamPull { public: //! Default Constructor ParamPull(std::string name, std::string inputfile, std::string type, std::string dials=""); //! Default destructor virtual ~ParamPull(void) {}; // Set dial types (DEFAULT,ABS,FRAC) void SetType(std::string type); // Setup Histogram inputs (from previous fit file, or ROOT file) void SetupHistograms(std::string input); // Read a previous NUISANCE file void ReadFitFile(std::string input); // Read a ROOT file with any histograms in void ReadRootFile(std::string input); // Read Text file void ReadVectFile(std::string input); // Read a single dial central value and error void ReadDialInput(std::string input); //! Reconfigure function reads in current RW engine dials and sets their value to MC void Reconfigure(void); //! Get likelihood given the current values double GetLikelihood(void); //! Get NDOF if used in likelihoods int GetNDOF(void); // Get Covariance Matrices as plots TH2D GetCovar(void); TH2D GetFullCovar(void); TH2D GetDecompCovar(void); // Get Covariance Matrices inline TMatrixDSym GetCovarMatrix (void) const { return *fInvCovar; }; inline TMatrixDSym GetFullCovarMatrix (void) const { return *fCovar; }; inline TMatrixDSym GetDecompCovarMatrix (void) const { return *fDecomp; }; //! Save the histograms void Write(std::string writeopt=""); //! Throw the dial values using the current covariance. Useful for parameter throws. void ThrowCovariance(void); //! Compare dials to RW bool CheckDialsValid(void); //! Reset toy data back to original data void ResetToy(void); //! Read fake data from MC void SetFakeData(std::string fakeinput); //! Reset fake data back to original data (before fake data or throws) void RemoveFakeData(); // Get Functions inline std::string GetName (void) const { return fName; }; inline std::string GetInput (void) const { return fInput; }; inline std::string GetType (void) const { return fType; }; inline std::string GetFileType (void) const { return fFileType; }; inline std::string GetDialOptions (void) const { return fDialOptions; }; std::map GetAllDials(); inline TH1D GetDataHist (void) const { return *fDataHist; }; inline TH1D GetDataTrue (void) const { return *fDataTrue; }; inline TH1D GetDataOrig (void) const { return *fDataOrig; }; inline TH1D GetMCHist (void) const { return *fMCHist; }; inline TH1D GetMaxHist (void) const { return *fMaxHist; }; inline TH1D GetMinHist (void) const { return *fMinHist; }; inline TH1I GetDialTypes (void) const { return *fTypeHist; }; inline TH1D GetLimitHist (void) const { return *fLimitHist; }; private: TH1D RemoveBinsNotInString(TH1D hist, std::string mystr); TH1I RemoveBinsNotInString(TH1I hist, std::string mystr); std::string fName; //!< Pull Name std::string fInput; //!< Pull input string std::string fType; //!< Pull options type std::string fFileType; //!< Pull input file types std::string fPlotTitles; //! Axis format std::string fDialOptions; //!< Dial handling options std::string fDialSelection; //!< Dial Selection TH1D* fMCHist; //!< Current MC Histogram TH1D* fDataHist; //!< Current data Histogram TH1D* fDataTrue; //!< True Data (before histogram throws) TH1D* fDataOrig; //!< Orig Data (without toys or fake data) TH1D* fMaxHist; //!< Maximum limit on MC/Data TH1D* fMinHist; //!< Maximum limit on MC/Data TH1I* fTypeHist; //!< Dial Types int fCalcType; //!< Method to calculate likelihood int fThrowType; //!< Method to calculate throws TMatrixDSym* fCovar; //!< Covariance TMatrixDSym* fInvCovar; //!< Inverted Covariance TMatrixDSym* fDecomp; //!< Decomposition TH1D* fLimitHist; }; // Class TypeDefs typedef std::list::const_iterator PullListConstIter; typedef std::list::iterator PullListIter; typedef std::vector::const_iterator PullVectConstIter; typedef std::vector::iterator PullVectIter; /*! @} */ #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/BaseFitEvt.cxx b/src/InputHandler/BaseFitEvt.cxx index a85065c..4c0cf07 100644 --- a/src/InputHandler/BaseFitEvt.cxx +++ b/src/InputHandler/BaseFitEvt.cxx @@ -1,328 +1,243 @@ // 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 "BaseFitEvt.h" #include "FitParticle.h" #include "GIBUUInputHandler.h" BaseFitEvt::BaseFitEvt() { Mode = 0; probe_E = 0xdeadbeef; probe_pdg = 0; Weight = 1.0; InputWeight = 1.0; RWWeight = 1.0; CustomWeight = 1.0; SavedRWWeight = 1.0; fSplineCoeff = NULL; fSplineRead = NULL; fGenInfo = NULL; fType = 9999; #ifdef __NEUT_ENABLED__ fNeutVect = NULL; #endif #ifdef __NUWRO_ENABLED__ #ifndef __USE_NUWRO_SRW_EVENTS__ fNuwroEvent = NULL; #endif #endif #ifdef __GENIE_ENABLED__ genie_event = NULL; genie_record = NULL; #endif #ifdef __NUANCE_ENABLED__ nuance_event = NULL; #endif #ifdef __GiBUU_ENABLED__ GiRead = NULL; #endif }; BaseFitEvt::~BaseFitEvt() { #ifdef __NEUT_ENABLED__ if (fNeutVect) delete fNeutVect; #endif #ifdef __NUWRO_ENABLED__ #ifndef __USE_NUWRO_SRW_EVENTS__ if (fNuwroEvent) delete fNuwroEvent; #endif #endif #ifdef __GENIE_ENABLED__ if (genie_event) delete genie_event; #endif #ifdef __NUANCE_ENABLED__ if (nuance_event) delete nuance_event; #endif #ifdef __GiBUU_ENABLED__ if (GiRead) delete GiRead; #endif }; BaseFitEvt::BaseFitEvt(const BaseFitEvt* obj) { Mode = obj->Mode; probe_E = obj->probe_E; probe_pdg = obj->probe_pdg; Weight = obj->Weight; InputWeight = obj->InputWeight; RWWeight = obj->RWWeight; CustomWeight = obj->CustomWeight; SavedRWWeight = obj->SavedRWWeight; fSplineCoeff = obj->fSplineCoeff; fSplineRead = obj->fSplineRead; fGenInfo = obj->fGenInfo; fType = obj->fType; #ifdef __NEUT_ENABLED__ fNeutVect = obj->fNeutVect; #endif #ifdef __NUWRO_ENABLED__ fNuwroEvent = obj->fNuwroEvent; #endif #ifdef __GENIE_ENABLED__ genie_event = obj->genie_event; #endif #ifdef __NUANCE_ENABLED__ nuance_event = obj->nuance_event; #endif #ifdef __GiBUU_ENABLED__ GiRead = obj->GiRead; #endif }; BaseFitEvt::BaseFitEvt(BaseFitEvt const& other) { Mode = other.Mode; probe_E = other.probe_E; probe_pdg = other.probe_pdg; Weight = other.Weight; InputWeight = other.InputWeight; RWWeight = other.RWWeight; CustomWeight = other.CustomWeight; SavedRWWeight = other.SavedRWWeight; fSplineCoeff = other.fSplineCoeff; fSplineRead = other.fSplineRead; fGenInfo = other.fGenInfo; fType = other.fType; #ifdef __NEUT_ENABLED__ fNeutVect = other.fNeutVect; #endif #ifdef __NUWRO_ENABLED__ fNuwroEvent = other.fNuwroEvent; #ifdef __USE_NUWRO_SRW_EVENTS__ fNuwroSRWEvent = other.fNuwroSRWEvent; ///< Pointer to Nuwro event fNuwroParams = other.fNuwroParams; #endif #endif #ifdef __GENIE_ENABLED__ genie_event = other.genie_event; #endif #ifdef __NUANCE_ENABLED__ nuance_event = other.nuance_event; #endif #ifdef __GiBUU_ENABLED__ GiRead = other.GiRead; #endif }; BaseFitEvt BaseFitEvt::operator=(BaseFitEvt const& other) { Mode = other.Mode; probe_E = other.probe_E; probe_pdg = other.probe_pdg; Weight = other.Weight; InputWeight = other.InputWeight; RWWeight = other.RWWeight; CustomWeight = other.CustomWeight; SavedRWWeight = other.SavedRWWeight; fSplineCoeff = other.fSplineCoeff; fSplineRead = other.fSplineRead; fGenInfo = other.fGenInfo; fType = other.fType; #ifdef __NEUT_ENABLED__ fNeutVect = other.fNeutVect; #endif #ifdef __NUWRO_ENABLED__ fNuwroEvent = other.fNuwroEvent; #ifdef __USE_NUWRO_SRW_EVENTS__ fNuwroSRWEvent = other.fNuwroSRWEvent; ///< Pointer to Nuwro event fNuwroParams = other.fNuwroParams; #endif #endif #ifdef __GENIE_ENABLED__ genie_event = other.genie_event; #endif #ifdef __NUANCE_ENABLED__ nuance_event = other.nuance_event; #endif #ifdef __GiBUU_ENABLED__ GiRead = other.GiRead; #endif return *this; } void BaseFitEvt::ResetWeight() { InputWeight = 1.0; } double BaseFitEvt::GetWeight() { return InputWeight * RWWeight * CustomWeight; }; #ifdef __NEUT_ENABLED__ void BaseFitEvt::SetNeutVect(NeutVect* v) { fType = kNEUT; fNeutVect = v; - -#ifdef __PROB3PP_ENABLED__ - for (size_t i = 0; i < npart; i++) { - NeutPart* part = fNeutVect->PartInfo(i); - if ((part->fIsAlive == false) && (part->fStatus == -1) && - std::count(PhysConst::pdg_neutrinos, PhysConst::pdg_neutrinos + 4, - part->fPID)) { - probe_E = part->fP.T(); - probe_pdg = part->fPID; - break; - } else { - continue; - } - } -#endif -} -#endif - -#ifdef __NUWRO_ENABLED__ - -void BaseFitEvt::SetNuwroEvent(event* e) { -#ifdef __USE_NUWRO_SRW_EVENTS__ - fNuwroSRWEvent = SRW::SRWEvent(*e); - probe_E = fNuwroSRWEvent.NeutrinoEnergy; - probe_pdg = fNuwroSRWEvent.NeutrinoPDG; - fNuwroParams = NULL; -#endif - fType = kNUWRO; - fNuwroEvent = e; - -#ifdef __PROB3PP_ENABLED__ -#ifndef __USE_NUWRO_SRW_EVENTS__ - for (size_t i = 0; i < fNuwroEvent->in.size(); i++) { - if (std::count(PhysConst::pdg_neutrinos, PhysConst::pdg_neutrinos + 4, - fNuwroEvent->in[i].pdg)) { - probe_E = fNuwroEvent->in[i].t; - probe_pdg = fNuwroEvent->in[i].pdg; - break; - } - } -#endif -#endif } #endif #ifdef __GENIE_ENABLED__ void BaseFitEvt::SetGenieEvent(NtpMCEventRecord* ntpl) { fType = kGENIE; genie_event = ntpl; - -#ifdef __PROB3PP_ENABLED__ - GHepRecord* GenieGHep = static_cast(fGenieNtpl->event); - if (!GenieGHep) return; - TObjArrayIter iter(GenieGHep); - while ((p = (dynamic_cast((iter).Next())))) { - if (!p) { - continue; - } - - // Get Status - int state = GetGENIEParticleStatus(p, fNUISANCEEvent->fMode); - if (state != genie::kIStInitialState) { - continue; - } - probe_E = p->E() * 1.E3; - probe_pdg = p->Pdg(); - break; - } -#endif } #endif #ifdef __NUANCE_ENABLED__ void BaseFitEvt::SetNuanceEvent(NuanceEvent* e) { fType = kNUANCE; nuance_event = e; } #endif -#ifdef __GiBUU_ENABLED__ -void BaseFitEvt::SetGiBUUReader(GiBUUStdHepReader* g) { - fType = kGiBUU; - GiRead = g; - -#ifdef __PROB3PP_ENABLED__ - for (int i = 0; i < GiRead->StdHepN; i++) { - int state = - GetGIBUUParticleStatus(GiRead->StdHepStatus[i], GiRead->StdHepPdg[i]); - if (state != kInitialState) { - continue; - } - if (std::count(PhysConst::pdg_neutrinos, PhysConst::pdg_neutrinos + 4, - GiRead->StdHepPdg[i])) { - probe_E = GiRead->StdHepP4[i][3] * 1.E3; - probe_pdg = GiRead->StdHepPdg[i]; - break; - } - } -#endif -} -#endif - void BaseFitEvt::SetInputFitEvent() { fType = kINPUTFITEVENT; } void BaseFitEvt::SetInputFitSpline() { fType = kNEWSPLINE; } void BaseFitEvt::SetInputHepMC() { fType = kHEPMC; } diff --git a/src/InputHandler/BaseFitEvt.h b/src/InputHandler/BaseFitEvt.h index 312b8c4..448c130 100644 --- a/src/InputHandler/BaseFitEvt.h +++ b/src/InputHandler/BaseFitEvt.h @@ -1,143 +1,139 @@ // 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 FITEVENTBASE_H_SEEN #define FITEVENTBASE_H_SEEN /*! * \addtogroup InputHandler * @{ */ #ifdef __NEUT_ENABLED__ #include "neutpart.h" #include "neutvect.h" #endif #ifdef __NUWRO_ENABLED__ #ifdef __USE_NUWRO_SRW_EVENTS__ #include "NuwroReWeightSimpleEvent.h" #else #include "event1.h" #endif #endif #ifdef __GENIE_ENABLED__ #include "EVGCore/EventRecord.h" #include "GHEP/GHepRecord.h" #include "Ntuple/NtpMCEventRecord.h" using namespace genie; #endif #ifdef __NUANCE_ENABLED__ #include "NuanceEvent.h" #endif #include "StdHepEvt.h" #include "SplineReader.h" #include "InputTypes.h" #include "GeneratorInfoBase.h" /// Base Event Class used to store just the generator event pointers class BaseFitEvt { public: /// Base Constructor BaseFitEvt(void); ~BaseFitEvt(); /// Copy base fit event pointers BaseFitEvt(const BaseFitEvt* obj); BaseFitEvt(BaseFitEvt const &); BaseFitEvt operator=(BaseFitEvt const &); /// Reset weight to 1.0 void ResetWeight(); /// Return combined weight for this event double GetWeight(); /// Manually set event type inline void SetType(int type){fType = type;}; // Global Event Variables/Weights int Mode; ///< True interaction mode double probe_E; ///< True probe energy double probe_pdg; // Weighting Info double Weight; ///< Total Weight For Event double InputWeight; ///< Input Starting Weight (used for GiBUU) double RWWeight; ///< Saved RW from FitWeight double CustomWeight; ///< Extra custom weight that samples can set double SavedRWWeight; ///< Saved RW value for FitEvents // Spline Info Coefficients and Readers float* fSplineCoeff; ///< ND Array of Spline Coefficients SplineReader* fSplineRead; ///< Spline Interpretter // Generator Info GeneratorInfoBase* fGenInfo; ///< Generator Variable Box UInt_t fType; ///< Generator Event Type #ifdef __NEUT_ENABLED__ /// Setup Event Reading from NEUT Event void SetNeutVect(NeutVect* v); NeutVect* fNeutVect; ///< Pointer to Neut Vector #endif #ifdef __NUWRO_ENABLED__ - /// Setup Event Reading from NuWro Event #ifdef __USE_NUWRO_SRW_EVENTS__ SRW::SRWEvent fNuwroSRWEvent; ///< Pointer to Nuwro event params * fNuwroParams; #endif - void SetNuwroEvent(event* e); event* fNuwroEvent; ///< Pointer to Nuwro event #endif #ifdef __GENIE_ENABLED__ /// Setup Event Reading from GENIE Event void SetGenieEvent(NtpMCEventRecord* ntpl); NtpMCEventRecord* genie_event; ///< Pointer to NTuple Genie Event GHepRecord* genie_record; ///< Pointer to actually accessible Genie Record #endif #ifdef __NUANCE_ENABLED__ /// Setup Event Reading from NUANCE Event void SetNuanceEvent(NuanceEvent* e); NuanceEvent* nuance_event; ///< Pointer to Nuance reader #endif #ifdef __GiBUU_ENABLED__ - /// Setup Event Reading from GIBUU Event - void SetGiBUUReader(GiBUUStdHepReader* g); GiBUUStdHepReader* GiRead; ///< Pointer to GiBUU reader #endif /// Setup Event Type to FitEvent void SetInputFitEvent(); /// Setup Event Type to FitSpline void SetInputFitSpline(); /// Setup Event Type to HepMC void SetInputHepMC(); }; /*! @} */ #endif diff --git a/src/InputHandler/CMakeLists.txt b/src/InputHandler/CMakeLists.txt index c96a4c2..5b2cf1d 100644 --- a/src/InputHandler/CMakeLists.txt +++ b/src/InputHandler/CMakeLists.txt @@ -1,91 +1,93 @@ # 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 BaseFitEvt.cxx FitParticle.cxx FitEvent.cxx GeneratorUtils.cxx StdHepEvt.cxx InputUtils.cxx NEUTInputHandler.cxx GENIEInputHandler.cxx NuWroInputHandler.cxx GIBUUInputHandler.cxx NUANCEInputHandler.cxx InputHandler.cxx NuanceEvent.cxx FitEventInputHandler.cxx SplineInputHandler.cxx GeneratorInfoBase.h InputTypes.h HepMCTextInputHandler.cxx InputFactory.cxx SigmaQ0HistogramInputHandler.cxx +HistogramInputHandler.cxx ) set(HEADERFILES NuanceEvent.h BaseFitEvt.h FitEvent.h FitParticle.h GeneratorUtils.h StdHepEvt.h InputUtils.h NEUTInputHandler.h HepMCTextInputHandler.h GENIEInputHandler.h NuWroInputHandler.h InputHandler.h GIBUUInputHandler.h NUANCEInputHandler.h FitEventInputHandler.h SplineInputHandler.h GeneratorInfoBase.h InputFactory.h InteractionModes.h SigmaQ0HistogramInputHandler.h +HistogramInputHandler.h ) set(LIBNAME InputHandler) 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() if(HEPMC_USED_EP) add_dependencies(${LIBNAME} HepMC) 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/InputHandler/FitEvent.cxx b/src/InputHandler/FitEvent.cxx index 13a4e14..61751f8 100644 --- a/src/InputHandler/FitEvent.cxx +++ b/src/InputHandler/FitEvent.cxx @@ -1,459 +1,429 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is pddrt of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "FitEvent.h" #include #include "TObjArray.h" FitEvent::FitEvent() { - fGenInfo = NULL; kRemoveFSIParticles = true; kRemoveUndefParticles = true; AllocateParticleStack(400); - }; - void FitEvent::AddGeneratorInfo(GeneratorInfoBase* gen) { fGenInfo = gen; gen->AllocateParticleStack(kMaxParticles); } void FitEvent::AllocateParticleStack(int stacksize) { LOG(DEB) << "Allocating particle stack of size: " << stacksize << std::endl; kMaxParticles = stacksize; - fParticleList = new FitParticle*[kMaxParticles]; + fParticleList = new FitParticle*[kMaxParticles]; - fParticleMom = new double*[kMaxParticles]; + fParticleMom = new double*[kMaxParticles]; fParticleState = new UInt_t[kMaxParticles]; - fParticlePDG = new int[kMaxParticles]; + fParticlePDG = new int[kMaxParticles]; - fOrigParticleMom = new double*[kMaxParticles]; + fOrigParticleMom = new double*[kMaxParticles]; fOrigParticleState = new UInt_t[kMaxParticles]; - fOrigParticlePDG = new int[kMaxParticles]; + fOrigParticlePDG = new int[kMaxParticles]; for (size_t i = 0; i < kMaxParticles; i++) { - fParticleList[i] = NULL; - fParticleMom[i] = new double[4]; + fParticleList[i] = NULL; + fParticleMom[i] = new double[4]; fOrigParticleMom[i] = new double[4]; } if (fGenInfo) fGenInfo->AllocateParticleStack(kMaxParticles); - } void FitEvent::ExpandParticleStack(int stacksize) { DeallocateParticleStack(); AllocateParticleStack(stacksize); } void FitEvent::DeallocateParticleStack() { - for (size_t i = 0; i < kMaxParticles; i++) { if (fParticleList[i]) delete fParticleList[i]; delete fParticleMom[i]; delete fOrigParticleMom[i]; } delete fParticleMom; delete fOrigParticleMom; delete fParticleList; delete fParticleState; delete fParticlePDG; delete fOrigParticleState; delete fOrigParticlePDG; - if (fGenInfo) fGenInfo -> DeallocateParticleStack(); + if (fGenInfo) fGenInfo->DeallocateParticleStack(); kMaxParticles = 0; - } void FitEvent::ClearFitParticles() { for (size_t i = 0; i < kMaxParticles; i++) { fParticleList[i] = NULL; } } void FitEvent::FreeFitParticles() { for (size_t i = 0; i < kMaxParticles; i++) { FitParticle* fp = fParticleList[i]; if (fp) delete fp; fParticleList[i] = NULL; } } void FitEvent::ResetParticleList() { for (unsigned int i = 0; i < kMaxParticles; i++) { FitParticle* fp = fParticleList[i]; if (fp) delete fp; fParticleList[i] = NULL; } } void FitEvent::HardReset() { for (unsigned int i = 0; i < kMaxParticles; i++) { fParticleList[i] = NULL; } } void FitEvent::ResetEvent() { - - fMode = 9999; Mode = 9999; fEventNo = -1; fTotCrs = -1.0; fTargetA = -1; fTargetZ = -1; fTargetH = -1; fBound = false; fNParticles = 0; if (fGenInfo) fGenInfo->Reset(); for (unsigned int i = 0; i < kMaxParticles; i++) { if (fParticleList[i]) delete fParticleList[i]; fParticleList[i] = NULL; continue; fParticlePDG[i] = 0; fParticleState[i] = kUndefinedState; fParticleMom[i][0] = 0.0; fParticleMom[i][1] = 0.0; fParticleMom[i][2] = 0.0; fParticleMom[i][3] = 0.0; fOrigParticlePDG[i] = 0; fOrigParticleState[i] = kUndefinedState; fOrigParticleMom[i][0] = 0.0; fOrigParticleMom[i][1] = 0.0; fOrigParticleMom[i][2] = 0.0; fOrigParticleMom[i][3] = 0.0; } - } void FitEvent::OrderStack() { - // Copy current stack int npart = fNParticles; for (int i = 0; i < npart; i++) { - fOrigParticlePDG[i] = fParticlePDG[i]; - fOrigParticleState[i] = fParticleState[i]; + fOrigParticlePDG[i] = fParticlePDG[i]; + fOrigParticleState[i] = fParticleState[i]; fOrigParticleMom[i][0] = fParticleMom[i][0]; fOrigParticleMom[i][1] = fParticleMom[i][1]; fOrigParticleMom[i][2] = fParticleMom[i][2]; fOrigParticleMom[i][3] = fParticleMom[i][3]; } // Now run loops for each particle fNParticles = 0; int stateorder[6] = {kInitialState, kFinalState, kFSIState, - kNuclearInitial, kNuclearRemnant, kUndefinedState - }; + kNuclearInitial, kNuclearRemnant, kUndefinedState}; for (int s = 0; s < 6; s++) { for (int i = 0; i < npart; i++) { if ((UInt_t)fOrigParticleState[i] != (UInt_t)stateorder[s]) continue; - fParticlePDG[fNParticles] = fOrigParticlePDG[i]; - fParticleState[fNParticles] = fOrigParticleState[i]; + fParticlePDG[fNParticles] = fOrigParticlePDG[i]; + fParticleState[fNParticles] = fOrigParticleState[i]; fParticleMom[fNParticles][0] = fOrigParticleMom[i][0]; fParticleMom[fNParticles][1] = fOrigParticleMom[i][1]; fParticleMom[fNParticles][2] = fOrigParticleMom[i][2]; fParticleMom[fNParticles][3] = fOrigParticleMom[i][3]; fNParticles++; } } if (LOG_LEVEL(DEB)) { LOG(DEB) << "Ordered stack" << std::endl; for (int i = 0; i < fNParticles; i++) { LOG(DEB) << "Particle " << i << ". " << fParticlePDG[i] << " " << fParticleMom[i][0] << " " << fParticleMom[i][1] << " " << fParticleMom[i][2] << " " << fParticleMom[i][3] << " " << fParticleState[i] << std::endl; } } if (fNParticles != npart) { ERR(FTL) << "Dropped some particles when ordering the stack!" << std::endl; } return; } - void FitEvent::Print() { - if (LOG_LEVEL(FIT)) { LOG(FIT) << "FITEvent print" << std::endl; - LOG(FIT) << "Mode: " << fMode << std::endl; + LOG(FIT) << "Mode: " << Mode << std::endl; LOG(FIT) << "Particles: " << fNParticles << std::endl; LOG(FIT) << " -> Particle Stack " << std::endl; for (int i = 0; i < fNParticles; i++) { LOG(FIT) << " -> -> " << i << ". " << fParticlePDG[i] << " " << fParticleState[i] << " " << " Mom(" << fParticleMom[i][0] << ", " << fParticleMom[i][1] - << ", " << fParticleMom[i][2] << ", " << fParticleMom[i][3] << ")." - << std::endl; + << ", " << fParticleMom[i][2] << ", " << fParticleMom[i][3] + << ")." << std::endl; } } return; } /* Read/Write own event class */ void FitEvent::SetBranchAddress(TChain* tn) { - - tn->SetBranchAddress("Mode", &fMode); - tn->SetBranchAddress("Mode", &Mode); + tn->SetBranchAddress("Mode", &Mode); tn->SetBranchAddress("EventNo", &fEventNo); - tn->SetBranchAddress("TotCrs", &fTotCrs); + tn->SetBranchAddress("TotCrs", &fTotCrs); tn->SetBranchAddress("TargetA", &fTargetA); tn->SetBranchAddress("TargetH", &fTargetH); - tn->SetBranchAddress("Bound", &fBound); + tn->SetBranchAddress("Bound", &fBound); - tn->SetBranchAddress("RWWeight", &SavedRWWeight); + tn->SetBranchAddress("RWWeight", &SavedRWWeight); tn->SetBranchAddress("InputWeight", &InputWeight); - - - - // This has to be setup by the handler now :( - // tn->SetBranchAddress("NParticles", &fNParticles); - // tn->SetBranchAddress("ParticleState", &fParticleState); - // tn->SetBranchAddress("ParticlePDG", &fParticlePDG); - // tn->SetBranchAddress("ParticleMom", &fParticleMom); - } void FitEvent::AddBranchesToTree(TTree* tn) { - tn->Branch("Mode", &Mode, "Mode/I"); tn->Branch("EventNo", &fEventNo, "EventNo/i"); - tn->Branch("TotCrs", &fTotCrs, "TotCrs/D"); + tn->Branch("TotCrs", &fTotCrs, "TotCrs/D"); tn->Branch("TargetA", &fTargetA, "TargetA/I"); tn->Branch("TargetH", &fTargetH, "TargetH/I"); - tn->Branch("Bound", &fBound, "Bound/O"); + tn->Branch("Bound", &fBound, "Bound/O"); - tn->Branch("RWWeight", &RWWeight, "RWWeight/D"); + tn->Branch("RWWeight", &RWWeight, "RWWeight/D"); tn->Branch("InputWeight", &InputWeight, "InputWeight/D"); - tn->Branch("NParticles", &fNParticles, "NParticles/I"); - tn->Branch("ParticleState", fOrigParticleState, "ParticleState[NParticles]/i"); - tn->Branch("ParticlePDG", fOrigParticlePDG, "ParticlePDG[NParticles]/I"); - tn->Branch("ParticleMom", fOrigParticleMom, "ParticleMom[NParticles][4]/D"); - + tn->Branch("NParticles", &fNParticles, "NParticles/I"); + tn->Branch("ParticleState", fOrigParticleState, + "ParticleState[NParticles]/i"); + tn->Branch("ParticlePDG", fOrigParticlePDG, "ParticlePDG[NParticles]/I"); + tn->Branch("ParticleMom", fOrigParticleMom, "ParticleMom[NParticles][4]/D"); } - // ------- EVENT ACCESS FUNCTION --------- // -TLorentzVector FitEvent::GetParticleP4 (int index) const { +TLorentzVector FitEvent::GetParticleP4(int index) const { if (index == -1 or index >= fNParticles) return TLorentzVector(); - return TLorentzVector( fParticleMom[index][0], - fParticleMom[index][1], - fParticleMom[index][2], - fParticleMom[index][3] ); + return TLorentzVector(fParticleMom[index][0], fParticleMom[index][1], + fParticleMom[index][2], fParticleMom[index][3]); } -TVector3 FitEvent::GetParticleP3 (int index) const { +TVector3 FitEvent::GetParticleP3(int index) const { if (index == -1 or index >= fNParticles) return TVector3(); - return TVector3( fParticleMom[index][0], - fParticleMom[index][1], - fParticleMom[index][2] ); + return TVector3(fParticleMom[index][0], fParticleMom[index][1], + fParticleMom[index][2]); } -double FitEvent::GetParticleMom (int index) const { +double FitEvent::GetParticleMom(int index) const { if (index == -1 or index >= fNParticles) return 0.0; return sqrt(fParticleMom[index][0] * fParticleMom[index][0] + fParticleMom[index][1] * fParticleMom[index][1] + fParticleMom[index][2] * fParticleMom[index][2]); } -double FitEvent::GetParticleMom2 (int index) const { +double FitEvent::GetParticleMom2(int index) const { if (index == -1 or index >= fNParticles) return 0.0; return fabs((fParticleMom[index][0] * fParticleMom[index][0] + fParticleMom[index][1] * fParticleMom[index][1] + fParticleMom[index][2] * fParticleMom[index][2])); } -double FitEvent::GetParticleE (int index) const { +double FitEvent::GetParticleE(int index) const { if (index == -1 or index >= fNParticles) return 0.0; return fParticleMom[index][3]; } -int FitEvent::GetParticleState (int index) const { +int FitEvent::GetParticleState(int index) const { if (index == -1 or index >= fNParticles) return kUndefinedState; return (fParticleState[index]); } -int FitEvent::GetParticlePDG (int index) const { +int FitEvent::GetParticlePDG(int index) const { if (index == -1 or index >= fNParticles) return 0; return (fParticlePDG[index]); } -FitParticle* FitEvent::GetParticle (int const i) { - +FitParticle* FitEvent::GetParticle(int const i) { // Check Valid Index - if (i == -1){ + if (i == -1) { return NULL; } // Check Valid if (i > fNParticles) { ERR(FTL) << "Requesting particle beyond stack!" << std::endl << "i = " << i << " N = " << fNParticles << std::endl - << "Mode = " << fMode << std::endl; + << "Mode = " << Mode << std::endl; throw; } if (!fParticleList[i]) { /* std::cout << "Creating particle with values i " << i << " "; - std::cout << fParticleMom[i][0] << " " << fParticleMom[i][1] << " " << fParticleMom[i][2] << " " << fParticleMom[i][3] << " "; + std::cout << fParticleMom[i][0] << " " << fParticleMom[i][1] << " " << + fParticleMom[i][2] << " " << fParticleMom[i][3] << " "; std::cout << fParticlePDG[i] << " " << fParticleState[i] << std::endl; */ fParticleList[i] = new FitParticle(fParticleMom[i][0], fParticleMom[i][1], fParticleMom[i][2], fParticleMom[i][3], fParticlePDG[i], fParticleState[i]); } else { /* std::cout << "Filling particle with values i " << i << " "; - std::cout << fParticleMom[i][0] << " " << fParticleMom[i][1] << " " << fParticleMom[i][2] << " " << fParticleMom[i][3] << " "; + std::cout << fParticleMom[i][0] << " " << fParticleMom[i][1] << " " << + fParticleMom[i][2] << " " << fParticleMom[i][3] << " "; std::cout << fParticlePDG[i] << " "<< fParticleState[i] <SetValues(fParticleMom[i][0], fParticleMom[i][1], fParticleMom[i][2], fParticleMom[i][3], fParticlePDG[i], fParticleState[i]); - } return fParticleList[i]; } bool FitEvent::HasParticle(int const pdg, int const state) const { bool found = false; for (int i = 0; i < fNParticles; i++) { if (state != -1 && fParticleState[i] != (uint)state) continue; if (fParticlePDG[i] == pdg) found = true; } return found; } int FitEvent::NumParticle(int const pdg, int const state) const { int nfound = 0; for (int i = 0; i < fNParticles; i++) { if (state != -1 and fParticleState[i] != (uint)state) continue; if (pdg == 0 or fParticlePDG[i] == pdg) nfound += 1; } return nfound; } -std::vector FitEvent::GetAllParticleIndices (int const pdg, int const state) const { +std::vector FitEvent::GetAllParticleIndices(int const pdg, + int const state) const { std::vector indexlist; for (int i = 0; i < fNParticles; i++) { if (state != -1 and fParticleState[i] != (uint)state) continue; if (pdg == 0 or fParticlePDG[i] == pdg) { indexlist.push_back(i); } } return indexlist; } -std::vector FitEvent::GetAllParticle(int const pdg, int const state) { +std::vector FitEvent::GetAllParticle(int const pdg, + int const state) { std::vector indexlist = GetAllParticleIndices(pdg, state); std::vector plist; for (std::vector::iterator iter = indexlist.begin(); iter != indexlist.end(); iter++) { - plist.push_back( GetParticle((*iter)) ); + plist.push_back(GetParticle((*iter))); } return plist; } -int FitEvent::GetHMParticleIndex (int const pdg, int const state) const { +int FitEvent::GetHMParticleIndex(int const pdg, int const state) const { double maxmom2 = -9999999.9; int maxind = -1; for (int i = 0; i < fNParticles; i++) { if (state != -1 and fParticleState[i] != (uint)state) continue; if (pdg == 0 or fParticlePDG[i] == pdg) { - double newmom2 = GetParticleMom2(i); if (newmom2 > maxmom2) { maxind = i; maxmom2 = newmom2; } } } return maxind; } -int FitEvent::GetBeamNeutrinoIndex (void) const { - for (int i = 0; i < fNParticles; i++){ +int FitEvent::GetBeamNeutrinoIndex(void) const { + for (int i = 0; i < fNParticles; i++) { if (fParticleState[i] != kInitialState) continue; int pdg = abs(fParticlePDG[i]); - if (pdg == 12 or pdg == 14 or pdg == 16){ + if (pdg == 12 or pdg == 14 or pdg == 16) { return i; } } return 0; } - -int FitEvent::GetBeamElectronIndex (void) const { - return GetHMISParticleIndex( 11 ); +int FitEvent::GetBeamElectronIndex(void) const { + return GetHMISParticleIndex(11); } -int FitEvent::GetBeamPionIndex (void) const { - return GetHMISParticleIndex( PhysConst::pdg_pions ); +int FitEvent::GetBeamPionIndex(void) const { + return GetHMISParticleIndex(PhysConst::pdg_pions); } int FitEvent::NumFSMesons() { int nMesons = 0; for (int i = 0; i < fNParticles; i++) { if (fParticleState[i] != kFinalState) continue; if (abs(fParticlePDG[i]) >= 111 && abs(fParticlePDG[i]) <= 557) nMesons += 1; } return nMesons; } -int FitEvent::NumFSLeptons(void) const{ - +int FitEvent::NumFSLeptons(void) const { int nLeptons = 0; for (int i = 0; i < fNParticles; i++) { if (fParticleState[i] != kFinalState) continue; if (abs(fParticlePDG[i]) == 11 || abs(fParticlePDG[i]) == 13 || - abs(fParticlePDG[i]) == 15) + abs(fParticlePDG[i]) == 15) nLeptons += 1; } return nLeptons; } diff --git a/src/InputHandler/FitEvent.h b/src/InputHandler/FitEvent.h index c8916c6..ddc5f99 100644 --- a/src/InputHandler/FitEvent.h +++ b/src/InputHandler/FitEvent.h @@ -1,613 +1,636 @@ // 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; }; + inline int GetMode (void) const { return Mode; }; /// 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); }; + inline bool IsCC() const { return (abs(Mode) <= 30); }; /// Is Event Neutral Current? - inline bool IsNC() const { return (abs(fMode) > 30); }; + inline bool IsNC() const { return (abs(Mode) > 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/FitEventInputHandler.cxx b/src/InputHandler/FitEventInputHandler.cxx index 969c245..441f648 100644 --- a/src/InputHandler/FitEventInputHandler.cxx +++ b/src/InputHandler/FitEventInputHandler.cxx @@ -1,130 +1,143 @@ +// 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 "FitEventInputHandler.h" +#include "InputUtils.h" + +FitEventInputHandler::FitEventInputHandler(std::string const& handle, + std::string const& rawinputs) { + LOG(SAM) << "Creating FitEventInputHandler : " << handle << std::endl; + + // Run a joint input handling + fName = handle; + fFitEventTree = new TChain("nuisance_events"); + fCacheSize = FitPar::Config().GetParI("CacheSize"); + + std::vector inputs = InputUtils::ParseInputFileList(rawinputs); + for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) { + // Open File for histogram access + TFile* inp_file = new TFile(inputs[inp_it].c_str(), "READ"); + if (!inp_file or inp_file->IsZombie()) { + ERR(FTL) << "FitEvent File IsZombie() at " << inputs[inp_it] << std::endl; + throw; + } + + // Get Flux/Event hist + TH1D* fluxhist = (TH1D*)inp_file->Get("nuisance_fluxhist"); + TH1D* eventhist = (TH1D*)inp_file->Get("nuisance_eventhist"); + if (!fluxhist or !eventhist) { + ERR(FTL) << "FitEvent FILE doesn't contain flux/xsec info" << std::endl; + throw; + } -FitEventInputHandler::FitEventInputHandler(std::string const& handle, std::string const& rawinputs) { - LOG(SAM) << "Creating FitEventInputHandler : " << handle << std::endl; - - // Run a joint input handling - fName = handle; - fFitEventTree = new TChain("nuisance_events"); - fCacheSize = FitPar::Config().GetParI("CacheSize"); - - std::vector inputs = InputUtils::ParseInputFileList(rawinputs); - for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) { - - - // Open File for histogram access - TFile* inp_file = new TFile(inputs[inp_it].c_str(), "READ"); - if (!inp_file or inp_file->IsZombie()) { - ERR(FTL) << "FitEvent File IsZombie() at " << inputs[inp_it] << std::endl; - throw; - } - - // Get Flux/Event hist - TH1D* fluxhist = (TH1D*)inp_file->Get("nuisance_fluxhist"); - TH1D* eventhist = (TH1D*)inp_file->Get("nuisance_eventhist"); - if (!fluxhist or !eventhist) { - ERR(FTL) << "FitEvent FILE doesn't contain flux/xsec info" << std::endl; - throw; - } - - // Get N Events - TTree* eventtree = (TTree*)inp_file->Get("nuisance_events"); - if (!eventtree) { - ERR(FTL) << "nuisance_events not located in GENIE file! " << inputs[inp_it] << std::endl; - throw; - } - int nevents = eventtree->GetEntries(); - - // Register input to form flux/event rate hists - RegisterJointInput(inputs[inp_it], nevents, fluxhist, eventhist); - - // Add to TChain - fFitEventTree->Add( inputs[inp_it].c_str() ); + // Get N Events + TTree* eventtree = (TTree*)inp_file->Get("nuisance_events"); + if (!eventtree) { + ERR(FTL) << "nuisance_events not located in GENIE file! " + << inputs[inp_it] << std::endl; + throw; } + int nevents = eventtree->GetEntries(); - // Registor all our file inputs - SetupJointInputs(); + // Register input to form flux/event rate hists + RegisterJointInput(inputs[inp_it], nevents, fluxhist, eventhist); - // Assign to tree - fEventType = kINPUTFITEVENT; + // Add to TChain + fFitEventTree->Add(inputs[inp_it].c_str()); + } - // Create Fit Event - fNUISANCEEvent = new FitEvent(); - fNUISANCEEvent->HardReset(); - fNUISANCEEvent->SetBranchAddress(fFitEventTree); - - fFitEventTree->SetBranchAddress("NParticles", &fReadNParticles); - fFitEventTree->SetBranchAddress("ParticleState", &fReadParticleState); - fFitEventTree->SetBranchAddress("ParticlePDG", &fReadParticlePDG); - fFitEventTree->SetBranchAddress("ParticleMom", &fReadParticleMom); + // Registor all our file inputs + SetupJointInputs(); + // Assign to tree + fEventType = kINPUTFITEVENT; - fFitEventTree->Show(0); - fNUISANCEEvent = GetNuisanceEvent(0); - std::cout << "NParticles = " << fNUISANCEEvent->Npart() << std::endl; - std::cout << "Event Info " << fNUISANCEEvent->PartInfo(0)->fPID << std::endl; - + // Create Fit Event + fNUISANCEEvent = new FitEvent(); + fNUISANCEEvent->HardReset(); + fNUISANCEEvent->SetBranchAddress(fFitEventTree); + + fFitEventTree->SetBranchAddress("NParticles", &fReadNParticles); + fFitEventTree->SetBranchAddress("ParticleState", &fReadParticleState); + fFitEventTree->SetBranchAddress("ParticlePDG", &fReadParticlePDG); + fFitEventTree->SetBranchAddress("ParticleMom", &fReadParticleMom); + + fFitEventTree->Show(0); + fNUISANCEEvent = GetNuisanceEvent(0); + std::cout << "NParticles = " << fNUISANCEEvent->Npart() << std::endl; + std::cout << "Event Info " << fNUISANCEEvent->PartInfo(0)->fPID << std::endl; } -FitEventInputHandler::~FitEventInputHandler(){ - if (fFitEventTree) delete fFitEventTree; +FitEventInputHandler::~FitEventInputHandler() { + if (fFitEventTree) delete fFitEventTree; } void FitEventInputHandler::CreateCache() { // fFitEventTree->SetCacheEntryRange(0, fNEvents); - // fFitEventTree->AddBranchToCache("*", 1); - // fFitEventTree->SetCacheSize(fCacheSize); + // fFitEventTree->AddBranchToCache("*", 1); + // fFitEventTree->SetCacheSize(fCacheSize); } void FitEventInputHandler::RemoveCache() { - //fFitEventTree->SetCacheEntryRange(0, fNEvents); + // fFitEventTree->SetCacheEntryRange(0, fNEvents); // fFitEventTree->AddBranchToCache("*", 0); // fFitEventTree->SetCacheSize(0); } -FitEvent* FitEventInputHandler::GetNuisanceEvent(const UInt_t entry, const bool lightweight) { +FitEvent* FitEventInputHandler::GetNuisanceEvent(const UInt_t entry, + const bool lightweight) { + // Return NULL if out of bounds + if (entry >= (UInt_t)fNEvents) return NULL; - // Return NULL if out of bounds - if (entry >= (UInt_t)fNEvents) return NULL; + // Reset all variables before tree read + fNUISANCEEvent->ResetEvent(); - // Reset all variables before tree read - fNUISANCEEvent->ResetEvent(); + // Read NUISANCE Tree + fFitEventTree->GetEntry(entry); - // Read NUISANCE Tree - fFitEventTree->GetEntry(entry); + // Fill Stack + fNUISANCEEvent->fNParticles = 0; + for (size_t i = 0; i < fReadNParticles; i++) { + size_t curpart = fNUISANCEEvent->fNParticles; + fNUISANCEEvent->fParticleState[curpart] = fReadParticleState[i]; - // Fill Stack - fNUISANCEEvent->fNParticles = 0; - for (size_t i = 0; i < fReadNParticles; i++){ - size_t curpart = fNUISANCEEvent->fNParticles; - fNUISANCEEvent->fParticleState[curpart] = fReadParticleState[i]; + // Mom + fNUISANCEEvent->fParticleMom[curpart][0] = fReadParticleMom[i][0]; + fNUISANCEEvent->fParticleMom[curpart][1] = fReadParticleMom[i][1]; + fNUISANCEEvent->fParticleMom[curpart][2] = fReadParticleMom[i][2]; + fNUISANCEEvent->fParticleMom[curpart][3] = fReadParticleMom[i][3]; - // Mom - fNUISANCEEvent->fParticleMom[curpart][0] = fReadParticleMom[i][0]; - fNUISANCEEvent->fParticleMom[curpart][1] = fReadParticleMom[i][1]; - fNUISANCEEvent->fParticleMom[curpart][2] = fReadParticleMom[i][2]; - fNUISANCEEvent->fParticleMom[curpart][3] = fReadParticleMom[i][3]; + // PDG + fNUISANCEEvent->fParticlePDG[curpart] = fReadParticlePDG[i]; - // PDG - fNUISANCEEvent->fParticlePDG[curpart] = fReadParticlePDG[i]; + // Add to N particle count + fNUISANCEEvent->fNParticles++; + } - // Add to N particle count - fNUISANCEEvent->fNParticles++; - } + // Setup Input scaling for joint inputs + fNUISANCEEvent->InputWeight = GetInputWeight(entry); - // Setup Input scaling for joint inputs - fNUISANCEEvent->InputWeight = GetInputWeight(entry); - - return fNUISANCEEvent; + return fNUISANCEEvent; } - double FitEventInputHandler::GetInputWeight(int entry) { - double w = InputHandlerBase::GetInputWeight(entry); - return w * fNUISANCEEvent->SavedRWWeight; + double w = InputHandlerBase::GetInputWeight(entry); + return w * fNUISANCEEvent->SavedRWWeight; } -void FitEventInputHandler::Print() { -} - - +void FitEventInputHandler::Print() {} diff --git a/src/InputHandler/FitEventInputHandler.h b/src/InputHandler/FitEventInputHandler.h index 5bdc84c..0f38ce6 100644 --- a/src/InputHandler/FitEventInputHandler.h +++ b/src/InputHandler/FitEventInputHandler.h @@ -1,43 +1,61 @@ +// 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 FITEVENT_INPUTHANDLER_H #define FITEVENT_INPUTHANDLER_H /*! * \addtogroup InputHandler * @{ */ #include "InputHandler.h" #include "FitEvent.h" #include "PlotUtils.h" /// Class to read in NUISANCE FitEvents that have been saved to tree class FitEventInputHandler : public InputHandlerBase { public: /// Standard constructor given name and inputs FitEventInputHandler(std::string const& handle, std::string const& rawinputs); virtual ~FitEventInputHandler(); /// Create a TTree Cache to speed up file read void CreateCache(); /// Remove TTree Cache to save memory void RemoveCache(); /// Returns NUISANCE FitEvent from the TTree. If lightweight does nothing. FitEvent* GetNuisanceEvent(const UInt_t entry, const bool lightweight=false); /// Alongside InputWeight also returns any saved RWWeights double GetInputWeight(int entry); /// Print out event information void Print(); TChain* fFitEventTree; ///< TTree from FitEvent file. int fReadNParticles; double fReadParticleMom[400][4]; UInt_t fReadParticleState[400]; int fReadParticlePDG[400]; }; /*! @} */ #endif diff --git a/src/InputHandler/FitParticle.h b/src/InputHandler/FitParticle.h index 5823109..fa9c263 100644 --- a/src/InputHandler/FitParticle.h +++ b/src/InputHandler/FitParticle.h @@ -1,109 +1,109 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #ifndef FITPARTICLE_H_SEEN #define FITPARTICLE_H_SEEN /*! * \addtogroup InputHandler * @{ */ #include "TLorentzVector.h" /// Partle state flags for its position in the event enum particle_state{ kUndefinedState = 5, kInitialState = 0, kFSIState = 1, kFinalState = 2, kNuclearInitial = 3, kNuclearRemnant = 4 }; /// Condensed FitParticle class which acts a common format between the generators class FitParticle { public: /// Create particle of given pdg from momentum variables and state FitParticle(double x, double y, double z, double t, int pdg, Int_t state); /// Create empty particle (zero momentum) FitParticle(){}; ~FitParticle(){}; /// Used to change values after creation void SetValues(double x, double y, double z, double t, int pdg, Int_t state); /// Return Status Code according to particle_state enum inline int Status (void) const { return fStatus; }; /// Get Particle PDF inline int PDG (void) const { return fPID; }; /// Check if particle makes it to final state inline bool IsFinalState (void) const { return (fStatus == kFinalState); }; /// Was particle involved in intermediate state inline bool IsFSIState (void) const { return (fStatus == kFSIState); }; /// Was particle incoming inline bool IsInitialState (void) const { return (fStatus == kInitialState); }; /// Get Mass - inline double M (void){ return fP.Mag(); }; + inline double M (void){ return fP.Mag(); }; /// Get Kinetic Energy - inline double KE (void){ return fP.E() - fP.Mag(); }; + inline double KE (void){ return fP.E() - fP.Mag(); }; /// Get Total Energy inline double E (void){ return fP.E(); }; /// Get 4 Momentum - inline TLorentzVector P4(void) {return fP;}; + inline TLorentzVector P4(void) {return fP;}; /// Get 3 Momentum - inline TVector3 P3(void) {return fP.Vect();}; + inline TVector3 P3(void) {return fP.Vect();}; /// Get 3 momentum magnitude inline double p(void) { return fP.Vect().Mag(); }; /// Get 3 momentum magnitude squared inline double p2(void) { return fP.Vect().Mag2(); }; /// Data Members TLorentzVector fP; ///< Particle 4 Momentum int fPID; ///< Particle PDG Code int fIsAlive; ///< Whether the particle is alive at the end of the event (Yes 1, No 0, Other? -1) int fNEUTStatusCode; ///< Particle Status (Incoming 1, FSI 2, Outgoing 0, Other 3) double fMass; ///< Particle Mass int fStatus; ///< State corresponding to particle_state enum }; inline std::ostream& operator<<(std::ostream& os, FitParticle const& p){ return os << " Particle[pdgc:" << p.fPID << ", stat:"<. +*******************************************************************************/ #ifdef __GENIE_ENABLED__ +#include "GENIEInputHandler.h" -GENIEGeneratorInfo::~GENIEGeneratorInfo() { - DeallocateParticleStack(); -} +#include "InputUtils.h" + +GENIEGeneratorInfo::~GENIEGeneratorInfo() { DeallocateParticleStack(); } void GENIEGeneratorInfo::AddBranchesToTree(TTree* tn) { tn->Branch("GenieParticlePDGs", &fGenieParticlePDGs, "GenieParticlePDGs/I"); } void GENIEGeneratorInfo::SetBranchesFromTree(TTree* tn) { tn->SetBranchAddress("GenieParticlePDGs", &fGenieParticlePDGs); } void GENIEGeneratorInfo::AllocateParticleStack(int stacksize) { fGenieParticlePDGs = new int[stacksize]; } void GENIEGeneratorInfo::DeallocateParticleStack() { delete fGenieParticlePDGs; } void GENIEGeneratorInfo::FillGeneratorInfo(NtpMCEventRecord* ntpl) { Reset(); // Check for GENIE Event if (!ntpl) return; if (!ntpl->event) return; // Cast Event Record GHepRecord* ghep = static_cast(ntpl->event); if (!ghep) return; // Fill Particle Stack GHepParticle* p = 0; TObjArrayIter iter(ghep); // Loop over all particles int i = 0; while ((p = (dynamic_cast((iter).Next())))) { if (!p) continue; // Get PDG fGenieParticlePDGs[i] = p->Pdg(); i++; } } void GENIEGeneratorInfo::Reset() { for (int i = 0; i < kMaxParticles; i++) { fGenieParticlePDGs[i] = 0; } } - -GENIEInputHandler::GENIEInputHandler(std::string const& handle, std::string const& rawinputs) { +GENIEInputHandler::GENIEInputHandler(std::string const& handle, + std::string const& rawinputs) { LOG(SAM) << "Creating GENIEInputHandler : " << handle << std::endl; // Run a joint input handling fName = handle; // Setup the TChain fGENIETree = new TChain("gtree"); fSaveExtra = FitPar::Config().GetParB("SaveExtraGenie"); fCacheSize = FitPar::Config().GetParI("CacheSize"); fMaxEvents = FitPar::Config().GetParI("MAXEVENTS"); // Loop over all inputs and grab flux, eventhist, and nevents std::vector inputs = InputUtils::ParseInputFileList(rawinputs); for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) { - // Open File for histogram access - TFile* inp_file = new TFile(InputUtils::ExpandInputDirectories(inputs[inp_it]).c_str(), "READ"); + TFile* inp_file = new TFile( + InputUtils::ExpandInputDirectories(inputs[inp_it]).c_str(), "READ"); if (!inp_file or inp_file->IsZombie()) { - THROW( "GENIE File IsZombie() at : '" << inputs[inp_it] << "'" << std::endl - << "Check that your file paths are correct and the file exists!" << std::endl - << "$ ls -lh " << inputs[inp_it] ); + THROW("GENIE File IsZombie() at : '" + << inputs[inp_it] << "'" << std::endl + << "Check that your file paths are correct and the file exists!" + << std::endl + << "$ ls -lh " << inputs[inp_it]); } // Get Flux/Event hist - TH1D* fluxhist = (TH1D*)inp_file->Get("nuisance_flux"); + TH1D* fluxhist = (TH1D*)inp_file->Get("nuisance_flux"); TH1D* eventhist = (TH1D*)inp_file->Get("nuisance_events"); if (!fluxhist or !eventhist) { - ERROR(FTL, "Input File Contents: " << inputs[inp_it] ); + ERROR(FTL, "Input File Contents: " << inputs[inp_it]); inp_file->ls(); - THROW( "GENIE FILE doesn't contain flux/xsec info." << std::endl - << "Try running the app PrepareGENIE first on :" << inputs[inp_it] << std::endl - << "$ PrepareGENIE -h" ); + THROW("GENIE FILE doesn't contain flux/xsec info." + << std::endl + << "Try running the app PrepareGENIE first on :" << inputs[inp_it] + << std::endl + << "$ PrepareGENIE -h"); } // Get N Events TTree* genietree = (TTree*)inp_file->Get("gtree"); if (!genietree) { ERROR(FTL, "gtree not located in GENIE file: " << inputs[inp_it]); THROW("Check your inputs, they may need to be completely regenerated!"); throw; } int nevents = genietree->GetEntries(); - if (nevents <= 0){ - THROW("Trying to a TTree with " << nevents << " to TChain from : " << inputs[inp_it]); + if (nevents <= 0) { + THROW("Trying to a TTree with " + << nevents << " to TChain from : " << inputs[inp_it]); } - // Register input to form flux/event rate hists RegisterJointInput(inputs[inp_it], nevents, fluxhist, eventhist); // Add To TChain - fGENIETree->AddFile( inputs[inp_it].c_str() ); + fGENIETree->AddFile(inputs[inp_it].c_str()); } // Registor all our file inputs SetupJointInputs(); // Assign to tree fEventType = kGENIE; fGenieNtpl = NULL; fGENIETree->SetBranchAddress("gmcrec", &fGenieNtpl); // Libraries should be seen but not heard... StopTalking(); fGENIETree->GetEntry(0); StartTalking(); // Create Fit Event fNUISANCEEvent = new FitEvent(); fNUISANCEEvent->SetGenieEvent(fGenieNtpl); if (fSaveExtra) { - fGenieInfo = new GENIEGeneratorInfo(); + fGenieInfo = new GENIEGeneratorInfo(); fNUISANCEEvent->AddGeneratorInfo(fGenieInfo); } fNUISANCEEvent->HardReset(); - }; GENIEInputHandler::~GENIEInputHandler() { - //if (fGenieGHep) delete fGenieGHep; - //if (fGenieNtpl) delete fGenieNtpl; - //if (fGENIETree) delete fGENIETree; - //if (fGenieInfo) delete fGenieInfo; + // if (fGenieGHep) delete fGenieGHep; + // if (fGenieNtpl) delete fGenieNtpl; + // if (fGENIETree) delete fGENIETree; + // if (fGenieInfo) delete fGenieInfo; } void GENIEInputHandler::CreateCache() { if (fCacheSize > 0) { // fGENIETree->SetCacheEntryRange(0, fNEvents); fGENIETree->AddBranchToCache("*", 1); fGENIETree->SetCacheSize(fCacheSize); } } void GENIEInputHandler::RemoveCache() { // fGENIETree->SetCacheEntryRange(0, fNEvents); fGENIETree->AddBranchToCache("*", 0); fGENIETree->SetCacheSize(0); } -FitEvent* GENIEInputHandler::GetNuisanceEvent(const UInt_t entry, const bool lightweight) { +FitEvent* GENIEInputHandler::GetNuisanceEvent(const UInt_t entry, + const bool lightweight) { if (entry >= (UInt_t)fNEvents) return NULL; // Read Entry from TTree to fill NEUT Vect in BaseFitEvt; fGENIETree->GetEntry(entry); // Run NUISANCE Vector Filler if (!lightweight) { CalcNUISANCEKinematics(); } +#ifdef __PROB3PP_ENABLED__ + else { + // Check for GENIE Event + if (!fGenieNtpl) return NULL; + if (!fGenieNtpl->event) return NULL; + + // Cast Event Record + fGenieGHep = static_cast(fGenieNtpl->event); + if (!fGenieGHep) return NULL; + + TObjArrayIter iter(fGenieGHep); + genie::GHepParticle* p; + while ((p = (dynamic_cast((iter).Next())))) { + if (!p) { + continue; + } + + // Get Status + int state = GetGENIEParticleStatus(p, fNUISANCEEvent->Mode); + if (state != genie::kIStInitialState) { + continue; + } + fNUISANCEEvent->probe_E = p->E() * 1.E3; + fNUISANCEEvent->probe_pdg = p->Pdg(); + break; + } + } +#endif // Setup Input scaling for joint inputs fNUISANCEEvent->InputWeight = GetInputWeight(entry); return fNUISANCEEvent; } - -int GENIEInputHandler::GetGENIEParticleStatus(genie::GHepParticle* p, int mode) { +int GENIEInputHandler::GetGENIEParticleStatus(genie::GHepParticle* p, + int mode) { /* kIStUndefined = -1, kIStInitialState = 0, / generator-level initial state / kIStStableFinalState = 1, / generator-level final state: particles to be tracked by detector-level MC / kIStIntermediateState = 2, kIStDecayedState = 3, kIStCorrelatedNucleon = 10, kIStNucleonTarget = 11, kIStDISPreFragmHadronicState = 12, kIStPreDecayResonantState = 13, kIStHadronInTheNucleus = 14, / hadrons inside the nucleus: marked for hadron transport modules to act on / kIStFinalStateNuclearRemnant = 15, / low energy nuclear fragments entering the record collectively as a 'hadronic blob' pseudo-particle / kIStNucleonClusterTarget = 16, // for composite nucleons before phase space decay */ int state = kUndefinedState; switch (p->Status()) { - case genie::kIStNucleonTarget: - case genie::kIStInitialState: - case genie::kIStCorrelatedNucleon: - case genie::kIStNucleonClusterTarget: - state = kInitialState; - break; - - case genie::kIStStableFinalState: - state = kFinalState; - break; - - case genie::kIStHadronInTheNucleus: - if (abs(mode) == 2) + case genie::kIStNucleonTarget: + case genie::kIStInitialState: + case genie::kIStCorrelatedNucleon: + case genie::kIStNucleonClusterTarget: state = kInitialState; - else + break; + + case genie::kIStStableFinalState: + state = kFinalState; + break; + + case genie::kIStHadronInTheNucleus: + if (abs(mode) == 2) + state = kInitialState; + else + state = kFSIState; + break; + + case genie::kIStPreDecayResonantState: + case genie::kIStDISPreFragmHadronicState: + case genie::kIStIntermediateState: state = kFSIState; - break; - - case genie::kIStPreDecayResonantState: - case genie::kIStDISPreFragmHadronicState: - case genie::kIStIntermediateState: - state = kFSIState; - break; - - case genie::kIStFinalStateNuclearRemnant: - case genie::kIStUndefined: - case genie::kIStDecayedState: - default: - break; + break; + + case genie::kIStFinalStateNuclearRemnant: + case genie::kIStUndefined: + case genie::kIStDecayedState: + default: + break; } // Flag to remove nuclear part in genie if (p->Pdg() > 1000000) { if (state == kInitialState) state = kNuclearInitial; else if (state == kFinalState) state = kNuclearRemnant; } return state; } #endif #ifdef __GENIE_ENABLED__ int GENIEInputHandler::ConvertGENIEReactionCode(GHepRecord* gheprec) { - // Electron Scattering if (gheprec->Summary()->ProcInfo().IsEM()) { if (gheprec->Summary()->InitState().ProbePdg() == 11) { - if (gheprec->Summary()->ProcInfo().IsQuasiElastic()) return 1; - else if (gheprec->Summary()->ProcInfo().IsMEC()) return 2; - else if (gheprec->Summary()->ProcInfo().IsResonant()) return 13; - else if (gheprec->Summary()->ProcInfo().IsDeepInelastic()) return 26; + if (gheprec->Summary()->ProcInfo().IsQuasiElastic()) + return 1; + else if (gheprec->Summary()->ProcInfo().IsMEC()) + return 2; + else if (gheprec->Summary()->ProcInfo().IsResonant()) + return 13; + else if (gheprec->Summary()->ProcInfo().IsDeepInelastic()) + return 26; else { - ERROR(WRN, "Unknown GENIE Electron Scattering Mode!" << std::endl - << "ScatteringTypeId = " << gheprec->Summary()->ProcInfo().ScatteringTypeId() << " " - << "InteractionTypeId = " << gheprec->Summary()->ProcInfo().InteractionTypeId() << std::endl - << genie::ScatteringType::AsString(gheprec->Summary()->ProcInfo().ScatteringTypeId()) << " " - << genie::InteractionType::AsString(gheprec->Summary()->ProcInfo().InteractionTypeId()) << " " - << gheprec->Summary()->ProcInfo().IsMEC()); + ERROR(WRN, + "Unknown GENIE Electron Scattering Mode!" + << std::endl + << "ScatteringTypeId = " + << gheprec->Summary()->ProcInfo().ScatteringTypeId() << " " + << "InteractionTypeId = " + << gheprec->Summary()->ProcInfo().InteractionTypeId() + << std::endl + << genie::ScatteringType::AsString( + gheprec->Summary()->ProcInfo().ScatteringTypeId()) + << " " + << genie::InteractionType::AsString( + gheprec->Summary()->ProcInfo().InteractionTypeId()) + << " " << gheprec->Summary()->ProcInfo().IsMEC()); return 0; } } // Weak CC } else if (gheprec->Summary()->ProcInfo().IsWeakCC()) { - // CC MEC if (gheprec->Summary()->ProcInfo().IsMEC()) { - if (pdg::IsNeutrino(gheprec->Summary()->InitState().ProbePdg())) return 2; - else if (pdg::IsAntiNeutrino(gheprec->Summary()->InitState().ProbePdg())) return -2; + if (pdg::IsNeutrino(gheprec->Summary()->InitState().ProbePdg())) + return 2; + else if (pdg::IsAntiNeutrino(gheprec->Summary()->InitState().ProbePdg())) + return -2; // CC OTHER } else { return utils::ghep::NeutReactionCode(gheprec); } // Weak NC } else if (gheprec->Summary()->ProcInfo().IsWeakNC()) { // NC MEC if (gheprec->Summary()->ProcInfo().IsMEC()) { - if (pdg::IsNeutrino(gheprec->Summary()->InitState().ProbePdg())) return 32; - else if (pdg::IsAntiNeutrino(gheprec->Summary()->InitState().ProbePdg())) return -32; + if (pdg::IsNeutrino(gheprec->Summary()->InitState().ProbePdg())) + return 32; + else if (pdg::IsAntiNeutrino(gheprec->Summary()->InitState().ProbePdg())) + return -32; // NC OTHER } else { return utils::ghep::NeutReactionCode(gheprec); } } return 0; } void GENIEInputHandler::CalcNUISANCEKinematics() { - // Reset all variables fNUISANCEEvent->ResetEvent(); // Check for GENIE Event if (!fGenieNtpl) return; if (!fGenieNtpl->event) return; // Cast Event Record fGenieGHep = static_cast(fGenieNtpl->event); if (!fGenieGHep) return; // Convert GENIE Reaction Code - fNUISANCEEvent->fMode = ConvertGENIEReactionCode(fGenieGHep); + fNUISANCEEvent->Mode = ConvertGENIEReactionCode(fGenieGHep); // Set Event Info - fNUISANCEEvent->Mode = fNUISANCEEvent->fMode; fNUISANCEEvent->fEventNo = 0.0; fNUISANCEEvent->fTotCrs = fGenieGHep->XSec(); fNUISANCEEvent->fTargetA = 0.0; fNUISANCEEvent->fTargetZ = 0.0; fNUISANCEEvent->fTargetH = 0; - fNUISANCEEvent->fBound = 0.0; - fNUISANCEEvent->InputWeight = 1.0; //(1E+38 / genie::units::cm2) * fGenieGHep->XSec(); + fNUISANCEEvent->fBound = 0.0; + fNUISANCEEvent->InputWeight = + 1.0; //(1E+38 / genie::units::cm2) * fGenieGHep->XSec(); // Get N Particle Stack unsigned int npart = fGenieGHep->GetEntries(); unsigned int kmax = fNUISANCEEvent->kMaxParticles; if (npart > kmax) { ERR(WRN) << "GENIE has too many particles, expanding stack." << std::endl; fNUISANCEEvent->ExpandParticleStack(npart); } // Fill Particle Stack GHepParticle* p = 0; TObjArrayIter iter(fGenieGHep); fNUISANCEEvent->fNParticles = 0; // Loop over all particles while ((p = (dynamic_cast((iter).Next())))) { if (!p) continue; // Get Status - int state = GetGENIEParticleStatus(p, fNUISANCEEvent->fMode); + int state = GetGENIEParticleStatus(p, fNUISANCEEvent->Mode); // Remove Undefined - if (kRemoveUndefParticles && - state == kUndefinedState) continue; + if (kRemoveUndefParticles && state == kUndefinedState) continue; // Remove FSI - if (kRemoveFSIParticles && - state == kFSIState) continue; + if (kRemoveFSIParticles && state == kFSIState) continue; if (kRemoveNuclearParticles && - (state == kNuclearInitial || state == kNuclearRemnant)) continue; + (state == kNuclearInitial || state == kNuclearRemnant)) + continue; // Fill Vectors int curpart = fNUISANCEEvent->fNParticles; fNUISANCEEvent->fParticleState[curpart] = state; // Mom fNUISANCEEvent->fParticleMom[curpart][0] = p->Px() * 1.E3; fNUISANCEEvent->fParticleMom[curpart][1] = p->Py() * 1.E3; fNUISANCEEvent->fParticleMom[curpart][2] = p->Pz() * 1.E3; fNUISANCEEvent->fParticleMom[curpart][3] = p->E() * 1.E3; // PDG fNUISANCEEvent->fParticlePDG[curpart] = p->Pdg(); // Add to N particle count fNUISANCEEvent->fNParticles++; // Extra Check incase GENIE fails. if ((UInt_t)fNUISANCEEvent->fNParticles == kmax) { ERR(WRN) << "Number of GENIE Particles exceeds maximum!" << std::endl; - ERR(WRN) << "Extend kMax, or run without including FSI particles!" << std::endl; + ERR(WRN) << "Extend kMax, or run without including FSI particles!" + << std::endl; break; } } // Fill Extra Stack if (fSaveExtra) fGenieInfo->FillGeneratorInfo(fGenieNtpl); // Run Initial, FSI, Final, Other ordering. - fNUISANCEEvent-> OrderStack(); + fNUISANCEEvent->OrderStack(); FitParticle* ISNeutralLepton = fNUISANCEEvent->GetHMISParticle(PhysConst::pdg_neutrinos); if (ISNeutralLepton) { fNUISANCEEvent->probe_E = ISNeutralLepton->E(); fNUISANCEEvent->probe_pdg = ISNeutralLepton->PDG(); } return; } -void GENIEInputHandler::Print() { -} +void GENIEInputHandler::Print() {} #endif - - diff --git a/src/InputHandler/GIBUUInputHandler.cxx b/src/InputHandler/GIBUUInputHandler.cxx index e69963e..c0e8724 100644 --- a/src/InputHandler/GIBUUInputHandler.cxx +++ b/src/InputHandler/GIBUUInputHandler.cxx @@ -1,513 +1,301 @@ #ifdef __GiBUU_ENABLED__ #include "GIBUUInputHandler.h" +#include "InputUtils.h" + GIBUUGeneratorInfo::~GIBUUGeneratorInfo() { DeallocateParticleStack(); } void GIBUUGeneratorInfo::AddBranchesToTree(TTree* tn) { // tn->Branch("NEUTParticleN", fNEUTParticleN, "NEUTParticleN/I"); // tn->Branch("NEUTParticleStatusCode", fNEUTParticleStatusCode, // "NEUTParticleStatusCode[NEUTParticleN]/I"); // tn->Branch("NEUTParticleAliveCode", fNEUTParticleAliveCode, // "NEUTParticleAliveCode[NEUTParticleN]/I"); } void GIBUUGeneratorInfo::SetBranchesFromTree(TTree* tn) { // tn->SetBranchAddress("NEUTParticleN", &fNEUTParticleN ); // tn->SetBranchAddress("NEUTParticleStatusCode", &fNEUTParticleStatusCode ); // tn->SetBranchAddress("NEUTParticleAliveCode", &fNEUTParticleAliveCode ); } void GIBUUGeneratorInfo::AllocateParticleStack(int stacksize) { // fNEUTParticleN = 0; // fNEUTParticleStatusCode = new int[stacksize]; // fNEUTParticleStatusCode = new int[stacksize]; } void GIBUUGeneratorInfo::DeallocateParticleStack() { // delete fNEUTParticleStatusCode; // delete fNEUTParticleAliveCode; } void GIBUUGeneratorInfo::FillGeneratorInfo(GiBUUStdHepReader* nevent) { Reset(); // for (int i = 0; i < nevent->Npart(); i++) { // fNEUTParticleStatusCode[i] = nevent->PartInfo(i)->fStatus; // fNEUTParticleAliveCode[i] = nevent->PartInfo(i)->fIsAlive; // fNEUTParticleN++; // } } void GIBUUGeneratorInfo::Reset() { // for (int i = 0; i < fNEUTParticleN; i++) { // fNEUTParticleStatusCode[i] = -1; // fNEUTParticleAliveCode[i] = 9; // } // fNEUTParticleN = 0; } GIBUUInputHandler::GIBUUInputHandler(std::string const& handle, std::string const& rawinputs) { LOG(SAM) << "Creating GiBUUInputHandler : " << handle << std::endl; // Run a joint input handling fName = handle; fEventType = kGiBUU; - - // Open Root File - LOG(SAM) << "Opening event file " << rawinputs << std::endl; - TFile* rootFile = new TFile(rawinputs.c_str(), "READ"); - // Get flux histograms NEUT supplies - TH1D* numuFlux = dynamic_cast(rootFile->Get("numu_flux")); - TH1D* numubFlux = dynamic_cast(rootFile->Get("numub_flux")); - TH1D* nueFlux = dynamic_cast(rootFile->Get("nue_flux")); - TH1D* nuebFlux = dynamic_cast(rootFile->Get("nueb_flux")); - TH1D* eFlux = dynamic_cast(rootFile->Get("e_flux")); - std::vector fFluxList; - - // Replace local pointers with NULL dir'd clones. - if (numuFlux) { - numuFlux = static_cast(numuFlux->Clone()); - numuFlux->Scale(1.0 / numuFlux->Integral("width")); - std::cout << "GiBUU Flux: numuFlux, Width integral = " - << numuFlux->Integral("width") << std::endl; - numuFlux->SetDirectory(NULL); - numuFlux->SetNameTitle( - (fName + "_numu_FLUX").c_str(), - (fName + "; E_{#nu} (GeV); #Phi_{#nu} (A.U.)").c_str()); - fFluxList.push_back(numuFlux); - } - if (numubFlux) { - numubFlux = static_cast(numubFlux->Clone()); - numubFlux->Scale(1.0 / numubFlux->Integral("width")); - std::cout << "GiBUU Flux: numubFlux, Width integral = " - << numubFlux->Integral("width") << std::endl; - numubFlux->SetDirectory(NULL); - numubFlux->SetNameTitle( - (fName + "_numub_FLUX").c_str(), - (fName + "; E_{#nu} (GeV); #Phi_{#bar{#nu}} (A.U.)").c_str()); - fFluxList.push_back(numubFlux); - } - if (nueFlux) { - nueFlux = static_cast(nueFlux->Clone()); - nueFlux->Scale(1.0 / nueFlux->Integral("width")); - std::cout << "GiBUU Flux: nueFlux, Width integral = " - << nueFlux->Integral("width") << std::endl; - nueFlux->SetDirectory(NULL); - nueFlux->SetNameTitle( - (fName + "_nue_FLUX").c_str(), - (fName + "; E_{#nu} (GeV); #Phi_{#nu} (A.U.)").c_str()); - fFluxList.push_back(nueFlux); - } - if (nuebFlux) { - nuebFlux = static_cast(nuebFlux->Clone()); - nuebFlux->Scale(1.0 / nuebFlux->Integral("width")); - std::cout << "GiBUU Flux: nuebFlux, Width integral = " - << nuebFlux->Integral("width") << std::endl; - nuebFlux->SetDirectory(NULL); - nuebFlux->SetNameTitle( - (fName + "_nueb_FLUX").c_str(), - (fName + "; E_{#nu} (GeV); #Phi_{#bar{#nu}} (A.U.)").c_str()); - fFluxList.push_back(nuebFlux); - } - if (eFlux) { - eFlux = static_cast(eFlux->Clone()); - eFlux->Scale(1.0 / eFlux->Integral("width")); - std::cout << "GiBUU Flux: eFlux, Width integral = " - << eFlux->Integral("width") << std::endl; - eFlux->SetDirectory(NULL); - eFlux->SetNameTitle((fName + "_e_FLUX").c_str(), - (fName + "; E_{#nu} (GeV); #Phi_{e} (A.U.)").c_str()); - fFluxList.push_back(eFlux); - } - rootFile->Close(); - fGIBUUTree = new TChain("giRooTracker"); - fGIBUUTree->AddFile(rawinputs.c_str()); - - fGiReader = new GiBUUStdHepReader(); - fGiReader->SetBranchAddresses(fGIBUUTree); - - bool IsEScattering = bool(eFlux); - bool IsNuBarDominant = false; - - double SpeciesWeights[] = {0, 0, 0, 0}; - fNEvents = fGIBUUTree->GetEntries(); - fNUISANCEEvent = new FitEvent(); - TH1D* flux = NULL; - size_t Found_nuMask = ((numuFlux ? 1 : 0) + (numubFlux ? 2 : 0) + - (nueFlux ? 4 : 0) + (nuebFlux ? 8 : 0)); - size_t maskHW = GeneralUtils::GetHammingWeight(Found_nuMask); - - if (!IsEScattering) { - size_t Found_nu = 0; - - static const char* specNames[] = {"numu", "numubar", "nue", "nuebar"}; - size_t nExpected = (Found_nuMask & (1 << 0)) + (Found_nuMask & (1 << 1)) + - (Found_nuMask & (1 << 2)) + (Found_nuMask & (1 << 3)); - size_t nFound = 0; - std::string expectStr = ""; - for (size_t sn_it = 0; sn_it < 4; ++sn_it) { - if (Found_nuMask & (1 << sn_it)) { - if (!nFound) { - expectStr = "("; - } - expectStr += specNames[sn_it]; - nFound++; - if (nFound == nExpected) { - expectStr += ")"; - } else { - expectStr += ", "; - } - } + // Loop over all inputs and grab flux, eventhist, and nevents + std::vector inputs = InputUtils::ParseInputFileList(rawinputs); + for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) { + // Open File for histogram access + LOG(SAM) << "Opening event file " << inputs[inp_it] << std::endl; + TFile* inp_file = new TFile(inputs[inp_it].c_str(), "READ"); + if ((!inp_file) || (!inp_file->IsOpen())) { + THROW("GiBUU file !IsOpen() at : '" + << inputs[inp_it] << "'" << std::endl + << "Check that your file paths are correct and the file exists!"); } - LOG(SAM) << "Looking for dominant vector species in GiBUU file (" - << rawinputs - << ") expecting to find: " << (eFlux ? "e_Flux" : expectStr) - << std::endl; - - if (maskHW > 2) { - LOG(SAM) - << "We are looking for more than two species... this will have to " - "loop through a large portion of the vector. Please be patient." - << std::endl; + int NFluxes = bool(dynamic_cast(inp_file->Get("numu_flux"))) + + bool(dynamic_cast(inp_file->Get("numub_flux"))) + + bool(dynamic_cast(inp_file->Get("nue_flux"))) + + bool(dynamic_cast(inp_file->Get("nueb_flux"))) + + bool(dynamic_cast(inp_file->Get("e_flux"))); + + if (NFluxes != 1) { + THROW("Found " << NFluxes << " input fluxes in " << inputs[inp_it] + << ". The NUISANCE GiBUU interface expects to be " + "passed multiple species vectors as separate " + "input files like: " + "\"GiBUU:(MINERVA_FHC_numu_evts.root,MINERVA_FHC_" + "numubar_evts.root,[...])\""); } - Long64_t nevt = 0; - - while ((Found_nu != Found_nuMask) && (nevt < fNEvents)) { - if ((maskHW == 2) && flux) { // If we have found the dominant one can - // now guess the other - size_t OtherBit = GeneralUtils::GetFirstOnBit(Found_nuMask - Found_nu); - SpeciesWeights[OtherBit] = 1 - fGiReader->SpeciesWght; - Found_nu += (1 << OtherBit); - - LOG(SAM) << "\tGuessing other species weight as we are only expecting " - "two species. Other species weight: " - << SpeciesWeights[OtherBit] << std::endl; - continue; - } - - this->GetNuisanceEvent(nevt++); - FitParticle* isnu = - fNUISANCEEvent->GetHMISParticle(PhysConst::pdg_neutrinos); - if (!isnu) { - continue; - } - switch (isnu->fPID) { - case 12: { - if ((Found_nu & 4)) { - continue; - } - Found_nu += 4; - SpeciesWeights[2] = fGiReader->SpeciesWght; - LOG(SAM) << "\tGiBUU File: " << rawinputs << " -- ev: " << nevt - << " has IS nu (" << isnu->fPID - << "), species weight: " << fGiReader->SpeciesWght - << std::endl; - if ((fGiReader->SpeciesWght < 0.5) && - (maskHW > 1)) { // If we only care about a single species, then - // species-weight might not be filled. - continue; - } - flux = nueFlux; - LOG(SAM) << "\tInput file: " << rawinputs - << " determined to be nue dominated vector." << std::endl; - break; - } - case -12: { - if ((Found_nu & 8)) { - continue; - } - Found_nu += 8; - SpeciesWeights[3] = fGiReader->SpeciesWght; - LOG(SAM) << "\tGiBUU File: " << rawinputs << " -- ev: " << nevt - << " has IS nu (" << isnu->fPID - << "), species weight: " << fGiReader->SpeciesWght - << std::endl; - if ((fGiReader->SpeciesWght < 0.5) && - (maskHW > 1)) { // If we only care about a single species, then - // species-weight might not be filled. - continue; - } - IsNuBarDominant = true; - flux = nuebFlux; - LOG(SAM) << "\tInput file: " << rawinputs - << " determined to be nuebar dominated vector." << std::endl; - break; - } - case 14: { - if ((Found_nu & 1)) { - continue; - } - Found_nu += 1; - SpeciesWeights[0] = fGiReader->SpeciesWght; - LOG(SAM) << "\tGiBUU File: " << rawinputs << " -- ev: " << nevt - << " has IS nu (" << isnu->fPID - << "), species weight: " << fGiReader->SpeciesWght - << std::endl; - if ((fGiReader->SpeciesWght < 0.5) && - (maskHW > 1)) { // If we only care about a single species, then - // species-weight might not be filled. - continue; - } - flux = numuFlux; - LOG(SAM) << "\tInput file: " << rawinputs - << " determined to be numu dominated vector." << std::endl; - break; - } - case -14: { - if ((Found_nu & 2)) { - continue; - } - Found_nu += 2; - SpeciesWeights[1] = fGiReader->SpeciesWght; - LOG(SAM) << "\tGiBUU File: " << rawinputs << " -- ev: " << nevt - << " has IS nu (" << isnu->fPID - << "), species weight: " << fGiReader->SpeciesWght - << std::endl; - if ((fGiReader->SpeciesWght < 0.5) && - (maskHW > 1)) { // If we only care about a single species, then - // species-weight might not be filled. - continue; - } - IsNuBarDominant = true; - flux = numubFlux; - LOG(SAM) << "\tInput file: " << rawinputs - << " determined to be numubar dominated vector." - << std::endl; - break; - } - default: {} - } + // Get Flux/Event hist + TH1D* fluxhist = dynamic_cast(inp_file->Get("flux")); + TH1D* eventhist = dynamic_cast(inp_file->Get("evt")); + if (!fluxhist || !eventhist) { + ERROR(FTL, "Input File Contents: " << inputs[inp_it]); + inp_file->ls(); + THROW( + "GiBUU FILE doesn't contain flux/xsec info. You may have to " + "regenerate your MC!"); } - if (Found_nu != Found_nuMask) { - ERR(FTL) - << "Input GiBUU file (" << rawinputs - << ") appeared to not contain all the relevant incoming neutrino " - "species: Found (numu:" - << ((Found_nu & (1 << 0)) ? 1 : 0) - << ",numub:" << ((Found_nu & (1 << 1)) ? 1 : 0) - << ",nue:" << ((Found_nu & (1 << 2)) ? 1 : 0) - << ",nueb:" << ((Found_nu & (1 << 3)) ? 1 : 0) - << "), expected: (numu:" << ((Found_nuMask & (1 << 0)) ? 1 : 0) - << ",numub:" << ((Found_nuMask & (1 << 1)) ? 1 : 0) - << ",nue:" << ((Found_nuMask & (1 << 2)) ? 1 : 0) - << ",nueb:" << ((Found_nuMask & (1 << 3)) ? 1 : 0) << ")" - << std::endl; + // Get N Events + TTree* giRooTracker = dynamic_cast(inp_file->Get("giRooTracker")); + if (!giRooTracker) { + ERROR(FTL, + "giRooTracker Tree not located in NEUT file: " << inputs[inp_it]); + THROW("Check your inputs, they may need to be completely regenerated!"); throw; } - } else { - flux = eFlux; - } - - if (!flux) { - ERR(FTL) << "Couldn't find flux(" - << (IsEScattering ? "e_Flux" - : (IsNuBarDominant ? "nuXb_flux" : "nuX_flux")) - << ") in input file: " << rootFile->GetName() << std::endl; - throw; - } - - if (numuFlux) { - if ((maskHW > 1) && !GeneralUtils::IsSmallNum(SpeciesWeights[0])) { - numuFlux->Scale(SpeciesWeights[0]); - } - - TH1D* numuEvt = - static_cast(numuFlux->Clone((fName + "_numu_EVT").c_str())); - numuEvt->Reset(); - numuEvt->SetBinContent(1, SpeciesWeights[0] * double(fNEvents) / - numuEvt->GetXaxis()->GetBinWidth(1)); - - TH1D* numuXSec = - static_cast(numuEvt->Clone((fName + "_numu_XSEC").c_str())); - numuXSec->Divide(flux); - - numuXSec->SetTitle((fName + "; E_{#nu} (GeV);XSec").c_str()); - } - if (numubFlux) { - if ((maskHW > 1) && !GeneralUtils::IsSmallNum(SpeciesWeights[1])) { - numubFlux->Scale(SpeciesWeights[1]); - } - TH1D* numubEvt = - static_cast(numubFlux->Clone((fName + "_numub_EVT").c_str())); - numubEvt->Reset(); - numubEvt->SetBinContent(1, SpeciesWeights[1] * double(fNEvents) / - numubEvt->GetXaxis()->GetBinWidth(1)); - - TH1D* numubXSec = - static_cast(numubEvt->Clone((fName + "_numub_XSEC").c_str())); - numubXSec->Divide(flux); - - numubXSec->SetTitle((fName + "; E_{#nu} (GeV);XSec").c_str()); - } - if (nueFlux) { - if ((maskHW > 1) && !GeneralUtils::IsSmallNum(SpeciesWeights[2])) { - nueFlux->Scale(SpeciesWeights[2]); - } - TH1D* nueEvt = - static_cast(nueFlux->Clone((fName + "_nue_EVT").c_str())); - nueEvt->Reset(); - nueEvt->SetBinContent(1, SpeciesWeights[2] * double(fNEvents) / - nueEvt->GetXaxis()->GetBinWidth(1)); - - TH1D* nueXSec = - static_cast(nueEvt->Clone((fName + "_nue_XSEC").c_str())); - nueXSec->Divide(flux); - - nueXSec->SetTitle((fName + "; E_{#nu} (GeV);XSec").c_str()); - } - if (nuebFlux) { - if ((maskHW > 1) && !GeneralUtils::IsSmallNum(SpeciesWeights[3])) { - nuebFlux->Scale(SpeciesWeights[3]); + int nevents = giRooTracker->GetEntries(); + if (nevents <= 0) { + THROW("Trying to a TTree with " + << nevents << " to TChain from : " << inputs[inp_it]); } - TH1D* nuebEvt = - static_cast(nuebFlux->Clone((fName + "_nueb_EVT").c_str())); - nuebEvt->Reset(); - nuebEvt->SetBinContent(1, SpeciesWeights[3] * double(fNEvents) / - nuebEvt->GetXaxis()->GetBinWidth(1)); - TH1D* nuebXSec = - static_cast(nuebEvt->Clone((fName + "_nueb_XSEC").c_str())); - nuebXSec->Divide(flux); + // Register input to form flux/event rate hists + RegisterJointInput(inputs[inp_it], nevents, fluxhist, eventhist); - nuebXSec->SetTitle((fName + "; E_{#nu} (GeV);XSec").c_str()); + // Add To TChain + fGIBUUTree->AddFile(inputs[inp_it].c_str()); } - fGIBUUTree->GetEntry(0); - - LOG(SAM) << "\tInput GiBUU file species weights: (numu:" << SpeciesWeights[0] - << ",numub:" << SpeciesWeights[1] << ",nue:" << SpeciesWeights[2] - << ",nueb:" << SpeciesWeights[3] << ")" << std::endl; - - flux->SetNameTitle( - (fName + "_FLUX").c_str(), - (fName + "; E_{#nu} (GeV);" + - (IsNuBarDominant ? "#Phi_{#bar{#nu}} (A.U.)" : "#Phi_{#nu} (A.U.)")) - .c_str()); - - TH1D* eventhist = static_cast(flux->Clone((fName + "_EVT").c_str())); - eventhist->Reset(); - eventhist->SetBinContent(1, double(fNEvents)); + // Registor all our file inputs + SetupJointInputs(); - TH1D* xsechist = - static_cast(eventhist->Clone((fName + "_XSEC").c_str())); - xsechist->Divide(flux); + // Create Fit Event + fNUISANCEEvent = new FitEvent(); - xsechist->SetTitle((fName + "; E_{#nu} (GeV);XSec").c_str()); + fGiReader = new GiBUUStdHepReader(); + fGiReader->SetBranchAddresses(fGIBUUTree); - RegisterJointInput(rawinputs, fNEvents, flux, eventhist); - SetupJointInputs(); + fNUISANCEEvent->HardReset(); }; FitEvent* GIBUUInputHandler::GetNuisanceEvent(const UInt_t entry, const bool lightweight) { // Check out of bounds if (entry >= (UInt_t)fNEvents) return NULL; // Read Entry from TTree to fill NEUT Vect in BaseFitEvt; fGIBUUTree->GetEntry(entry); // Run NUISANCE Vector Filler if (!lightweight) { CalcNUISANCEKinematics(); } +#ifdef __PROB3PP_ENABLED__ + else { + for (int i = 0; i < fGiReader->StdHepN; i++) { + int state = GetGIBUUParticleStatus(fGiReader->StdHepStatus[i], + fGiReader->StdHepPdg[i]); + if (state != kInitialState) { + continue; + } + if (std::count(PhysConst::pdg_neutrinos, PhysConst::pdg_neutrinos + 4, + fGiReader->StdHepPdg[i])) { + fNUISANCEEvent->probe_E = fGiReader->StdHepP4[i][3] * 1.E3; + fNUISANCEEvent->probe_pdg = fGiReader->StdHepPdg[i]; + break; + } + } + } +#endif + + fNUISANCEEvent->InputWeight *= GetInputWeight(entry); return fNUISANCEEvent; } int GetGIBUUParticleStatus(int status, int pdg) { int state = kUndefinedState; switch (status) { case 0: // Incoming case 11: // Struck nucleon state = kInitialState; break; case 1: // Good Final State state = kFinalState; break; default: // Other break; } // Set Nuclear States Flag if (pdg > 1000000) { if (state == kInitialState) state = kNuclearInitial; else if (state == kFinalState) state = kNuclearRemnant; else state = kUndefinedState; } return state; } void GIBUUInputHandler::CalcNUISANCEKinematics() { // Reset all variables fNUISANCEEvent->ResetEvent(); FitEvent* evt = fNUISANCEEvent; - evt->fMode = fGiReader->GiBUU2NeutCode; - evt->Mode = evt->fMode; + evt->Mode = fGiReader->GiBUU2NeutCode; evt->fEventNo = 0.0; evt->fTotCrs = 0; evt->fTargetA = 0.0; // Change to get these from nuclear remnant. evt->fTargetZ = 0.0; evt->fTargetH = 0; evt->fBound = 0.0; // Extra GiBUU Input Weight evt->InputWeight = fGiReader->EvtWght; // Check Stack N int npart = fGiReader->StdHepN; int kmax = evt->kMaxParticles; if ((UInt_t)npart > (UInt_t)kmax) { - ERR(FTL) << "GiBUU has too many particles. Expanding Stack." << std::endl; + ERROR(WRN, "GiBUU has too many particles. Expanding Stack."); fNUISANCEEvent->ExpandParticleStack(npart); } // Create Stack evt->fNParticles = 0; for (int i = 0; i < npart; i++) { // State int state = GetGIBUUParticleStatus(fGiReader->StdHepStatus[i], fGiReader->StdHepPdg[i]); int curpart = evt->fNParticles; // Set State evt->fParticleState[evt->fNParticles] = state; // Mom evt->fParticleMom[curpart][0] = fGiReader->StdHepP4[i][0] * 1.E3; evt->fParticleMom[curpart][1] = fGiReader->StdHepP4[i][1] * 1.E3; evt->fParticleMom[curpart][2] = fGiReader->StdHepP4[i][2] * 1.E3; evt->fParticleMom[curpart][3] = fGiReader->StdHepP4[i][3] * 1.E3; // PDG evt->fParticlePDG[curpart] = fGiReader->StdHepPdg[i]; // Add to total particles evt->fNParticles++; } // Run Initial, FSI, Final, Other ordering. fNUISANCEEvent->OrderStack(); FitParticle* ISNeutralLepton = fNUISANCEEvent->GetHMISParticle(PhysConst::pdg_neutrinos); if (ISNeutralLepton) { fNUISANCEEvent->probe_E = ISNeutralLepton->E(); fNUISANCEEvent->probe_pdg = ISNeutralLepton->PDG(); } return; } void GIBUUInputHandler::Print() {} + +void GIBUUInputHandler::SetupJointInputs() { + if (jointeventinputs.size() <= 1) { + jointinput = false; + } else if (jointeventinputs.size() > 1) { + jointinput = true; + jointindexswitch = 0; + } + fMaxEvents = FitPar::Config().GetParI("MAXEVENTS"); + if (fMaxEvents != -1 and jointeventinputs.size() > 1) { + THROW("Can only handle joint inputs when config MAXEVENTS = -1!"); + } + + for (size_t i = 0; i < jointeventinputs.size(); i++) { + double scale = double(fNEvents) / fEventHist->Integral("width"); + scale *= jointfluxinputs.at(i)->Integral("width"); + + jointindexscale.push_back(scale); + } + + fEventHist->SetNameTitle((fName + "_EVT").c_str(), (fName + "_EVT").c_str()); + fFluxHist->SetNameTitle((fName + "_FLUX").c_str(), (fName + "_FLUX").c_str()); + + // Setup Max Events + if (fMaxEvents > 1 && fMaxEvents < fNEvents) { + if (LOG_LEVEL(SAM)) { + std::cout << "\t\t|-> Read Max Entries : " << fMaxEvents << std::endl; + } + fNEvents = fMaxEvents; + } + + // Print out Status + if (LOG_LEVEL(SAM)) { + std::cout << "\t\t|-> Total Entries : " << fNEvents << std::endl + << "\t\t|-> Event Integral : " + << fEventHist->Integral("width") * 1.E-38 << " events/nucleon" + << std::endl + << "\t\t|-> Flux Integral : " << fFluxHist->Integral("width") + << " /cm2" << std::endl + << "\t\t|-> Event/Flux : " + << fEventHist->Integral("width") * 1.E-38 / + fFluxHist->Integral("width") + << " cm2/nucleon" << std::endl; + } +} + #endif diff --git a/src/InputHandler/GIBUUInputHandler.h b/src/InputHandler/GIBUUInputHandler.h index 5b67165..6a8027a 100644 --- a/src/InputHandler/GIBUUInputHandler.h +++ b/src/InputHandler/GIBUUInputHandler.h @@ -1,67 +1,70 @@ #ifndef GIBUUINPUTHANDLER_H #define GIBUUINPUTHANDLER_H #ifdef __GiBUU_ENABLED__ /*! * \addtogroup InputHandler * @{ */ #include "InputHandler.h" #include "PlotUtils.h" #include "StdHepEvt.h" /// GIBUU Generator Container to save extra particle status codes. class GIBUUGeneratorInfo : public GeneratorInfoBase { public: GIBUUGeneratorInfo() {}; virtual ~GIBUUGeneratorInfo(); /// Assigns information to branches void AddBranchesToTree(TTree* tn); /// Setup reading information from branches void SetBranchesFromTree(TTree* tn); /// Allocate any dynamic arrays for a new particle stack size void AllocateParticleStack(int stacksize); /// Clear any dynamic arrays void DeallocateParticleStack(); /// Read extra GIBUU information from the event void FillGeneratorInfo(GiBUUStdHepReader* nevent); /// Reset extra information to default/empty values void Reset(); // int kMaxParticles; ///< Number of particles in stack // int* fNEUTParticleStatusCode; ///= fHistos.size()) { + THROW("Requested histogram, index " << i << ", but only specified " + << fHistos.size() << " input histos."); + } + return fHistos[i]; +} +std::vector HistoInputHandler::GetHistograms(int i, int j) { + size_t from = (i < 0) ? 0 : i; + size_t to = (j < 0) ? fHistos.size() : j; + if (j <= i) { + THROW( + "Lower bound of GetHistograms range is larger than or equal to the " + "upper bound: [" + << i << ", " << j << "]."); + } + + std::vector rtnv; + for (size_t it = from; it < to; ++it) { + rtnv.push_back(GetHistogram(it)); + } + return rtnv; +} + +HistoInputHandler::HistoInputHandler(std::string const& handle, + std::string const& rawinputs) { + LOG(SAM) << "Creating HistoInputHandler : " << handle << std::endl; + + // Run a joint input handling + fName = handle; + fNEvents = 1; + fEventType = kHISTO; + + fFluxHist = new TH1D("flux", "dummy", 1, 1, 2); + fFluxHist->SetBinContent(1, 1); + fEventHist = new TH1D("event", "dummy", 1, 1, 2); + fEventHist->SetBinContent(1, 1); + + // Loop over all inputs and grab flux, eventhist, and nevents + std::vector inputs = InputUtils::ParseInputFileList(rawinputs); + for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) { + // Open File for histogram access + LOG(SAM) << "Reading histograms from descriptor " << inputs[inp_it] + << std::endl; + + std::vector histos = PlotUtils::GetTH1sFromRootFile(inputs[inp_it]); + + for (size_t h_it = 0; h_it < histos.size(); ++h_it) { + LOG(SAM) << "Read " << histos[h_it]->GetName() << std::endl; + fHistos.push_back(histos[h_it]); + } + } +}; + +void HistoInputHandler::Print() {} diff --git a/src/InputHandler/HistogramInputHandler.h b/src/InputHandler/HistogramInputHandler.h new file mode 100644 index 0000000..cd7e42f --- /dev/null +++ b/src/InputHandler/HistogramInputHandler.h @@ -0,0 +1,33 @@ +#ifndef HISTOINPUTHANDLER_H +#define HISTOINPUTHANDLER_H +/*! + * \addtogroup InputHandler + * @{ + */ +#include "InputHandler.h" +#include "PlotUtils.h" +#include "StdHepEvt.h" + +/// Histogram input handler to read root histograms +class HistoInputHandler : public InputHandlerBase { + public: + /// Standard constructor given name and inputs + HistoInputHandler(std::string const& handle, std::string const& rawinputs); + ~HistoInputHandler(){}; + + /// Returns NUISANCE Format Event from GiReader + FitEvent* GetNuisanceEvent(const UInt_t entry, + const bool lightweight = false) { + return NULL; + } + + size_t NHistograms() { return fHistos.size(); } + TH1* GetHistogram(int i = -1); + std::vector GetHistograms(int i = -1, int j = -1); + + /// Print event information + void Print(); + + std::vector fHistos; +}; +#endif diff --git a/src/InputHandler/InputFactory.cxx b/src/InputHandler/InputFactory.cxx index 3333916..c3536ad 100644 --- a/src/InputHandler/InputFactory.cxx +++ b/src/InputHandler/InputFactory.cxx @@ -1,111 +1,122 @@ // 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 "FitEventInputHandler.h" +#include "GENIEInputHandler.h" +#include "GIBUUInputHandler.h" +#include "HistogramInputHandler.h" +#include "NEUTInputHandler.h" +#include "NUANCEInputHandler.h" +#include "NuWroInputHandler.h" +#include "SigmaQ0HistogramInputHandler.h" +#include "SplineInputHandler.h" + #include "InputFactory.h" +#include "TFile.h" namespace InputUtils { InputHandlerBase* CreateInputHandler(std::string const& handle, InputUtils::InputType inpType, std::string const& inputs) { InputHandlerBase* input = NULL; std::string newinputs = InputUtils::ExpandInputDirectories(inputs); switch (inpType) { - - - case (kNEUT_Input): + case (kNEUT_Input): #ifdef __NEUT_ENABLED__ - input = new NEUTInputHandler(handle, newinputs); + input = new NEUTInputHandler(handle, newinputs); #else - ERROR(FTL, "Tried to create NEUTInputHandler : " - << handle << " " << inpType << " " << inputs); - THROW("NEUT is not enabled!"); + ERROR(FTL, "Tried to create NEUTInputHandler : " + << handle << " " << inpType << " " << inputs); + THROW("NEUT is not enabled!"); #endif - break; + break; - case (kGENIE_Input): + case (kGENIE_Input): #ifdef __GENIE_ENABLED__ - input = new GENIEInputHandler(handle, newinputs); + input = new GENIEInputHandler(handle, newinputs); #else - ERROR(FTL, "Tried to create GENIEInputHandler : " - << handle << " " << inpType << " " << inputs); - THROW("GENIE is not enabled!"); + ERROR(FTL, "Tried to create GENIEInputHandler : " + << handle << " " << inpType << " " << inputs); + THROW("GENIE is not enabled!"); #endif - break; + break; - - case (kNUWRO_Input): + case (kNUWRO_Input): #ifdef __NUWRO_ENABLED__ - input = new NuWroInputHandler(handle, newinputs); + input = new NuWroInputHandler(handle, newinputs); #else - ERROR(FTL, "Tried to create NuWroInputHandler : " - << handle << " " << inpType << " " << inputs); - THROW("NuWro is not enabled!"); + ERROR(FTL, "Tried to create NuWroInputHandler : " + << handle << " " << inpType << " " << inputs); + THROW("NuWro is not enabled!"); #endif - break; + break; - case (kGiBUU_Input): + case (kGiBUU_Input): #ifdef __GiBUU_ENABLED__ - input = new GIBUUInputHandler(handle, newinputs); + input = new GIBUUInputHandler(handle, newinputs); #else - ERROR(FTL, "Tried to create GiBUUInputHandler : " - << handle << " " << inpType << " " << inputs); - THROW("GiBUU is not enabled!"); + ERROR(FTL, "Tried to create GiBUUInputHandler : " + << handle << " " << inpType << " " << inputs); + THROW("GiBUU is not enabled!"); #endif - break; + break; - case (kNUANCE_Input): + case (kNUANCE_Input): #ifdef __NUANCE_ENABLED__ - input = new NUANCEInputHandler(handle, newinputs); + input = new NUANCEInputHandler(handle, newinputs); #else - ERROR(FTL, "Tried to create NUANCEInputHandler : " - << handle << " " << inpType << " " << inputs); - THROW("NUANCE is not enabled!"); + ERROR(FTL, "Tried to create NUANCEInputHandler : " + << handle << " " << inpType << " " << inputs); + THROW("NUANCE is not enabled!"); #endif - break; + break; + + case (kFEVENT_Input): + input = new FitEventInputHandler(handle, newinputs); + break; - case (kFEVENT_Input): - input = new FitEventInputHandler(handle, newinputs); - break; + case (kEVSPLN_Input): + input = new SplineInputHandler(handle, newinputs); + break; - case (kEVSPLN_Input): - input = new SplineInputHandler(handle, newinputs); - break; + case (kSIGMAQ0HIST_Input): + input = new SigmaQ0HistogramInputHandler(handle, newinputs); + break; - case (kSIGMAQ0HIST_Input): - input = new SigmaQ0HistogramInputHandler(handle, newinputs); - break; + case (kHISTO_Input): + input = new HistoInputHandler(handle, newinputs); + break; - default: - break; + default: + break; } /// Input failed if (!input) { ERR(FTL) << "Input handler creation failed!" << std::endl; std::cout << "Generator Type " << inpType << " not enabled!" << std::endl; throw; } - return input; }; } diff --git a/src/InputHandler/InputFactory.h b/src/InputHandler/InputFactory.h index 9e5ef19..b06d5ad 100644 --- a/src/InputHandler/InputFactory.h +++ b/src/InputHandler/InputFactory.h @@ -1,46 +1,37 @@ // 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 INPUT_FACTORY_H #define INPUT_FACTORY_H #include -#include "TFile.h" #include "InputUtils.h" #include "InputHandler.h" -#include "NEUTInputHandler.h" -#include "GENIEInputHandler.h" -#include "NuWroInputHandler.h" -#include "GIBUUInputHandler.h" -#include "NUANCEInputHandler.h" -#include "FitEventInputHandler.h" -#include "SplineInputHandler.h" -#include "SigmaQ0HistogramInputHandler.h" namespace InputUtils { -InputHandlerBase* CreateInputHandler(std::string const& handle, +InputHandlerBase* CreateInputHandler(std::string const& handle, InputUtils::InputType inpType, std::string const& inputs); } #endif diff --git a/src/InputHandler/InputHandler.cxx b/src/InputHandler/InputHandler.cxx index c21c968..b400590 100644 --- a/src/InputHandler/InputHandler.cxx +++ b/src/InputHandler/InputHandler.cxx @@ -1,263 +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 . *******************************************************************************/ #include "InputHandler.h" +#include "InputUtils.h" InputHandlerBase::InputHandlerBase() { fName = ""; fFluxHist = NULL; fEventHist = NULL; fNEvents = 0; fNUISANCEEvent = NULL; fBaseEvent = NULL; kRemoveUndefParticles = FitPar::Config().GetParB("RemoveUndefParticles"); kRemoveFSIParticles = FitPar::Config().GetParB("RemoveFSIParticles"); kRemoveNuclearParticles = FitPar::Config().GetParB("RemoveNuclearParticles"); fMaxEvents = FitPar::Config().GetParI("MAXEVENTS"); fTTreePerformance = NULL; - }; InputHandlerBase::~InputHandlerBase() { - if (fFluxHist) delete fFluxHist; if (fEventHist) delete fEventHist; // if (fXSecHist) delete fXSecHist; // if (fNUISANCEEvent) delete fNUISANCEEvent; jointfluxinputs.clear(); jointeventinputs.clear(); jointindexlow.clear(); jointindexhigh.clear(); jointindexallowed.clear(); jointindexscale.clear(); // if (fTTreePerformance) { - // fTTreePerformance->SaveAs(("ttreeperfstats_" + fName + ".root").c_str()); - // } + // fTTreePerformance->SaveAs(("ttreeperfstats_" + fName + + // ".root").c_str()); + // } } -void InputHandlerBase::Print() { -}; +void InputHandlerBase::Print(){}; TH1D* InputHandlerBase::GetXSecHistogram(void) { fXSecHist = (TH1D*)fFluxHist->Clone(); fXSecHist->Divide(fEventHist); return fXSecHist; }; double InputHandlerBase::PredictedEventRate(double low, double high, - std::string intOpt) { - + std::string intOpt) { int minBin = fFluxHist->GetXaxis()->FindBin(low); int maxBin = fFluxHist->GetXaxis()->FindBin(high); return fEventHist->Integral(minBin, maxBin + 1, intOpt.c_str()); }; double InputHandlerBase::TotalIntegratedFlux(double low, double high, - std::string intOpt) { - + std::string intOpt) { Int_t minBin = fFluxHist->GetXaxis()->FindFixBin(low); Int_t maxBin = fFluxHist->GetXaxis()->FindFixBin(high); if ((fFluxHist->IsBinOverflow(minBin) && (low != -9999.9))) { minBin = 1; } if ((fFluxHist->IsBinOverflow(maxBin) && (high != -9999.9))) { maxBin = fFluxHist->GetXaxis()->GetNbins() + 1; } // If we are within a single bin if (minBin == maxBin) { // Get the contained fraction of the single bin's width return ((high - low) / fFluxHist->GetXaxis()->GetBinWidth(minBin)) * fFluxHist->Integral(minBin, minBin, intOpt.c_str()); } double lowBinUpEdge = fFluxHist->GetXaxis()->GetBinUpEdge(minBin); double highBinLowEdge = fFluxHist->GetXaxis()->GetBinLowEdge(maxBin); double lowBinfracIntegral = - ((lowBinUpEdge - low) / fFluxHist->GetXaxis()->GetBinWidth(minBin)) * - fFluxHist->Integral(minBin, minBin, intOpt.c_str()); + ((lowBinUpEdge - low) / fFluxHist->GetXaxis()->GetBinWidth(minBin)) * + fFluxHist->Integral(minBin, minBin, intOpt.c_str()); double highBinfracIntegral = - ((high - highBinLowEdge) / fFluxHist->GetXaxis()->GetBinWidth(maxBin)) * - fFluxHist->Integral(maxBin, maxBin, intOpt.c_str()); + ((high - highBinLowEdge) / fFluxHist->GetXaxis()->GetBinWidth(maxBin)) * + fFluxHist->Integral(maxBin, maxBin, intOpt.c_str()); // If they are neighbouring bins if ((minBin + 1) == maxBin) { std::cout << "Get lowfrac + highfrac" << std::endl; // Get the contained fraction of the two bin's width return lowBinfracIntegral + highBinfracIntegral; } + double ContainedIntegral = + fFluxHist->Integral(minBin + 1, maxBin - 1, intOpt.c_str()); // If there are filled bins between them - return lowBinfracIntegral + highBinfracIntegral + - fFluxHist->Integral(minBin + 1, maxBin - 1, intOpt.c_str()); + return lowBinfracIntegral + highBinfracIntegral + ContainedIntegral; // return fFluxHist->Integral(minBin + 1, maxBin - 1, intOpt.c_str()); } - std::vector InputHandlerBase::GetFluxList(void) { return std::vector(1, fFluxHist); }; std::vector InputHandlerBase::GetEventList(void) { return std::vector(1, fEventHist); }; std::vector InputHandlerBase::GetXSecList(void) { return std::vector(1, GetXSecHistogram()); }; FitEvent* InputHandlerBase::FirstNuisanceEvent() { fCurrentIndex = 0; return GetNuisanceEvent(fCurrentIndex); }; - - FitEvent* InputHandlerBase::NextNuisanceEvent() { fCurrentIndex++; + if ((fMaxEvents != -1) && (fCurrentIndex > fMaxEvents)) { + return NULL; + } return GetNuisanceEvent(fCurrentIndex); }; - BaseFitEvt* InputHandlerBase::FirstBaseEvent() { fCurrentIndex = 0; return GetBaseEvent(fCurrentIndex); }; BaseFitEvt* InputHandlerBase::NextBaseEvent() { fCurrentIndex++; if (jointinput and fMaxEvents != -1) { - while ( fCurrentIndex < jointindexlow[jointindexswitch] || - fCurrentIndex >= jointindexhigh[jointindexswitch] ) { + while (fCurrentIndex < jointindexlow[jointindexswitch] || + fCurrentIndex >= jointindexhigh[jointindexswitch]) { jointindexswitch++; // Loop Around if (jointindexswitch == jointindexlow.size()) { jointindexswitch = 0; } } - - if (fCurrentIndex > jointindexlow[jointindexswitch] + jointindexallowed[jointindexswitch]) { + if (fCurrentIndex > + jointindexlow[jointindexswitch] + jointindexallowed[jointindexswitch]) { fCurrentIndex = jointindexlow[jointindexswitch]; } } return GetBaseEvent(fCurrentIndex); }; - -void InputHandlerBase::RegisterJointInput(std::string input, int n, TH1D* f, TH1D* e) { - +void InputHandlerBase::RegisterJointInput(std::string input, int n, TH1D* f, + TH1D* e) { if (jointfluxinputs.size() == 0) { jointindexswitch = 0; fNEvents = 0; } // Push into individual input vectors - jointfluxinputs.push_back( (TH1D*) f->Clone() ); - jointeventinputs.push_back( (TH1D*) e->Clone() ); + jointfluxinputs.push_back((TH1D*)f->Clone()); + jointeventinputs.push_back((TH1D*)e->Clone()); jointindexlow.push_back(fNEvents); jointindexhigh.push_back(fNEvents + n); fNEvents += n; // Add to the total flux/event hist - if (!fFluxHist) fFluxHist = (TH1D*) f->Clone(); - else fFluxHist->Add(f); - - if (!fEventHist) fEventHist = (TH1D*) e->Clone(); - else fEventHist->Add(e); - + if (!fFluxHist) + fFluxHist = (TH1D*)f->Clone(); + else + fFluxHist->Add(f); + + if (!fEventHist) + fEventHist = (TH1D*)e->Clone(); + else + fEventHist->Add(e); } - void InputHandlerBase::SetupJointInputs() { - if (jointeventinputs.size() <= 1) { jointinput = false; } else if (jointeventinputs.size() > 1) { jointinput = true; jointindexswitch = 0; } fMaxEvents = FitPar::Config().GetParI("MAXEVENTS"); - if (fMaxEvents != -1 and jointeventinputs.size() > 1){ + if (fMaxEvents != -1 and jointeventinputs.size() > 1) { THROW("Can only handle joint inputs when config MAXEVENTS = -1!"); } - - for (size_t i = 0; i < jointeventinputs.size(); i++) { - TH1D* eventhist = (TH1D*) jointeventinputs.at(i)->Clone(); + if (jointeventinputs.size() > 1) { + ERROR(WRN, + "GiBUU sample contains multiple inputs. This will only work for " + "samples that expect multi-species inputs. If this sample does, you " + "can ignore this warning."); + } + + for (size_t i = 0; i < jointeventinputs.size(); i++) { double scale = double(fNEvents) / fEventHist->Integral("width"); - scale *= eventhist->Integral("width"); + scale *= jointeventinputs.at(i)->Integral("width"); scale /= double(jointindexhigh[i] - jointindexlow[i]); - jointindexscale .push_back(scale); + jointindexscale.push_back(scale); } fEventHist->SetNameTitle((fName + "_EVT").c_str(), (fName + "_EVT").c_str()); fFluxHist->SetNameTitle((fName + "_FLUX").c_str(), (fName + "_FLUX").c_str()); // Setup Max Events if (fMaxEvents > 1 && fMaxEvents < fNEvents) { if (LOG_LEVEL(SAM)) { std::cout << "\t\t|-> Read Max Entries : " << fMaxEvents << std::endl; } fNEvents = fMaxEvents; } // Print out Status if (LOG_LEVEL(SAM)) { std::cout << "\t\t|-> Total Entries : " << fNEvents << std::endl - << "\t\t|-> Event Integral : " << fEventHist->Integral("width") * 1.E-38 << " events/nucleon" << std::endl - << "\t\t|-> Flux Integral : " << fFluxHist->Integral("width") << " /cm2" << std::endl + << "\t\t|-> Event Integral : " + << fEventHist->Integral("width") * 1.E-38 << " events/nucleon" + << std::endl + << "\t\t|-> Flux Integral : " << fFluxHist->Integral("width") + << " /cm2" << std::endl << "\t\t|-> Event/Flux : " - << fEventHist->Integral("width") * 1.E-38 / fFluxHist->Integral("width") << " cm2/nucleon" << std::endl; + << fEventHist->Integral("width") * 1.E-38 / + fFluxHist->Integral("width") + << " cm2/nucleon" << std::endl; } - } BaseFitEvt* InputHandlerBase::GetBaseEvent(const UInt_t entry) { return static_cast(GetNuisanceEvent(entry, true)); } double InputHandlerBase::GetInputWeight(int entry) { - if (!jointinput) return 1.0; // Find Switch Scale - while ( entry < jointindexlow[jointindexswitch] || - entry >= jointindexhigh[jointindexswitch] ) { + while (entry < jointindexlow[jointindexswitch] || + entry >= jointindexhigh[jointindexswitch]) { jointindexswitch++; // Loop Around if (jointindexswitch >= jointindexlow.size()) { jointindexswitch = 0; } } return jointindexscale[jointindexswitch]; }; - diff --git a/src/InputHandler/InputHandler.h b/src/InputHandler/InputHandler.h index a04cbf2..3377403 100644 --- a/src/InputHandler/InputHandler.h +++ b/src/InputHandler/InputHandler.h @@ -1,146 +1,145 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #ifndef INPUTHANDLER2_H #define INPUTHANDLER2_H /*! * \addtogroup InputHandler * @{ */ #include "TH1D.h" #include "FitEvent.h" #include "BaseFitEvt.h" #include "TTreePerfStats.h" -#include "InputUtils.h" /// Base InputHandler class defining how events are requested and setup. class InputHandlerBase { public: /// Base constructor resets everything to default InputHandlerBase(); /// Removes flux/event rate histograms virtual ~InputHandlerBase(); /// Return NUISANCE FitEvent Class from given event entry. /// Must be overriden by GeneratorInputHandler. Lightweight allows a faster option /// to be given where only RW information is needed. virtual FitEvent* GetNuisanceEvent(const UInt_t entry, const bool lightweight=false) = 0; /// Calls GetNuisanceEvent(entry, TRUE); virtual BaseFitEvt* GetBaseEvent(const UInt_t entry); /// Print current event information virtual void Print(); /// Return handler ID inline std::string GetName (void) {return fName; }; /// Return Handler Event Type Index inline int GetType (void) {return fEventType;}; /// Get Total Number of Events being Handled inline virtual int GetNEvents (void) {return fNEvents; }; /// Get the Total Flux Histogram these events were generated with inline virtual TH1D* GetFluxHistogram (void) {return fFluxHist; }; /// Get the Total Event Histogram these events were generated with inline virtual TH1D* GetEventHistogram (void) {return fEventHist;}; /// Get the Total Cross-section Histogram (EventHist/FluxHist) virtual TH1D* GetXSecHistogram(void); /// Return all Flux Histograms for all InputFiles. virtual std::vector GetFluxList(void); /// Return all Event Histograms for all InputFiles virtual std::vector GetEventList(void); /// Return all Xsec Histograms for all InputFiles virtual std::vector GetXSecList(void); /// Placeholder to create a cache to speed up reads in GeneratorInputHandler inline virtual void CreateCache(){}; /// Placeholder to remove optional cache to free up memory inline virtual void RemoveCache(){}; /// Return starting NUISANCE event pointer (entry=0) FitEvent* FirstNuisanceEvent(); /// Iterate to next NUISANCE event. Returns NULL when entry > fNEvents. FitEvent* NextNuisanceEvent(); /// Returns starting Base Event Pointer (entry=0) BaseFitEvt* FirstBaseEvent(); /// Iterate to next NUISANCE Base Event. Returns NULL when entry > fNEvents. BaseFitEvt* NextBaseEvent(); /// Register an input file and update event/flux information virtual void RegisterJointInput(std::string input, int n, TH1D* f, TH1D* e); /// Finalise setup of Input event/flux information and calculate /// joint input weights if joint input is provided. virtual void SetupJointInputs(); /// Calculate a weight for the event given the joint input information. /// Used to scale the relative proportion of multiple inputs correctly /// with respect to one another. virtual double GetInputWeight(int entry); /// Returns the total predicted event rate for this input given the /// low and high energy ranges. intOpt specifies the option the ROOT /// TH1D integral should use. e.g. "" or "width" double PredictedEventRate(double low, double high, std::string intOpt); /// Returns the total generated flux for this input given the /// low and high energy ranges. intOpt specifies the option the ROOT /// TH1D integral should use. e.g. "" or "width" double TotalIntegratedFlux(double low = -9999.9, double high = -9999.9, std::string intOpt = ""); /// Actual data members. std::vector jointfluxinputs; std::vector jointeventinputs; std::vector jointindexlow; std::vector jointindexhigh; std::vector jointindexallowed; size_t jointindexswitch; bool jointinput; std::vector jointindexscale; std::string fName; TH1D* fFluxHist; TH1D* fEventHist; TH1D* fXSecHist; int fNEvents; int fMaxEvents; FitEvent* fNUISANCEEvent; BaseFitEvt* fBaseEvent; int fEventType; int fCurrentIndex; int fCacheSize; bool kRemoveUndefParticles; bool kRemoveFSIParticles; bool kRemoveNuclearParticles; TTreePerfStats* fTTreePerformance; }; /*! @} */ #endif diff --git a/src/InputHandler/InputTypes.h b/src/InputHandler/InputTypes.h index eacac10..7a78145 100644 --- a/src/InputHandler/InputTypes.h +++ b/src/InputHandler/InputTypes.h @@ -1,159 +1,160 @@ // 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 INPUTTYPES_SEEN_H #define INPUTTYPES_SEEN_H /// Global Enum to define generator type being read with FitEvent /// Have to define kNORM as if its a generator for the time being. enum generator_event_type { kUNKNOWN = 999, kNEUT = 0, kNIWG = 1, kNUWRO = 2, kT2K = 3, kCUSTOM = 4, kGENIE = 5, kEVTSPLINE = 6, kNUANCE = 7, kGiBUU = 8, kNORM = 9, - kMODENORM = 10, - kEMPTY = 11, - kINPUTFITEVENT = 12, - kNEWSPLINE = 13, - kLIKEWEIGHT = 14, - kSPLINEPARAMETER = 15, - kHEPMC = 16, - kHISTEVENT = 17, - kSIGMAQ0HIST = 18, + kEMPTY = 10, + kINPUTFITEVENT = 11, + kNEWSPLINE = 12, + kLIKEWEIGHT = 13, + kSPLINEPARAMETER = 14, + kHEPMC = 15, + kHISTO = 16, + kSIGMAQ0HIST = 17, kLast_generator_event_type }; namespace InputUtils { enum InputType { kNEUT_Input = 0, kNUWRO_Input = 1, kGENIE_Input = 2, kGiBUU_Input, kNUANCE_Input, kEVSPLN_Input, kEMPTY_Input, kFEVENT_Input, kJOINT_Input, kSIGMAQ0HIST_Input, + kHISTO_Input, kInvalid_Input, - kHIST_Input, // Not sure if this are currently used. kBNSPLN_Input, // Not sure if this are currently used. }; } inline std::ostream& operator<<(std::ostream& os, generator_event_type const& gs) { switch (gs) { case kUNKNOWN: { return os << "kUNKNOWN"; } case kNEUT: { return os << "kNEUT"; } case kNIWG: { return os << "kNIWG"; } case kNUWRO: { return os << "kNUWRO"; } case kT2K: { return os << "kT2K"; } case kCUSTOM: { return os << "kCUSTOM"; } case kGENIE: { return os << "kGENIE"; } case kEVTSPLINE: { return os << "kEVTSPLINE"; } case kNUANCE: { return os << "kNUANCE"; } case kGiBUU: { return os << "kGiBUU"; } case kNORM: { return os << "kNORM"; } - case kMODENORM: { - return os << "kMODENORM"; - } case kHEPMC: { return os << "kHEPMC"; } case kSIGMAQ0HIST: { return os << "kSIGMAQ0HIST"; } + case kHISTO: { + return os << "kHISTO"; + } default: { return os << "kUNKNOWN"; } } } inline std::ostream &operator<<(std::ostream &os, InputUtils::InputType it) { switch (it) { case InputUtils::kNEUT_Input: { return os << "kNEUT_Input"; } case InputUtils::kNUWRO_Input: { return os << "kNUWRO_Input"; } case InputUtils::kGENIE_Input: { return os << "kGENIE_Input"; } case InputUtils::kGiBUU_Input: { return os << "kGiBUU_Input"; } case InputUtils::kNUANCE_Input: { return os << "kNUANCE_Input"; } case InputUtils::kEVSPLN_Input: { return os << "kEVSPLN_Input"; } case InputUtils::kEMPTY_Input: { return os << "kEMPTY_Input"; } case InputUtils::kFEVENT_Input: { return os << "kFEVENT_Input"; } case InputUtils::kJOINT_Input: { return os << "kJOINT_Input"; } case InputUtils::kSIGMAQ0HIST_Input: { return os << "kSIGMAQ0HIST_Input"; } + case InputUtils::kHISTO_Input: { + return os << "kHISTO_Input"; + } case InputUtils::kInvalid_Input: - case InputUtils::kHIST_Input: case InputUtils::kBNSPLN_Input: default: { return os << "kInvalid_Input"; } } } #endif diff --git a/src/InputHandler/InputUtils.cxx b/src/InputHandler/InputUtils.cxx index 27340dd..cb6047d 100644 --- a/src/InputHandler/InputUtils.cxx +++ b/src/InputHandler/InputUtils.cxx @@ -1,169 +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 "GeneratorUtils.h" -#include "InputUtils.h" #include "InputHandler.h" +#include "InputUtils.h" namespace InputUtils { -std::vector ParseInputFileList(std::string const& inpFile) { - +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" - }; + 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 \'" + "(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" - }; + "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]; - size_t torpl = expandedInputs.find(tempdir); + 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) { - std::string event_folder = FitPar::Config().GetParS(filedir[i]); - expandedInputs.replace(torpl, tempdir.size(), event_folder); - break; + 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 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(GeneratorUtils::NEUT_TreeName.c_str())); + TTree *NEUT_Input = dynamic_cast(inpF->Get(NEUT_TreeName.c_str())); if (NEUT_Input) { return kNEUT_Input; } - TTree *NUWRO_Input = - dynamic_cast(inpF->Get(GeneratorUtils::NuWro_TreeName.c_str())); + TTree *NUWRO_Input = dynamic_cast(inpF->Get(NuWro_TreeName.c_str())); if (NUWRO_Input) { return kNUWRO_Input; } - TTree *GENIE_Input = - dynamic_cast(inpF->Get(GeneratorUtils::GENIE_TreeName.c_str())); + TTree *GENIE_Input = dynamic_cast(inpF->Get(GENIE_TreeName.c_str())); if (GENIE_Input) { return kGENIE_Input; } - TTree *GiBUU_Input = - dynamic_cast(inpF->Get(GeneratorUtils::GiBUU_TreeName.c_str())); + 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()) { - ERR(FTL) << "Couldn't open \"" << inpFName << "\" for reading." - << std::endl; - throw; + THROW("Couldn't open \"" << inpFName << "\" for reading."); } InputType iType = GuessInputTypeFromFile(inpF); if (iType == kInvalid_Input) { - ERR(FTL) << "Couldn't determine input type from file: " << inpFName - << "." << std::endl; - throw; + 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; - } + 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/InputHandler/NEUTInputHandler.cxx b/src/InputHandler/NEUTInputHandler.cxx index 0165497..189026d 100644 --- a/src/InputHandler/NEUTInputHandler.cxx +++ b/src/InputHandler/NEUTInputHandler.cxx @@ -1,440 +1,459 @@ #ifdef __NEUT_ENABLED__ #include "NEUTInputHandler.h" +#include "InputUtils.h" + NEUTGeneratorInfo::~NEUTGeneratorInfo() { DeallocateParticleStack(); } void NEUTGeneratorInfo::AddBranchesToTree(TTree* tn) { tn->Branch("NEUTParticleN", fNEUTParticleN, "NEUTParticleN/I"); tn->Branch("NEUTParticleStatusCode", fNEUTParticleStatusCode, "NEUTParticleStatusCode[NEUTParticleN]/I"); tn->Branch("NEUTParticleAliveCode", fNEUTParticleAliveCode, "NEUTParticleAliveCode[NEUTParticleN]/I"); } void NEUTGeneratorInfo::SetBranchesFromTree(TTree* tn) { tn->SetBranchAddress("NEUTParticleN", &fNEUTParticleN); tn->SetBranchAddress("NEUTParticleStatusCode", &fNEUTParticleStatusCode); tn->SetBranchAddress("NEUTParticleAliveCode", &fNEUTParticleAliveCode); } void NEUTGeneratorInfo::AllocateParticleStack(int stacksize) { fNEUTParticleN = 0; fNEUTParticleStatusCode = new int[stacksize]; fNEUTParticleStatusCode = new int[stacksize]; } void NEUTGeneratorInfo::DeallocateParticleStack() { delete fNEUTParticleStatusCode; delete fNEUTParticleAliveCode; } void NEUTGeneratorInfo::FillGeneratorInfo(NeutVect* nevent) { Reset(); for (int i = 0; i < nevent->Npart(); i++) { fNEUTParticleStatusCode[i] = nevent->PartInfo(i)->fStatus; fNEUTParticleAliveCode[i] = nevent->PartInfo(i)->fIsAlive; fNEUTParticleN++; } } void NEUTGeneratorInfo::Reset() { for (int i = 0; i < fNEUTParticleN; i++) { fNEUTParticleStatusCode[i] = -1; fNEUTParticleAliveCode[i] = 9; } fNEUTParticleN = 0; } NEUTInputHandler::NEUTInputHandler(std::string const& handle, std::string const& rawinputs) { LOG(SAM) << "Creating NEUTInputHandler : " << handle << std::endl; // Run a joint input handling fName = handle; // Setup the TChain fNEUTTree = new TChain("neuttree"); fSaveExtra = FitPar::Config().GetParB("SaveExtraNEUT"); fCacheSize = FitPar::Config().GetParI("CacheSize"); fMaxEvents = FitPar::Config().GetParI("MAXEVENTS"); // Loop over all inputs and grab flux, eventhist, and nevents std::vector inputs = InputUtils::ParseInputFileList(rawinputs); for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) { // Open File for histogram access TFile* inp_file = new TFile(inputs[inp_it].c_str(), "READ"); if (!inp_file or inp_file->IsZombie()) { THROW("NEUT File IsZombie() at : '" << inputs[inp_it] << "'" << std::endl << "Check that your file paths are correct and the file exists!" << std::endl << "$ ls -lh " << inputs[inp_it]); } // Get Flux/Event hist TH1D* fluxhist = (TH1D*)inp_file->Get( (PlotUtils::GetObjectWithName(inp_file, "flux")).c_str()); TH1D* eventhist = (TH1D*)inp_file->Get( (PlotUtils::GetObjectWithName(inp_file, "evt")).c_str()); if (!fluxhist or !eventhist) { ERROR(FTL, "Input File Contents: " << inputs[inp_it]); inp_file->ls(); THROW( "NEUT FILE doesn't contain flux/xsec info. You may have to " "regenerate your MC!"); } // Get N Events TTree* neuttree = (TTree*)inp_file->Get("neuttree"); if (!neuttree) { ERROR(FTL, "neuttree not located in NEUT file: " << inputs[inp_it]); THROW("Check your inputs, they may need to be completely regenerated!"); throw; } int nevents = neuttree->GetEntries(); if (nevents <= 0) { THROW("Trying to a TTree with " << nevents << " to TChain from : " << inputs[inp_it]); } // Register input to form flux/event rate hists RegisterJointInput(inputs[inp_it], nevents, fluxhist, eventhist); // Add To TChain fNEUTTree->AddFile(inputs[inp_it].c_str()); } // Registor all our file inputs SetupJointInputs(); // Assign to tree fEventType = kNEUT; fNeutVect = NULL; fNEUTTree->SetBranchAddress("vectorbranch", &fNeutVect); fNEUTTree->GetEntry(0); // Create Fit Event fNUISANCEEvent = new FitEvent(); fNUISANCEEvent->SetNeutVect(fNeutVect); if (fSaveExtra) { fNeutInfo = new NEUTGeneratorInfo(); fNUISANCEEvent->AddGeneratorInfo(fNeutInfo); } fNUISANCEEvent->HardReset(); }; NEUTInputHandler::~NEUTInputHandler(){ // if (fNEUTTree) delete fNEUTTree; // if (fNeutVect) delete fNeutVect; // if (fNeutInfo) delete fNeutInfo; }; void NEUTInputHandler::CreateCache() { if (fCacheSize > 0) { // fNEUTTree->SetCacheEntryRange(0, fNEvents); fNEUTTree->AddBranchToCache("vectorbranch", 1); fNEUTTree->SetCacheSize(fCacheSize); } } void NEUTInputHandler::RemoveCache() { // fNEUTTree->SetCacheEntryRange(0, fNEvents); fNEUTTree->AddBranchToCache("vectorbranch", 0); fNEUTTree->SetCacheSize(0); } FitEvent* NEUTInputHandler::GetNuisanceEvent(const UInt_t entry, const bool lightweight) { // Catch too large entries if (entry >= (UInt_t)fNEvents) return NULL; // Read Entry from TTree to fill NEUT Vect in BaseFitEvt; fNEUTTree->GetEntry(entry); // Run NUISANCE Vector Filler if (!lightweight) { CalcNUISANCEKinematics(); } +#ifdef __PROB3PP_ENABLED__ + else { + + UInt_t npart = fNeutVect->Npart(); + for (size_t i = 0; i < npart; i++) { + NeutPart* part = fNUISANCEEvent->fNeutVect->PartInfo(i); + if ((part->fIsAlive == false) && (part->fStatus == -1) && + std::count(PhysConst::pdg_neutrinos, PhysConst::pdg_neutrinos + 4, + part->fPID)) { + fNUISANCEEvent->probe_E = part->fP.T(); + fNUISANCEEvent->probe_pdg = part->fPID; + break; + } else { + continue; + } + } + } +#endif // Setup Input scaling for joint inputs fNUISANCEEvent->InputWeight = GetInputWeight(entry); // Return event pointer return fNUISANCEEvent; } int NEUTInputHandler::GetNeutParticleStatus(NeutPart* part) { // State int state = kUndefinedState; // fStatus == -1 means initial state if (part->fIsAlive == false && part->fStatus == -1) { state = kInitialState; // NEUT has a bit of a strange convention for fIsAlive and fStatus // combinations // for NC and neutrino particle isAlive true/false and status 2 means // final state particle // for other particles in NC status 2 means it's an FSI particle // for CC it means it was an FSI particle } else if (part->fStatus == 2) { // NC case is a little strange... The outgoing neutrino might be alive or // not alive. Remaining particles with status 2 are FSI particles that // reinteracted if (abs(fNeutVect->Mode) > 30 && (abs(part->fPID) == 14 || abs(part->fPID) == 12)) { state = kFinalState; // The usual CC case } else if (part->fIsAlive == true) { state = kFSIState; } } else if (part->fIsAlive == true && part->fStatus == 2 && (abs(part->fPID) == 14 || abs(part->fPID) == 12)) { state = kFinalState; } else if (part->fIsAlive == true && part->fStatus == 0) { state = kFinalState; } else if (part->fIsAlive == true) { ERR(WRN) << "Undefined NEUT state " << " Alive: " << part->fIsAlive << " Status: " << part->fStatus << " PDG: " << part->fPID << std::endl; throw; } return state; } void NEUTInputHandler::CalcNUISANCEKinematics() { // Reset all variables fNUISANCEEvent->ResetEvent(); // Fill Globals - fNUISANCEEvent->fMode = fNeutVect->Mode; fNUISANCEEvent->Mode = fNeutVect->Mode; fNUISANCEEvent->fEventNo = fNeutVect->EventNo; fNUISANCEEvent->fTargetA = fNeutVect->TargetA; fNUISANCEEvent->fTargetZ = fNeutVect->TargetZ; fNUISANCEEvent->fTargetH = fNeutVect->TargetH; fNUISANCEEvent->fBound = bool(fNeutVect->Ibound); if (fNUISANCEEvent->fBound) { fNUISANCEEvent->fTargetPDG = TargetUtils::GetTargetPDGFromZA( fNUISANCEEvent->fTargetZ, fNUISANCEEvent->fTargetA); } else { fNUISANCEEvent->fTargetPDG = 1000010010; } // Check Particle Stack UInt_t npart = fNeutVect->Npart(); UInt_t kmax = fNUISANCEEvent->kMaxParticles; if (npart > kmax) { ERR(FTL) << "NEUT has too many particles. Expanding stack." << std::endl; fNUISANCEEvent->ExpandParticleStack(npart); throw; } // Fill Particle Stack for (size_t i = 0; i < npart; i++) { // Get Current Count int curpart = fNUISANCEEvent->fNParticles; // Get NEUT Particle NeutPart* part = fNeutVect->PartInfo(i); // State int state = GetNeutParticleStatus(part); // Remove Undefined if (kRemoveUndefParticles && state == kUndefinedState) continue; // Remove FSI if (kRemoveFSIParticles && state == kFSIState) continue; // Remove Nuclear if (kRemoveNuclearParticles && (state == kNuclearInitial || state == kNuclearRemnant)) continue; // State fNUISANCEEvent->fParticleState[curpart] = state; // Mom fNUISANCEEvent->fParticleMom[curpart][0] = part->fP.X(); fNUISANCEEvent->fParticleMom[curpart][1] = part->fP.Y(); fNUISANCEEvent->fParticleMom[curpart][2] = part->fP.Z(); fNUISANCEEvent->fParticleMom[curpart][3] = part->fP.T(); // PDG fNUISANCEEvent->fParticlePDG[curpart] = part->fPID; // Add up particle count fNUISANCEEvent->fNParticles++; } // Save Extra Generator Info if (fSaveExtra) { fNeutInfo->FillGeneratorInfo(fNeutVect); } // Run Initial, FSI, Final, Other ordering. fNUISANCEEvent->OrderStack(); FitParticle* ISNeutralLepton = fNUISANCEEvent->GetHMISParticle(PhysConst::pdg_neutrinos); if (ISNeutralLepton) { fNUISANCEEvent->probe_E = ISNeutralLepton->E(); fNUISANCEEvent->probe_pdg = ISNeutralLepton->PDG(); } return; } void NEUTUtils::FillNeutCommons(NeutVect* nvect) { // WARNING: This has only been implemented for a neuttree and not GENIE // This should be kept in sync with T2KNIWGUtils::GetNIWGEvent(TTree) // NEUT version info. Can't get it to compile properly with this yet // neutversion_.corev = nvect->COREVer; // neutversion_.nucev = nvect->NUCEVer; // neutversion_.nuccv = nvect->NUCCVer; // Documentation: See nework.h nework_.modene = nvect->Mode; nework_.numne = nvect->Npart(); nemdls_.mdlqeaf = nvect->QEVForm; nemdls_.mdlqe = nvect->QEModel; nemdls_.mdlspi = nvect->SPIModel; nemdls_.mdldis = nvect->DISModel; nemdls_.mdlcoh = nvect->COHModel; neutcoh_.necohepi = nvect->COHModel; nemdls_.xmaqe = nvect->QEMA; nemdls_.xmvqe = nvect->QEMV; nemdls_.kapp = nvect->KAPPA; // nemdls_.sccfv = SCCFVdef; // nemdls_.sccfa = SCCFAdef; // nemdls_.fpqe = FPQEdef; nemdls_.xmaspi = nvect->SPIMA; nemdls_.xmvspi = nvect->SPIMV; nemdls_.xmares = nvect->RESMA; nemdls_.xmvres = nvect->RESMV; neut1pi_.xmanffres = nvect->SPIMA; neut1pi_.xmvnffres = nvect->SPIMV; neut1pi_.xmarsres = nvect->RESMA; neut1pi_.xmvrsres = nvect->RESMV; neut1pi_.neiff = nvect->SPIForm; neut1pi_.nenrtype = nvect->SPINRType; neut1pi_.rneca5i = nvect->SPICA5I; neut1pi_.rnebgscl = nvect->SPIBGScale; nemdls_.xmacoh = nvect->COHMA; nemdls_.rad0nu = nvect->COHR0; // nemdls_.fa1coh = nvect->COHA1err; // nemdls_.fb1coh = nvect->COHb1err; // neutdis_.nepdf = NEPDFdef; // neutdis_.nebodek = NEBODEKdef; neutcard_.nefrmflg = nvect->FrmFlg; neutcard_.nepauflg = nvect->PauFlg; neutcard_.nenefo16 = nvect->NefO16; neutcard_.nemodflg = nvect->ModFlg; // neutcard_.nenefmodl = 1; // neutcard_.nenefmodh = 1; // neutcard_.nenefkinh = 1; // neutpiabs_.neabspiemit = 1; nenupr_.iformlen = nvect->FormLen; neutpiless_.ipilessdcy = nvect->IPilessDcy; neutpiless_.rpilessdcy = nvect->RPilessDcy; neutpiless_.ipilessdcy = nvect->IPilessDcy; neutpiless_.rpilessdcy = nvect->RPilessDcy; neffpr_.fefqe = nvect->NuceffFactorPIQE; neffpr_.fefqeh = nvect->NuceffFactorPIQEH; neffpr_.fefinel = nvect->NuceffFactorPIInel; neffpr_.fefabs = nvect->NuceffFactorPIAbs; neffpr_.fefcx = nvect->NuceffFactorPICX; neffpr_.fefcxh = nvect->NuceffFactorPICXH; neffpr_.fefcoh = nvect->NuceffFactorPICoh; neffpr_.fefqehf = nvect->NuceffFactorPIQEHKin; neffpr_.fefcxhf = nvect->NuceffFactorPICXKin; neffpr_.fefcohf = nvect->NuceffFactorPIQELKin; for (int i = 0; i < nework_.numne; i++) { nework_.ipne[i] = nvect->PartInfo(i)->fPID; nework_.pne[i][0] = (float)nvect->PartInfo(i)->fP.X() / 1000; // VC(NE)WORK in M(G)eV nework_.pne[i][1] = (float)nvect->PartInfo(i)->fP.Y() / 1000; // VC(NE)WORK in M(G)eV nework_.pne[i][2] = (float)nvect->PartInfo(i)->fP.Z() / 1000; // VC(NE)WORK in M(G)eV } // fsihist.h // neutroot fills a dummy object for events with no FSI to prevent memory leak // when // reading the TTree, so check for it here if ((int)nvect->NfsiVert() == 1) { // An event with FSI must have at least two vertices // if (nvect->NfsiPart()!=1 || nvect->Fsiprob!=-1) // ERR(WRN) << "T2KNeutUtils::fill_neut_commons(TTree) NfsiPart!=1 or // Fsiprob!=-1 when NfsiVert==1" << std::endl; fsihist_.nvert = 0; fsihist_.nvcvert = 0; fsihist_.fsiprob = 1; } else { // Real FSI event fsihist_.nvert = (int)nvect->NfsiVert(); for (int ivert = 0; ivert < fsihist_.nvert; ivert++) { fsihist_.iflgvert[ivert] = nvect->FsiVertInfo(ivert)->fVertID; fsihist_.posvert[ivert][0] = (float)nvect->FsiVertInfo(ivert)->fPos.X(); fsihist_.posvert[ivert][1] = (float)nvect->FsiVertInfo(ivert)->fPos.Y(); fsihist_.posvert[ivert][2] = (float)nvect->FsiVertInfo(ivert)->fPos.Z(); } fsihist_.nvcvert = nvect->NfsiPart(); for (int ip = 0; ip < fsihist_.nvcvert; ip++) { fsihist_.abspvert[ip] = (float)nvect->FsiPartInfo(ip)->fMomLab; fsihist_.abstpvert[ip] = (float)nvect->FsiPartInfo(ip)->fMomNuc; fsihist_.ipvert[ip] = nvect->FsiPartInfo(ip)->fPID; fsihist_.iverti[ip] = nvect->FsiPartInfo(ip)->fVertStart; fsihist_.ivertf[ip] = nvect->FsiPartInfo(ip)->fVertEnd; fsihist_.dirvert[ip][0] = (float)nvect->FsiPartInfo(ip)->fDir.X(); fsihist_.dirvert[ip][1] = (float)nvect->FsiPartInfo(ip)->fDir.Y(); fsihist_.dirvert[ip][2] = (float)nvect->FsiPartInfo(ip)->fDir.Z(); } fsihist_.fsiprob = nvect->Fsiprob; } neutcrscom_.crsx = nvect->Crsx; neutcrscom_.crsy = nvect->Crsy; neutcrscom_.crsz = nvect->Crsz; neutcrscom_.crsphi = nvect->Crsphi; neutcrscom_.crsq2 = nvect->Crsq2; neuttarget_.numbndn = nvect->TargetA - nvect->TargetZ; neuttarget_.numbndp = nvect->TargetZ; neuttarget_.numfrep = nvect->TargetH; neuttarget_.numatom = nvect->TargetA; posinnuc_.ibound = nvect->Ibound; // put empty nucleon FSI history (since it is not saved in the NeutVect // format) // Comment out as NEUT does not have the necessary proton FSI information yet // nucleonfsihist_.nfnvert = 0; // nucleonfsihist_.nfnstep = 0; } #endif diff --git a/src/InputHandler/NUANCEInputHandler.cxx b/src/InputHandler/NUANCEInputHandler.cxx index 178c36b..7814f4a 100644 --- a/src/InputHandler/NUANCEInputHandler.cxx +++ b/src/InputHandler/NUANCEInputHandler.cxx @@ -1,835 +1,836 @@ #ifdef __NUANCE_ENABLED__ #include "NUANCEInputHandler.h" +#include "InputUtils.h" + NUANCEGeneratorInfo::~NUANCEGeneratorInfo() { DeallocateParticleStack(); } void NUANCEGeneratorInfo::AddBranchesToTree(TTree * tn) { // tn->Branch("NEUTParticleN", fNEUTParticleN, "NEUTParticleN/I"); // tn->Branch("NEUTParticleStatusCode", fNEUTParticleStatusCode, "NEUTParticleStatusCode[NEUTParticleN]/I"); // tn->Branch("NEUTParticleAliveCode", fNEUTParticleAliveCode, "NEUTParticleAliveCode[NEUTParticleN]/I"); } void NUANCEGeneratorInfo::SetBranchesFromTree(TTree* tn) { // tn->SetBranchAddress("NEUTParticleN", &fNEUTParticleN ); // tn->SetBranchAddress("NEUTParticleStatusCode", &fNEUTParticleStatusCode ); // tn->SetBranchAddress("NEUTParticleAliveCode", &fNEUTParticleAliveCode ); } void NUANCEGeneratorInfo::AllocateParticleStack(int stacksize) { // fNEUTParticleN = 0; // fNEUTParticleStatusCode = new int[stacksize]; // fNEUTParticleStatusCode = new int[stacksize]; } void NUANCEGeneratorInfo::DeallocateParticleStack() { // delete fNEUTParticleStatusCode; // delete fNEUTParticleAliveCode; } void NUANCEGeneratorInfo::FillGeneratorInfo(NuanceEvent* nevent) { Reset(); // for (int i = 0; i < nevent->Npart(); i++) { // fNEUTParticleStatusCode[i] = nevent->PartInfo(i)->fStatus; // fNEUTParticleAliveCode[i] = nevent->PartInfo(i)->fIsAlive; // fNEUTParticleN++; // } } void NUANCEGeneratorInfo::Reset() { // for (int i = 0; i < fNEUTParticleN; i++) { // fNEUTParticleStatusCode[i] = -1; // fNEUTParticleAliveCode[i] = 9; // } // fNEUTParticleN = 0; } NUANCEInputHandler::NUANCEInputHandler(std::string const& handle, std::string const& rawinputs) { LOG(SAM) << "Creating NUANCEInputHandler : " << handle << std::endl; // Run a joint input handling fName = handle; fSaveExtra = FitPar::Config().GetParB("SaveExtraNUANCE"); fCacheSize = FitPar::Config().GetParI("CacheSize"); fMaxEvents = FitPar::Config().GetParI("MAXEVENTS"); // Parse Inputs std::vector inputs = InputUtils::ParseInputFileList(rawinputs); if (inputs.size() > 1) { ERR(FTL) << "NUANCE is not currently setup to handle joint inputs sorry!" << std::endl << "If you know how to correctly normalise the events for this" << " please let us know!" << std::endl; } // Read in NUANCE Tree fNUANCETree = new TChain("h3"); fNUANCETree->AddFile(rawinputs.c_str()); // Get entries and fNuwroEvent int nevents = fNUANCETree->GetEntries(); double EnuMin = 0.0; double EnuMax = 1000.0; TH1D* fluxhist = new TH1D((fName + "_FLUX").c_str(), (fName + "_FLUX").c_str(), 100, EnuMin, EnuMax); for (int i = 0; i < fluxhist->GetNbinsX(); i++) { fluxhist->SetBinContent(i + 1, 1.0); } fluxhist->Scale(1.0 / fluxhist->Integral()); TH1D* eventhist = new TH1D((fName + "_EVT").c_str(), (fName + "_EVT").c_str(), 100, EnuMin, EnuMax); for (int i = 0; i < fluxhist->GetNbinsX(); i++) { eventhist->SetBinContent(i + 1, 1.0); } eventhist->Scale(1.0 / eventhist->Integral()); RegisterJointInput( rawinputs, nevents, fluxhist, eventhist ); SetupJointInputs(); // Setup Reader fNuanceEvent = new NuanceEvent(); fNuanceEvent->SetBranchAddresses(fNUANCETree); fNUANCETree->GetEntry(0); // Setup Event in FitEvent fNUISANCEEvent = new FitEvent(); fNUISANCEEvent->SetNuanceEvent(fNuanceEvent); // Setup extra if needed if (fSaveExtra){ ERR(FTL) << "NO SAVEExtra Implemented for NUANCE YET!" << std::endl; throw; // fNuanceInfo = new NUANCEGeneratorInfo(); // fNUISANCEEvent->AddGeneratorInfo(fNuanceInfo); } }; NUANCEInputHandler::~NUANCEInputHandler() { if (fNuanceEvent) delete fNuanceEvent; if (fNUANCETree) delete fNUANCETree; // if (fNuanceInfo) delete fNuanceInfo; } void NUANCEInputHandler::CreateCache() { if (fCacheSize > 0) { fNUANCETree->SetCacheEntryRange(0, fNEvents); fNUANCETree->AddBranchToCache("h3", 1); fNUANCETree->SetCacheSize(fCacheSize); } } void NUANCEInputHandler::RemoveCache() { fNUANCETree->SetCacheEntryRange(0, fNEvents); fNUANCETree->AddBranchToCache("h3", 0); fNUANCETree->SetCacheSize(0); } FitEvent* NUANCEInputHandler::GetNuisanceEvent(const UInt_t entry, const bool lightweight) { // Check out of bounds if (entry >= (UInt_t)fNEvents) return NULL; // Read Entry from TTree to fill NEUT Vect in BaseFitEvt; fNUANCETree->GetEntry(entry); // Setup Input scaling for joint inputs fNUISANCEEvent->InputWeight = GetInputWeight(entry); // Run NUISANCE Vector Filler if (!lightweight) { CalcNUISANCEKinematics(); } return fNUISANCEEvent; } void NUANCEInputHandler::CalcNUISANCEKinematics() { // Reset all variables fNUISANCEEvent->ResetEvent(); // Get shortened pointer FitEvent* evt = fNUISANCEEvent; // Fill Global - evt->fMode = ConvertNuanceMode(fNuanceEvent); - evt->Mode = evt->fMode; + evt->Mode = ConvertNuanceMode(fNuanceEvent); evt->fEventNo = 0.0; evt->fTotCrs = 1.0; evt->fTargetA = 0.0; evt->fTargetZ = 0.0; evt->fTargetH = 0; evt->fBound = 0.0; // Fill particle Stack evt->fNParticles = 0; // Check Particle Stack UInt_t npart = 2 + fNuanceEvent->n_leptons + fNuanceEvent->n_hadrons; UInt_t kmax = evt->kMaxParticles; if (npart > kmax) { ERR(FTL) << "NUANCE has too many particles" << std::endl; ERR(FTL) << "npart=" << npart << " kMax=" << kmax << std::endl; throw; } // Fill Neutrino evt->fParticleState[0] = kInitialState; evt->fParticleMom[0][0] = fNuanceEvent->p_neutrino[0]; evt->fParticleMom[0][1] = fNuanceEvent->p_neutrino[1]; evt->fParticleMom[0][2] = fNuanceEvent->p_neutrino[2]; evt->fParticleMom[0][3] = fNuanceEvent->p_neutrino[3]; evt->fParticlePDG[0] = fNuanceEvent->neutrino; // Fill Target Nucleon evt->fParticleState[1] = kInitialState; evt->fParticleMom[1][0] = fNuanceEvent->p_targ[0]; evt->fParticleMom[1][1] = fNuanceEvent->p_targ[1]; evt->fParticleMom[1][2] = fNuanceEvent->p_targ[2]; evt->fParticleMom[1][3] = fNuanceEvent->p_targ[3]; evt->fParticlePDG[1] = fNuanceEvent->target; evt->fNParticles = 2; // Fill Outgoing Leptons for (int i = 0; i < fNuanceEvent->n_leptons; i++) { evt->fParticleState[evt->fNParticles] = kFinalState; evt->fParticleMom[evt->fNParticles][0] = fNuanceEvent->p_lepton[i][0]; evt->fParticleMom[evt->fNParticles][1] = fNuanceEvent->p_lepton[i][1]; evt->fParticleMom[evt->fNParticles][2] = fNuanceEvent->p_lepton[i][2]; evt->fParticleMom[evt->fNParticles][3] = fNuanceEvent->p_lepton[i][3]; evt->fParticlePDG[evt->fNParticles] = fNuanceEvent->lepton[i]; evt->fNParticles++; } // Fill Outgoing Hadrons for (int i = 0; i < fNuanceEvent->n_hadrons; i++) { evt->fParticleState[evt->fNParticles] = kFinalState; evt->fParticleMom[evt->fNParticles][0] = fNuanceEvent->p_hadron[i][0]; evt->fParticleMom[evt->fNParticles][1] = fNuanceEvent->p_hadron[i][1]; evt->fParticleMom[evt->fNParticles][2] = fNuanceEvent->p_hadron[i][2]; evt->fParticleMom[evt->fNParticles][3] = fNuanceEvent->p_hadron[i][3]; evt->fParticlePDG[evt->fNParticles] = fNuanceEvent->hadron[i]; evt->fNParticles++; } // Save Extra info if (fSaveExtra) { // fNuanceInfo->FillGeneratorInfo(fNuanceEvent); } // Run Initial, FSI, Final, Other ordering. fNUISANCEEvent-> OrderStack(); return; } void NUANCEInputHandler::Print() {} int NUANCEInputHandler::ConvertNuanceMode(NuanceEvent * evt) { int ch = evt->channel; int sg = 1; if (evt->neutrino < 0) sg = -1; switch (ch) { // 1 NUANCE CCQE -> NEUT CCQE 1 case 1: return sg * 1; // 2 NUANCE NCEL -> NEUT NCEL 51,52 -> Set from whether target is p or n case 2: if (evt->target == 2212) return sg * 51; else return sg * 52; // 3 NUANCE CCPIP -> NEUT CCPIP 11 case 3: return sg * 11; // 4 NUANCE CCPI0 -> NEUT CCPI0 = 12 case 4: return sg * 12; // 5 NUANCE CCPIPn -> NEUT CCPIPn 13 case 5: return sg * 13; // 6 NUANCE NCpPI0 -> NEUT NCpPI0 32 case 6: return sg * 32; // 7 NUANCE NCpPI+ -> NEUT NCpPI+ 34 case 7: return sg * 34; // 8 NUANCE NCnPI0 -> NEUT NCnPI0 31 case 8: return sg * 31; // 9 NUANCE NCnPIM -> NEUT NCnPIM 33 case 9: return sg * 33; // 10 NUANCE CCPIP -> NEUT CCPIP -11 case 10: return sg * 11; // 11 NUANCE CCPI0 -> NEUT CCPI0 -12 case 11: return sg * 12; // 12 NUANCE CCPIPn -> NEUT CCPIPn 13 case 12: return sg * 13; // 13 NUANCE NCpPI0 -> NEUT NCnPI0 -32 case 13: return sg * 32; // 14 NUANCE NCpPI+ -> NEUT NCpPI+ -34 case 14: return sg * 34; // 15 NUANCE NCnPI0 -> NEUT NCnPI0 -31 case 15: return sg * 31; // 16 NUANCE NCnPIM -> NEUT NCnPIM -33 case 16: return sg * 33; // 17 NUANCE -> NEUT 21 CC MULTIPI case 17: return sg * 21; // 18 NUANCE -> NEUT 21 CC MULTIPI case 18: return sg * 21; // 19 NUANCE -> NEUT 21 CC MULTIPI case 19: return sg * 21; // 20 NUANCE -> NEUT 21 CC MULTIPI case 20: return sg * 21; // 21 NUANCE -> NEUT 21 CC MULTIPI case 21: return sg * 21; // 22 NUANCE -> NEUT 41 NC MULTIPI case 22: return sg * 41; // 23 NUANCE -> NEUT 41 NC MULTIPI case 23: return sg * 41; // 24 NUANCE -> NEUT 41 NC MULTIPI case 24: return sg * 41; // 25 NUANCE -> NEUT 41 NC MULTIPI case 25: return sg * 41; // 26 NUANCE -> NEUT 41 NC MULTIPI case 26: return sg * 41; // 27 NUANCE -> NEUT -41 "NC (1.3 < W < 2 GeV) case 27: return sg * 41; // 28 NUANCE -> NEUT -21 CC (1.3 < W < 2 GeV) case 28: return sg * 21; // 29 NUANCE -> NEUT -21 CC (1.3 < W < 2 GeV) case 29: return sg * 21; // 30 NUANCE -> NEUT -21 CC (1.3 < W < 2 GeV) case 30: return sg * 21; // 31 NUANCE -> NEUT -21 CC (1.3 < W < 2 GeV) case 31: return sg * 21; // 32 NUANCE -> NEUT -21 CC (1.3 < W < 2 GeV) case 32: return sg * 21; // 33 NUANCE -> NEUT -41 "NC (1.3 < W < 2 GeV) case 33: return sg * 41; // 34 NUANCE -> NEUT -41 "NC (1.3 < W < 2 GeV) case 34: return sg * 41; // 35 NUANCE -> NEUT -41 "NC (1.3 < W < 2 GeV) case 35: return sg * 41; // 36 NUANCE -> NEUT -41 "NC (1.3 < W < 2 GeV) case 36: return sg * 41; // 37 NUANCE -> NEUT -41 "NC (1.3 < W < 2 GeV) case 37: return sg * 41; // 38 NUANCE -> NEUT -41 "NC (1.3 < W < 2 GeV) case 38: return sg * 41; // 39 NUANCE -> NEUT 22 case 39: return sg * 22; // 40 NUANCE -> NEUT 22 case 40: return sg * 22; // 41 NUANCE -> NEUT 22 case 41: return sg * 22; // 42 NUANCE -> NEUT 43 case 42: return sg * 43; // 43 NUANCE -> NEUT 43 case 43: return sg * 43; // 44 NUANCE -> NUET 42 case 44: return sg * 42; // 45 NUANCE -> NEUT -42 case 45: return sg * 42; // 46 NUANCE -> NEUT -22 case 46: return sg * 22; // 47 NUANCE -> NEUT -22 case 47: return sg * 22; // 48 NUANCE -> NEUT -22 case 48: return sg * 22; // 49 NUANCE -> NEUT -43 case 49: return sg * 43; // 50 NUANCE -> NEUT -43 case 50: return sg * 43; // 51 NUANCE -> NEUT -42 case 51: return sg * 42; // 52 NUANCE -> NEUT -42 case 52: return sg * 42; // 53 NUANCE -> NEUT 23 CC 1K case 53: return sg * 23; // 54 NUANCE -> NEUT 23 CC 1K case 54: return sg * 23; // 55 NUANCE -> NEUT 23 CC 1K case 55: return sg * 23; // 56 NUANCE -> NEUT 45 NC 1K case 56: return sg * 45; // 57 NUANCE -> NEUT 44 NC 1K case 57: return sg * 44; // 58 NUANCE -> NEUT 44 NC 1K case 58: return sg * 44; // 59 NUANCE -> NEUT 44 NC 1K case 59: return sg * 44; // 60 NUANCE -> NEUT -23 CC 1K case 60: return sg * 23; // 61 NUANCE -> NEUT -23 CC 1K case 61: return sg * 23; // 62 NUANCE -> NEUT -23 CC 1K case 62: return sg * 23; // 63 NUANCE -> NEUT -23 CC 1K case 63: return sg * 23; // 64 NUANCE -> NEUT -44 NC 1K case 64: return sg * 44; // 65 NUANCE -> NEUT -44 NC 1K case 65: return sg * 44; // 66 NUANCE -> NEUT -45 NC 1K case 66: return sg * 45; // 67 NUANCE -> NEUT 22 CC1eta case 67: return sg * 22; // 68 NUANCE -> NEUT 43 NC p eta case 68: return sg * 43; // 69 NUANCE -> NEUT 43 NC n eta case 69: return sg * 43; // 70 NUANCE -> NEUT -22 CC1eta case 70: return sg * 22; // 71 NUANCE -> NEUT -43 NC p eta case 71: return sg * 43; // 72 NUANCE -> NEUT 42 NC n eta case 72: return sg * 42; // 73 NUANCE -> NEUT 21 CC Multi Pi case 73: return sg * 21; // 74 NUANCE -> NEUT 41 NC Multi Pi case 74: return sg * 41; // 75 NUANCE -> NEUT 41 NC Multi Pi case 75: return sg * 41; // 76 NUANCE -> NEUT -21 CC Multi Pi case 76: return sg * 21; // 77 NUANCE -> NEUT -41 NC Multi Pi case 77: return sg * 41; // 78 NUANCE -> NEUT -41 NC Multi Pi case 78: return sg * 41; // 79 NUANCE -> NEUT 21 CC Multi Pi case 79: return sg * 21; // 80 NUANCE -> NEUT 21 CC Multi Pi case 80: return sg * 21; // 81 NUANCE -> NEUT 41 NC Multi Pi case 81: return sg * 41; // 82 NUANCE -> NEUT 41 NC Multi Pi case 82: return sg * 41; // 83 NUANCE -> NEUT 41 NC Multi Pi case 83: return sg * 41; // 84 NUANCE -> NEUT 41 NC Multi Pi case 84: return sg * 84; // 85 NUANCE -> NEUT -21 CC Multi Pi case 85: return sg * 21; // 86 NUANCE -> NEUT -21 CC Multi Pi case 86: return sg * 21; // 87 NUANCE -> NEUT -41 CC Multi Pi case 87: return sg * 41; // 88 NUANCE -> NEUT -41 case 88: return sg * 41; // 89 NUANCE -> NEUT -41 case 89: return sg * 41; // 90 NUANCE -> NEUT -41 case 90: return sg * 41; // 91 NUANCE -> NEUT 26 CC DIS case 91: return sg * 26; // 92 NUANCE -> NEUT 46 NC DIS case 92: return sg * 46; // 93 NUANCE -> NEUT 17 1#gamma from #Delta case 93: return sg * 17; // 94 NUANCE -> NEUT 39 1#gamma from #Delta case 94: return sg * 39; // 95 -> UNKOWN NEUT MODE case 95: return sg * 0; // 96 NUANCE -> NEUT 36 NC COH case 96: return sg * 36; // 97 NUANCE -> NEUT 16 case 97: return sg * 16; // 98 -> UNKNOWN NEUT MODE case 98: return sg * 0; // 99 -> UNKNOWN NEUT MODE case 99: return sg * 0; default: ERR(FTL) << "Unknown Nuance Channel ID = " << ch << std::endl; throw ("Exiting."); return 0; } return 0; } /* // Notes copied from NuanceChannels.pdf 1 NUANCE CCQE -> NEUT CCQE 1 CC, numu n --> mu- p Cabibbo-allowed quasi-elastic scattering from nucleons 2 NUANCE NCEL -> NEUT NCEL 51,52 -> Set from whether target is p or n NC, numu N --> num N, (N=n,p) (quasi)-elastic scattering from nucleons 3 NUANCE CCPIP -> NEUT CCPIP 11 CC, numu p --> mu- p pi+ resonant single pion production 4 NUANCE CCPI0 -> NEUT CCPI0 = 12 CC, numu n --> mu- p pi0 resonant single pion production 5 NUANCE CCPIPn -> NEUT CCPIPn 13 CC, numu n --> mu- n pi+ resonant single pion production 6 NUANCE NCpPI0 -> NEUT NCpPI0 32 NC, numu p --> numu p pi0 resonant single pion production 7 NUANCE NCpPI+ -> NEUT NCpPI+ 34 NC, numu p --> numu n pi+ resonant single pion production 8 NUANCE NCnPI0 -> NEUT NCnPI0 31 NC, numu n --> numu n pi0 resonant single pion production 9 NUANCE NCnPIM -> NEUT NCnPIM 33 NC, numu n --> numu p pi- resonant single pion production 10 NUANCE CCPIP -> NEUT CCPIP -11 CC, numubar p --> mu- p pi+ resonant single pion production 11 NUANCE CCPI0 -> NEUT CCPI0 -12 CC, numubar n --> mu- p pi0 resonant single pion production 12 NUANCE CCPIPn -> NEUT CCPIPn -13 CC, numubar n --> mu- n pi+ resonant single pion production 13 NUANCE NCpPI0 -> NEUT NCnPI0 -32 NC, numubar p --> numubar p pi0 resonant single pion production 14 NUANCE NCpPI+ -> NEUT NCpPI+ -34 NC, numubar p --> numubar n pi+ resonant single pion production 15 NUANCE NCnPI0 -> NEUT NCnPI0 -31 NC, numubar n --> numubar n pi0 resonant single pion production 16 NUANCE NCnPIM -> NEUT NCnPIM -33 NC, numubar n --> numubar p pi- resonant single pion production 17 NUANCE -> NEUT 21 CC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow l^{-} N' multi-#pi CC, numu p --> mu- Delta+ pi+ resonant processes involving more than a single pion 18 NUANCE -> NEUT 21 CC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow l^{-} N' multi-#pi CC, numu p --> mu- Delta++ pi0 resonant processes involving more than a single pion 19 NUANCE -> NEUT 21 CC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow l^{-} N' multi-#pi CC, numu n --> mu- Delta+ pi0 resonant processes involving more than a single pion 20 NUANCE -> NEUT 21 CC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow l^{-} N' multi-#pi CC, numu n --> mu- Delta0 pi+ resonant processes involving more than a single pion 21 NUANCE -> NEUT 21 CC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow l^{-} N' multi-#pi CC, numu n --> mu- Delta++ pi- resonant processes involving more than a single pion 22 NUANCE -> NEUT 41 "NC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow #nu_{l} N multi-#pi" NC, numu p+ --> numu Delta+ pi0 resonant processes involving more than a single pion 23 NUANCE -> NEUT 41 "NC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow #nu_{l} N multi-#pi" NC,numu p --> numu Delta0 pi+ resonant processes involving more than a single pion 24 NUANCE -> NEUT 41 "NC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow #nu_{l} N multi-#pi" NC, numu p --> numu Delta++ pi- resonant processes involving more than a single pion 25 NUANCE -> NEUT 41 "NC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow #nu_{l} N multi-#pi" NC, numu n --> numu Delta+ pi- resonant processes involving more than a single pion 26 NUANCE -> NEUT 41 "NC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow #nu_{l} N multi-#pi" NC, numu n --> numu Delta0 pi0 resonant processes involving more than a single pion 27 NUANCE -> NEUT -41 "NC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow #nu_{l} N multi-#pi" NC, numubar n --> numubar Delta- pi+ resonant processes involving more than a single pion 28 NUANCE -> NEUT -21 CC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow l^{-} N' multi-#pi CC, numubar p --> mu- Delta+ pi+ resonant processes involving more than a single pion 29 UANCE -> NEUT -21 CC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow l^{-} N' multi-#pi CC, numubar p --> mu- Delta++ pi0 resonant processes involving more than a single pion 30 NUANCE -> NEUT -21 CC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow l^{-} N' multi-#pi CC, numubar n --> mu- Delta+ pi0 resonant processes involving more than a single pion 31 NUANCE -> NEUT -21 CC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow l^{-} N' multi-#pi CC, numubar n --> mu- Delta0 pi+ resonant processes involving more than a single pion 32 NUANCE -> NEUT -21 CC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow l^{-} N' multi-#pi CC, numubar n --> mu- Delta++ pi- resonant processes involving more than a single pion 33 NUANCE -> NEUT -41 "NC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow #nu_{l} N multi-#pi" NC, numubar p+ --> numubar Delta+ pi0 resonant processes involving more than a single pion 34 NUANCE -> NEUT -41 "NC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow #nu_{l} N multi-#pi" NC,numubar p --> numubar Delta0 pi+ resonant processes involving more than a single pion 35 NUANCE -> NEUT -41 "NC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow #nu_{l} N multi-#pi" NC, numubar p --> numubar Delta++ pi- resonant processes involving more than a single pion 36 NUANCE -> NEUT -41 "NC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow #nu_{l} N multi-#pi" NC, numubar n --> numubar Delta+ pi- resonant processes involving more than a single pion 37 NUANCE -> NEUT -41 "NC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow #nu_{l} N multi-#pi" NC, numubar n --> numubar Delta0 pi0 resonant processes involving more than a single pion 38 NUANCE -> NEUT -41 "NC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow #nu_{l} N multi-#pi" NC, numubar n --> numubar Delta- pi+ resonant processes involving more than a single pion // RHO Production lumped in with eta production 22 CCeta 43 NCeta on p 42 NCeta on n 39 NUANCE -> NEUT 22 CC, numu p --> mu- p rho+(770) resonant processes involving more than a single pion 40 NUANCE -> NEUT 22 CC, numu n --> mu- p rho0(770) resonant processes involving more than a single pion 41 NUANCE -> NEUT 22 CC, numu n --> mu- n rho+(770) resonant processes involving more than a single pion 42 NUANCE -> NEUT 43 NC, numu p --> numu p rho0(770) resonant processes involving more than a single pion 43 NUANCE -> NEUT 43 NC, numu p --> numu n rho+(770) resonant processes involving more than a single pion 44 NUANCE -> NUET 42 NC, numu n --> numu n rho0(770) resonant processes involving more than a single pion 45 NUANCE -> NEUT -42 NC, numubar n --> numubar p rho-(770) resonant processes involving more than a single pion 46 NUANCE -> NEUT -22 CC, numubar p --> mu- p rho+(770) resonant processes involving more than a single pion 47 NUANCE -> NEUT -22 CC, numubar n --> mu- p rho0(770) resonant processes involving more than a single pion 48 NUANCE -> NEUT -22 CC, numubar n --> mu- n rho+(770) resonant processes involving more than a single pion 49 NUANCE -> NEUT -43 NC, numubar p --> numubar p rho0(770) resonant processes involving more than a single pion 50 NUANCE -> NEUT -43 NC, numubar p --> numubar n rho+(770) resonant processes involving more than a single pion 51 NUANCE -> NEUT -42 NC, numubar n --> numubar n rho0(770) resonant processes involving more than a single pion 52 NUANCE -> NEUT -42 NC, numubar n --> numubar p rho-(770) resonant processes involving more than a single pion 53 NUANCE -> NEUT 23 CC 1K: #nu_{l} n #rightarrow l^{-} #Lambda K^{+} CC, numu p --> mu- Sigma+ K+ resonant processes involving more than a single pion 54 NUANCE -> NEUT 23 CC 1K: #nu_{l} n #rightarrow l^{-} #Lambda K^{+} CC, numu n --> mu- Sigma0 K+ resonant processes involving more than a single pion 55 NUANCE -> NEUT 23 CC 1K: #nu_{l} n #rightarrow l^{-} #Lambda K^{+} CC, numu n --> mu- Sigma+ K0 resonant processes involving more than a single pion 56 NUANCE -> NEUT 45 NC 1K: #nu_{l} n #rightarrow #nu_{l} #Lambda K^{+} NC, numu p --> numu Sigma0 K+ resonant processes involving more than a single pion 57 NUANCE -> NEUT 44 NC 1K: #nu_{l} n #rightarrow #nu_{l} #Lambda K^{0} NC, numu p --> numu Sigma+ K0 resonant processes involving more than a single pion 58 NUANCE -> NEUT 44 NC 1K: #nu_{l} n #rightarrow #nu_{l} #Lambda K^{0} NC, numu n --> numu Sigma0 K0 resonant processes involving more than a single pion 59 NUANCE -> NEUT 45 NC 1K: #nu_{l} n #rightarrow #nu_{l} #Lambda K^{+} NC, numu n --> numu Sigma- K+ resonant processes involving more than a single pion 60 NUANCE -> NEUT -23 CC 1K: #nu_{l} n #rightarrow l^{-} #Lambda K^{+} CC, numubar p --> mu- Sigma+ K+ resonant processes involving more than a single pion 61 NUANCE -> NEUT -23 CC 1K: #nu_{l} n #rightarrow l^{-} #Lambda K^{+} CC, numubar n --> mu- Sigma0 K+ resonant processes involving more than a single pion 62 NUANCE -> NEUT -23 CC 1K: #nu_{l} n #rightarrow l^{-} #Lambda K^{+} CC, numubar n --> mu- Sigma+ K0 resonant processes involving more than a single pion 63 NUANCE -> NEUT -45 NC 1K: #nu_{l} n #rightarrow #nu_{l} #Lambda K^{+} NC, numubar p --> numubar Sigma0 K+ resonant processes involving more than a single pion 64 NUANCE -> NEUT -44 NC 1K: #nu_{l} n #rightarrow #nu_{l} #Lambda K^{0} NC, numubar p --> numubar Sigma+ K0 resonant processes involving more than a single pion 65 NUANCE -> NEUT -44 NC 1K: #nu_{l} n #rightarrow #nu_{l} #Lambda K^{0} NC, numubar n --> numubar Sigma0 K0 resonant processes involving more than a single pion 66 NUANCE -> NEUT -45 NC 1K: #nu_{l} n #rightarrow #nu_{l} #Lambda K^{+} NC, numubar n --> numubar Sigma- K+ resonant processes involving more than a single pion 67 NUANCE -> NEUT 22 ModeStack[22]->SetTitle("CC1#eta^{0} on n"); CC, numu n --> mu- p eta resonant processes involving more than a single pion 68 NUANCE -> NEUT 43 NC, numu p --> numu p eta resonant processes involving more than a single pion 69 NUANCE -> NEUT 42 NC, numu n --> numu n eta resonant processes involving more than a single pion 70 NUANCE -> NEUT -22 ModeStack[22]->SetTitle("CC1#eta^{0} on n"); CC, numubar n --> mu- p eta resonant processes involving more than a single pion 71 NUANCE -> NEUT -43 ModeStack[43]->SetTitle("NC1#eta^{0} on p"); NC, numubar p --> numubar p eta resonant processes involving more than a single pion 72 NUANCE -> NEUT -42 ModeStack[42]->SetTitle("NC1#eta^{0} on n"); NC, numubar n --> numubar n eta resonant processes involving more than a single pion 73 NUANCE -> NEUT 21 ModeStack[21]->SetTitle("Multi #pi (1.3 < W < 2.0)"); CC, numu n --> mu- K+ Lambda resonant processes involving more than a single pion 74 NUANCE -> NEUT 41 ModeStack[41]->SetTitle("Multi #pi (1.3 < W < 2.0)"); NC, numu p --> numu K+ Lambda resonant processes involving more than a single pion 75 NUANCE -> NEUT 41 ModeStack[41]->SetTitle("Multi #pi (1.3 < W < 2.0)"); NC, numu n --> numu K0 Lambda resonant processes involving more than a single pion 76 NUANCE -> NEUT -21 ModeStack[21]->SetTitle("Multi #pi (1.3 < W < 2.0)"); CC, numubar n --> mu- K+ Lambda resonant processes involving more than a single pion 77 NUANCE -> NEUT -41 ModeStack[41]->SetTitle("Multi #pi (1.3 < W < 2.0)"); NC, numubar p --> numubar K+ Lambda resonant processes involving more than a single pion 78 NUANCE -> NEUT -41 ModeStack[41]->SetTitle("Multi #pi (1.3 < W < 2.0)"); NC, numubar n --> numubar K0 Lambda resonant processes involving more than a single pion CC Multipi ModeStack[21]->SetTitle("Multi #pi (1.3 < W < 2.0)"); NC Multipi ModeStack[41]->SetTitle("Multi #pi (1.3 < W < 2.0)"); 79 NUANCE -> NEUT 21 CC, numu n --> mu- p pi+ pi- two pion production 80 NUANCE -> NEUT 21 CC, numu n --> mu- p pi0 pi0 two pion production 81 NUANCE -> NEUT 41 NC, numu p --> numu p pi+ pi- two pion production 82 NUANCE -> NEUT 41 NC, numu p --> numu p pi0 pi0 two pion production 83 NUANCE -> NEUT 41 NC, numu n --> numu n pi+ pi- two pion production 84 NUANCE -> NEUT 41 NC, numu n --> numu n pi0 pi0 two pion production 85 NUANCE -> NEUT -21 CC, numubar n --> mu- p pi+ pi- two pion production 86 NUANCE -> NEUT -21 CC, numubar n --> mu- p pi0 pi0 two pion production 87 NUANCE -> NEUT -41 ModeStack[41]->SetTitle("Multi #pi (1.3 < W < 2.0)"); NC, numubar p --> numubar p pi+ pi- two pion production 88 NUANCE -> NEUT -41 ModeStack[41]->SetTitle("Multi #pi (1.3 < W < 2.0)"); NC, numubar p --> numubar p pi0 pi0 two pion production 89 NUANCE -> NEUT -41 ModeStack[41]->SetTitle("Multi #pi (1.3 < W < 2.0)"); NC, numubar n --> numubar n pi+ pi- two pion production 90 NUANCE -> NEUT -41 ModeStack[41]->SetTitle("Multi #pi (1.3 < W < 2.0)"); NC, numubar n --> numubar n pi0 pi0 two pion production 91 NUANCE -> NEUT 26 ModeStack[26]->SetTitle("DIS (W > 2.0)"); CC, numu N --> mu- X (where N=n,p) deep inelastic scattering (nu or nubar) 92 NUANCE -> NEUT 46 ModeStack[46]->SetTitle("DIS (W > 2.0)"); NC, numu N --> numu X (where N=n,p) deep inelastic scattering (nu or nubar) 93 NUANCE -> NEUT 17 1#gamma from #Delta: #nu_{l} n #rightarrow l^{-} p #gamma CC, numu n --> mu- p gamma Delta radiative decay, Delta --> N gamma (only in NUANCE versions v3 and and higher) 94 NUANCE -> NEUT 39 1#gamma from #Delta: #nu_{l} p #rightarrow #nu_{l} p #gamma neutModeID[15] = 38; neutModeName[15] = "ncngam"; neutModeTitle[15] = "1#gamma from #Delta: #nu_{l} n #rightarrow #nu_{l} n #gamma"; neutModeID[16] = 39; neutModeName[16] = "ncpgam"; neutModeTitle[16] = "1#gamma from #Delta: #nu_{l} p #rightarrow #nu_{l} p #gamma"; NC, numu N --> numu N gamma Delta radiative decay, Delta --> N gamma (only in NUANCE versions v3 and and higher) 95 -> UNKOWN NEUT MODE CC, numubar p --> mu+ Lambda, numubar n -- > mu+ Sigma-, numubar p --> mu+ Sigma0 Cabibbo-suppressed QE hyperon production from nucleons 96 NUANCE -> NEUT 36 neutModeID[14] = 36; neutModeName[14] = "nccoh"; neutModeTitle[14] = "NC coherent-#pi: #nu_{l} ^{16}O #rightarrow #nu_{l} ^{16}O #pi^{0}"; NC, numu A --> numu pi0 A coherent or diffractive pi0 production 97 NUANCE -> NEUT 16 neutModeID[4] = 16; neutModeName[4] = "cccoh"; neutModeTitle[4] = "CC coherent-#pi: #nu_{l} ^{16}O #rightarrow l^{-} ^{16}O #pi^{+}"; CC, numu A --> mu- pi+ A (or numubar A --> coherent or diffractive pi0 production 98 -> UNKNOWN NEUT MODE NC, numu e- --> numu e- (or numubar e- --> neutrino + electron elastic scattering 99 -> UNKNOWN NEUT MODE CC, numu e- --> mu- nue neutrino + electron inverse muon decay NEUT Modes: // CC Modes neutModeID[0] = 1; neutModeName[0] = "ccqe"; neutModeTitle[0] = "CCQE: #nu_{l} n #rightarrow l^{-} p"; neutModeID[1] = 11; neutModeName[1] = "ccppip"; neutModeTitle[1] = "CC 1#pi: #nu_{l} p #rightarrow l^{-} p #pi^{+}"; neutModeID[2] = 12; neutModeName[2] = "ccppi0"; neutModeTitle[2] = "CC 1#pi: #nu_{l} n #rightarrow l^{-} p #pi^{0}"; neutModeID[3] = 13; neutModeName[3] = "ccnpip"; neutModeTitle[3] = "CC 1#pi: #nu_{l} n #rightarrow l^{-} n #pi^{+}"; neutModeID[4] = 16; neutModeName[4] = "cccoh"; neutModeTitle[4] = "CC coherent-#pi: #nu_{l} ^{16}O #rightarrow l^{-} ^{16}O #pi^{+}"; neutModeID[5] = 17; neutModeName[5] = "ccgam"; neutModeTitle[5] = "1#gamma from #Delta: #nu_{l} n #rightarrow l^{-} p #gamma"; neutModeID[6] = 21; neutModeName[6] = "ccmpi"; neutModeTitle[6] = "CC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow l^{-} N' multi-#pi"; neutModeID[7] = 22; neutModeName[7] = "cceta"; neutModeTitle[7] = "CC 1#eta: #nu_{l} n #rightarrow l^{-} p #eta"; neutModeID[8] = 23; neutModeName[8] = "cck"; neutModeTitle[8] = "CC 1K: #nu_{l} n #rightarrow l^{-} #Lambda K^{+}"; neutModeID[9] = 26; neutModeName[9] = "ccdis"; neutModeTitle[9] = "CC DIS (2 GeV < W): #nu_{l} N #rightarrow l^{-} N' mesons"; neutModeID[10] = 31; neutModeName[10] = "ncnpi0"; neutModeTitle[10] = "NC 1#pi: #nu_{l} n #rightarrow #nu_{l} n #pi^{0}"; neutModeID[11] = 32; neutModeName[11] = "ncppi0"; neutModeTitle[11] = "NC 1#pi: #nu_{l} p #rightarrow #nu_{l} p #pi^{0}"; neutModeID[12] = 33; neutModeName[12] = "ncppim"; neutModeTitle[12] = "NC 1#pi: #nu_{l} n #rightarrow #nu_{l} p #pi^{-}"; neutModeID[13] = 34; neutModeName[13] = "ncnpip"; neutModeTitle[13] = "NC 1#pi: #nu_{l} p #rightarrow #nu_{l} n #pi^{+}"; neutModeID[14] = 36; neutModeName[14] = "nccoh"; neutModeTitle[14] = "NC coherent-#pi: #nu_{l} ^{16}O #rightarrow #nu_{l} ^{16}O #pi^{0}"; neutModeID[15] = 38; neutModeName[15] = "ncngam"; neutModeTitle[15] = "1#gamma from #Delta: #nu_{l} n #rightarrow #nu_{l} n #gamma"; neutModeID[16] = 39; neutModeName[16] = "ncpgam"; neutModeTitle[16] = "1#gamma from #Delta: #nu_{l} p #rightarrow #nu_{l} p #gamma"; neutModeID[17] = 41; neutModeName[17] = "ncmpi"; neutModeTitle[17] = "NC (1.3 < W < 2 GeV): #nu_{l} N #rightarrow #nu_{l} N multi-#pi"; neutModeID[18] = 42; neutModeName[18] = "ncneta"; neutModeTitle[18] = "NC 1#eta: #nu_{l} n #rightarrow #nu_{l} n #eta"; neutModeID[19] = 43; neutModeName[19] = "ncpeta"; neutModeTitle[19] = "NC 1#eta: #nu_{l} p #rightarrow #nu_{l} p #eta"; neutModeID[20] = 44; neutModeName[20] = "nck0"; neutModeTitle[20] = "NC 1K: #nu_{l} n #rightarrow #nu_{l} #Lambda K^{0}"; neutModeID[21] = 45; neutModeName[21] = "nckp"; neutModeTitle[21] = "NC 1K: #nu_{l} n #rightarrow #nu_{l} #Lambda K^{+}"; neutModeID[22] = 46; neutModeName[22] = "ncdis"; neutModeTitle[22] = "NC DIS (2 GeV < W): #nu_{l} N #rightarrow #nu_{l} N' mesons"; neutModeID[23] = 51; neutModeName[23] = "ncqep"; neutModeTitle[23] = "NC elastic: #nu_{l} p #rightarrow #nu_{l} p"; neutModeID[24] = 52; neutModeName[24] = "ncqen"; neutModeTitle[24] = "NC elastic: #nu_{l} n #rightarrow #nu_{l} n"; */ #endif diff --git a/src/InputHandler/NuWroInputHandler.cxx b/src/InputHandler/NuWroInputHandler.cxx index 0a8e9ec..f4c62ee 100644 --- a/src/InputHandler/NuWroInputHandler.cxx +++ b/src/InputHandler/NuWroInputHandler.cxx @@ -1,461 +1,473 @@ #ifdef __NUWRO_ENABLED__ #include "NuWroInputHandler.h" +#include "InputUtils.h" NuWroGeneratorInfo::~NuWroGeneratorInfo() { delete fNuWroParticlePDGs; } void NuWroGeneratorInfo::AddBranchesToTree(TTree* tn) { tn->Branch("NuWroParticlePDGs", &fNuWroParticlePDGs, "NuWroParticlePDGs/I"); } void NuWroGeneratorInfo::SetBranchesFromTree(TTree* tn) { tn->SetBranchAddress("NuWroParticlePDGs", &fNuWroParticlePDGs); } void NuWroGeneratorInfo::AllocateParticleStack(int stacksize) { fNuWroParticlePDGs = new int[stacksize]; } void NuWroGeneratorInfo::DeallocateParticleStack() { delete fNuWroParticlePDGs; } void NuWroGeneratorInfo::FillGeneratorInfo(event* e) { Reset(); } void NuWroGeneratorInfo::Reset() { for (int i = 0; i < kMaxParticles; i++) { fNuWroParticlePDGs[i] = 0; } } int event1_nof(event* e, int pdg) { int c = 0; for (size_t i = 0; i < e->out.size(); i++) if (e->out[i].pdg == pdg) c++; return c; } NuWroInputHandler::NuWroInputHandler(std::string const& handle, std::string const& rawinputs) { LOG(SAM) << "Creating NuWroInputHandler : " << handle << std::endl; // Run a joint input handling fName = handle; fMaxEvents = FitPar::Config().GetParI("MAXEVENTS"); fSaveExtra = false; // FitPar::Config().GetParB("NuWroSaveExtra"); // Setup the TChain fNuWroTree = new TChain("treeout"); // Loop over all inputs and grab flux, eventhist, and nevents std::vector inputs = InputUtils::ParseInputFileList(rawinputs); for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) { // Open File for histogram access TFile* inp_file = new TFile(inputs[inp_it].c_str(), "READ"); if (!inp_file or inp_file->IsZombie()) { ERR(FTL) << "nuwro File IsZombie() at " << inputs[inp_it] << std::endl; throw; } // Get Flux/Event hist TH1D* fluxhist = (TH1D*)inp_file->Get( (PlotUtils::GetObjectWithName(inp_file, "FluxHist")).c_str()); TH1D* eventhist = (TH1D*)inp_file->Get( (PlotUtils::GetObjectWithName(inp_file, "EvtHist")).c_str()); if (!fluxhist or !eventhist) { ERR(FTL) << "nuwro FILE doesn't contain flux/xsec info" << std::endl; if (FitPar::Config().GetParB("regennuwro")) { ERR(FTL) << "Regen NuWro has not been added yet. Email the developers!" << std::endl; // ProcessNuWroInputFlux(inputs[inp_it]); throw; } else { ERR(FTL) << "If you would like NUISANCE to generate these for you " << "please set parameter regennuwro=1 and re-run." << std::endl; throw; } } // Get N Events TTree* nuwrotree = (TTree*)inp_file->Get("treeout"); if (!nuwrotree) { ERR(FTL) << "treeout not located in nuwro file! " << inputs[inp_it] << std::endl; throw; } int nevents = nuwrotree->GetEntries(); // Register input to form flux/event rate hists RegisterJointInput(inputs[inp_it], nevents, fluxhist, eventhist); // Add to TChain fNuWroTree->Add(inputs[inp_it].c_str()); } // Registor all our file inputs SetupJointInputs(); // Setup Events fNuWroEvent = NULL; fNuWroTree->SetBranchAddress("e", &fNuWroEvent); fNuWroTree->GetEntry(0); fNUISANCEEvent = new FitEvent(); - fNUISANCEEvent->SetNuwroEvent(fNuWroEvent); + fNUISANCEEvent->fType = kNUWRO; + fNUISANCEEvent->fNuwroEvent = fNuWroEvent; + fNUISANCEEvent->HardReset(); if (fSaveExtra) { fNuWroInfo = new NuWroGeneratorInfo(); fNUISANCEEvent->AddGeneratorInfo(fNuWroInfo); } }; NuWroInputHandler::~NuWroInputHandler() { if (fNuWroTree) delete fNuWroTree; } void NuWroInputHandler::CreateCache() { // fNuWroTree->SetCacheEntryRange(0, fNEvents); // fNuWroTree->AddBranchToCache("*", 1); // fNuWroTree->SetCacheSize(fCacheSize); } void NuWroInputHandler::RemoveCache() { // fNuWroTree->SetCacheEntryRange(0, fNEvents); // fNuWroTree->AddBranchToCache("*", 0); // fNuWroTree->SetCacheSize(0); } void NuWroInputHandler::ProcessNuWroInputFlux(const std::string file) {} FitEvent* NuWroInputHandler::GetNuisanceEvent(const UInt_t entry, const bool lightweight) { // Catch too large entries if (entry >= (UInt_t)fNEvents) return NULL; // Read Entry from TTree to fill NEUT Vect in BaseFitEvt; fNuWroTree->GetEntry(entry); // Run NUISANCE Vector Filler if (!lightweight) { CalcNUISANCEKinematics(); } - +#ifdef __PROB3PP_ENABLED__ + for (size_t i = 0; i < fNUISANCEEvent->fNuwroEvent->in.size(); i++) { + if (std::count(PhysConst::pdg_neutrinos, PhysConst::pdg_neutrinos + 4, + fNUISANCEEvent->fNuwroEvent->in[i].pdg)) { + fNUISANCEEvent->probe_E = fNUISANCEEvent->fNuwroEvent->in[i].t; + fNUISANCEEvent->probe_pdg = fNUISANCEEvent->fNuwroEvent->in[i].pdg; + break; + } + } +#endif // Setup Input scaling for joint inputs fNUISANCEEvent->InputWeight = GetInputWeight(entry); #ifdef __USE_NUWRO_SRW_EVENTS__ - if(!rwEvs.size()){ + if (!rwEvs.size()) { fNuwroParams = fNuWroEvent->par; } + + if (entry >= rwEvs.size()) { rwEvs.push_back(BaseFitEvt()); - rwEvs.back().SetNuwroEvent(fNuWroEvent); + rwEvs.back().fNuwroSRWEvent = SRW::SRWEvent(*fNuWroEvent); rwEvs.back().fNuwroEvent = NULL; rwEvs.back().fNuwroParams = &fNuwroParams; + rwEvs.back().probe_E = rwEvs.back().fNuwroSRWEvent.NeutrinoEnergy; + rwEvs.back().probe_pdg = rwEvs.back().fNuwroSRWEvent.NeutrinoPDG; } #endif return fNUISANCEEvent; } int NuWroInputHandler::ConvertNuwroMode(event* e) { Int_t proton_pdg, neutron_pdg, pion_pdg, pion_plus_pdg, pion_minus_pdg, lambda_pdg, eta_pdg, kaon_pdg, kaon_plus_pdg; proton_pdg = 2212; eta_pdg = 221; neutron_pdg = 2112; pion_pdg = 111; pion_plus_pdg = 211; pion_minus_pdg = -211; // O_16_pdg = 100069; // oznacznie z Neuta lambda_pdg = 3122; kaon_pdg = 311; kaon_plus_pdg = 321; if (e->flag.qel) // kwiazielastyczne oddziaływanie { if (e->flag.anty) // jeśli jest to oddziaływanie z antyneutrinem { if (e->flag.cc) return -1; else { if (event1_nof(e, proton_pdg)) return -51; else if (event1_nof(e, neutron_pdg)) return -52; // sprawdzam dodatkowo ? } } else // oddziaływanie z neutrinem { if (e->flag.cc) return 1; else { if (event1_nof(e, proton_pdg)) return 51; else if (event1_nof(e, neutron_pdg)) return 52; } } } if (e->flag.mec) { if (e->flag.anty) return -2; else return 2; } if (e->flag.res) // rezonansowa produkcja: pojedynczy pion, pojed.eta, kaon, // multipiony { Int_t liczba_pionow, liczba_kaonow; liczba_pionow = event1_nof(e, pion_pdg) + event1_nof(e, pion_plus_pdg) + event1_nof(e, pion_minus_pdg); liczba_kaonow = event1_nof(e, kaon_pdg) + event1_nof(e, kaon_pdg); if (liczba_pionow > 1 || liczba_pionow == 0) // multipiony { if (e->flag.anty) { if (e->flag.cc) return -21; else return -41; } else { if (e->flag.cc) return 21; else return 41; } } if (liczba_pionow == 1) { if (e->flag.anty) // jeśli jest to oddziaływanie z antyneutrinem { if (e->flag.cc) { if (event1_nof(e, neutron_pdg) && event1_nof(e, pion_minus_pdg)) return -11; if (event1_nof(e, neutron_pdg) && event1_nof(e, pion_pdg)) return -12; if (event1_nof(e, proton_pdg) && event1_nof(e, pion_minus_pdg)) return -13; } else { if (event1_nof(e, proton_pdg)) { if (event1_nof(e, pion_minus_pdg)) return -33; else if (event1_nof(e, pion_pdg)) return -32; } else if (event1_nof(e, neutron_pdg)) { if (event1_nof(e, pion_plus_pdg)) return -34; else if (event1_nof(e, pion_pdg)) return -31; } } } else // oddziaływanie z neutrinem { if (e->flag.cc) { if (event1_nof(e, proton_pdg) && event1_nof(e, pion_plus_pdg)) return 11; if (event1_nof(e, proton_pdg) && event1_nof(e, pion_pdg)) return 12; if (event1_nof(e, neutron_pdg) && event1_nof(e, pion_plus_pdg)) return 13; } else { if (event1_nof(e, proton_pdg)) { if (event1_nof(e, pion_minus_pdg)) return 33; else if (event1_nof(e, pion_pdg)) return 32; } else if (event1_nof(e, neutron_pdg)) { if (event1_nof(e, pion_plus_pdg)) return 34; else if (event1_nof(e, pion_pdg)) return 31; } } } } if (event1_nof(e, eta_pdg)) // produkcja rezonansowa ety { if (e->flag.anty) // jeśli jest to oddziaływanie z antyneutrinem { if (e->flag.cc) return -22; else { if (event1_nof(e, neutron_pdg)) return -42; else if (event1_nof(e, proton_pdg)) return -43; // sprawdzam dodatkowo ? } } else // oddziaływanie z neutrinem { if (e->flag.cc) return 22; else { if (event1_nof(e, neutron_pdg)) return 42; else if (event1_nof(e, proton_pdg)) return 43; } } } if (event1_nof(e, lambda_pdg) == 1 && liczba_kaonow == 1) // produkcja rezonansowa kaonu { if (e->flag.anty) // jeśli jest to oddziaływanie z antyneutrinem { if (e->flag.cc && event1_nof(e, kaon_pdg)) return -23; else { if (event1_nof(e, kaon_pdg)) return -44; else if (event1_nof(e, kaon_plus_pdg)) return -45; } } else // oddziaływanie z neutrinem { if (e->flag.cc && event1_nof(e, kaon_plus_pdg)) return 23; else { if (event1_nof(e, kaon_pdg)) return 44; else if (event1_nof(e, kaon_plus_pdg)) return 45; } } } } if (e->flag.coh) // koherentne oddziaływanie tylko na O(16) { Int_t _target; _target = e->par.nucleus_p + e->par.nucleus_n; // liczba masowa O(16) if (_target == 16) { if (e->flag.anty) // jeśli jest to oddziaływanie z antyneutrinem { if (e->flag.cc && event1_nof(e, pion_minus_pdg)) return -16; else if (event1_nof(e, pion_pdg)) return -36; } else // oddziaływanie z neutrinem { if (e->flag.cc && event1_nof(e, pion_plus_pdg)) return 16; else if (event1_nof(e, pion_pdg)) return 36; } } } // gleboko nieelastyczne rozpraszanie if (e->flag.dis) { if (e->flag.anty) { if (e->flag.cc) return -26; else return -46; } else { if (e->flag.cc) return 26; else return 46; } } return 9999; } void NuWroInputHandler::CalcNUISANCEKinematics() { // std::cout << "NuWro Event Address " << fNuWroEvent << std::endl; // Reset all variables fNUISANCEEvent->ResetEvent(); FitEvent* evt = fNUISANCEEvent; // Sort Event Info - evt->fMode = ConvertNuwroMode(fNuWroEvent); - - if (abs(evt->fMode) > 60) { - evt->fMode = 0; + evt->Mode = ConvertNuwroMode(fNuWroEvent); - // Remove failed mode converts - // return; + if (abs(evt->Mode) > 60) { + evt->Mode = 0; } - evt->Mode = evt->fMode; evt->fEventNo = 0.0; evt->fTotCrs = 0.0; evt->fTargetA = fNuWroEvent->par.nucleus_p + fNuWroEvent->par.nucleus_n; evt->fTargetZ = fNuWroEvent->par.nucleus_p; evt->fTargetH = 0; evt->fBound = (evt->fTargetA) == 1; // Check Particle Stack UInt_t npart_in = fNuWroEvent->in.size(); UInt_t npart_out = fNuWroEvent->out.size(); UInt_t npart_post = fNuWroEvent->post.size(); UInt_t npart = npart_in + npart_out + npart_post; UInt_t kmax = evt->kMaxParticles; if (npart > kmax) { ERR(WRN) << "NUWRO has too many particles. Expanding stack." << std::endl; fNUISANCEEvent->ExpandParticleStack(npart); } // Sort Particles evt->fNParticles = 0; std::vector::iterator p_iter; // Initial State for (p_iter = fNuWroEvent->in.begin(); p_iter != fNuWroEvent->in.end(); p_iter++) { AddNuWroParticle(fNUISANCEEvent, (*p_iter), kInitialState); } // FSI State // for (size_t i = 0; i < npart_in; i++ ) { // AddNuWroParticle(fNUISANCEEvent, (*p_iter), kFSIState); // } // Final State for (p_iter = fNuWroEvent->post.begin(); p_iter != fNuWroEvent->post.end(); p_iter++) { AddNuWroParticle(fNUISANCEEvent, (*p_iter), kFinalState); } // Fill Generator Info if (fSaveExtra) fNuWroInfo->FillGeneratorInfo(fNuWroEvent); // Run Initial, FSI, Final, Other ordering. fNUISANCEEvent->OrderStack(); FitParticle* ISNeutralLepton = fNUISANCEEvent->GetHMISParticle(PhysConst::pdg_neutrinos); if (ISNeutralLepton) { fNUISANCEEvent->probe_E = ISNeutralLepton->E(); fNUISANCEEvent->probe_pdg = ISNeutralLepton->PDG(); } return; } void NuWroInputHandler::AddNuWroParticle(FitEvent* evt, particle& p, int state) { // Add Mom evt->fParticleMom[evt->fNParticles][0] = static_cast(p).x; evt->fParticleMom[evt->fNParticles][1] = static_cast(p).y; evt->fParticleMom[evt->fNParticles][2] = static_cast(p).z; evt->fParticleMom[evt->fNParticles][3] = static_cast(p).t; // Status/PDG evt->fParticleState[evt->fNParticles] = state; evt->fParticlePDG[evt->fNParticles] = p.pdg; // Add to particle count evt->fNParticles++; } void NuWroInputHandler::Print() {} #endif diff --git a/src/InputHandler/SigmaQ0HistogramInputHandler.cxx b/src/InputHandler/SigmaQ0HistogramInputHandler.cxx index 1f306bf..dc6c2ab 100644 --- a/src/InputHandler/SigmaQ0HistogramInputHandler.cxx +++ b/src/InputHandler/SigmaQ0HistogramInputHandler.cxx @@ -1,265 +1,264 @@ #include "SigmaQ0HistogramInputHandler.h" SigmaQ0HistogramInputHandler::SigmaQ0HistogramInputHandler(std::string const& handle, std::string const& rawinputs) { LOG(SAM) << "Creating SigmaQ0HistogramInputHandler : " << handle << std::endl; // Run a joint input handling fName = handle; // Assign to hist event format - fEventType = kHISTEVENT; + fEventType = kSIGMAQ0HIST; // Parse our input file // SIGMAQ0HIST:path.txt,ENERGY=0.25,THETA=0.34,Q0COL=1,XSCOL=2,SCL=10 std::vector parsedinputs = GeneralUtils::ParseToStr(rawinputs, ","); fFilePath = parsedinputs[0]; // Setup Defaults incase none given fEnergy = -1.0; fTheta = -1.0; fQ0Column = 0; fSigmaColumn = 1; fBeamPDG = -1; // Assume electron by default fDelim = " "; fScaling = 1.E38; // Now Loop through and parse possible inputs for (uint i = 1; i < parsedinputs.size(); i++) { std::vector parsedspec = GeneralUtils::ParseToStr(parsedinputs[i], "="); if (parsedspec.size() < 2) { THROW("NO VALUE GIVEN TO SPECIFIER : " << parsedinputs[0]); } std::string spec = parsedspec[0]; std::string value = parsedspec[1]; // Read Energy if (!spec.compare("ENERGY") or !spec.compare("E")) { fEnergy = GeneralUtils::StrToDbl(value); // Read Theta } else if (!spec.compare("THETA") or !spec.compare("T")) { fTheta = GeneralUtils::StrToDbl(value); // Set Q0 Column } else if (!spec.compare("Q0") or !spec.compare("Q0COL")) { fQ0Column = GeneralUtils::StrToInt(value); // Set XSec Column } else if (!spec.compare("XSCOL") or !spec.compare("XS") or !spec.compare("X") or !spec.compare("SIG") or !spec.compare("SIGMA")) { fSigmaColumn = GeneralUtils::StrToInt(value); } else if (!spec.compare("BEAM") or !spec.compare("P") or !spec.compare("PDG")) { fBeamPDG = GeneralUtils::StrToInt(value); } else if (!spec.compare("SCL") or !spec.compare("SC") or !spec.compare("S")) { fScaling = GeneralUtils::StrToDbl(value); // Throw } else { THROW("Unknown argument given to SigmaQ0 InputHandler!" ); } } // Check we got everything if (fEnergy == -1 or fEnergy < 0) { THROW("Energy for SigmaQ0 Handler either invalid or not given! Specify with ',E=ENERGY' in the input spec."); } // Default to Electron if (fBeamPDG == -1) { ERR(WRN) << "No Beam PDG Given in SigmaQ0 Handler so assuming electron. " << "If input is not electron scattering please specify using : PDG=PDGCODE" << std::endl; } // Convert Theta fTheta = fTheta * M_PI / 180.0; LOG(FIT) << "Set Theta to = " << fTheta << std::endl; // Have to create a dummy flux and event rate histogram :( fFluxHist = new TH1D("fluxhist", "fluxhist", 100.0, 0.0, 2.0 * fEnergy); fFluxHist->SetBinContent( fFluxHist->FindBin(fEnergy), 1.0 ); fEventHist = new TH1D("eventhist", "eventhist", 100.0, 0.0, 2.0 * fEnergy); fEventHist->SetBinContent( fEventHist->FindBin(fEnergy), 1.0 ); fEnergy = fEnergy * 1.E3; LOG(FIT) << "Set E energy" << std::endl; // Now parse the lines in our input file. fApplyInterpolation = FitPar::Config().GetParB("InterpolateSigmaQ0Histogram"); double interpolation_res = FitPar::Config().GetParD("InterpolateSigmaQ0HistogramRes"); fMaxValue = 0.0; fMaxX = 0.0; fMinX = 1.E10; // Create a TGraph of Points TGraph* gr = new TGraph(); std::vector inputlines = GeneralUtils::ParseFileToStr(fFilePath, "\n"); for (uint i = 0; i < inputlines.size(); i++) { std::vector splitline = GeneralUtils::ParseToDbl(inputlines[i], fDelim.c_str()); double q0 = splitline[fQ0Column]; double sig = splitline[fSigmaColumn]; gr->SetPoint(gr->GetN(), q0, sig); if (sig > fMaxValue) fMaxValue = sig; if (q0 > fMaxX) fMaxX = q0; if (q0 < fMinX) fMinX = q0; } fInputGraph = new TGraph(); for (int i = 0; i < gr->GetN(); i++){ fInputGraph->SetPoint(fInputGraph->GetN(), gr->GetX()[i], gr->GetY()[i]); fNEvents++; if (fApplyInterpolation){ // If not last point create extra events if (i != gr->GetN()-1){ double xlow = gr->GetX()[i]; double xhigh = gr->GetX()[i+1]; for (int j = 1; j < int(interpolation_res); j++){ double x = xlow + double(j) * (xhigh - xlow) / interpolation_res; fInputGraph->SetPoint(fInputGraph->GetN(),x, gr->Eval(x)); fNEvents++; } } } } delete gr; - + fFluxHist->Scale(1.0 / fFluxHist->Integral("width") ); fEventHist->Scale( fScaling * double(fNEvents) / fEventHist->Integral() ); if (fApplyInterpolation){ fEventHist->Scale(1.0 / interpolation_res); } - + fUseAcceptReject = FitPar::Config().GetParB("InterpolateSigmaQ0HistogramThrow"); if (fUseAcceptReject){ std::cout << "USING ACCEPT REJECT" << std::endl; fEventHist->Scale( fMaxValue / double(fNEvents) ); fNEvents = FitPar::Config().GetParI("InterpolateSigmaQ0HistogramNTHROWS"); std::cout << "NEvents = " << fNEvents << std::endl; sleep(1); } fNUISANCEEvent = new FitEvent(); - + }; SigmaQ0HistogramInputHandler::~SigmaQ0HistogramInputHandler() { }; FitEvent* SigmaQ0HistogramInputHandler::GetNuisanceEvent(const UInt_t entry, const bool lightweight) { // Catch too large entries if (entry >= (UInt_t)fNEvents) return NULL; // Evaluate Graph to Create an Event if (!fUseAcceptReject){ double q0 = fInputGraph->GetX()[entry]; double sig = fInputGraph->GetY()[entry]; FillNuisanceEvent(q0, sig); } else { double q0 = ThrowQ0(); FillNuisanceEvent(q0, 1.0); } // Return event pointer return fNUISANCEEvent; } double SigmaQ0HistogramInputHandler::ThrowQ0(){ // Use input graph to Throw Q0. int count = 0; while (count < 1E7){ double x = fRandom.Uniform(fMinX,fMaxX); if (fRandom.Uniform(0.0,1.0) <= fInputGraph->Eval(x) / fMaxValue){ return x; }; std::cout << "THROW " << count << " : " << x << std::endl; } return 0.0; } - + void SigmaQ0HistogramInputHandler::FillNuisanceEvent(double q0, double sig) { - + // Reset all variables - + fNUISANCEEvent->ResetEvent(); - + // Fill Globals - fNUISANCEEvent->fMode = 1; // Assume CCQE for now... fNUISANCEEvent->Mode = 1; fNUISANCEEvent->fEventNo = 0; fNUISANCEEvent->fTargetA = 0; // Should the User Specify these? fNUISANCEEvent->fTargetZ = 0; // Should the User Specify these? fNUISANCEEvent->fTargetH = 0; // Should the User Specify these? fNUISANCEEvent->fBound = 1; // Should the User Specify these? fNUISANCEEvent->InputWeight = sig; // Add incoming beam particle along Z with energy E and outgoing with theta if (fBeamPDG == 11) { // Initial Beam fNUISANCEEvent->fParticleState[0] = kInitialState; fNUISANCEEvent->fParticlePDG[0] = 11; double mass = 0.511; // Get Momentum of Electron moving along Z fNUISANCEEvent->fParticleMom[0][0] = 0.0; fNUISANCEEvent->fParticleMom[0][1] = 0.0; LOG(FIT) << "Setting Energy = " << fEnergy << std::endl; fNUISANCEEvent->fParticleMom[0][2] = sqrt(fEnergy * fEnergy - mass * mass); fNUISANCEEvent->fParticleMom[0][3] = fEnergy; // Outgoing particle fNUISANCEEvent->fParticleState[1] = kFinalState; fNUISANCEEvent->fParticlePDG[1] = 11; // Get Momentum of Electron outgoing minus q0 double oute = fEnergy - q0; double outp = sqrt(oute * oute - mass * mass); fNUISANCEEvent->fParticleMom[1][0] = 0.0; fNUISANCEEvent->fParticleMom[1][1] = sin(fTheta) * outp; fNUISANCEEvent->fParticleMom[1][2] = cos(fTheta) * outp; fNUISANCEEvent->fParticleMom[1][3] = oute; } // Update Particles fNUISANCEEvent->fNParticles = 2; // Run Initial, FSI, Final, Other ordering. fNUISANCEEvent-> OrderStack(); // Check Q0 // FitParticle* ein = fNUISANCEEvent->PartInfo(0); // FitParticle* eout = fNUISANCEEvent->GetHMFSParticle(11); // double newq0 = fabs(ein->fP.E() - eout->fP.E()) / 1000.0; // double E = ein->fP.E() / 1000.0; // double theta = ein->fP.Vect().Angle(eout->fP.Vect()) * 180. / M_PI; // LOG(FIT) << "Extracted event from line: theirs-" << q0/1.E3 << " ours-" << newq0 << " E-" << fEnergy << " T-" << theta << " X-" << sig << std::endl; return; } diff --git a/src/InputHandler/StdHepEvt.cxx b/src/InputHandler/StdHepEvt.cxx index 3e2db14..dfa93f8 100644 --- a/src/InputHandler/StdHepEvt.cxx +++ b/src/InputHandler/StdHepEvt.cxx @@ -1,153 +1,135 @@ // 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 #include #include #include "StdHepEvt.h" // Include logging #include "FitLogger.h" StdHepReader::StdHepReader(){}; bool StdHepReader::SetBranchAddresses(TChain *chain) { bool ok = true; int SBAStatus = 0; SBAStatus = chain->SetBranchAddress("StdHepN", &StdHepN); ok = ok && (SBAStatus || SBAStatus == 5); if (!(!SBAStatus || SBAStatus == 5)) { ERR(WRN) << "Failed to set branch address for \"StdHepN\": " << SBAStatus << std::endl; } SBAStatus = chain->SetBranchAddress("StdHepPdg", StdHepPdg); ok = ok && (SBAStatus || SBAStatus == 5); if (!(!SBAStatus || SBAStatus == 5)) { ERR(WRN) << "Failed to set branch address for \"StdHepPdg\": " << SBAStatus << std::endl; } SBAStatus = chain->SetBranchAddress("StdHepStatus", StdHepStatus); ok = ok && (SBAStatus || SBAStatus == 5); if (!(!SBAStatus || SBAStatus == 5)) { ERR(WRN) << "Failed to set branch address for \"StdHepStatus\": " << SBAStatus << std::endl; } SBAStatus = chain->SetBranchAddress("StdHepP4", StdHepP4); ok = ok && (SBAStatus || SBAStatus == 5); if (!(!SBAStatus || SBAStatus == 5)) { ERR(WRN) << "Failed to set branch address for \"StdHepP4\": " << SBAStatus << std::endl; } return ok; } bool GiBUUStdHepReader::SetBranchAddresses(TChain *chain) { bool ok = true; int SBAStatus = 0; ok = ok && StdHepReader::SetBranchAddresses(chain); SBAStatus = chain->SetBranchAddress("GiBUU2NeutCode", &GiBUU2NeutCode); ok = ok && (SBAStatus || SBAStatus == 5); if (!(!SBAStatus || SBAStatus == 5)) { ERR(WRN) << "Failed to set branch address for \"GiBUU2NeutCode\": " << SBAStatus << std::endl; } SBAStatus = chain->SetBranchAddress("EvtWght", &EvtWght); ok = ok && (SBAStatus || SBAStatus == 5); if (!(!SBAStatus || SBAStatus == 5)) { ERR(WRN) << "Failed to set branch address for \"EvtWght\": " << SBAStatus << std::endl; } - SBAStatus = chain->SetBranchAddress("SpeciesWght_numu", &SpeciesWght_numu); - ok = ok && (SBAStatus || SBAStatus == 5); - if (!(!SBAStatus || SBAStatus == 5)) { - ERR(WRN) << "Failed to set branch address for \"SpeciesWght_numu\": " - << SBAStatus << std::endl; - } - SBAStatus = chain->SetBranchAddress("SpeciesWght_nue", &SpeciesWght_nue); - ok = ok && (SBAStatus || SBAStatus == 5); - if (!(!SBAStatus || SBAStatus == 5)) { - ERR(WRN) << "Failed to set branch address for \"SpeciesWght_nue\": " - << SBAStatus << std::endl; - } - SBAStatus = chain->SetBranchAddress("SpeciesWght", &SpeciesWght); - ok = ok && (SBAStatus || SBAStatus == 5); - if (!(!SBAStatus || SBAStatus == 5)) { - ERR(WRN) << "Failed to set branch address for \"SpeciesWght\": " - << SBAStatus << std::endl; - } return ok; } std::string NegSpacer(double const &num) { return (num >= 0) ? " " : ""; } std::ostream &operator<<(std::ostream &os, TLorentzVector const &tlv) { std::streamsize prec = os.precision(); std::ios_base::fmtflags flags = os.flags(); os.precision(2); os.flags(std::ios::scientific); os << "[" << NegSpacer(tlv[0]) << tlv[0] << "," << NegSpacer(tlv[1]) << tlv[1] << "," << NegSpacer(tlv[2]) << tlv[2] << "," << NegSpacer(tlv[3]) << tlv[3] << ":M(" << tlv.M() << ")]"; os.precision(prec); os.flags(flags); return os; } std::string WriteGiBUUEvent(GiBUUStdHepReader const &gi) { std::stringstream ss(""); ss << "[INFO]: contained " << gi.StdHepN << ", Event Weight: " << std::setprecision(3) << gi.EvtWght << ", NeutConventionReactionCode: " << gi.GiBUU2NeutCode << "\n\t[Lep In](" << std::setw(3) << gi.StdHepPdg[0] << ") " << TLorentzVector(gi.StdHepP4[0][StdHepReader::kStdHepIdxPx], gi.StdHepP4[0][StdHepReader::kStdHepIdxPy], gi.StdHepP4[0][StdHepReader::kStdHepIdxPz], gi.StdHepP4[0][StdHepReader::kStdHepIdxE]) << std::endl; ss << "\t[Target] : " << gi.StdHepPdg[1] << std::endl; ss << "\t[Nuc In] : " << TLorentzVector(gi.StdHepP4[3][StdHepReader::kStdHepIdxPx], gi.StdHepP4[3][StdHepReader::kStdHepIdxPy], gi.StdHepP4[3][StdHepReader::kStdHepIdxPz], gi.StdHepP4[3][StdHepReader::kStdHepIdxE]) << " (" << std::setw(4) << gi.StdHepPdg[3] << ")" << std::endl; for (Int_t stdHepInd = 4; stdHepInd < gi.StdHepN; ++stdHepInd) { ss << "\t[" << std::setw(2) << (stdHepInd - (4)) << "](" << std::setw(5) << gi.StdHepPdg[stdHepInd] << ") " << TLorentzVector(gi.StdHepP4[stdHepInd][StdHepReader::kStdHepIdxPx], gi.StdHepP4[stdHepInd][StdHepReader::kStdHepIdxPy], gi.StdHepP4[stdHepInd][StdHepReader::kStdHepIdxPz], gi.StdHepP4[stdHepInd][StdHepReader::kStdHepIdxE]) << std::endl; } ss << "\t[Lep Out](" << std::setw(3) << gi.StdHepPdg[2] << ") " << TLorentzVector(gi.StdHepP4[2][StdHepReader::kStdHepIdxPx], gi.StdHepP4[2][StdHepReader::kStdHepIdxPy], gi.StdHepP4[2][StdHepReader::kStdHepIdxPz], gi.StdHepP4[2][StdHepReader::kStdHepIdxE]) << std::endl; return ss.str(); } diff --git a/src/Smearceptance/CMakeLists.txt b/src/Logger/CMakeLists.txt similarity index 91% copy from src/Smearceptance/CMakeLists.txt copy to src/Logger/CMakeLists.txt index a0f7251..dee1fc1 100644 --- a/src/Smearceptance/CMakeLists.txt +++ b/src/Logger/CMakeLists.txt @@ -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 . ################################################################################ set(HEADERFILES -ISmearcepter.h -Smearcepterton.h - -ThresholdAccepter.h +FitLogger.h +Initialiser.h ) set(IMPLFILES -ISmearcepter.cxx -Smearcepterton.cxx - -ThresholdAccepter.cxx +PythiaQuiet.f +FitLogger.cxx +Initialiser.cxx ) -set(LIBNAME Smearceptance) +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(${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/Utils/FitLogger.cxx b/src/Logger/FitLogger.cxx similarity index 57% rename from src/Utils/FitLogger.cxx rename to src/Logger/FitLogger.cxx index 6819b20..f675869 100644 --- a/src/Utils/FitLogger.cxx +++ b/src/Logger/FitLogger.cxx @@ -1,310 +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; +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. +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::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__)); + // 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) { - +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; + 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; + 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; + 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 << "] : "; + std::cout << " : " << filename << "::" << funct << "[l. " << line + << "] : "; } return *(Logger::__LOG_outstream); } } -void SETVERBOSITY(int level) { - Logger::log_verb = level; -} +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()); + 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; -} +void SETTRACE(bool val) { Logger::showtrace = val; } // ------ ERROR FUNCTIONS ---------- // -std::ostream& __OUTERR(int level, const char* filename, const char* funct, int line) { +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; + 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 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; + //****************************************** + + 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; + 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) { + if (Logger::log_verb == (unsigned int)DEB) { return true; } - if (Logger::log_verb < (unsigned int) level) { + if (Logger::log_verb < (unsigned int)level) { return false; } return true; } -void SET_TRACE(bool val) { - Logger::showtrace = val; -} - +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; + 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/Logger/FitLogger.h b/src/Logger/FitLogger.h new file mode 100644 index 0000000..ce46f6c --- /dev/null +++ b/src/Logger/FitLogger.h @@ -0,0 +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 "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 (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/CMakeLists.txt b/src/MCStudies/CMakeLists.txt index 5df0948..b77401f 100644 --- a/src/MCStudies/CMakeLists.txt +++ b/src/MCStudies/CMakeLists.txt @@ -1,79 +1,81 @@ # 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 ExpMultDist_CCQE_XSec_1DVar_FakeStudy.cxx ExpMultDist_CCQE_XSec_2DVar_FakeStudy.cxx GenericFlux_Tester.cxx GenericFlux_Vectors.cxx #MCStudy_KaonPreSelection.cxx MCStudy_MuonValidation.cxx ElectronFlux_FlatTree.cxx T2K2017_FakeData.cxx MCStudy_CCQEHistograms.cxx OfficialNIWGPlots.cxx Smearceptance_Tester.cxx Simple_Osc.cxx +Smear_SVDUnfold_Propagation_Osc.cxx ) set(HEADERFILES ExpMultDist_CCQE_XSec_1DVar_FakeStudy.h ExpMultDist_CCQE_XSec_2DVar_FakeStudy.h GenericFlux_Tester.h GenericFlux_Vectors.h #MCStudy_KaonPreSelection.h MCStudy_MuonValidation.h ElectronFlux_FlatTree.h T2K2017_FakeData.h MCStudy_CCQEHistograms.h OfficialNIWGPlots.h Smearceptance_Tester.h Simple_Osc.h +Smear_SVDUnfold_Propagation_Osc.h ) set(LIBNAME MCStudies) 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}) # Needed for experiment specific signal flags include_directories(${CMAKE_SOURCE_DIR}/src/T2K) include_directories(${CMAKE_SOURCE_DIR}/src/MINERvA) include_directories(${CMAKE_SOURCE_DIR}/src/Smearceptance) 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() if(USE_PROB3PP) add_dependencies(${LIBNAME} prob3pp) 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/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..5834274 100644 --- a/src/MCStudies/GenericFlux_Tester.cxx +++ b/src/MCStudies/GenericFlux_Tester.cxx @@ -1,559 +1,564 @@ // 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; + LOG(SAM) << " Generic Flux Scaling Factor = " << fScaleFactor + << " [= " << (GetEventHistogram()->Integral("width") * 1E-38) << "/(" + << (fNEvents + 0.) << "*" << this->TotalIntegratedFlux() << ")]" + << std::endl; if (fScaleFactor <= 0.0) { ERR(WRN) << "SCALE FACTOR TOO LOW " << std::endl; sleep(20); } // Setup our TTrees this->AddEventVariablesToTree(); this->AddSignalFlagsToTree(); } void GenericFlux_Tester::AddEventVariablesToTree() { // Setup the TTree to save everything if (!eventVariables) { - 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; + 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(); + 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/OscStudies.md b/src/MCStudies/OscStudies.md new file mode 100644 index 0000000..9cda387 --- /dev/null +++ b/src/MCStudies/OscStudies.md @@ -0,0 +1,150 @@ +# Oscillation studies in NUISANCE + +This simple module allows the construction of simple NOvA-style unfold/propagate/refold/compare style neutrino oscillation studies in NUSIANCE. It is implemented as a standard NUSIANCE sample, although with signficantly more complicated markup than usual. + +## Full example + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +## Details + +### NUISANCE Parameters + +Explained in detail elsewhere, but briefly repeated here for completeness. +A reweightable parameter is specified by an element like: +```xml + +``` +where the attributes are hopefully self explanatory. The state should be `FREE` +or `FIXED` depending on whether in a minimisation or chi2 scan the parameter +should be allowed to vary. The valid names for oscillation parameters currently +implemented through Prob3++ are: +* `sinsq_theta12` +* `sinsq_theta13` +* `sinsq_theta23` +* `dm12` +* `dm23` +* `dcp` + +In general, all parameters should be specified if any are, as the default values +may not be sensible. + +The baseline is calculated from the assumption of a beam passing through the +earth to be detected on the surface. + +### Analysis structure + +The oscillation analysis inputs are near detector observations, far detector +observations and neutrino energy migration matricies that encode how detector +effects cause interactions of some true neutrino energy to be reconstructed +with some other neutrino energy. As oscillations happen as a function of +neutrino energy, being able to corectly identify the energy spectrum of +neutrinos before and after oscillation is the most key aspect of an oscillation +analysis. + +The obseved near detector reconstructed energy spectrum is unfolded through the +near detector migration matrix to give the data-motivated, estimated true energy +spectrum of interactions at the near detector. This is then oscillated according +to the current PMNS parameters and corrected for far/near beam divergence and +detector mass. The true energy spectrum at the far detector is then smeared with +the far detector migration matrix, which may or may not be the same as the near +detector one, to give the predicted far detector reconstructed energy spectrum. +A test statistic is evaluated between the predicted and observed far detector +spectrum for the current set of oscillation, and potentially nuisance, +parameters. + +In general the unfolding can be used to estimate the true energy spectrum of +the observed interactions, the true energy spectrum of the interactions that +occured (including efficiency), or the true energy spectrum of the neutrino +flux (also including cross-section). As the far over near correction can +currently only be a single number to account for beam divergence, it is advised +that the supplied migration matrices should account for the migration from true +interactions to true energy spectra (i.e. include the efficiency +correction/application at the near and far detectors). Currently, the nue and +numu cross sections are assumed identical. + +**N.B.:** The near and far detector samples are assigned a neutrino PDG code, *i.e.* they must represent a CCInclusive sample of a single neutrino flavor. There is no support for interaction model-fitting style (T2K) analyses. + +### The Sample element + +```xml + +... + +``` + +Every oscillation analysis needs at least one near and one far detector sample. +To keep the structure of NUISANCE sample elements, the first near +detector sample is specified slightly differently to subsequent samples. + +The sample element specifies the near detector mass through the attributes `DetectorVolume` and `DetectorDensity`, the separation is purely for your bookkeeping, they must multiply to give a mass in the same units as the far detector masses that will be specified. This is purely used for near-to-far extrapolation, the input histograms are expected to be well-normalised event rate predictions in the relevant near and far detector configurations. + +The `ScalePOT` attribute is applied to all input histograms as a re-normalisation factor, this allows event rate predictions to be recalculated by a simple scale factor at runtime. + +The `SetErrorsFromRate` attribute specifies whether the input histogram errors should be respected or they should be rescaled to the poisson error on the fully normalised event rate (included the `ScalePOT` attributed) in each bin. + +**N.B.:** Only a single near detector can be specified, it would be fairly trivial to add multiple near detector setups, but that is currently not implemented. However, multiple near detector CCInc samples may be declared. + +### ND sample descriptors + +```xml + +``` + +The input histograms for each ND sample should be given in the order: [observed rate in ERec], [ERec:ETrue migration matrix]. These can come from a single ROOT file, as shown above, or from two separate ROOT files, specified like: `ObsInput="FILE1.root[ObsRateERecHistName],FILE2.root[ERecETrueMigrationMatrixTH2DName]"`. The first ND sample, which is specified in the sample element, as opposed to in a child element named `NDObs`, must be prefixed with `HISTO:` to satisfy NUISANCE's requirement for input types. + +The `NuPDG` attribute specifies the neutrinp PDG code which is observed sample corresponds to, most likely one of `-12,12,-14,14`, depending on the analysis setup. + +The `TruncateStart` and `TruncateUpTo` attributes specify the number of singular values that may be set to 0 in the SVD decoposition to ensure that the unfolded spectrum at the near detector is >= 0 within the union of specified `FitRegion`s in the far detector samples (see the next section). If there are still negative values after the maximum allowed regularisation has been attempted, the analysis will throw an exception. + +### FD sample descriptors + +```xml + + + + +``` + +Each far detector sample has the same inputs as each near detector sample, an observed histogram (correctly normalised) and a migration matrix. For the far detector samples, the migration matrix is not inverted, but used to forward-fold the true spectrum prediction at the far detector. + +The two elements `FitRegion_Min` and `FitRegion_Max` are used to specify the range of the observation histogram that is included in the Chi2 calculation. These ranges are also used to inform the regularisation of the SVD inversion used ont he near detector samples. + +Each far detector sample receives contributions from every near detector sample, these may well be 0, but the extrapolation is performed independently for each far detector sample. Therefore, each far detector sample element must set up its detector mass, even if they are all the same. In the example shown above the far detector is set up to have a 40 kilotonne fiducial mass. + +The `OscillateToPDG` attribtue functions similarly to the `NuPDG` attribute for the near detector samples and specifies what species of neutrino the sample characterises, muon neutrino, electron anti-neutrino, etc... This is used to calculate the correction oscillation probability from each of the near detector samples. *e.g.* For a electron neutrino far detector sample, the muon neutrino to electron neutrino appearance probability is applied during the propagation to a muon neutrino near detector sample, and the electron neutrino survival probability is applied to an intrinsic electron neutrino near detector sample. + +To inform the correct propagation of each near detector sample, a child `FDNDRatio` tag must be supplied. This specifies the beam divergence factor for each near detector sample --- linked via its `NuPDG` --- this is applied as a simple scale factor during near-to-far propagation. It would be possible to allow this a functional form to account for the relative difference in shape of the unoscillated flux at the near and far detector, but this is not yet implemented. Any near detector samples which do not have a corresponding `FDNDRatio` tag are given a divergence factor of `0` and effectively do not contribute to the far detector prediction. *e.g.* In the example at the top of this note, the far detector muon neutrino disapeerance sample recieves no contribution from the intrinsic electron neutrino sample, this is trivial to enable, but makes a completely insignificant difference to the far detector prediction. + +## Input generation details + +The input histograms are simplest to prepare through the `nuissmear` application, which by default will output both that are required for each input. + +The observed ERec distribution for each sample should be self-explanatory. The response matrix should be supplied as a TH2D, with the true energy on the X axis and the reconstructed energy on the Y axis. The generation shape should be divided out of this. There is a small choice to be made here, either the efficiency correction can be included as part of the unfolding, this would involve dividing every bin by the total number of interaction generated in that bin of true neutrino energy -- events that are not reconstructed and thus do not make it into the histogram are accounted for by the sum of each Y slice of bins not totalling unity. Alternatively, you could re-normalised each Y slice so that the sum of bins totals to unity and this would mean that the unfolding only accounted for the migration and not the detector/selection efficiency. This implicitly would include the assumption into any susequent analysis that the detectors are functionally identical. It would also be possible to apply the efficiency ratio during the propagation, but this can only be a flat scale calculated from the ratio of detector masses and the beam divergence factor, it is not currently possible. diff --git a/src/MCStudies/Simple_Osc.cxx b/src/MCStudies/Simple_Osc.cxx index 331606d..b45505b 100644 --- a/src/MCStudies/Simple_Osc.cxx +++ b/src/MCStudies/Simple_Osc.cxx @@ -1,77 +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 . *******************************************************************************/ #include "Simple_Osc.h" //******************************************************************** Simple_Osc::Simple_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("cos(#theta*)"); + 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.); // Plot Setup ------------------------------------------------------- if (samplekey.Has("Target_Simple_Osc_File")) { SetDataFromRootFile(samplekey.GetS("Target_Simple_Osc_File"), (fSettings.GetName() + "_MC").c_str()); } else { fDataHist = new TH1D((fSettings.GetName() + "_data").c_str(), - fSettings.GetFullTitles().c_str(), 50, 0, 3); + fSettings.GetFullTitles().c_str(), 200, 0, 3); } SetCovarFromDiagonal(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void Simple_Osc::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(13) == 0) { // Final state particles return; } TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; ThetaMu = Pnu.Vect().Angle(Pmu.Vect()); fXVar = FitUtils::EnuQErec(Pmu, cos(ThetaMu), 34, true); return; }; bool Simple_Osc::isSignal(FitEvent *event) { return SignalDef::isCCINC(event, 14, EnuMin, EnuMax); } diff --git a/src/MCStudies/Simple_Osc.h b/src/MCStudies/Simple_Osc.h index a04029a..03bd18c 100644 --- a/src/MCStudies/Simple_Osc.h +++ b/src/MCStudies/Simple_Osc.h @@ -1,41 +1,36 @@ // 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 SIMPLE_OSC_H_SEEN #define SIMPLE_OSC_H_SEEN #include "Measurement1D.h" -/// A simple MCStudy measurement for making and fitting fake EnuRecQE data. -/// -/// Run as a normal sample to generate fake data. -/// Include extra attribute Target_Simple_Osc_File in the sample xml element -// whose value points to a nuiscomp output file to use as fake data for a fit. class Simple_Osc : public Measurement1D { public: Simple_Osc(nuiskey samplekey); virtual ~Simple_Osc() {}; void FillEventVariables(FitEvent *event); bool isSignal(FitEvent *event); }; #endif diff --git a/src/MCStudies/Smear_SVDUnfold_Propagation_Osc.cxx b/src/MCStudies/Smear_SVDUnfold_Propagation_Osc.cxx new file mode 100644 index 0000000..8b11a3f --- /dev/null +++ b/src/MCStudies/Smear_SVDUnfold_Propagation_Osc.cxx @@ -0,0 +1,913 @@ +// 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"); + QLOG(SAM, "FD Sample [" << FDSamples.size() << "] imposes FitRegion E_nu > " + << fds.FitRegion_Min); + } + if ((FitRegion_Min == 0xdeadbeef) || FitRegion_Min > fds.FitRegion_Min) { + FitRegion_Min = fds.FitRegion_Min; + } + + nk.Print(); + fds.FitRegion_Max = 0xdeadbeef; + if (nk.Has("FitRegion_Max")) { + fds.FitRegion_Max = nk.GetD("FitRegion_Max"); + QLOG(SAM, "FD Sample [" << FDSamples.size() << "] imposes FitRegion E_nu < " + << fds.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); + } + } + + if ((FitRegion_Min != 0xdeadbeef) || (FitRegion_Max != 0xdeadbeef)) { + QLOG(SAM, "When unfolding, interested region limited to:"); + if (FitRegion_Min != 0xdeadbeef) { + QLOG(SAM, "\tE_nu > " << FitRegion_Min); + } + if (FitRegion_Max != 0xdeadbeef) { + QLOG(SAM, "\tE_nu < " << FitRegion_Max); + } + } + + 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 DumpUnfoldDebugInfo(Smear_SVDUnfold_Propagation_Osc::NDSample &nds, + size_t nd_it, size_t truncations) { + TDirectory *ogDir = gDirectory; + std::stringstream ss; + ss.str(""); + ss << "DEBUG_FailedInvert_NDSample_" << nd_it; + + Config::Get().out->mkdir(ss.str().c_str()); + Config::Get().out->cd(ss.str().c_str()); + + ss.str(""); + ss << "ND_Smearing_Matrix_" << nd_it; + nds.NDToSpectrumSmearingMatrix->Write(ss.str().c_str(), TObject::kOverwrite); + ss.str(""); + ss << "ND_Inverse_Smearing_Matrix_" << nd_it; + SmearceptanceUtils::SVDGetInverse(nds.NDToSpectrumSmearingMatrix, 0) + ->Write(ss.str().c_str(), TObject::kOverwrite); + + ss.str(""); + ss << "ND_Inverse_Smearing_Matrix_" << nd_it << "_Trunc_" << truncations; + SmearceptanceUtils::SVDGetInverse(nds.NDToSpectrumSmearingMatrix, truncations) + ->Write(ss.str().c_str(), TObject::kOverwrite); + + ss.str(""); + ss << "ND_Obs_" << nd_it; + nds.NDDataHist->Write(ss.str().c_str(), TObject::kOverwrite); + + TMatrixD NDToSpectrumResponseMatrix_notrunc = SmearceptanceUtils::GetMatrix( + SmearceptanceUtils::SVDGetInverse(nds.NDToSpectrumSmearingMatrix, 0)); + + nds.NDToSpectrumResponseMatrix.ResizeTo(NDToSpectrumResponseMatrix_notrunc); + nds.NDToSpectrumResponseMatrix = NDToSpectrumResponseMatrix_notrunc; + + SmearceptanceUtils::PushTH1ThroughMatrixWithErrors( + nds.NDDataHist, nds.ND_Unfolded_Spectrum_Hist, + nds.NDToSpectrumResponseMatrix, 1000, false); + + ss.str(""); + ss << "ND_Unfolded_" << nd_it; + nds.ND_Unfolded_Spectrum_Hist->Write(ss.str().c_str(), TObject::kOverwrite); + + TMatrixD NDToSpectrumResponseMatrix_trunc = + SmearceptanceUtils::GetMatrix(SmearceptanceUtils::SVDGetInverse( + nds.NDToSpectrumSmearingMatrix, truncations)); + + nds.NDToSpectrumResponseMatrix.ResizeTo(NDToSpectrumResponseMatrix_trunc); + nds.NDToSpectrumResponseMatrix = NDToSpectrumResponseMatrix_trunc; + + SmearceptanceUtils::PushTH1ThroughMatrixWithErrors( + nds.NDDataHist, nds.ND_Unfolded_Spectrum_Hist, + nds.NDToSpectrumResponseMatrix, 1000, false); + + ss.str(""); + ss << "ND_Unfolded_" << nd_it << "_Trunc_" << truncations; + nds.ND_Unfolded_Spectrum_Hist->Write(ss.str().c_str(), TObject::kOverwrite); + + if (ogDir) { + ogDir->cd(); + } else { + Config::Get().out->cd(); + } +} + +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) { + DumpUnfoldDebugInfo(nds, nd_it, truncations); + + 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; + QLOG(SAM, + "After " + << truncations << " truncations, bin " << (bi_it - 1) << " [" + << nds.ND_Unfolded_Spectrum_Hist->GetXaxis()->GetBinLowEdge( + bi_it) + << " -- " + << nds.ND_Unfolded_Spectrum_Hist->GetXaxis()->GetBinUpEdge( + bi_it) + << " ] has value: " + << nds.ND_Unfolded_Spectrum_Hist->GetBinContent(bi_it)); + 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 { + 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 { + 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 { + 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 { + Config::Get().out->cd(); + } + } + + fMCHist->Write("Pred_FD", TObject::kOverwrite); + fDataHist->Write("Obs_FD", TObject::kOverwrite); + + Measurement1D::Write(drawOpt); +} diff --git a/src/MCStudies/Smear_SVDUnfold_Propagation_Osc.h b/src/MCStudies/Smear_SVDUnfold_Propagation_Osc.h new file mode 100644 index 0000000..752888f --- /dev/null +++ b/src/MCStudies/Smear_SVDUnfold_Propagation_Osc.h @@ -0,0 +1,119 @@ +// 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 Smear_SVDUnfold_Propagation_Osc_H_SEEN +#define Smear_SVDUnfold_Propagation_Osc_H_SEEN + +#include "Measurement1D.h" +/// Class for building simple oscillation analyses. +/// +/// An example tag which runs a FHC beam and performs a numudisp and nue app +/// measurement might look like: +/// +/// +/// +/// +/// +/// +class Smear_SVDUnfold_Propagation_Osc : public Measurement1D { +public: + struct FDSample { + TH1D *FDDataHist; + + std::vector FD_Propagated_Spectrum_Hist_NDSamples; + std::vector NDFD_Corrected_Spectrum_Hist_NDSamples; + + TH1D *FD_Propagated_Spectrum_Hist; + TH1D *NDFD_Corrected_Spectrum_Hist; + TH1D *FD_Smeared_Spectrum_Hist; + + TH2D *SpectrumToFDSmearingMatrix_TH2; + TMatrixD SpectrumToFDSmearingMatrix; + Int_t OscillateToPDG; + + double FitRegion_Min; + double FitRegion_Max; + std::map FDNDRatios; + double FDNDMassRatio; + + std::pair DetectorInfo; + }; + + struct NDSample { + TH1D *NDDataHist; + Int_t TruncateStart; + Int_t TruncateUpTo; + + TH1D *ND_Unfolded_Spectrum_Hist; + TH2D *NDToSpectrumSmearingMatrix; + + TMatrixD NDToSpectrumResponseMatrix; + + Int_t NuPDG; + + double XSecToEvRateScale; + }; + + public: + Smear_SVDUnfold_Propagation_Osc(nuiskey samplekey); + + virtual ~Smear_SVDUnfold_Propagation_Osc(){}; + + void FillEventVariables(FitEvent *event); + bool isSignal(FitEvent *event); + + void UnfoldToNDETrueSpectrum(size_t); + void ConvertEventRates(void); + void Write(std::string drawOpt); + + void ReadExtraConfig(nuiskey &samplekey); + void SetupChi2Hists(); + void UpdateChi2Hists(); + + // ----- Near detector things + void AddNDInputs(nuiskey &samplekey); + void SetupNDInputs(); + std::vector NDSamples; + + std::pair NDetectorInfo; + double FitRegion_Min; + double FitRegion_Max; + + // ----- Far detector things + Int_t NFDAnalysisBins; + Int_t GetFDSampleNAnalysisBins(size_t fds_it); + void AddFDTarget(nuiskey &nk); + void PropagateFDSample(size_t fds_it); + void FinaliseFDSamples(); + std::vector FDSamples; + + double ScalePOT; + + // ----- Other config + bool UseRateErrors; +}; + +#endif diff --git a/src/MCStudies/Smearceptance_Tester.cxx b/src/MCStudies/Smearceptance_Tester.cxx index d81862e..072f2bd 100644 --- a/src/MCStudies/Smearceptance_Tester.cxx +++ b/src/MCStudies/Smearceptance_Tester.cxx @@ -1,516 +1,884 @@ // 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(std::string name, - std::string inputfile, FitWeight *rw, - std::string type, - std::string fakeDataFile) { +Smearceptance_Tester::Smearceptance_Tester(nuiskey samplekey) { //******************************************************************** - // Measurement Details - std::vector splitName = GeneralUtils::ParseToStr(name, "_"); - size_t firstUS = name.find_first_of("_"); + samplekey.Print(); - std::string smearceptorName = name.substr(firstUS + 1); + // Sample overview --------------------------------------------------- + std::string descrip = + "Simple measurement class for producing an event summary tree of smeared " + "events.\n"; - fName = name.substr(0, firstUS); - eventVariables = NULL; + if (Config::HasPar("NPOT")) { + samplekey.SetS("NPOT", Config::GetParS("NPOT")); + } + if (Config::HasPar("FluxIntegralOverride")) { + samplekey.SetS("FluxIntegralOverride", + Config::GetParS("FluxIntegralOverride")); + } + if (Config::HasPar("TargetVolume")) { + samplekey.SetS("TargetVolume", Config::GetParS("TargetVolume")); + } + if (Config::HasPar("TargetMaterialDensity")) { + samplekey.SetS("TargetMaterialDensity", + Config::GetParS("TargetMaterialDensity")); + } - // Define our energy range for flux calcs - EnuMin = 0.; - EnuMax = 100.; // Arbritrarily high energy limit + OutputSummaryTree = true; + if (Config::HasPar("smear.OutputSummaryTree")) { + OutputSummaryTree = Config::GetParI("smear.OutputSummaryTree"); + } - // Set default fitter flags - fIsDiag = true; - fIsShape = false; - fIsRawEvents = false; + // Setup common settings + fSettings = LoadSampleSettings(samplekey); - // 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); + 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("*"); - eventVariables = NULL; + FinaliseSampleSettings(); + + // Scaling Setup --------------------------------------------------- + // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon + fScaleFactor = + (GetEventHistogram()->Integral("width") * 1E-38 / (fNEvents + 0.)) / + TotalIntegratedFlux(); + + // Measurement Details + std::vector splitName = GeneralUtils::ParseToStr(fName, "_"); + size_t firstUS = fName.find_first_of("_"); + + std::string smearceptorName = samplekey.GetS("smearceptor"); + QLOG(SAM, "Using smearceptor: " << smearceptorName + << " (parsed from: " << fName << ")."); - // Setup fDataHist as a placeholder - this->fDataHist = new TH1D(("empty_data"), ("empty-data"), 1, 0, 1); - this->SetupDefaultHist(); + fDataHist = new TH1D(("empty_data"), ("empty-data"), 1, 0, 1); + SetupDefaultHist(); fFullCovar = StatUtils::MakeDiagonalCovarMatrix(fDataHist); covar = StatUtils::GetInvert(fFullCovar); - this->fScaleFactor = - (GetEventHistogram()->Integral("width") * 1E-38 / (fNEvents + 0.)) / - this->TotalIntegratedFlux(); + 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 - this->AddEventVariablesToTree(); + AddEventVariablesToTree(); smearceptor = &Smearcepterton::Get().GetSmearcepter(smearceptorName); -#ifdef __PROB3PP_ENABLED__ - OscWeighter = new OscWeightEngine(); - OscWeighter->Config(); -#endif + Int_t RecNBins = 20, TrueNBins = 20; + double RecBinL = 0xdeadbeef, TrueBinL = 0, RecBinH = 10, TrueBinH = 10; + + if (Config::HasPar("smear.reconstructed.binning")) { + std::vector args = GeneralUtils::ParseToStr( + Config::GetParS("smear.reconstructed.binning"), ","); + RecNBins = GeneralUtils::StrToInt(args[0]); + RecBinL = GeneralUtils::StrToDbl(args[1]); + RecBinH = GeneralUtils::StrToDbl(args[2]); + TrueNBins = RecNBins; + TrueBinL = RecBinL; + TrueBinH = RecBinH; + } + + if (Config::HasPar("smear.true.binning")) { + std::vector args = + GeneralUtils::ParseToStr(Config::GetParS("smear.true.binning"), ","); + TrueNBins = GeneralUtils::StrToInt(args[0]); + TrueBinL = GeneralUtils::StrToDbl(args[1]); + TrueBinH = GeneralUtils::StrToDbl(args[2]); + } + SVDTruncation = 0; + if (Config::HasPar("smear.true.binning")) { + SVDTruncation = Config::GetParI("smear.SVD.truncation"); + QLOG(SAM, "Applying SVD truncation of: " << SVDTruncation) + } + + ETrueDistrib = NULL; + ETrueDistrib_noweight = NULL; + ERecDistrib = NULL; + RecoSmear = NULL; + if (RecBinL != 0xdeadbeef) { + QLOG(SAM, "Using binning True: " << TrueNBins << ", [" << TrueBinL << " -- " + << TrueBinH << "], Rec: " << RecNBins + << ", [" << RecBinL << " -- " << RecBinH + << "]"); + + ETrueDistrib = new TH1D("ELep_rate", ";True E_{#nu};Count", TrueNBins, + TrueBinL, TrueBinH); + ETrueDistrib_noweight = + new TH1D("ELep_rate_noweight", ";True E_{#nu};Count", TrueNBins, + TrueBinL, TrueBinH); + ERecDistrib = new TH1D("ELepRec_rate", ";Rec E_{#nu};Count", RecNBins, + RecBinL, RecBinH); + ETrueDistrib->Sumw2(); + ERecDistrib->Sumw2(); + + RecoSmear = + new TH2D("ELepHadVis_Recon", ";True E_{#nu};Recon. E_{#nu}", RecNBins, + RecBinL, RecBinH, TrueNBins, TrueBinL, TrueBinH); + RecoSmear->Sumw2(); + } + + // Final setup --------------------------------------------------- + FinaliseMeasurement(); } void Smearceptance_Tester::AddEventVariablesToTree() { - // Setup the TTree to save everything - if (!eventVariables) { - FitPar::Config().out->cd(); - eventVariables = new TTree((this->fName + "_VARS").c_str(), - (this->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("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("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("xsecScaling", &xsecScaling, "xsecScaling/F"); - - eventVariables->Branch("flagCCINC_true", &flagCCINC_true, "flagCCINC_true/O"); - eventVariables->Branch("flagCC0Pi_true", &flagCC0Pi_true, "flagCC0Pi_true/O"); - - eventVariables->Branch("flagCCINC_rec", &flagCCINC_rec, "flagCCINC_rec/O"); - eventVariables->Branch("flagCC0Pi_rec", &flagCC0Pi_rec, "flagCC0Pi_rec/O"); + if (OutputSummaryTree) { + // Setup the TTree to save everything + if (!eventVariables) { + Config::Get().out->cd(); + eventVariables = + new TTree((fName + "_VARS").c_str(), (fName + "_VARS").c_str()); + } -#ifdef __PROB3PP_ENABLED__ - eventVariables->Branch("OscWeight", &OscWeight, "OscWeight/F"); -#endif + LOG(SAM) << "Adding Event Variables" << std::endl; + + eventVariables->Branch("Omega_true", &Omega_true, "Omega_true/F"); + eventVariables->Branch("Q2_true", &Q2_true, "Q2_true/F"); + eventVariables->Branch("Mode_true", &Mode_true, "Mode_true/I"); + + eventVariables->Branch("EISLep_true", &EISLep_true, "EISLep_true/F"); + + eventVariables->Branch("HMFS_clep_true", &HMFS_clep_true); + eventVariables->Branch("HMFS_pip_true", &HMFS_pip_true); + eventVariables->Branch("HMFS_pim_true", &HMFS_pim_true); + eventVariables->Branch("HMFS_cpi_true", &HMFS_cpi_true); + eventVariables->Branch("HMFS_pi0_true", &HMFS_pi0_true); + eventVariables->Branch("HMFS_cK_true", &HMFS_cK_true); + eventVariables->Branch("HMFS_K0_true", &HMFS_K0_true); + eventVariables->Branch("HMFS_p_true", &HMFS_p_true); + + eventVariables->Branch("KEFSHad_cpip_true", &KEFSHad_cpip_true, + "KEFSHad_cpip_true/F"); + eventVariables->Branch("KEFSHad_cpim_true", &KEFSHad_cpim_true, + "KEFSHad_cpim_true/F"); + eventVariables->Branch("KEFSHad_cpi_true", &KEFSHad_cpi_true, + "KEFSHad_cpi_true/F"); + eventVariables->Branch("TEFSHad_pi0_true", &TEFSHad_pi0_true, + "TEFSHad_pi0_true/F"); + eventVariables->Branch("KEFSHad_cK_true", &KEFSHad_cK_true, + "KEFSHad_cK_true/F"); + eventVariables->Branch("KEFSHad_K0_true", &KEFSHad_K0_true, + "KEFSHad_K0_true/F"); + eventVariables->Branch("KEFSHad_p_true", &KEFSHad_p_true, + "KEFSHad_p_true/F"); + eventVariables->Branch("KEFSHad_n_true", &KEFSHad_n_true, + "KEFSHad_n_true/F"); + + eventVariables->Branch("EFSHad_true", &EFSHad_true, "EFSHad_true/F"); + eventVariables->Branch("EFSChargedEMHad_true", &EFSChargedEMHad_true, + "EFSChargedEMHad_true/F"); + + eventVariables->Branch("EFSLep_true", &EFSLep_true, "EFSLep_true/F"); + eventVariables->Branch("EFSgamma_true", &EFSgamma_true, "EFSgamma_true/F"); + + eventVariables->Branch("PDGISLep_true", &PDGISLep_true, "PDGISLep_true/I"); + eventVariables->Branch("PDGFSLep_true", &PDGFSLep_true, "PDGFSLep_true/I"); + + eventVariables->Branch("Nprotons_true", &Nprotons_true, "Nprotons_true/I"); + eventVariables->Branch("Nneutrons_true", &Nneutrons_true, + "Nneutrons_true/I"); + eventVariables->Branch("Ncpiplus_true", &Ncpiplus_true, "Ncpiplus_true/I"); + eventVariables->Branch("Ncpiminus_true", &Ncpiminus_true, + "Ncpiminus_true/I"); + eventVariables->Branch("Ncpi_true", &Ncpi_true, "Ncpi_true/I"); + eventVariables->Branch("Npi0_true", &Npi0_true, "Npi0_true/I"); + eventVariables->Branch("NcK_true", &NcK_true, "NcK_true/I"); + eventVariables->Branch("NK0_true", &NK0_true, "NK0_true/I"); + + eventVariables->Branch("HMFS_clep_rec", &HMFS_clep_rec); + eventVariables->Branch("HMFS_pip_rec", &HMFS_pip_rec); + eventVariables->Branch("HMFS_pim_rec", &HMFS_pim_rec); + eventVariables->Branch("HMFS_cpi_rec", &HMFS_cpi_rec); + eventVariables->Branch("HMFS_pi0_rec", &HMFS_pi0_rec); + eventVariables->Branch("HMFS_cK_rec", &HMFS_cK_rec); + eventVariables->Branch("HMFS_K0_rec", &HMFS_K0_rec); + eventVariables->Branch("HMFS_p_rec", &HMFS_p_rec); + + eventVariables->Branch("KEFSHad_cpip_rec", &KEFSHad_cpip_rec, + "KEFSHad_cpip_rec/F"); + eventVariables->Branch("KEFSHad_cpim_rec", &KEFSHad_cpim_rec, + "KEFSHad_cpim_rec/F"); + eventVariables->Branch("KEFSHad_cpi_rec", &KEFSHad_cpi_rec, + "KEFSHad_cpi_rec/F"); + eventVariables->Branch("TEFSHad_pi0_rec", &TEFSHad_pi0_rec, + "TEFSHad_pi0_rec/F"); + eventVariables->Branch("KEFSHad_cK_rec", &KEFSHad_cK_rec, + "KEFSHad_cK_rec/F"); + eventVariables->Branch("KEFSHad_K0_rec", &KEFSHad_K0_rec, + "KEFSHad_K0_rec/F"); + eventVariables->Branch("KEFSHad_p_rec", &KEFSHad_p_rec, "KEFSHad_p_rec/F"); + eventVariables->Branch("KEFSHad_n_rec", &KEFSHad_n_rec, "KEFSHad_n_rec/F"); + + eventVariables->Branch("EFSHad_rec", &EFSHad_rec, "EFSHad_rec/F"); + eventVariables->Branch("EFSLep_rec", &EFSLep_rec, "EFSLep_rec/F"); + + eventVariables->Branch("EFSVis_cpip", &EFSVis_cpip, "EFSVis_cpip/F"); + eventVariables->Branch("EFSVis_cpim", &EFSVis_cpim, "EFSVis_cpim/F"); + eventVariables->Branch("EFSVis_cpi", &EFSVis_cpi, "EFSVis_cpi/F"); + eventVariables->Branch("EFSVis_pi0", &EFSVis_pi0, "EFSVis_pi0/F"); + eventVariables->Branch("EFSVis_cK", &EFSVis_cK, "EFSVis_cK/F"); + eventVariables->Branch("EFSVis_K0", &EFSVis_K0, "EFSVis_K0/F"); + eventVariables->Branch("EFSVis_p", &EFSVis_p, "EFSVis_p/F"); + eventVariables->Branch("EFSVis_n", &EFSVis_n, "EFSVis_n/F"); + eventVariables->Branch("EFSVis_gamma", &EFSVis_gamma, "EFSVis_gamma/F"); + eventVariables->Branch("EFSVis_other", &EFSVis_other, "EFSVis_other/F"); + eventVariables->Branch("EFSVis", &EFSVis, "EFSVis/F"); + + eventVariables->Branch("FSCLep_seen", &FSCLep_seen, "FSCLep_seen/I"); + eventVariables->Branch("Nprotons_seen", &Nprotons_seen, "Nprotons_seen/I"); + eventVariables->Branch("Nneutrons_seen", &Nneutrons_seen, + "Nneutrons_seen/I"); + eventVariables->Branch("Ncpip_seen", &Ncpip_seen, "Ncpip_seen/I"); + eventVariables->Branch("Ncpim_seen", &Ncpim_seen, "Ncpim_seen/I"); + eventVariables->Branch("Ncpi_seen", &Ncpi_seen, "Ncpi_seen/I"); + eventVariables->Branch("Npi0_seen", &Npi0_seen, "Npi0_seen/I"); + eventVariables->Branch("NcK_seen", &NcK_seen, "NcK_seen/I"); + eventVariables->Branch("NK0_seen", &NK0_seen, "NK0_seen/I"); + eventVariables->Branch("Nothers_seen", &Nothers_seen, "Nothers_seen/I"); + + eventVariables->Branch("EISLep_QE_rec", &EISLep_QE_rec, "EISLep_QE_rec/F"); + eventVariables->Branch("EISLep_LepHad_rec", &EISLep_LepHad_rec, + "EISLep_LepHad_rec/F"); + eventVariables->Branch("EISLep_LepHadVis_rec", &EISLep_LepHadVis_rec, + "EISLep_LepHadVis_rec/F"); + + eventVariables->Branch("Nprotons_contributed", &Nprotons_contributed, + "Nprotons_contributed/I"); + eventVariables->Branch("Nneutrons_contributed", &Nneutrons_contributed, + "Nneutrons_contributed/I"); + eventVariables->Branch("Ncpip_contributed", &Ncpip_contributed, + "Ncpip_contributed/I"); + eventVariables->Branch("Ncpim_contributed", &Ncpim_contributed, + "Ncpim_contributed/I"); + eventVariables->Branch("Ncpi_contributed", &Ncpi_contributed, + "Ncpi_contributed/I"); + eventVariables->Branch("Npi0_contributed", &Npi0_contributed, + "Npi0_contributed/I"); + eventVariables->Branch("NcK_contributed", &NcK_contributed, + "NcK_contributed/I"); + eventVariables->Branch("NK0_contributed", &NK0_contributed, + "NK0_contributed/I"); + eventVariables->Branch("Ngamma_contributed", &Ngamma_contributed, + "Ngamma_contributed/I"); + eventVariables->Branch("Nothers_contibuted", &Nothers_contibuted, + "Nothers_contibuted/I"); + + eventVariables->Branch("Weight", &Weight, "Weight/F"); + eventVariables->Branch("RWWeight", &RWWeight, "RWWeight/F"); + eventVariables->Branch("InputWeight", &InputWeight, "InputWeight/F"); + eventVariables->Branch("FluxWeight", &FluxWeight, "FluxWeight/F"); + eventVariables->Branch("EffWeight", &EffWeight, "EffWeight/F"); + + xsecScaling = fScaleFactor; + eventVariables->Branch("xsecScaling", &xsecScaling, "xsecScaling/F"); + + eventVariables->Branch("flagCCINC_true", &flagCCINC_true, + "flagCCINC_true/O"); + eventVariables->Branch("flagCC0K_true", &flagCC0K_true, + "flagCC0K_true/O"); + eventVariables->Branch("flagCC0Pi_true", &flagCC0Pi_true, + "flagCC0Pi_true/O"); + eventVariables->Branch("flagCC1Pi_true", &flagCC1Pi_true, + "flagCC1Pi_true/O"); + + eventVariables->Branch("flagCCINC_rec", &flagCCINC_rec, "flagCCINC_rec/O"); + eventVariables->Branch("flagCC0K_rec", &flagCC0K_rec, "flagCC0K_rec/O"); + eventVariables->Branch("flagCC0Pi_rec", &flagCC0Pi_rec, "flagCC0Pi_rec/O"); + eventVariables->Branch("flagCC1Pi_rec", &flagCC1Pi_rec, "flagCC1Pi_rec/O"); + } + + PredEvtRateWeight = 1; + if (fEvtRateScaleFactor != 0xdeadbeef) { + if (OutputSummaryTree) { + eventVariables->Branch("PredEvtRateWeight", &PredEvtRateWeight, + "PredEvtRateWeight/F"); + } + PredEvtRateWeight = fScaleFactor * fEvtRateScaleFactor; + } } template -int CountNPdgsSeen(RecoInfo ri, int (&pdgs)[N]) { +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 (&pdgs)[N]) { +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 (&pdgs)[N]) { +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 (&pdgs)[N]) { +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; } -TVector3 GetHMFSRecParticles(RecoInfo ri, int pdg) { - TVector3 mom(0, 0, 0); +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 = ri.RecObjMom[p_it]; + 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 (&pdgs)[N], double mass) { +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 (&pdgs)[N], double mass) { +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 (&pdgs)[N]) { +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 (&pdgs)[N]) { +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) { //******************************************************************** - int cpipPDG[] = {211}; - int cpimPDG[] = {-211}; - int pi0PDG[] = {111}; - int ProtonPDG[] = {2212}; - int NeutronPDG[] = {2112}; - int GammaPDG[] = {22}; - int CLeptonPDGs[] = {11, 13, 15}; - int ExplicitPDGs[] = {211, -211, 11, 2212, 2112, 22, 11, 13, 15, 12, 14, 16}; + static int const cpipPDG[] = {211}; + static int const cpimPDG[] = {-211}; + static int const pi0PDG[] = {111}; + + static int const cKPDG[] = {321, -321}; + static int const K0PDG[] = {311, 310, 130}; + + static int const ProtonPDG[] = {2212}; + static int const NeutronPDG[] = {2112}; + static int const GammaPDG[] = {22}; + static int const CLeptonPDGs[] = {11, 13, 15, -11, -13, -15}; + static int const ExplicitPDGs[] = {211, -211, 111, 321, -321, 311, 310, 130, + 2212, 2112, 22, 11, 13, 15, 12, 14, + 16, -11, -13, -15, -12, -14, -16}; RecoInfo *ri = smearceptor->Smearcept(event); + //** START Pions + + HMFS_clep_true = TLorentzVector(0, 0, 0, 0); + HMFS_clep_rec = TLorentzVector(0, 0, 0, 0); + FitParticle *fsCLep = event->GetHMFSParticle(CLeptonPDGs); + if (fsCLep) { + HMFS_clep_true = fsCLep->P4(); + HMFS_clep_rec = GetHMFSRecParticles(*ri, fsCLep->PDG()); + } + + //** END Charged leptons + + //** START Pions + + HMFS_pip_true = TLorentzVector(0, 0, 0, 0); + HMFS_pip_rec = TLorentzVector(0, 0, 0, 0); + FitParticle *fsPip = event->GetHMFSPiPlus(); + if (fsPip) { + HMFS_pip_true = fsPip->P4(); + HMFS_pip_rec = GetHMFSRecParticles(*ri, fsPip->PDG()); + } + + HMFS_pim_true = TLorentzVector(0, 0, 0, 0); + HMFS_pim_rec = TLorentzVector(0, 0, 0, 0); + FitParticle *fsPim = event->GetHMFSPiMinus(); + if (fsPim) { + HMFS_pim_true = fsPim->P4(); + HMFS_pim_rec = GetHMFSRecParticles(*ri, fsPim->PDG()); + } + + HMFS_cpi_true = TLorentzVector(0, 0, 0, 0); + HMFS_cpi_rec = TLorentzVector(0, 0, 0, 0); + if (fsPip || fsPim) { + if (!fsPip) { + HMFS_cpi_true = HMFS_pim_true; + HMFS_cpi_rec = HMFS_pim_rec; + } else if (!fsPim) { + HMFS_cpi_true = HMFS_pip_true; + HMFS_cpi_rec = HMFS_pip_rec; + } else { + HMFS_cpi_true = + (fsPip->p2() > fsPim->p2()) ? HMFS_pip_true : HMFS_pim_true; + HMFS_cpi_rec = (fsPip->p2() > fsPim->p2()) ? HMFS_pip_rec : HMFS_pim_rec; + } + } + + HMFS_pi0_true = TLorentzVector(0, 0, 0, 0); + HMFS_pi0_rec = TLorentzVector(0, 0, 0, 0); + FitParticle *fsPi0 = event->GetHMFSPiZero(); + if (fsPi0) { + HMFS_pi0_true = fsPi0->P4(); + HMFS_pi0_rec = GetHMFSRecParticles(*ri, fsPi0->PDG()); + } + + //** END Pions + + //** START Kaons + + HMFS_cK_true = TLorentzVector(0, 0, 0, 0); + HMFS_cK_rec = TLorentzVector(0, 0, 0, 0); + FitParticle *fscK = event->GetHMFSParticle(cKPDG); + if (fscK) { + HMFS_cK_true = fscK->P4(); + HMFS_cK_rec = GetHMFSRecParticles(*ri, fscK->PDG()); + } + + HMFS_K0_true = TLorentzVector(0, 0, 0, 0); + HMFS_K0_rec = TLorentzVector(0, 0, 0, 0); + FitParticle *fsK0 = event->GetHMFSParticle(K0PDG); + if (fsK0) { + HMFS_K0_true = fsK0->P4(); + HMFS_K0_rec = GetHMFSRecParticles(*ri, fsK0->PDG()); + } + + //** END Kaons + + //** START Nucleons + + HMFS_p_true = TLorentzVector(0, 0, 0, 0); + HMFS_p_rec = TLorentzVector(0, 0, 0, 0); + FitParticle *fsP = event->GetHMFSProton(); + if (fsP) { + HMFS_p_true = fsP->P4(); + HMFS_p_rec = GetHMFSRecParticles(*ri, fsP->PDG()); + } + TLorentzVector FourMomentumTransfer = (event->GetHMISAnyLeptons()->P4() - event->GetHMFSAnyLeptons()->P4()); Omega_true = FourMomentumTransfer.E(); Q2_true = -1 * FourMomentumTransfer.Mag2(); Mode_true = event->Mode; EISLep_true = event->GetHMISAnyLeptons()->E(); KEFSHad_cpip_true = FitUtils::SumTE_PartVect(event->GetAllFSPiPlus()); KEFSHad_cpim_true = FitUtils::SumTE_PartVect(event->GetAllFSPiMinus()); KEFSHad_cpi_true = KEFSHad_cpip_true + KEFSHad_cpim_true; TEFSHad_pi0_true = FitUtils::SumTE_PartVect(event->GetAllFSPiZero()); + KEFSHad_cK_true = FitUtils::SumTE_PartVect(event->GetAllFSParticle(cKPDG)); + KEFSHad_K0_true = FitUtils::SumTE_PartVect(event->GetAllFSParticle(K0PDG)); KEFSHad_p_true = FitUtils::SumKE_PartVect(event->GetAllFSProton()); KEFSHad_n_true = FitUtils::SumKE_PartVect(event->GetAllFSNeutron()); EFSHad_true = KEFSHad_cpi_true + TEFSHad_pi0_true + KEFSHad_p_true + KEFSHad_n_true; - EFSChargedEMHad_true = KEFSHad_cpi_true + TEFSHad_pi0_true + KEFSHad_p_true; + EFSChargedEMHad_true = KEFSHad_cpi_true + TEFSHad_pi0_true + KEFSHad_p_true + + KEFSHad_cK_true + KEFSHad_K0_true; EFSLep_true = event->GetHMFSAnyLeptons()->E(); EFSgamma_true = FitUtils::SumTE_PartVect(event->GetAllFSPhoton()); PDGISLep_true = event->GetHMISAnyLeptons()->PDG(); PDGFSLep_true = event->GetHMFSAnyLeptons()->PDG(); Nprotons_true = event->GetAllFSProton().size(); Nneutrons_true = event->GetAllFSNeutron().size(); Ncpiplus_true = event->GetAllFSPiPlus().size(); Ncpiminus_true = event->GetAllFSPiMinus().size(); Ncpi_true = Ncpiplus_true + Ncpiminus_true; Npi0_true = event->GetAllFSPiZero().size(); + NcK_true = event->GetAllFSParticle(cKPDG).size(); + NK0_true = event->GetAllFSParticle(K0PDG).size(); KEFSHad_cpip_rec = SumKE_RecoInfo(*ri, cpipPDG, PhysConst::mass_cpi * PhysConst::mass_MeV); KEFSHad_cpim_rec = SumKE_RecoInfo(*ri, cpimPDG, PhysConst::mass_cpi * PhysConst::mass_MeV); KEFSHad_cpi_rec = KEFSHad_cpip_rec + KEFSHad_cpim_rec; + TEFSHad_pi0_rec = SumTE_RecoInfo(*ri, pi0PDG, PhysConst::mass_pi0 * PhysConst::mass_MeV); + + KEFSHad_cK_rec = + SumKE_RecoInfo(*ri, cKPDG, PhysConst::mass_cK * PhysConst::mass_MeV); + KEFSHad_K0_rec = + SumKE_RecoInfo(*ri, K0PDG, PhysConst::mass_K0 * PhysConst::mass_MeV); + KEFSHad_p_rec = SumKE_RecoInfo(*ri, ProtonPDG, PhysConst::mass_proton * PhysConst::mass_MeV); KEFSHad_n_rec = SumKE_RecoInfo(*ri, NeutronPDG, PhysConst::mass_neutron * PhysConst::mass_MeV); EFSHad_rec = KEFSHad_cpi_rec + TEFSHad_pi0_rec + KEFSHad_p_rec + KEFSHad_n_rec; - TVector3 FSLepMom_rec(0, 0, 0); + TLorentzVector FSLepMom_rec(0, 0, 0, 0); if (event->GetHMFSAnyLeptons()) { - double massLep = event->GetHMFSAnyLeptons()->M(); FSLepMom_rec = GetHMFSRecParticles(*ri, event->GetHMFSAnyLeptons()->PDG()); - EFSLep_rec = (FSLepMom_rec.Mag() > 1E-5) - ? sqrt(FSLepMom_rec * FSLepMom_rec + massLep * massLep) - : 0; + EFSLep_rec = FSLepMom_rec.E(); } else { EFSLep_rec = 0; } EFSVis_cpip = SumVisE_RecoInfo(*ri, cpipPDG); EFSVis_cpim = SumVisE_RecoInfo(*ri, cpimPDG); EFSVis_cpi = EFSVis_cpip + EFSVis_cpim; EFSVis_pi0 = SumVisE_RecoInfo(*ri, pi0PDG); + EFSVis_cK = SumVisE_RecoInfo(*ri, cKPDG); + EFSVis_K0 = SumVisE_RecoInfo(*ri, K0PDG); EFSVis_p = SumVisE_RecoInfo(*ri, ProtonPDG); EFSVis_n = SumVisE_RecoInfo(*ri, NeutronPDG); EFSVis_gamma = SumVisE_RecoInfo(*ri, GammaPDG); EFSVis_other = SumVisE_RecoInfo_NotPdgs(*ri, ExplicitPDGs); - EFSVis = EFSVis_cpip + EFSVis_cpim + EFSVis_cpi + EFSVis_pi0 + EFSVis_p + - EFSVis_n + EFSVis_gamma; + EFSVis = EFSVis_cpi + EFSVis_pi0 + EFSVis_p + EFSVis_n + EFSVis_gamma + + EFSVis_cK + EFSVis_K0; FSCLep_seen = CountNPdgsSeen(*ri, CLeptonPDGs); Nprotons_seen = CountNPdgsSeen(*ri, ProtonPDG); Nneutrons_seen = CountNPdgsSeen(*ri, NeutronPDG); Ncpip_seen = CountNPdgsSeen(*ri, cpipPDG); Ncpim_seen = CountNPdgsSeen(*ri, cpimPDG); Ncpi_seen = Ncpip_seen + Ncpim_seen; Npi0_seen = CountNPdgsSeen(*ri, pi0PDG); + NcK_seen = CountNPdgsSeen(*ri, cKPDG); + NK0_seen = CountNPdgsSeen(*ri, K0PDG); Nothers_seen = CountNNotPdgsSeen(*ri, ExplicitPDGs); if (FSCLep_seen && (FSLepMom_rec.Mag() > 1E-8)) { - EISLep_QE_rec = FSCLep_seen && FitUtils::EnuQErec(FSLepMom_rec.Mag(), - FSLepMom_rec.Unit().Z(), - 34, PDGFSLep_true > 0); + EISLep_QE_rec = + FitUtils::EnuQErec(FSLepMom_rec.Mag() / 1000.0, FSLepMom_rec.CosTheta(), + 34, PDGFSLep_true > 0) * + 1000.0; } else { EISLep_QE_rec = 0; } EISLep_LepHad_rec = EFSLep_rec + EFSHad_rec; EISLep_LepHadVis_rec = EFSLep_rec + EFSHad_rec + EFSVis; Nprotons_contributed = CountNPdgsContributed(*ri, ProtonPDG); Nneutrons_contributed = CountNPdgsContributed(*ri, NeutronPDG); Ncpip_contributed = CountNPdgsContributed(*ri, cpipPDG); Ncpim_contributed = CountNPdgsContributed(*ri, cpimPDG); Ncpi_contributed = Ncpip_contributed + Ncpim_contributed; Npi0_contributed = CountNPdgsContributed(*ri, pi0PDG); + NcK_contributed = CountNPdgsContributed(*ri, cKPDG); + NK0_contributed = CountNPdgsContributed(*ri, K0PDG); Ngamma_contributed = CountNPdgsContributed(*ri, GammaPDG); Nothers_contibuted = CountNNotPdgsContributed(*ri, ExplicitPDGs); Weight = event->RWWeight * event->InputWeight; RWWeight = event->RWWeight; InputWeight = event->InputWeight; FluxWeight = GetFluxHistogram()->GetBinContent( GetFluxHistogram()->FindBin(EISLep_true)) / GetFluxHistogram()->Integral(); - - xsecScaling = fScaleFactor; + EffWeight = ri->Weight; flagCCINC_true = PDGFSLep_true & 1; - flagCC0Pi_true = (Ncpi_true + Npi0_true) == 0; + flagCC0K_true = (NcK_true + NK0_true) == 0; + flagCC0Pi_true = + flagCCINC_true && flagCC0K_true && ((Ncpi_true + Npi0_true) == 0); + flagCC1Pi_true = + flagCCINC_true && flagCC0K_true && ((Ncpi_true + Npi0_true) == 1); + + flagCCINC_rec = FSCLep_seen && flagCCINC_true; + flagCC0K_rec = (NcK_seen + NK0_seen) == 0; + flagCC0Pi_rec = + flagCCINC_rec && flagCC0K_rec && ((Ncpi_seen + Npi0_seen) == 0); + flagCC1Pi_rec = + flagCCINC_rec && flagCC0K_rec && ((Ncpi_seen + Npi0_seen) == 1); + + if (OutputSummaryTree) { + // Fill the eventVariables Tree + eventVariables->Fill(); + } - flagCCINC_rec = FSCLep_seen && PDGFSLep_true & 1; - flagCC0Pi_rec = ((Ncpi_seen + Npi0_seen) == 0) && flagCCINC_rec; + 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); -#ifdef __PROB3PP_ENABLED__ - OscWeight = OscWeighter->CalcWeight(event); -#endif - // Fill the eventVariables Tree - eventVariables->Fill(); - return; + 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) { //******************************************************************** - // First save the TTree - eventVariables->Write(); + if (OutputSummaryTree) { + // First save the TTree + eventVariables->Write(); + } // Save Flux and Event Histograms too GetInput()->GetFluxHistogram()->Write(); GetInput()->GetEventHistogram()->Write(); - return; + if (!RecoSmear) { + return; + } + + TH2D *SmearMatrix_ev = + static_cast(RecoSmear->Clone("ELepHadVis_Smear_ev")); + + for (Int_t trueAxis_it = 1; + trueAxis_it < RecoSmear->GetXaxis()->GetNbins() + 1; ++trueAxis_it) { + double NEISLep = ETrueDistrib_noweight->GetBinContent(trueAxis_it); + + for (Int_t recoAxis_it = 1; + recoAxis_it < RecoSmear->GetYaxis()->GetNbins() + 1; ++recoAxis_it) { + if (NEISLep > std::numeric_limits::epsilon()) { + SmearMatrix_ev->SetBinContent( + trueAxis_it, recoAxis_it, + SmearMatrix_ev->GetBinContent(trueAxis_it, recoAxis_it) / NEISLep); + } + } + } + + ETrueDistrib_noweight->Write(); + ETrueDistrib->Write(); + ERecDistrib->Write(); + + RecoSmear->Write(); + + SmearMatrix_ev->Write(); + + TH2D *ResponseMatrix_ev = + SmearceptanceUtils::SVDGetInverse(SmearMatrix_ev, SVDTruncation); + ResponseMatrix_ev->SetName("ResponseMatrix_ev"); + ResponseMatrix_ev->Write(); + +#ifdef DEBUG_SMEARTESTER + + TMatrixD SmearMatrix_ev_md = SmearceptanceUtils::GetMatrix(SmearMatrix_ev); + + TH1D *SmearedEvt = static_cast(ERecDistrib->Clone()); + SmearedEvt->SetNameTitle("SmearedEvt", ";Rec E_{#nu}; count"); + + SmearceptanceUtils::PushTH1ThroughMatrixWithErrors( + ETrueDistrib, SmearedEvt, SmearMatrix_ev_md, 5000, false); + + SmearedEvt->Write(); + + SmearedEvt->Scale(1, "width"); + SmearedEvt->SetName("SmearedEvt_bw"); + SmearedEvt->Write(); + +#endif + +#ifdef __PROB3PP_ENABLED__ + FitWeight *fw = FitBase::GetRW(); + if (fw->HasRWEngine(kOSCILLATION)) { + OscWeightEngine *oscWE = + dynamic_cast(fw->GetRWEngine(kOSCILLATION)); + TGraph POsc; + + POsc.Set(1E4 - 1); + + double min = ETrueDistrib->GetXaxis()->GetBinLowEdge(1); + double step = (ETrueDistrib->GetXaxis()->GetBinUpEdge( + ETrueDistrib->GetXaxis()->GetNbins()) - + ETrueDistrib->GetXaxis()->GetBinLowEdge(1)) / + double(1E4); + + for (size_t i = 1; i < 1E4; ++i) { + double enu = min + i * step; + double ow = oscWE->CalcWeight(enu, 14); + if (ow != ow) { + std::cout << "Bad osc weight for ENu: " << enu << std::endl; + } + POsc.SetPoint(i - 1, enu, ow); + } + + POsc.Write("POsc", TObject::kOverwrite); + } +#endif + + TMatrixD ResponseMatrix_evt_md = + SmearceptanceUtils::GetMatrix(ResponseMatrix_ev); + + TH1D *Unfolded_enu_obs = static_cast(ETrueDistrib->Clone()); + Unfolded_enu_obs->SetNameTitle("UnfoldedENu_evt", ";True E_{#nu};count"); + + SmearceptanceUtils::PushTH1ThroughMatrixWithErrors( + ERecDistrib, Unfolded_enu_obs, ResponseMatrix_evt_md, 5000, false); + + Unfolded_enu_obs->Write(); + + Unfolded_enu_obs->Scale(1, "width"); + Unfolded_enu_obs->SetName("UnfoldedENu_evt_bw"); + Unfolded_enu_obs->Write(); + + ETrueDistrib->Scale(1, "width"); + ETrueDistrib->SetName("ELep_rate_bw"); + ETrueDistrib->Write(); + + ERecDistrib->Scale(1, "width"); + ERecDistrib->SetName("ELepRec_rate_bw"); + ERecDistrib->Write(); } // ------------------------------------------------------------------- // Purely MC Plot // Following functions are just overrides to handle this // ------------------------------------------------------------------- //******************************************************************** /// Everything is classed as signal... bool Smearceptance_Tester::isSignal(FitEvent *event) { //******************************************************************** (void)event; return true; }; //******************************************************************** void Smearceptance_Tester::ScaleEvents() { //******************************************************************** // Saving everything to a TTree so no scaling required return; } //******************************************************************** void Smearceptance_Tester::ApplyNormScale(float norm) { //******************************************************************** // Saving everything to a TTree so no scaling required - this->fCurrentNorm = norm; + fCurrentNorm = norm; return; } //******************************************************************** void Smearceptance_Tester::FillHistograms() { //******************************************************************** // No Histograms need filling........ return; } //******************************************************************** void Smearceptance_Tester::ResetAll() { //******************************************************************** - eventVariables->Reset(); + if (OutputSummaryTree) { + eventVariables->Reset(); + } return; } //******************************************************************** float Smearceptance_Tester::GetChi2() { //******************************************************************** // No Likelihood to test, purely MC return 0.0; } diff --git a/src/MCStudies/Smearceptance_Tester.h b/src/MCStudies/Smearceptance_Tester.h index ead3678..aa97221 100644 --- a/src/MCStudies/Smearceptance_Tester.h +++ b/src/MCStudies/Smearceptance_Tester.h @@ -1,160 +1,201 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #ifndef Smearceptance_Tester_H_SEEN #define Smearceptance_Tester_H_SEEN #include "Measurement1D.h" #include "ISmearcepter.h" #ifdef __PROB3PP_ENABLED__ #include "OscWeightEngine.h" #endif //******************************************************************** class Smearceptance_Tester : public Measurement1D { //******************************************************************** public: - Smearceptance_Tester(std::string name, std::string inputfile, FitWeight *rw, - std::string type, std::string fakeDataFile); + Smearceptance_Tester(nuiskey samplekey); virtual ~Smearceptance_Tester(){}; //! Grab info from event void FillEventVariables(FitEvent *event); //! Fill Custom Histograms void FillHistograms(); //! ResetAll void ResetAll(); //! Scale void ScaleEvents(); //! Norm void ApplyNormScale(float norm); //! Define this samples signal bool isSignal(FitEvent *nvect); //! Write Files void Write(std::string drawOpt); //! Get Chi2 float GetChi2(); void AddEventVariablesToTree(); private: ISmearcepter *smearceptor; -#ifdef __PROB3PP_ENABLED__ - OscWeightEngine *OscWeighter; - float OscWeight; -#endif TTree *eventVariables; float Omega_true; float Q2_true; int Mode_true; float EISLep_true; + TLorentzVector HMFS_clep_true; + TLorentzVector HMFS_pip_true; + TLorentzVector HMFS_pim_true; + TLorentzVector HMFS_cpi_true; + TLorentzVector HMFS_pi0_true; + TLorentzVector HMFS_cK_true; + TLorentzVector HMFS_K0_true; + TLorentzVector HMFS_p_true; + float KEFSHad_cpip_true; float KEFSHad_cpim_true; float KEFSHad_cpi_true; float TEFSHad_pi0_true; + float KEFSHad_cK_true; + float KEFSHad_K0_true; float KEFSHad_p_true; float KEFSHad_n_true; float EFSHad_true; float EFSChargedEMHad_true; float EFSLep_true; float EFSgamma_true; int PDGISLep_true; int PDGFSLep_true; int Nprotons_true; int Nneutrons_true; int Ncpiplus_true; int Ncpiminus_true; int Ncpi_true; int Npi0_true; + int NcK_true; + int NK0_true; + + TLorentzVector HMFS_clep_rec; + TLorentzVector HMFS_pip_rec; + TLorentzVector HMFS_pim_rec; + TLorentzVector HMFS_cpi_rec; + TLorentzVector HMFS_pi0_rec; + TLorentzVector HMFS_cK_rec; + TLorentzVector HMFS_K0_rec; + TLorentzVector HMFS_p_rec; float KEFSHad_cpip_rec; float KEFSHad_cpim_rec; float KEFSHad_cpi_rec; float TEFSHad_pi0_rec; + float KEFSHad_cK_rec; + float KEFSHad_K0_rec; float KEFSHad_p_rec; float KEFSHad_n_rec; float EFSHad_rec; float EFSLep_rec; float EFSVis_cpip; float EFSVis_cpim; float EFSVis_cpi; float EFSVis_pi0; + float EFSVis_cK; + float EFSVis_K0; float EFSVis_p; float EFSVis_n; float EFSVis_gamma; float EFSVis_other; float EFSVis; int FSCLep_seen; int Nprotons_seen; int Nneutrons_seen; int Ncpip_seen; int Ncpim_seen; int Ncpi_seen; int Npi0_seen; + int NcK_seen; + int NK0_seen; int Nothers_seen; float EISLep_QE_rec; float EISLep_LepHad_rec; float EISLep_LepHadVis_rec; int Nprotons_contributed; int Nneutrons_contributed; int Ncpip_contributed; int Ncpim_contributed; int Ncpi_contributed; int Npi0_contributed; + int NcK_contributed; + int NK0_contributed; int Ngamma_contributed; int Nothers_contibuted; float Weight; float RWWeight; float InputWeight; float FluxWeight; + float EffWeight; + float PredEvtRateWeight; float xsecScaling; bool flagCCINC_true; + bool flagCC0K_true; bool flagCC0Pi_true; + bool flagCC1Pi_true; bool flagCCINC_rec; + bool flagCC0K_rec; bool flagCC0Pi_rec; + bool flagCC1Pi_rec; + + bool OutputSummaryTree; + + int SVDTruncation; + + TH2D *RecoSmear; + TH1D *ETrueDistrib; + TH1D *ETrueDistrib_noweight; + TH1D *ERecDistrib; + }; #endif diff --git a/src/MINERvA/CMakeLists.txt b/src/MINERvA/CMakeLists.txt index d41a492..6e89fe5 100644 --- a/src/MINERvA/CMakeLists.txt +++ b/src/MINERvA/CMakeLists.txt @@ -1,156 +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_CC1pip_XSec_1D_2017Update.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_antinu.cxx b/src/MINERvA/MINERvA_CC0pi_XSec_2Dptpx_antinu.cxx new file mode 100755 index 0000000..36d7e17 --- /dev/null +++ b/src/MINERvA/MINERvA_CC0pi_XSec_2Dptpx_antinu.cxx @@ -0,0 +1,112 @@ +//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_antinu.h" + +//******************************************************************** +MINERvA_CC0pi_XSec_2Dptpx_antinu::MINERvA_CC0pi_XSec_2Dptpx_antinu(nuiskey samplekey) { +//******************************************************************** + + // Sample overview --------------------------------------------------- + std::string descrip = "MINERvA_CC0pi_XSec_2Dptpx_antinu 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_{t} (GeV)"); + fSettings.SetYTitle("p_{z} (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_antinu"); + + fSettings.SetDataInput( FitPar::GetDataBase() + "MINERvA/CC0pi/data_2D.txt" ); + fSettings.SetErrorInput( FitPar::GetDataBase() + "MINERvA/CC0pi/error_2D.txt" ); + fSettings.SetCovarInput( FitPar::GetDataBase() + "MINERvA/CC0pi/covar_2D.txt" ); + fSettings.SetMapInput( FitPar::GetDataBase() + "MINERvA/CC0pi/map_2D.txt" ); + fSettings.DefineAllowedSpecies("antinumu"); + FinaliseSampleSettings(); + + // Scaling Setup --------------------------------------------------- + // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon + fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38 / (fNEvents + 0.)) / this->TotalIntegratedFlux(); + + // Plot Setup ------------------------------------------------------- + Double_t P_t[7] = {0,0.15,0.25,0.4,0.7,1.0,1.5}; + Double_t P_z[12] = {1.5,2.0,2.5,3.0,3.5,4.0,4.5,5.0,6.0,8.0,10.0,15.0}; + + CreateDataHistogram(7, P_t, 12, P_z); + SetDataValuesFromTextFile( fSettings.GetDataInput() ); + ScaleData(1E-41); + + SetMapValuesFromText( fSettings.GetMapInput() ); + + SetDataErrorsFromTextFile( fSettings.GetErrorInput() ); + ScaleDataErrors(1E-41); + + //SetCholDecompFromTextFile( fSettings.GetCovarInput() ); + //ScaleCovar(1E-16); + + //StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, fMapHist, 1E-38); + + // Final setup --------------------------------------------------- + FinaliseMeasurement(); + +}; + +//******************************************************************** +void MINERvA_CC0pi_XSec_2Dptpx_antinu::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 = pz; + fXVar = pt; + + return; +}; + +//******************************************************************** +bool MINERvA_CC0pi_XSec_2Dptpx_antinu::isSignal(FitEvent *event) { +//******************************************************************** + return (SignalDef::isCC0pi_anti_MINERvAPTPZ(event, -14, EnuMin, EnuMax)/* && SignalDef::HasProtonMomBelowThreshold(event, 120)*/); +}; diff --git a/src/MCStudies/MCStudy_CCQEHistograms.h b/src/MINERvA/MINERvA_CC0pi_XSec_2Dptpx_antinu.h old mode 100644 new mode 100755 similarity index 54% copy from src/MCStudies/MCStudy_CCQEHistograms.h copy to src/MINERvA/MINERvA_CC0pi_XSec_2Dptpx_antinu.h index 455a9f2..1cbaac6 --- a/src/MCStudies/MCStudy_CCQEHistograms.h +++ b/src/MINERvA/MINERvA_CC0pi_XSec_2Dptpx_antinu.h @@ -1,75 +1,69 @@ +//Adrian Orea +//NEED TO MODIFY +//I used the file MINERvA_CCinc_XSec_2DEavq3_nu.h as a template + // 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" +#ifndef MINERVA_CC0PI_XSEC_2DPTPX_ANTINU_H_SEEN +#define MINERVA_CC0PI_XSEC_2DPTPX_ANTINU_H_SEEN -//******************************************************************** -class MCStudy_CCQEHistograms : public Measurement1D { -//******************************************************************** +#include "Measurement2D.h" -public: +//******************************************************************** +class MINERvA_CC0pi_XSec_2Dptpx_antinu : public Measurement2D { +//******************************************************************** - MCStudy_CCQEHistograms(std::string name, std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile); - virtual ~MCStudy_CCQEHistograms() {}; + public: - //! Grab info from event - void FillEventVariables(FitEvent *event); + // Constructor + MINERvA_CC0pi_XSec_2Dptpx_antinu(nuiskey samplekey); - void ScaleEvents(); - void ResetAll(); + // Destructor + virtual ~MINERvA_CC0pi_XSec_2Dptpx_antinu() { - //! Define this samples signal - bool isSignal(FitEvent *nvect); + // Remove all the content histograms * + // for (int i = 0; i < 9; i++) + // delete this->fMCHist_content[i]; - //! Write Files - void Write(std::string drawOpt); + // delete everything + /* delete difHist; */ + /* delete evtsignalHist; */ + /* delete fluxsignalHist; */ + /* delete fMapHist; */ + /* delete status; */ + /* delete PDGHistogram; */ + + /* // Delete MODE histograms */ + /* for (int i = 0; i < 60; i++) */ + /* delete fMCHist_PDG[i]; */ - 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 ; + return; + }; - TH1D* hist_Total; + // Required functions + bool isSignal(FitEvent *nvect); + void FillEventVariables(FitEvent *event); - TH2D* hist_TLepCosLep; - - double LocalRWWeight; - double LocalInputWeight; - + protected: + + // Cuts }; - + #endif diff --git a/src/MINERvA/MINERvA_CC0pi_XSec_2Dptpx_nu.cxx b/src/MINERvA/MINERvA_CC0pi_XSec_2Dptpx_nu.cxx new file mode 100755 index 0000000..ac88a09 --- /dev/null +++ b/src/MINERvA/MINERvA_CC0pi_XSec_2Dptpx_nu.cxx @@ -0,0 +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.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_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-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(14, P_t, 13, P_z); + + SetDataValuesFromTextFile( fSettings.GetDataInput() ); + // fDataHist->Scale(1.0, "width"); + + SetMapValuesFromText( fSettings.GetMapInput() ); + 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 = 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/MCStudies/MCStudy_CCQEHistograms.h b/src/MINERvA/MINERvA_CC0pi_XSec_2Dptpx_nu.h old mode 100644 new mode 100755 similarity index 54% copy from src/MCStudies/MCStudy_CCQEHistograms.h copy to src/MINERvA/MINERvA_CC0pi_XSec_2Dptpx_nu.h index 455a9f2..40bb3d0 --- a/src/MCStudies/MCStudy_CCQEHistograms.h +++ b/src/MINERvA/MINERvA_CC0pi_XSec_2Dptpx_nu.h @@ -1,75 +1,69 @@ +//Adrian Orea +//NEED TO MODIFY +//I used the file MINERvA_CCinc_XSec_2DEavq3_nu.h as a template + // 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" +#ifndef MINERVA_CC0PI_XSEC_2DPTPX_NU_H_SEEN +#define MINERVA_CC0PI_XSEC_2DPTPX_NU_H_SEEN -//******************************************************************** -class MCStudy_CCQEHistograms : public Measurement1D { -//******************************************************************** +#include "Measurement2D.h" -public: +//******************************************************************** +class MINERvA_CC0pi_XSec_2Dptpx_nu : public Measurement2D { +//******************************************************************** - MCStudy_CCQEHistograms(std::string name, std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile); - virtual ~MCStudy_CCQEHistograms() {}; + public: - //! Grab info from event - void FillEventVariables(FitEvent *event); + // Constructor + MINERvA_CC0pi_XSec_2Dptpx_nu(nuiskey samplekey); - void ScaleEvents(); - void ResetAll(); + // Destructor + virtual ~MINERvA_CC0pi_XSec_2Dptpx_nu() { - //! Define this samples signal - bool isSignal(FitEvent *nvect); + // Remove all the content histograms * + // for (int i = 0; i < 9; i++) + // delete this->fMCHist_content[i]; - //! Write Files - void Write(std::string drawOpt); + // delete everything + /* delete difHist; */ + /* delete evtsignalHist; */ + /* delete fluxsignalHist; */ + /* delete fMapHist; */ + /* delete status; */ + /* delete PDGHistogram; */ + + /* // Delete MODE histograms */ + /* for (int i = 0; i < 60; i++) */ + /* delete fMCHist_PDG[i]; */ - 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 ; + return; + }; - TH1D* hist_Total; + // Required functions + bool isSignal(FitEvent *nvect); + void FillEventVariables(FitEvent *event); - TH2D* hist_TLepCosLep; - - double LocalRWWeight; - double LocalInputWeight; - + protected: + + // Cuts }; - + #endif 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/MINERvA/MINERvA_CCCOHPI_XSec_joint.cxx b/src/MINERvA/MINERvA_CCCOHPI_XSec_joint.cxx new file mode 100644 index 0000000..5eca830 --- /dev/null +++ b/src/MINERvA/MINERvA_CCCOHPI_XSec_joint.cxx @@ -0,0 +1,203 @@ +// 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_CCCOHPI_XSec_joint.h" +#include "MINERvA_CCCOHPI_XSec_1DEpi_nu.h" +#include "MINERvA_CCCOHPI_XSec_1DEpi_antinu.h" +#include "MINERvA_CCCOHPI_XSec_1Dth_nu.h" +#include "MINERvA_CCCOHPI_XSec_1Dth_antinu.h" +#include "MINERvA_CCCOHPI_XSec_1DEnu_nu.h" +#include "MINERvA_CCCOHPI_XSec_1DEnu_antinu.h" +#include "MINERvA_CCCOHPI_XSec_1DQ2_nu.h" +#include "MINERvA_CCCOHPI_XSec_1DQ2_antinu.h" + +//******************************************************************** +void MINERvA_CCCOHPI_XSec_joint::SetupDataSettings(){ +//******************************************************************** + + // Set Distribution + std::string name = fSettings.GetS("name"); + if (!name.compare("MINERvA_CCCOHPI_XSec_1DEpi_joint")) fDist = kEpi; + else if (!name.compare("MINERvA_CCCOHPI_XSec_1Dth_joint")) fDist = kth; + else if (!name.compare("MINERvA_CCCOHPI_XSec_1DQ2_joint")) fDist = kQ2; + else if (!name.compare("MINERvA_CCCOHPI_XSec_1DEnu_joint")) fDist = kEnu; + + // Define what files to use from the dist + std::string datafile = ""; + std::string covarfile = ""; + std::string titles = ""; + std::string distdescript = ""; + switch(fDist){ + + case (kEpi): + datafile = "Epi_joint_data.csv"; + covarfile = "Epi_joint_cov.csv"; + titles = "CC-Coherent #pi;E_{#pi} Bins;d#sigma/dE_{#pi} (cm^{2}/GeV/C12)"; + break; + + case (kth): + datafile = "Thpi_joint_data.csv"; + covarfile = "Thpi_joint_cov.csv"; + titles = "CC-Coherent #pi;#theta_{#pi} Bins;d#sigma/d#theta_{#pi} (cm^{2}/C12)"; + break; + + case (kQ2): + datafile = "Q2_joint_data.csv"; + covarfile = "Q2_joint_cov.csv"; + titles ="CC-Coherent #pi;Q^{2} Bins;d#sigma/dQ^{2} (cm^{2}/GeV^{2}/C12)"; + break; + + case (kEnu): + datafile = "Enu_joint_data.csv"; + covarfile = "Enu_joint_cov.csv"; + titles ="CC-Coherent #pi;E_{#nu} Bins;#sigma(E_{#nu}) (cm^{2}/C12"; + break; + + default: + THROW("Unknown Analysis Distribution : " << fDist); + } + + // Now setup each data distribution and description. + std::string descrip = distdescript + \ + "Target: CH \n" \ + "Flux: 2 Files, MINERvA FHC numu;MINERvA FHC numubar \n" \ + "Signal: Any event with 1 electron, any nucleons, and no other FS particles \n"; + + fSettings.SetDescription(descrip); + fSettings.SetDataInput( GeneralUtils::GetTopLevelDir()+"/data/MINERvA/CCcoh/" + datafile ); + fSettings.SetCovarInput( GeneralUtils::GetTopLevelDir()+"/data/MINERvA/CCcoh/" + covarfile ); + fSettings.SetTitle( GeneralUtils::ParseToStr(titles,";")[0] ); + fSettings.SetXTitle( GeneralUtils::ParseToStr(titles,";")[1] ); + fSettings.SetYTitle( GeneralUtils::ParseToStr(titles,";")[2] ); + + return; +} + +//******************************************************************** +MINERvA_CCCOHPI_XSec_joint::MINERvA_CCCOHPI_XSec_joint(nuiskey samplekey) { +//******************************************************************** + + // Define Sample Settings common to all data distributions + fSettings = LoadSampleSettings(samplekey); + fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/FULL"); + fSettings.SetEnuRange(0.0, 20.0); + fSettings.DefineAllowedTargets("C,H"); + fSettings.DefineAllowedSpecies("numu"); + SetupDataSettings(); + FinaliseSampleSettings(); + + // Scaling Setup --------------------------------------------------- + fScaleFactor = 0.0; + + // Plot Setup ------------------------------------------------------- + SetDataFromTextFile( fSettings.GetDataInput() ); + SetCovarFromMultipleTextFiles(fSettings.GetCovarInput()); + + // Setup Sub Measurements ------------------------------------------------------- + SetupSubMeasurements(); + + // Final setup --------------------------------------------------- + FinaliseMeasurement(); + +}; + +//******************************************************************** +void MINERvA_CCCOHPI_XSec_joint::SetupSubMeasurements(){ +//******************************************************************** + + // Get parsed input files + if (fSubInFiles.size() != 2) { + ERR(FTL) << "MINERvA Joint requires input files in format: nu;antinu" << std::endl; + } + std::string inFileNeutrino = fSubInFiles.at(0); + std::string inFileAntineutrino = fSubInFiles.at(1); + + // Create some config keys + nuiskey nukey = Config::CreateKey("sample"); + nukey.SetS("input", inFileNeutrino); + nukey.SetS("type", fSettings.GetS("type")); + + nuiskey antinukey = Config::CreateKey("sample"); + antinukey.SetS("input", inFileAntineutrino); + antinukey.SetS("type", fSettings.GetS("type")); + + // Create samples for given DIST + switch(fDist){ + + case kEpi: + nukey.SetS("name","MINERvA_CCCOHPI_XSec_1DEpi_nu"); + MIN_nu = new MINERvA_CCCOHPI_XSec_1DEpi_nu(nukey); + antinukey.SetS("name","MINERvA_CCCOHPI_XSec_1DEpi_antinu"); + MIN_anu = new MINERvA_CCCOHPI_XSec_1DEpi_antinu(antinukey); + break; + + case kth: + nukey.SetS("name","MINERvA_CCCOHPI_XSec_1Dth_nu"); + MIN_nu = new MINERvA_CCCOHPI_XSec_1Dth_nu(nukey); + antinukey.SetS("name","MINERvA_CCCOHPI_XSec_1Dth_antinu"); + MIN_anu = new MINERvA_CCCOHPI_XSec_1Dth_antinu(antinukey); + break; + + case kEnu: + nukey.SetS("name","MINERvA_CCCOHPI_XSec_1DEnu_nu"); + MIN_nu = new MINERvA_CCCOHPI_XSec_1DEnu_nu(nukey); + antinukey.SetS("name","MINERvA_CCCOHPI_XSec_1DEnu_antinu"); + MIN_anu = new MINERvA_CCCOHPI_XSec_1DEnu_antinu(antinukey); + break; + + case kQ2: + nukey.SetS("name","MINERvA_CCCOHPI_XSec_1DQ2_nu"); + MIN_nu = new MINERvA_CCCOHPI_XSec_1DQ2_nu(nukey); + antinukey.SetS("name","MINERvA_CCCOHPI_XSec_1DQ2_antinu"); + MIN_anu = new MINERvA_CCCOHPI_XSec_1DQ2_antinu(antinukey); + break; + } + + // Add to chain for processing + fSubChain.clear(); + fSubChain.push_back(MIN_anu); + fSubChain.push_back(MIN_nu); +} + +//******************************************************************** +void MINERvA_CCCOHPI_XSec_joint::MakePlots() { +//******************************************************************** + + TH1D* MIN_nu_mc = (TH1D*) MIN_nu->GetMCHistogram(); + TH1D* MIN_anu_mc = (TH1D*) MIN_anu->GetMCHistogram(); + int count = 0; + for (int i = 0; i < MIN_nu_mc->GetNbinsX(); i++){ + fMCHist->SetBinContent( count+1, MIN_nu_mc->GetBinContent(i+1) ); + fMCHist->SetBinError( count+1, MIN_nu_mc->GetBinError(i+1) ); + fMCHist->GetXaxis()->SetBinLabel(count+1, GeneralUtils::IntToStr(count+1).c_str()); + count++; + } + for (int i = 0; i < MIN_anu_mc->GetNbinsX(); i++){ + fMCHist->SetBinContent(count+1, MIN_anu_mc->GetBinContent(i+1) ); + fMCHist->SetBinError(count+1, MIN_anu_mc->GetBinError(i+1) ); + fMCHist->GetXaxis()->SetBinLabel(count+1, GeneralUtils::IntToStr(count+1).c_str()); + count++; + } + + return; +} + + + diff --git a/src/MINERvA/MINERvA_CCCOHPI_XSec_joint.h b/src/MINERvA/MINERvA_CCCOHPI_XSec_joint.h new file mode 100644 index 0000000..e64205b --- /dev/null +++ b/src/MINERvA/MINERvA_CCCOHPI_XSec_joint.h @@ -0,0 +1,61 @@ +// 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_CCCOHPI_XSec_joint_H_SEEN +#define MINERVA_CCCOHPI_XSec_joint_H_SEEN + +// Fit Includes +#include "MeasurementBase.h" +#include "JointMeas1D.h" +#include "Measurement1D.h" +#include "MINERvA_CCCOHPI_XSec_1DEpi_nu.h" +#include "MINERvA_CCCOHPI_XSec_1DEpi_antinu.h" +#include "MINERvA_CCCOHPI_XSec_1Dth_nu.h" +#include "MINERvA_CCCOHPI_XSec_1Dth_antinu.h" +#include "MINERvA_CCCOHPI_XSec_1DEnu_nu.h" +#include "MINERvA_CCCOHPI_XSec_1DEnu_antinu.h" +#include "MINERvA_CCCOHPI_XSec_1DQ2_nu.h" +#include "MINERvA_CCCOHPI_XSec_1DQ2_antinu.h" + +class MINERvA_CCCOHPI_XSec_joint : public JointMeas1D { +public: + + MINERvA_CCCOHPI_XSec_joint(nuiskey samplekey); + virtual ~MINERvA_CCCOHPI_XSec_joint() {}; + void MakePlots(); + void SetupDataSettings(); + void SetupSubMeasurements(); + + enum DataDistribution { + kEpi, + kth, + kQ2, + kEnu + } CCCOH_DataDistributions; + + private: + + // This is a dummy, the signal is defined separately for each sample! + bool isSignal(){return false;}; + Measurement1D* MIN_nu; + Measurement1D* MIN_anu; + int fDist; +}; + +#endif diff --git a/src/MINERvA/MINERvA_CCinc_XSec_2DEavq3_nu.cxx b/src/MINERvA/MINERvA_CCinc_XSec_2DEavq3_nu.cxx index 02710ca..fde3809 100755 --- a/src/MINERvA/MINERvA_CCinc_XSec_2DEavq3_nu.cxx +++ b/src/MINERvA/MINERvA_CCinc_XSec_2DEavq3_nu.cxx @@ -1,153 +1,153 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MINERvA_SignalDef.h" #include "MINERvA_CCinc_XSec_2DEavq3_nu.h" //******************************************************************** MINERvA_CCinc_XSec_2DEavq3_nu::MINERvA_CCinc_XSec_2DEavq3_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MINERvA_CCinc_XSec_2DEavq3_nu sample. \n" \ "Target: CH \n" \ "Flux: MINERvA Medium Energy FHC numu \n" \ "Signal: CC-inclusive with theta < 20deg \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("q_{3} (GeV)"); fSettings.SetYTitle("E_{avail} (GeV)"); fSettings.SetZTitle("d^{2}#sigma/dq_{3}dE_{avail} (cm^{2}/GeV^{2})"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/MASK", "FIX/FULL"); fSettings.SetEnuRange(2.0, 6.0); fSettings.DefineAllowedTargets("C,H"); // CCQELike plot information fSettings.SetTitle("MINERvA_CCinc_XSec_2DEavq3_nu"); fSettings.SetDataInput( FitPar::GetDataBase() + "/MINERvA/CCEavq3/data_2D.txt" ); fSettings.SetCovarInput( FitPar::GetDataBase() + "/MINERvA/CCEavq3/covar_2D.txt" ); fSettings.SetMapInput( FitPar::GetDataBase() + "/MINERvA/CCEavq3/map_2D.txt" ); fSettings.DefineAllowedSpecies("numu"); hadroncut = FitPar::Config().GetParB("MINERvA_CCinc_XSec_2DEavq3_nu.hadron_cut"); useq3true = FitPar::Config().GetParB("MINERvA_CCinc_XSec_2DEavq3_nu.useq3true"); splitMEC_PN_NN = FitPar::Config().GetParB("Modes.split_PN_NN"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-42 / (fNEvents + 0.)) / this->TotalIntegratedFlux(); // Plot Setup ------------------------------------------------------- Double_t binx[7] = {0.0, 0.2, 0.3, 0.4, 0.5, 0.6, 0.8}; Double_t biny[17] = {0.0, 0.02, 0.04, 0.06, 0.08, 0.10, 0.12, 0.14, 0.16, 0.20, 0.25, 0.30, 0.35, 0.40, 0.50, 0.60, 0.80}; CreateDataHistogram(7, binx, 17, biny); SetDataValuesFromTextFile( fSettings.GetDataInput() ); ScaleData(1E-42); SetMapValuesFromText( fSettings.GetMapInput() ); - SetCholDecompFromTextFile( fSettings.GetCovarInput() ); + SetCholDecompFromTextFile( fSettings.GetCovarInput(), 67); ScaleCovar(1E-16); StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, fMapHist, 1E-38); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; //******************************************************************** void MINERvA_CCinc_XSec_2DEavq3_nu::FillEventVariables(FitEvent *event) { //******************************************************************** // Seperate MEC if (splitMEC_PN_NN) { int npr = 0; int nne = 0; for (UInt_t j = 0; j < event->Npart(); j++) { if ((event->PartInfo(j))->fIsAlive) continue; if (event->PartInfo(j)->fPID == 2212) npr++; else if (event->PartInfo(j)->fPID == 2112) nne++; } if (event->Mode == 2 and npr == 1 and nne == 1) { event->Mode = 2; Mode = 2; } else if (event->Mode == 2 and npr == 0 and nne == 2) { event->Mode = 3; Mode = 3; } } // Set Defaults double Eav = -999.9; double q3 = -999.9; // If muon found get kinematics FitParticle* muon = event->GetHMFSParticle(13); FitParticle* neutrino = event->GetNeutrinoIn(); if (muon && neutrino) { // Set Q from Muon TLorentzVector q = neutrino->fP - muon->fP; double q0 = (q.E()) / 1.E3; //double q3_true = (q.Vect().Mag())/1.E3; double thmu = muon->fP.Vect().Angle(neutrino->fP.Vect()); double pmu = muon->fP.Vect().Mag() / 1.E3; double emu = muon->fP.E() / 1.E3; double mmu = muon->fP.Mag() / 1.E3; // Get Enu Rec double enu_rec = emu + q0; // Set Q2 QE double q2qe = 2 * enu_rec * (emu - pmu * cos(thmu)) - mmu * mmu; // Calc Q3 from Q2QE and EnuTree q3 = sqrt(q2qe + q0 * q0); // Get Eav too Eav = FitUtils::GetErecoil_MINERvA_LowRecoil(event) / 1.E3; } // Set Hist Variables fXVar = q3; fYVar = Eav; return; } //******************************************************************** bool MINERvA_CCinc_XSec_2DEavq3_nu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCCincLowRecoil_MINERvA(event, EnuMin, EnuMax); } diff --git a/src/MINERvA/MINERvA_SignalDef.cxx b/src/MINERvA/MINERvA_SignalDef.cxx index 8c2be8c..bdc368c 100644 --- a/src/MINERvA/MINERvA_SignalDef.cxx +++ b/src/MINERvA/MINERvA_SignalDef.cxx @@ -1,305 +1,390 @@ // 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 "SignalDef.h" #include "FitUtils.h" #include "MINERvA_SignalDef.h" namespace SignalDef { -// ********************************* -// MINERvA CC1pi+/- signal definition (2015 release) -// Note: There is a 2016 release which is different to this (listed below), but -// it is CCNpi+ and has a different W cut -// Note2: The W cut is implemented in the class implementation in MINERvA/ -// rather than here so we can draw events that don't pass the W cut (W cut is -// 1.4 GeV) -// Could possibly be changed for slight speed increase since less events -// would be used -// -// MINERvA signal is slightly different to MiniBooNE -// -// Exactly one negative muon -// Exactly one charged pion (both + and -); however, there is a Michel e- -// requirement but UNCLEAR IF UNFOLDED OR NOT (so don't know if should be -// applied) -// Exactly 1 charged pion exits (so + and - charge), however, has Michel -// electron requirement, so look for + only here? -// No restriction on neutral pions or other mesons -// MINERvA has unfolded and not unfolded muon phase space for 2015 -// -// Possible issues with the data: -// 1) pi- is allowed in signal even when Michel cut included; most pi- is efficiency corrected in GENIE -// 2) There is a T_pi < 350 MeV cut coming from requiring a stopping pion; this is efficiency corrected in GENIE -// 3) There is a 1.5 < Enu < 10.0 cut in signal definition -// 4) There is an angular muon cut which is sometimes efficiency corrected (why we have bool isRestricted below) -// -// Nice things: -// Much data given: with and without muon angle cuts and with and without shape -// only data + covariance -// -bool isCC1pip_MINERvA(FitEvent *event, double EnuMin, double EnuMax, - bool isRestricted) { // ********************************* + // MINERvA CC1pi+/- signal definition (2015 release) + // Note: There is a 2016 release which is different to this (listed below), but + // it is CCNpi+ and has a different W cut + // Note2: The W cut is implemented in the class implementation in MINERvA/ + // rather than here so we can draw events that don't pass the W cut (W cut is + // 1.4 GeV) + // Could possibly be changed for slight speed increase since less events + // would be used + // + // MINERvA signal is slightly different to MiniBooNE + // + // Exactly one negative muon + // Exactly one charged pion (both + and -); however, there is a Michel e- + // requirement but UNCLEAR IF UNFOLDED OR NOT (so don't know if should be + // applied) + // Exactly 1 charged pion exits (so + and - charge), however, has Michel + // electron requirement, so look for + only here? + // No restriction on neutral pions or other mesons + // MINERvA has unfolded and not unfolded muon phase space for 2015 + // + // Possible issues with the data: + // 1) pi- is allowed in signal even when Michel cut included; most pi- is efficiency corrected in GENIE + // 2) There is a T_pi < 350 MeV cut coming from requiring a stopping pion; this is efficiency corrected in GENIE + // 3) There is a 1.5 < Enu < 10.0 cut in signal definition + // 4) There is an angular muon cut which is sometimes efficiency corrected (why we have bool isRestricted below) + // + // Nice things: + // Much data given: with and without muon angle cuts and with and without shape + // only data + covariance + // + bool isCC1pip_MINERvA(FitEvent *event, double EnuMin, double EnuMax, + bool isRestricted) { + // ********************************* + + // Signal is both pi+ and pi- + // WARNING: PI- CONTAMINATION IS FULLY GENIE BECAUSE THE MICHEL TAG + // First, make sure it's CCINC + if (!isCCINC(event, 14, EnuMin, EnuMax)) return false; + + // Allow pi+/pi- + int piPDG[] = {211, -211}; + int nLeptons = event->NumFSLeptons(); + int nPion = event->NumFSParticle(piPDG); + + // Check that the desired pion exists and is the only meson + if (nPion != 1) return false; + + // Check that there is only one final state lepton + if (nLeptons != 1) return false; + + // MINERvA released another CC1pi+ xsec without muon unfolding! + // here the muon angle is < 20 degrees (seen in MINOS) + TLorentzVector pnu = event->GetHMISParticle(14)->fP; + TLorentzVector pmu = event->GetHMFSParticle(13)->fP; + + if (isRestricted) { + double th_nu_mu = FitUtils::th(pmu, pnu) * 180. / M_PI; + if (th_nu_mu >= 20) return false; + } - // Signal is both pi+ and pi- - // WARNING: PI- CONTAMINATION IS FULLY GENIE BECAUSE THE MICHEL TAG - // First, make sure it's CCINC - if (!isCCINC(event, 14, EnuMin, EnuMax)) return false; - - // Allow pi+/pi- - int piPDG[] = {211, -211}; - int nLeptons = event->NumFSLeptons(); - int nPion = event->NumFSParticle(piPDG); - - // Check that the desired pion exists and is the only meson - if (nPion != 1) return false; - - // Check that there is only one final state lepton - if (nLeptons != 1) return false; - - // MINERvA released another CC1pi+ xsec without muon unfolding! - // here the muon angle is < 20 degrees (seen in MINOS) - TLorentzVector pnu = event->GetHMISParticle(14)->fP; - TLorentzVector pmu = event->GetHMFSParticle(13)->fP; - - if (isRestricted) { - double th_nu_mu = FitUtils::th(pmu, pnu) * 180. / M_PI; - if (th_nu_mu >= 20) return false; - } - - // Extract Hadronic Mass - double hadMass = FitUtils::Wrec(pnu, pmu); + // Extract Hadronic Mass + double hadMass = FitUtils::Wrec(pnu, pmu); - // Actual cut is True GENIE Ws! Arg.! Use gNtpcConv definition. + // Actual cut is True GENIE Ws! Arg.! Use gNtpcConv definition. #ifdef __GENIE_ENABLED__ - if (event->fType == kGENIE){ - EventRecord * gevent = static_cast(event->genie_event->event); - const Interaction * interaction = gevent->Summary(); - const Kinematics & kine = interaction->Kine(); - double Ws = kine.W (true); - // std::cout << "Ws versus WRec = " << Ws << " vs " << hadMass << " " << kine.W(false) << std::endl; - hadMass = Ws * 1000.0; - } + if (event->fType == kGENIE){ + EventRecord * gevent = static_cast(event->genie_event->event); + const Interaction * interaction = gevent->Summary(); + const Kinematics & kine = interaction->Kine(); + double Ws = kine.W (true); + // std::cout << "Ws versus WRec = " << Ws << " vs " << hadMass << " " << kine.W(false) << std::endl; + hadMass = Ws * 1000.0; + } #endif - if (hadMass > 1400.0) return false; + if (hadMass > 1400.0) return false; - return true; -}; + return true; + }; // Updated MINERvA 2017 Signal using Wexp and no restriction on angle -bool isCC1pip_MINERvA_2017(FitEvent *event, double EnuMin, double EnuMax){ - - // Signal is both pi+ and pi- - // WARNING: PI- CONTAMINATION IS FULLY GENIE BECAUSE THE MICHEL TAG - // First, make sure it's CCINC - if (!isCCINC(event, 14, EnuMin, EnuMax)) return false; - - // Allow pi+/pi- - int piPDG[] = {211, -211}; - int nLeptons = event->NumFSLeptons(); - int nPion = event->NumFSParticle(piPDG); - - // Check that the desired pion exists and is the only meson - if (nPion != 1) return false; - - // Check that there is only one final state lepton - if (nLeptons != 1) return false; - - // Get Muon and Lepton Kinematics - TLorentzVector pnu = event->GetHMISParticle(14)->fP; - TLorentzVector pmu = event->GetHMFSParticle(13)->fP; - - // Extract Hadronic Mass - double hadMass = FitUtils::Wrec(pnu, pmu); - if (hadMass > 1400.0) return false; - - return true; -}; - -// ********************************* -// MINERvA CCNpi+/- signal definition from 2016 publication -// Different to CC1pi+/- listed above; additional has W < 1.8 GeV -// -// For notes on strangeness of signal definition, see CC1pip_MINERvA -// -// One negative muon -// At least one charged pion -// 1.5 < Enu < 10 -// No restrictions on pi0 or other mesons or baryons -// W_reconstructed (ignoring initial state motion) cut at 1.8 GeV -// -// Also writes number of pions (nPions) if studies on this want to be done... -bool isCCNpip_MINERvA(FitEvent *event, double EnuMin, - double EnuMax, bool isRestricted, bool isWtrue) { - // ********************************* + bool isCC1pip_MINERvA_2017(FitEvent *event, double EnuMin, double EnuMax){ - // First, make sure it's CCINC - if (!isCCINC(event, 14, EnuMin, EnuMax)) return false; + // Signal is both pi+ and pi- + // WARNING: PI- CONTAMINATION IS FULLY GENIE BECAUSE THE MICHEL TAG + // First, make sure it's CCINC + if (!isCCINC(event, 14, EnuMin, EnuMax)) return false; - int nLeptons = event->NumFSLeptons(); + // Allow pi+/pi- + int piPDG[] = {211, -211}; + int nLeptons = event->NumFSLeptons(); + int nPion = event->NumFSParticle(piPDG); - // Write the number of pions to the measurement class... - // Maybe better to just do that inside the class? - int nPions = event->NumFSParticle(PhysConst::pdg_charged_pions); + // Check that the desired pion exists and is the only meson + if (nPion != 1) return false; - // Check that there is a pion! - if (nPions == 0) return false; + // Check that there is only one final state lepton + if (nLeptons != 1) return false; - // Check that there is only one final state lepton - if (nLeptons != 1) return false; + // Get Muon and Lepton Kinematics + TLorentzVector pnu = event->GetHMISParticle(14)->fP; + TLorentzVector pmu = event->GetHMFSParticle(13)->fP; - // Need the muon and the neutrino to check angles and W + // Extract Hadronic Mass + double hadMass = FitUtils::Wrec(pnu, pmu); + if (hadMass > 1400.0) return false; - TLorentzVector pnu = event->GetNeutrinoIn()->fP; - TLorentzVector pmu = event->GetHMFSParticle(13)->fP; - // MINERvA released some data with restricted muon angle - // Here the muon angle is < 20 degrees (seen in MINOS) - if (isRestricted) { + return true; + }; - double th_nu_mu = FitUtils::th(pmu, pnu) * 180. / M_PI; - if (th_nu_mu >= 20.) return false; - } + // ********************************* + // MINERvA CCNpi+/- signal definition from 2016 publication + // Different to CC1pi+/- listed above; additional has W < 1.8 GeV + // + // For notes on strangeness of signal definition, see CC1pip_MINERvA + // + // One negative muon + // At least one charged pion + // 1.5 < Enu < 10 + // No restrictions on pi0 or other mesons or baryons + // W_reconstructed (ignoring initial state motion) cut at 1.8 GeV + // + // Also writes number of pions (nPions) if studies on this want to be done... + bool isCCNpip_MINERvA(FitEvent *event, double EnuMin, + double EnuMax, bool isRestricted, bool isWtrue) { + // ********************************* + + // First, make sure it's CCINC + if (!isCCINC(event, 14, EnuMin, EnuMax)) return false; + + int nLeptons = event->NumFSLeptons(); + + // Write the number of pions to the measurement class... + // Maybe better to just do that inside the class? + int nPions = event->NumFSParticle(PhysConst::pdg_charged_pions); + + // Check that there is a pion! + if (nPions == 0) return false; + + // Check that there is only one final state lepton + if (nLeptons != 1) return false; + + // Need the muon and the neutrino to check angles and W + + TLorentzVector pnu = event->GetNeutrinoIn()->fP; + TLorentzVector pmu = event->GetHMFSParticle(13)->fP; + // MINERvA released some data with restricted muon angle + // Here the muon angle is < 20 degrees (seen in MINOS) + if (isRestricted) { + + double th_nu_mu = FitUtils::th(pmu, pnu) * 180. / M_PI; + if (th_nu_mu >= 20.) return false; + } - // Lastly check the W cut (always at 1.8 GeV) - double Wrec = FitUtils::Wrec(pnu, pmu) + 0.; + // Lastly check the W cut (always at 1.8 GeV) + double Wrec = FitUtils::Wrec(pnu, pmu) + 0.; - // Actual cut is True GENIE Ws! Arg.! Use gNtpcConv definition. - if (isWtrue){ + // Actual cut is True GENIE Ws! Arg.! Use gNtpcConv definition. + if (isWtrue){ #ifdef __GENIE_ENABLED__ - if (event->fType == kGENIE){ - GHepRecord* ghep = static_cast(event->genie_event->event); - const Interaction * interaction = ghep->Summary(); - const Kinematics & kine = interaction->Kine(); - double Ws = kine.W (true); - Wrec = Ws * 1000.0; // Say Wrec is Ws - } + if (event->fType == kGENIE){ + GHepRecord* ghep = static_cast(event->genie_event->event); + const Interaction * interaction = ghep->Summary(); + const Kinematics & kine = interaction->Kine(); + double Ws = kine.W (true); + Wrec = Ws * 1000.0; // Say Wrec is Ws + } #endif - } + } - if (Wrec > 1800. || Wrec < 0.0) return false; + if (Wrec > 1800. || Wrec < 0.0) return false; - return true; -}; + return true; + }; -//******************************************************************** -bool isCCQEnumu_MINERvA(FitEvent *event, double EnuMin, double EnuMax, - bool fullphasespace) { //******************************************************************** + bool isCCQEnumu_MINERvA(FitEvent *event, double EnuMin, double EnuMax, + bool fullphasespace) { + //******************************************************************** - if (!isCCQELike(event, 14, EnuMin, EnuMax)) return false; + if (!isCCQELike(event, 14, EnuMin, EnuMax)) return false; - TLorentzVector pnu = event->GetHMISParticle(14)->fP; - TLorentzVector pmu = event->GetHMFSParticle(13)->fP; + TLorentzVector pnu = event->GetHMISParticle(14)->fP; + TLorentzVector pmu = event->GetHMFSParticle(13)->fP; - double ThetaMu = pnu.Vect().Angle(pmu.Vect()); - double Enu_rec = FitUtils::EnuQErec(pmu, cos(ThetaMu), 34., true); + double ThetaMu = pnu.Vect().Angle(pmu.Vect()); + double Enu_rec = FitUtils::EnuQErec(pmu, cos(ThetaMu), 34., true); - // If Restricted phase space - if (!fullphasespace && ThetaMu > 0.34906585) return false; + // If Restricted phase space + if (!fullphasespace && ThetaMu > 0.34906585) return false; - // restrict energy range - if (Enu_rec < EnuMin || Enu_rec > EnuMax) return false; + // restrict energy range + if (Enu_rec < EnuMin || Enu_rec > EnuMax) return false; - return true; -}; + return true; + }; -//******************************************************************** -bool isCCQEnumubar_MINERvA(FitEvent *event, double EnuMin, double EnuMax, - bool fullphasespace) { //******************************************************************** + bool isCCQEnumubar_MINERvA(FitEvent *event, double EnuMin, double EnuMax, + bool fullphasespace) { + //******************************************************************** - if (!isCCQELike(event, -14, EnuMin, EnuMax)) return false; + if (!isCCQELike(event, -14, EnuMin, EnuMax)) return false; - TLorentzVector pnu = event->GetHMISParticle(-14)->fP; - TLorentzVector pmu = event->GetHMFSParticle(-13)->fP; + TLorentzVector pnu = event->GetHMISParticle(-14)->fP; + TLorentzVector pmu = event->GetHMFSParticle(-13)->fP; - double ThetaMu = pnu.Vect().Angle(pmu.Vect()); - double Enu_rec = FitUtils::EnuQErec(pmu, cos(ThetaMu), 30., true); + double ThetaMu = pnu.Vect().Angle(pmu.Vect()); + double Enu_rec = FitUtils::EnuQErec(pmu, cos(ThetaMu), 30., true); - // If Restricted phase space - if (!fullphasespace && ThetaMu > 0.34906585) return false; + // If Restricted phase space + if (!fullphasespace && ThetaMu > 0.34906585) return false; - // restrict energy range - if (Enu_rec < EnuMin || Enu_rec > EnuMax) return false; + // restrict energy range + if (Enu_rec < EnuMin || Enu_rec > EnuMax) return false; - return true; -} + return true; + } -//******************************************************************** -bool isCCincLowRecoil_MINERvA(FitEvent *event, double EnuMin, double EnuMax) { //******************************************************************** + bool isCCincLowRecoil_MINERvA(FitEvent *event, double EnuMin, double EnuMax) { + //******************************************************************** - if (!isCCINC(event, 14, EnuMin, EnuMax)) return false; + if (!isCCINC(event, 14, EnuMin, EnuMax)) return false; - // Need at least one muon - if (event->NumFSParticle(13) < 1) return false; - TLorentzVector pmu = event->GetHMFSParticle(13)->fP; - TLorentzVector pnu = event->GetHMISParticle(14)->fP; + // Need at least one muon + if (event->NumFSParticle(13) < 1) return false; + TLorentzVector pmu = event->GetHMFSParticle(13)->fP; + TLorentzVector pnu = event->GetHMISParticle(14)->fP; - // Cut on muon angle greated than 20deg - if (cos(pnu.Vect().Angle(pmu.Vect())) < 0.93969262078) return false; + // Cut on muon angle greated than 20deg + if (cos(pnu.Vect().Angle(pmu.Vect())) < 0.93969262078) return false; - // Cut on muon energy < 1.5 GeV - if (pmu.E()/1000.0 < 1.5) return false; + // Cut on muon energy < 1.5 GeV + if (pmu.E()/1000.0 < 1.5) return false; - return true; -} + return true; + } -bool isCC0pi1p_MINERvA(FitEvent *event, double enumin, double enumax) { - // Require numu CC0pi event with a proton above threshold - bool signal = (isCC0pi(event, 14, enumin, enumax) && - HasProtonKEAboveThreshold(event, 110.0)); + bool isCC0pi1p_MINERvA(FitEvent *event, double enumin, double enumax) { + // Require numu CC0pi event with a proton above threshold + bool signal = (isCC0pi(event, 14, enumin, enumax) && + HasProtonKEAboveThreshold(event, 110.0)); - return signal; -} + return signal; + } -// 2015 analysis just asks for 1pi0 and no pi+/pi- -bool isCC1pi0_MINERvA_2015(FitEvent *event, double EnuMin, double EnuMax) { - bool CC1pi0_anu = SignalDef::isCC1pi(event, -14, 111, EnuMin, EnuMax); - return CC1pi0_anu; -} + // 2015 analysis just asks for 1pi0 and no pi+/pi- + bool isCC1pi0_MINERvA_2015(FitEvent *event, double EnuMin, double EnuMax) { + bool CC1pi0_anu = SignalDef::isCC1pi(event, -14, 111, EnuMin, EnuMax); + return CC1pi0_anu; + } + + // 2016 analysis just asks for 1pi0 and no other charged tracks. Half-open to interpretation: we go with "charged tracks" meaning pions. You'll be forgiven for thinking proton tracks should be included here too but we checked with MINERvA + bool isCC1pi0_MINERvA_2016(FitEvent *event, double EnuMin, double EnuMax) { + bool CC1pi0_anu = SignalDef::isCC1pi(event, -14, 111, EnuMin, EnuMax); -// 2016 analysis just asks for 1pi0 and no other charged tracks -bool isCC1pi0_MINERvA_2016(FitEvent *event, double EnuMin, double EnuMax) { - bool CC1pi0_anu = SignalDef::isCC1pi(event, -14, 111, EnuMin, EnuMax); - - /* - // Additionally look for charged proton track - bool HasProton = event->HasFSParticle(2212); + /* + // Additionally look for charged proton track + bool HasProton = event->HasFSParticle(2212); - - if (CC1pi0_anu) { + if (CC1pi0_anu) { if (!HasProton) { - return true; + return true; } else { - return false; + return false; } - } else { + } else { return false; + } + */ + + return CC1pi0_anu; } - */ - return CC1pi0_anu; -} + // 2016 analysis just asks for 1pi0 and no other charged tracks + bool isCC1pi0_MINERvA_nu(FitEvent *event, double EnuMin, double EnuMax) { + bool CC1pi0_nu = SignalDef::isCC1pi(event, 14, 111, EnuMin, EnuMax); + return CC1pi0_nu; + } + + //******************************************************************** + bool isCC0pi_MINERvAPTPZ(FitEvent* event, int nuPDG, double emin, double emax){ + //******************************************************************** + // Check it's CCINC + if (!SignalDef::isCCINC(event, nuPDG, emin, emax)) return false; + + // Make Angle Cut > 20.0 + TLorentzVector pnu = event->GetHMISParticle(14)->fP; + TLorentzVector pmu = event->GetHMFSParticle(13)->fP; + double th_nu_mu = FitUtils::th(pmu, pnu) * 180. / M_PI; + if (th_nu_mu >= 20.0) return false; + + int genie_n_muons = 0; + int genie_n_mesons = 0; + int genie_n_heavy_baryons_plus_pi0s = 0; + int genie_n_photons = 0; + + for(int i = 0; i < event->NParticles(); ++i) { + FitParticle* p = event->GetParticle(i); + if (p->Status() != kFinalState) continue; + + int pdg = p->fPID; + double energy = p->fP.E(); + + if( abs(pdg) == 13 ) + genie_n_muons++; + else if( pdg == 22 && energy > 10.0 ) + genie_n_photons++; + else if( abs(pdg) == 211 || abs(pdg) == 321 || abs(pdg) == 323 || pdg == 111 || pdg == 130 || pdg == 310 || pdg == 311 || pdg == 313 ) + genie_n_mesons++; + else if( pdg == 3112 || pdg == 3122 || pdg == 3212 || pdg == 3222 || pdg == 4112 || + pdg == 4122 || pdg == 4212 || pdg == 4222 || pdg == 411 || pdg == 421 || pdg == 111 ) + genie_n_heavy_baryons_plus_pi0s++; + } + + if( genie_n_muons == 1 && + genie_n_mesons == 0 && + genie_n_heavy_baryons_plus_pi0s == 0 && + genie_n_photons == 0 ) return true; + return false; + } + + bool isCC0pi_anti_MINERvAPTPZ(FitEvent* event, int nuPDG, double emin, double emax){ + + // Check it's CCINC + if (!SignalDef::isCCINC(event, nuPDG, emin, emax)) return false; + // Make Angle Cut > 20.0 + TLorentzVector pnu = event->GetHMISParticle(-14)->fP; + TLorentzVector pmu = event->GetHMFSParticle(-13)->fP; + double th_nu_mu = FitUtils::th(pmu, pnu) * 180. / M_PI; + if (th_nu_mu >= 20.0) return false; + int genie_n_muons = 0; + int genie_n_mesons = 0; + int genie_n_heavy_baryons_plus_pi0s = 0; + int genie_n_photons = 0; + + for(int i = 0; i < event->NParticles(); ++i) { + FitParticle* p = event->GetParticle(i); + if (p->Status() != kFinalState) continue; + + int pdg = p->fPID; + double energy = p->fP.E(); + + if( abs(pdg) == 13 ) + genie_n_muons++; + else if( pdg == 22 && energy > 10.0 ) + genie_n_photons++; + else if( abs(pdg) == 211 || abs(pdg) == 321 || abs(pdg) == 323 || abs(pdg) == 111 || abs(pdg) == 130 || abs(pdg) == 310 || abs(pdg) == 311 || abs(pdg) == 313 ) + genie_n_mesons++; + else if( abs(pdg) == 3112 || abs(pdg) == 3122 || abs(pdg) == 3212 || abs(pdg) == 3222 || abs(pdg) == 4112 || + abs(pdg) == 4122 || abs(pdg) == 4212 || abs(pdg) == 4222 || abs(pdg) == 411 || abs(pdg) == 421 || + abs(pdg) == 111 ) + genie_n_heavy_baryons_plus_pi0s++; + } + + if( genie_n_muons == 1 && genie_n_mesons == 0 && genie_n_heavy_baryons_plus_pi0s == 0 && genie_n_photons == 0 ) + return true; + return false; + } } diff --git a/src/MINERvA/MINERvA_SignalDef.h b/src/MINERvA/MINERvA_SignalDef.h index 2b1f03e..65ad493 100644 --- a/src/MINERvA/MINERvA_SignalDef.h +++ b/src/MINERvA/MINERvA_SignalDef.h @@ -1,94 +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 MINERVA_SIGNALDEF_H_SEEN #define MINERVA_SIGNALDEF_H_SEEN #include "FitEvent.h" namespace SignalDef { // ********************************* /// MINERvA CC1pi+/- signal definition (2015 release) /// Note: There is a 2016 release which is different to this (listed below), /// but /// it is CCNpi+ and has a different W cut /// Note2: The W cut is implemented in the class implementation in MINERvA/ /// rather than here so we can draw events that don't pass the W cut (W cut is /// 1.4 GeV) /// Could possibly be changed for slight speed increase since less events /// would be used /// /// MINERvA signal is slightly different to MiniBooNE /// /// Exactly one negative muon /// Exactly one charged pion (both + and -); however, there is a Michel e- /// requirement but UNCLEAR IF UNFOLDED OR NOT (so don't know if should be /// applied) /// Exactly 1 charged pion exits (so + and - charge), however, has Michel /// electron requirement, so look for + only here? /// No restriction on neutral pions or other mesons /// MINERvA has unfolded and not unfolded muon phase space for 2015 /// /// Possible problems: /// 1) Should there be a pi+ only cut implemented due to Michel requirement, or /// is pi- events filled from MC? /// 2) There is a T_pi < 350 MeV cut coming from requiring a stopping pion so /// the /// Michel e is seen, this is also unclear if it's unfolded so any pion is OK /// /// Nice things: /// Much data given: with and without muon angle cuts and with and without shape /// only data + covariance bool isCC1pip_MINERvA(FitEvent *event, double EnuMin, double EnuMax, bool isRestricted = false); bool isCC1pip_MINERvA_2017(FitEvent *event, double EnuMin, double EnuMax); // ********************************* /// MINERvA CCNpi+/- signal definition from 2016 publication /// Different to CC1pi+/- listed above; additional has W < 1.8 GeV /// /// Still asks for a Michel e and still unclear if this is unfolded or not /// Says stuff like "requirement that a Michel e isolates a subsample that is /// more nearly a pi+ prodution", yet the signal definition is both pi+ and pi-? /// /// One negative muon /// At least one charged pion /// 1.5 < Enu < 10 /// No restrictions on pi0 or other mesons or baryons /// /// Also writes number of pions (nPions) if studies on this want to be done... bool isCCNpip_MINERvA(FitEvent *event, double EnuMin, double EnuMax, bool isRestricted = false, bool isWtrue=false); bool isCCQEnumu_MINERvA(FitEvent *event, double EnuMin, double EnuMax, bool fullphasespace = true); bool isCCQEnumubar_MINERvA(FitEvent *event, double EnuMin, double EnuMax, bool fullphasespace = true); bool isCCincLowRecoil_MINERvA(FitEvent *event, double EnuMin, double EnuMax); bool isCC0pi1p_MINERvA(FitEvent *event, double enumin, double enumax); bool isCC1pi0_MINERvA_2015(FitEvent *event, double EnuMin, double EnuMax); bool isCC1pi0_MINERvA_2016(FitEvent *event, double EnuMin, double EnuMax); +bool isCC1pi0_MINERvA_nu(FitEvent *event, double EnuMin, double EnuMax); + + + bool isCC0pi_MINERvAPTPZ(FitEvent *event, int nuPDG, double EnuMin = 0, double EnuMax = 0); + bool isCC0pi_anti_MINERvAPTPZ(FitEvent* event, int nuPDG, double EnuMin = 0, double EnuMax = 0); } #endif diff --git a/src/MiniBooNE/MiniBooNE_CCQE_XSec_1DQ2_antinu.cxx b/src/MiniBooNE/MiniBooNE_CCQE_XSec_1DQ2_antinu.cxx index 8483e70..3ee0d65 100644 --- a/src/MiniBooNE/MiniBooNE_CCQE_XSec_1DQ2_antinu.cxx +++ b/src/MiniBooNE/MiniBooNE_CCQE_XSec_1DQ2_antinu.cxx @@ -1,196 +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 . *******************************************************************************/ #include "MiniBooNE_CCQE_XSec_1DQ2_antinu.h" #include MiniBooNE_CCQE_XSec_1DQ2_antinu::MiniBooNE_CCQE_XSec_1DQ2_antinu(nuiskey samplekey) { // Sample overview std::string descrip = "MiniBooNE CCQE/CC0pi sample. \n" \ "Target: CH2.08 \n" \ "Flux: CCQE = Forward Horn Current numu \n" \ " CC0pi = Forward Horn Current numu+numub \n" \ "Signal: CCQE = True CCQE + True 2p2h (Mode == 1 or 2) \n" \ " CC0pi = Events with 1 mu+/mu-, N nucleons, 0 other"; // 1. Initalise sample Settings --------------------------------------- fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("Q^{2}_{QE} (GeV^{2})"); fSettings.SetYTitle("d#sigma/dQ_{QE}^{2} (cm^{2}/GeV^{2})"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG/NORM/MASK", "FIX/DIAG"); fSettings.SetEnuRange(0.0, 3.0); fSettings.SetSuggestedFlux( FitPar::GetDataBase() + "/MiniBooNE/ccqe/mb_ccqe_flux.root"); // Define input data information fSettings.FoundFill("name", "CCQELike", fCCQElike, true); fSettings.FoundFill("name", "CTarg", fUseCorrectedCTarget, true); if (fCCQElike && fUseCorrectedCTarget) { ERR(FTL) << "Sample: MiniBooNE_CCQE_XSec_1DQ2_antinu cannot run in both " "QELike and C-Target mode. You're welcome to add the data set." << std::endl; throw; } if (fCCQElike) { // CCQELike plot information fSettings.SetTitle("MiniBooNE #nu_#mu CCQE on CH"); - fSettings.SetDataInput( FitPar::GetDataBase() + "/MiniBooNE/anti-ccqe/asqq_like.txt" ); + fSettings.SetDataInput( FitPar::GetDataBase() + "/MiniBooNE/anti-ccqe/asqq_con.txt" ); fSettings.SetCovarInput( FitPar::GetDataBase() + "/MiniBooNE/anti-ccqe/asqq_diagcovar" ); fSettings.SetDefault( "ccqelikebkg_input", FitPar::GetDataBase() + "/MiniBooNE/anti-ccqe/asqq_bkg_ccqe.txt" ); fSettings.SetDefault( "ccpimbkg_input", FitPar::GetDataBase() + "/MiniBooNE/anti-ccqe/asqq_bkg_ccpim.txt" ); fSettings.SetHasExtraHistograms(true); fSettings.DefineAllowedSpecies("numu,numub"); fSettings.DefineAllowedTargets("C,H"); } else if (!fUseCorrectedCTarget) { // CCQE Plot Information fSettings.SetTitle("MiniBooNE #nu_#mu CC0#pi on CH"); fSettings.SetDataInput( FitPar::GetDataBase() + "/MiniBooNE/anti-ccqe/asqq_con.txt" ); fSettings.SetCovarInput( FitPar::GetDataBase() + "/MiniBooNE/anti-ccqe/asqq_diagcovar" ); fSettings.DefineAllowedSpecies("numu"); fSettings.DefineAllowedTargets("C,H"); } else { // CCQE Corrected Target Plot Information fSettings.SetTitle("MiniBooNE #nu_#mu CC0#pi on C"); fSettings.SetDataInput( FitPar::GetDataBase() + "/MiniBooNE/anti-ccqe/asqq_con_ctarget.txt" ); fSettings.SetCovarInput( FitPar::GetDataBase() + "/MiniBooNE/anti-ccqe/asqq_diagcovar" ); fSettings.DefineAllowedSpecies("numu"); fSettings.DefineAllowedTargets("C"); } FinaliseSampleSettings(); // 2. Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon // Multiply by 14.08/6.0 to get per neutron double NNucPerNTarg = fUseCorrectedCTarget ? 12.0 / 6.0 : 14.08 / 8.0; fScaleFactor = ((GetEventHistogram()->Integral("width") * 1E-38 / (fNEvents + 0.)) * NNucPerNTarg / TotalIntegratedFlux()); // 3. Plot Setup ------------------------------------------------------- SetDataFromTextFile( fSettings.GetDataInput() ); SetCovarFromDiagonal(); /// /// If CCQELike is used an additional the CCQELike BKG is used and a PDG /// Histogram is saved if (fCCQElike) { // CCQELike Data fDataHist_CCQELIKE = PlotUtils::GetTH1DFromFile( fSettings.GetS("ccqelikebkg_input"), fSettings.GetName() + "_CCQELIKE_data" ); fDataHist_CCQELIKE->SetNameTitle( (fSettings.Name() + "_CCQELIKE_BKG").c_str(), ("MiniBooNE #nu_#mu CCQE-Like Backgrounds" + fSettings.PlotTitles()).c_str() ); fDataHist->Add(fDataHist_CCQELIKE); SetAutoProcessTH1(fDataHist_CCQELIKE, kCMD_Write); // CCQELike MC fMCHist_CCQELIKE = new NuNuBarTrueModeStack( fSettings.Name() + "_CCQELIKE_MC", "CCQE-like MC" + fSettings.PlotTitles(), fDataHist_CCQELIKE ); SetAutoProcessTH1(fMCHist_CCQELIKE); // Data CCRES fDataHist_CCPIM = PlotUtils::GetTH1DFromFile( fSettings.GetS("ccpimbkg_input"), fSettings.GetName() + "_CCPIM_BKG_data" ); fDataHist_CCPIM->SetNameTitle( (fSettings.Name() + "_CCPIM_data").c_str(), ("MiniBooNE #nu_#mu CCQE-Like Backgrounds" + fSettings.PlotTitles()).c_str() ); SetAutoProcessTH1(fDataHist_CCQELIKE, kCMD_Write); // MC CCRES fMCHist_CCPIM = new NuNuBarTrueModeStack(fSettings.Name() + "_CCPIM_BKG_MC", "CCQE-like BKG CC-RES" + fSettings.PlotTitles(), fDataHist_CCPIM); SetAutoProcessTH1(fMCHist_CCPIM); // Make NON CCPIM fDataHist_NONCCPIM = (TH1D *)fDataHist_CCQELIKE->Clone(); fDataHist_NONCCPIM->SetNameTitle((fName + "_data_NONCCPIM").c_str(), (fName + "_data_NONCCPIM").c_str()); fDataHist_NONCCPIM->Add( fDataHist_CCPIM, -1.0 ); SetAutoProcessTH1(fDataHist_NONCCPIM, kCMD_Write); fMCHist_NONCCPIM = new NuNuBarTrueModeStack( fSettings.Name() + "_NONCCPIM_BKG", "CCQE-like BKG CC-NonRES" + fSettings.PlotTitles(), fDataHist_NONCCPIM); SetAutoProcessTH1(fMCHist_NONCCPIM); } FinaliseMeasurement(); }; void MiniBooNE_CCQE_XSec_1DQ2_antinu::FillEventVariables(FitEvent * event) { if (event->NumFSParticle(PhysConst::pdg_muons) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; // The highest momentum mu+/mu-. The isSignal definition should make sure we // only // accept events we want, so no need to do an additional check here. TLorentzVector Pmu = event->GetHMFSParticle(PhysConst::pdg_muons)->fP; // Set X Variables fXVar = FitUtils::Q2QErec(Pmu, cos(Pnu.Vect().Angle(Pmu.Vect())), 30., false); fPDGnu = event->PDGnu(); return; }; bool MiniBooNE_CCQE_XSec_1DQ2_antinu::isSignal(FitEvent * event) { // If CC0pi, include both charges if (fCCQElike) { if (SignalDef::isCC0pi(event, 14, EnuMin, EnuMax) || SignalDef::isCC0pi(event, -14, EnuMin, EnuMax)) { return true; } } else { if (SignalDef::isCCQELike(event, -14, EnuMin, EnuMax)) return true; } return false; }; void MiniBooNE_CCQE_XSec_1DQ2_antinu::FillExtraHistograms(MeasurementVariableBox* vars, double weight) { // No Extra Hists if not ccqelike if (!fCCQElike or !Signal) return; // Fill Stacks if (Mode != -1 and Mode != -2) { if (fabs(Mode) == 11 or fabs(Mode) == 12 or fabs(Mode == 13)) { fMCHist_CCPIM->Fill(fPDGnu, Mode, fXVar, weight); } else { fMCHist_NONCCPIM->Fill(fPDGnu, Mode, fXVar, weight); } } fMCHist_CCQELIKE->Fill(fPDGnu, Mode, fXVar, weight); } 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/FitWeight.cxx b/src/Reweight/FitWeight.cxx index 13b9e67..3559a3c 100644 --- a/src/Reweight/FitWeight.cxx +++ b/src/Reweight/FitWeight.cxx @@ -1,239 +1,274 @@ #include "FitWeight.h" +#include "GENIEWeightEngine.h" +#include "LikelihoodWeightEngine.h" +#include "ModeNormEngine.h" +#include "NEUTWeightEngine.h" +#include "NIWGWeightEngine.h" +#include "NUISANCEWeightEngine.h" +#include "NuWroWeightEngine.h" #include "OscWeightEngine.h" +#include "SampleNormEngine.h" +#include "SplineWeightEngine.h" +#include "T2KWeightEngine.h" void FitWeight::AddRWEngine(int type) { switch (type) { case kNEUT: fAllRW[type] = new NEUTWeightEngine("neutrw"); break; case kNUWRO: fAllRW[type] = new NuWroWeightEngine("nuwrorw"); break; case kGENIE: fAllRW[type] = new GENIEWeightEngine("genierw"); break; case kNORM: fAllRW[type] = new SampleNormEngine("normrw"); break; case kLIKEWEIGHT: fAllRW[type] = new LikelihoodWeightEngine("likerw"); break; case kT2K: fAllRW[type] = new T2KWeightEngine("t2krw"); break; case kCUSTOM: fAllRW[type] = new NUISANCEWeightEngine("nuisrw"); break; case kSPLINEPARAMETER: fAllRW[type] = new SplineWeightEngine("splinerw"); break; case kNIWG: fAllRW[type] = new NIWGWeightEngine("niwgrw"); break; case kOSCILLATION: fAllRW[type] = new OscWeightEngine(); break; + case kMODENORM: + fAllRW[type] = new ModeNormEngine(); + break; default: THROW("CANNOT ADD RW Engine for unknown dial type: " << type); break; } } +WeightEngineBase* FitWeight::GetRWEngine(int type) { + if (HasRWEngine(type)) { + return fAllRW[type]; + } + THROW("CANNOT get RW Engine for dial type: " << type); +} + +bool FitWeight::HasRWEngine(int type) { + switch (type) { + case kNEUT: + case kNUWRO: + case kGENIE: + case kNORM: + case kLIKEWEIGHT: + case kT2K: + case kCUSTOM: + case kSPLINEPARAMETER: + case kNIWG: + case kOSCILLATION: { + return fAllRW.count(type); + } + default: { THROW("CANNOT get RW Engine for dial type: " << type); } + } +} + void FitWeight::IncludeDial(std::string name, std::string type, double val) { // Should register the dial here. int typeenum = Reweight::ConvDialType(type); IncludeDial(name, typeenum, val); } void FitWeight::IncludeDial(std::string name, int dialtype, double val) { // Get the dial enum int nuisenum = Reweight::ConvDial(name, dialtype); if (nuisenum == -1) { THROW("NUISENUM == " << nuisenum << " for " << name); } // Setup RW Engine Pointer if (fAllRW.find(dialtype) == fAllRW.end()) { AddRWEngine(dialtype); } WeightEngineBase* rw = fAllRW[dialtype]; // Include the dial rw->IncludeDial(name, val); // Set Dial Value if (val != -9999.9) { rw->SetDialValue(name, val); } // Sort Maps fAllEnums[name] = nuisenum; fAllValues[nuisenum] = val; // Sort Lists fNameList.push_back(name); fEnumList.push_back(nuisenum); fValueList.push_back(val); } void FitWeight::Reconfigure(bool silent) { // Reconfigure all added RW engines for (std::map::iterator iter = fAllRW.begin(); iter != fAllRW.end(); iter++) { (*iter).second->Reconfigure(silent); } } void FitWeight::SetDialValue(std::string name, double val) { // Add extra check, if name not found look for one with name in it. int nuisenum = fAllEnums[name]; SetDialValue(nuisenum, val); } // Allow for name aswell using GlobalList to determine sample name. void FitWeight::SetDialValue(int nuisenum, double val) { // Conv dial type - int dialtype = int(nuisenum - (nuisenum % 1000)) / 1000; + int dialtype = Reweight::GetDialType(nuisenum); if (fAllRW.find(dialtype) == fAllRW.end()) { THROW("Cannot find RW Engine for dialtype = " - << dialtype << " " << nuisenum << " " - << (nuisenum - (nuisenum % 1000)) / 1000); + << dialtype << ", " << Reweight::RemoveDialType(nuisenum)); } // Get RW Engine for this dial fAllRW[dialtype]->SetDialValue(nuisenum, val); fAllValues[nuisenum] = val; // Update ValueList for (size_t i = 0; i < fEnumList.size(); i++) { if (fEnumList[i] == nuisenum) { fValueList[i] = val; } } } void FitWeight::SetAllDials(const double* x, int n) { for (size_t i = 0; i < (UInt_t)n; i++) { int rwenum = fEnumList[i]; SetDialValue(rwenum, x[i]); } Reconfigure(); } double FitWeight::GetDialValue(std::string name) { // Add extra check, if name not found look for one with name in it. int nuisenum = fAllEnums[name]; return GetDialValue(nuisenum); } double FitWeight::GetDialValue(int nuisenum) { return fAllValues[nuisenum]; } int FitWeight::GetDialPos(std::string name) { int rwenum = fAllEnums[name]; return GetDialPos(rwenum); } int FitWeight::GetDialPos(int nuisenum) { for (size_t i = 0; i < fEnumList.size(); i++) { if (fEnumList[i] == nuisenum) { return i; } } ERR(FTL) << "No Dial Found! " << std::endl; throw; return -1; } bool FitWeight::DialIncluded(std::string name) { return (fAllEnums.find(name) != fAllEnums.end()); } bool FitWeight::DialIncluded(int rwenum) { return (fAllValues.find(rwenum) != fAllValues.end()); } double FitWeight::CalcWeight(BaseFitEvt* evt) { double rwweight = 1.0; for (std::map::iterator iter = fAllRW.begin(); iter != fAllRW.end(); iter++) { double w = (*iter).second->CalcWeight(evt); - // LOG(FIT) << "Iter " << (*iter).second->fCalcName << " = " << w << - // std::endl; rwweight *= w; } return rwweight; } void FitWeight::UpdateWeightEngine(const double* x) { size_t count = 0; for (std::vector::iterator iter = fEnumList.begin(); iter != fEnumList.end(); iter++) { SetDialValue((*iter), x[count]); count++; } } void FitWeight::GetAllDials(double* x, int n) { for (int i = 0; i < n; i++) { x[i] = GetDialValue(fEnumList[i]); } } -bool FitWeight::NeedsEventReWeight(const double* x) { - bool haschange = false; - size_t count = 0; - - // Compare old to new and decide if RW needed. - for (std::vector::iterator iter = fEnumList.begin(); - iter != fEnumList.end(); iter++) { - int nuisenum = (*iter); - int type = (nuisenum / 1000) - (nuisenum % 1000); - - // Compare old to new - double oldval = GetDialValue(nuisenum); - double newval = x[count]; - if (oldval != newval) { - if (fAllRW[type]->NeedsEventReWeight()) { - haschange = true; - } - } - - count++; - } - - return haschange; -} +// bool FitWeight::NeedsEventReWeight(const double* x) { +// bool haschange = false; +// size_t count = 0; + +// // Compare old to new and decide if RW needed. +// for (std::vector::iterator iter = fEnumList.begin(); +// iter != fEnumList.end(); iter++) { +// int nuisenum = (*iter); +// int type = (nuisenum / 1000) - (nuisenum % 1000); + +// // Compare old to new +// double oldval = GetDialValue(nuisenum); +// double newval = x[count]; +// if (oldval != newval) { +// if (fAllRW[type]->NeedsEventReWeight()) { +// haschange = true; +// } +// } + +// count++; +// } + +// return haschange; +// } double FitWeight::GetSampleNorm(std::string name) { if (name.empty()) return 1.0; // Find norm dial if (fAllEnums.find(name + "_norm") != fAllEnums.end()) { if (fAllValues.find(fAllEnums[name + "_norm"]) != fAllValues.end()) { return fAllValues[fAllEnums[name + "_norm"]]; } else { return 1.0; } } else { return 1.0; } } void FitWeight::Print() { LOG(REC) << "Fit Weight State: " << std::endl; for (size_t i = 0; i < fNameList.size(); i++) { LOG(REC) << " -> Par " << i << ". " << fNameList[i] << " " << fValueList[i] << std::endl; } } diff --git a/src/Reweight/FitWeight.h b/src/Reweight/FitWeight.h index 20ecde0..0829ce8 100644 --- a/src/Reweight/FitWeight.h +++ b/src/Reweight/FitWeight.h @@ -1,72 +1,65 @@ #ifndef FITWEIGHT2_H #define FITWEIGHT2_H #include "WeightUtils.h" #include "WeightEngineBase.h" -#include "NEUTWeightEngine.h" -#include "GENIEWeightEngine.h" -#include "NuWroWeightEngine.h" -#include "SampleNormEngine.h" -#include "LikelihoodWeightEngine.h" -#include "SplineWeightEngine.h" -#include "NUISANCEWeightEngine.h" -#include "T2KWeightEngine.h" -#include "NIWGWeightEngine.h" #include #include class FitWeight { public: FitWeight(std::string name = "") {}; // Add a new RW engine given type void AddRWEngine(int rwtype); + WeightEngineBase* GetRWEngine(int type); + bool HasRWEngine(int type); // Includes void IncludeDial(std::string name, std::string type, double val = -9999.9); void IncludeDial(std::string name, int type, double val = -9999.9); // Update RW Engines void Reconfigure(bool silent = false); void SetDialValue(std::string name, double val); void SetDialValue(int rwenum, double val); double GetDialValue(std::string name); double GetDialValue(int rwenum); - + int GetDialPos(std::string name); int GetDialPos(int rwenum); bool DialIncluded(std::string name); bool DialIncluded(int rwenum); double CalcWeight(BaseFitEvt* evt); bool HasRWDialChanged(const double* x) { return true; }; - bool NeedsEventReWeight(const double* x); + // bool NeedsEventReWeight(const double* x); void SetAllDials(const double* x, int n); double GetSampleNorm(std::string name); void UpdateWeightEngine(const double* x); inline std::vector GetDialEnums() { return fEnumList; }; inline std::vector GetDialNames() { return fNameList; }; inline std::vector GetDialValues() { return fValueList; }; void GetAllDials(double* x, int n); void Print(); std::vector fEnumList; std::vector fNameList; std::vector fValueList; std::map fAllEnums; std::map fAllValues; std::map fAllRW; }; #endif 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/GlobalDialList.cxx b/src/Reweight/GlobalDialList.cxx index a3ef8f6..c9a0c65 100644 --- a/src/Reweight/GlobalDialList.cxx +++ b/src/Reweight/GlobalDialList.cxx @@ -1,56 +1,48 @@ #include "GlobalDialList.h" -int GlobalDialList::EnumFromNameAndType(std::string name, int type){ - +int GlobalDialList::EnumFromNameAndType(std::string name, int type) { // Setup Type Container - if (fTypeEnumCont.find(type) == fTypeEnumCont.end()){ + if (fTypeEnumCont.find(type) == fTypeEnumCont.end()) { std::map temp; temp[name] = 0; fTypeEnumCont[type] = temp; } // Get Type Container std::map enumcont = fTypeEnumCont[type]; - // LOG(FIT) << "Getting Enum From name and type " << name << " " << type << std::endl; // Check name is in container, if its not add it - if (enumcont.find(name) == enumcont.end()){ - // LOG(FIT) << " Name not found in Enum type " << type << std::endl; + if (enumcont.find(name) == enumcont.end()) { int index = enumcont.size(); enumcont[name] = index; - // LOG(FIT) << "Returning new index of " << index << std::endl; fTypeEnumCont[type][name] = index; return index; } return enumcont[name]; } -void GlobalDialList::RegisterDialEnum(std::string name, int type, int nuisenum){ - - if (std::find(fAllDialNames.begin(), fAllDialNames.end(), name) != fAllDialNames.end()){ +void GlobalDialList::RegisterDialEnum(std::string name, int type, + int nuisenum) { + if (std::find(fAllDialNames.begin(), fAllDialNames.end(), name) != + fAllDialNames.end()) { return; } - LOG(FIT) << "Registed Dial Enum : " << name << " " << type << " " << nuisenum << std::endl; + LOG(FIT) << "Registered Dial Enum : " << name << " " << type << " " + << nuisenum << std::endl; fAllDialNames.push_back(name); fAllDialTypes.push_back(type); fAllDialEnums.push_back(nuisenum); } - - - /// Singleton functions -GlobalDialList& Reweight::DialList(){ - return GlobalDialList::Get(); -} +GlobalDialList& Reweight::DialList() { return GlobalDialList::Get(); } GlobalDialList* GlobalDialList::m_diallistInstance = NULL; -GlobalDialList& GlobalDialList::Get(void){ +GlobalDialList& GlobalDialList::Get(void) { if (!m_diallistInstance) m_diallistInstance = new GlobalDialList; return *m_diallistInstance; } - 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/ModeNormEngine.h b/src/Reweight/ModeNormEngine.h new file mode 100644 index 0000000..4915298 --- /dev/null +++ b/src/Reweight/ModeNormEngine.h @@ -0,0 +1,82 @@ +#ifndef ModeNormEngine_H +#define ModeNormEngine_H + +#include "FitLogger.h" +#include "GeneratorUtils.h" +#include "WeightEngineBase.h" + +class ModeNormEngine : public WeightEngineBase { + public: + ModeNormEngine(std::string name = "ModeNormEngine") : fName(name){}; + ~ModeNormEngine(){}; + + void IncludeDial(std::string name, double startval) { + int rwenum = Reweight::ConvDial(name, kMODENORM); + int mode = Reweight::RemoveDialType(rwenum); + if (fDialEnumIndex.count(mode)) { + THROW("Mode dial: " << mode + << " already included. Cannot include twice."); + } + fDialEnumIndex[mode] = fDialValues.size(); + fDialValues.push_back(startval); + QLOG(FIT, "Added mode dial for mode: " << mode); + } + void SetDialValue(int rwenum, double val) { + int mode = Reweight::RemoveDialType(rwenum); + if (!fDialEnumIndex.count(mode)) { + THROW("Mode dial: " << mode + << " has not been included. Cannot set value."); + } + fDialValues[fDialEnumIndex[mode]] = val; + } + void SetDialValue(std::string name, double val) { + SetDialValue(Reweight::ConvDial(name, kMODENORM), val); + } + + void Reconfigure(bool silent = false) { (void)silent; } + + static int ModeToDial(int mode) { return 60 + mode; } + + double CalcWeight(BaseFitEvt* evt) { + int mode = ModeToDial(abs(evt->Mode)); + if (!fDialEnumIndex.count(mode)) { + return 1; + } + return fDialValues[fDialEnumIndex[mode]]; + }; + bool NeedsEventReWeight() { return false; }; + + double GetDialValue(std::string name) { + int rwenum = Reweight::ConvDial(name, kMODENORM); + int mode = Reweight::RemoveDialType(rwenum); + if (fDialEnumIndex.count(mode)) { + return fDialValues[fDialEnumIndex[mode]]; + } else { + return 0xdeadbeef; + } + } + + static int SystEnumFromString(std::string const& name) { + std::vector splits = GeneralUtils::ParseToStr(name, "_"); + if (splits.size() != 2) { + ERR(FTL) << "Attempting to parse dial name: \"" << name + << "\" as a mode norm dial but failed. Expect e.g. \"mode_2\"." + << std::endl; + } + + int mode_num = GeneralUtils::StrToInt(splits[1]); + if (!mode_num) { + ERR(FTL) << "Attempting to parse dial name: \"" << name + << "\" as a mode norm dial but failed." << std::endl; + throw; + } + return ModeToDial(mode_num); + } + + std::map fDialEnumIndex; + std::vector fDialValues; + + std::string fName; +}; + +#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.cxx b/src/Reweight/NUISANCEWeightCalcs.cxx index 1f3ddf2..4a70d6b 100644 --- a/src/Reweight/NUISANCEWeightCalcs.cxx +++ b/src/Reweight/NUISANCEWeightCalcs.cxx @@ -1,329 +1,346 @@ #include "NUISANCEWeightCalcs.h" +#include "GeneralUtils.h" +#include "FitEvent.h" +#include "WeightUtils.h" +#include "NUISANCESyst.h" + +using namespace Reweight; + ModeNormCalc::ModeNormCalc(){ fNormRES = 1.0; } double ModeNormCalc::CalcWeight(BaseFitEvt* evt) { - FitEvent* fevt = static_cast(evt); - int mode = abs(fevt->Mode); + int mode = abs(evt->Mode); double w = 1.0; - + if (mode == 11 or mode == 12 or mode == 13){ w *= fNormRES; - } + } return w; } void ModeNormCalc::SetDialValue(std::string name, double val) { SetDialValue(Reweight::ConvDial(name, kCUSTOM), val); } void ModeNormCalc::SetDialValue(int rwenum, double val) { int curenum = rwenum % 1000; - // Check Handled + // Check Handled if (!IsHandled(curenum)) return; if (curenum == kModeNorm_NormRES) fNormRES = val; } bool ModeNormCalc::IsHandled(int rwenum) { int curenum = rwenum % 1000; switch (curenum) { case kModeNorm_NormRES: return true; default: return false; } } - - - - - - GaussianModeCorr::GaussianModeCorr() { // Init fApply_CCQE = false; fGausVal_CCQE[kPosNorm] = 0.0; fGausVal_CCQE[kPosTilt] = 0.0; fGausVal_CCQE[kPosPq0] = 1.0; fGausVal_CCQE[kPosWq0] = 1.0; fGausVal_CCQE[kPosPq3] = 1.0; fGausVal_CCQE[kPosWq3] = 1.0; fApply_2p2h = false; fGausVal_2p2h[kPosNorm] = 0.0; fGausVal_2p2h[kPosTilt] = 0.0; fGausVal_2p2h[kPosPq0] = 1.0; fGausVal_2p2h[kPosWq0] = 1.0; fGausVal_2p2h[kPosPq3] = 1.0; fGausVal_2p2h[kPosWq3] = 1.0; fApply_2p2h_PPandNN = false; fGausVal_2p2h_PPandNN[kPosNorm] = 0.0; fGausVal_2p2h_PPandNN[kPosTilt] = 0.0; fGausVal_2p2h_PPandNN[kPosPq0] = 1.0; fGausVal_2p2h_PPandNN[kPosWq0] = 1.0; fGausVal_2p2h_PPandNN[kPosPq3] = 1.0; fGausVal_2p2h_PPandNN[kPosWq3] = 1.0; fApply_2p2h_NP = false; fGausVal_2p2h_NP[kPosNorm] = 0.0; fGausVal_2p2h_NP[kPosTilt] = 0.0; fGausVal_2p2h_NP[kPosPq0] = 1.0; fGausVal_2p2h_NP[kPosWq0] = 1.0; fGausVal_2p2h_NP[kPosPq3] = 1.0; fGausVal_2p2h_NP[kPosWq3] = 1.0; fApply_CC1pi = false; fGausVal_CC1pi[kPosNorm] = 0.0; fGausVal_CC1pi[kPosTilt] = 0.0; fGausVal_CC1pi[kPosPq0] = 1.0; fGausVal_CC1pi[kPosWq0] = 1.0; fGausVal_CC1pi[kPosPq3] = 1.0; fGausVal_CC1pi[kPosWq3] = 1.0; + fAllowSuppression = false; + fDebugStatements = FitPar::Config().GetParB("GaussianModeCorr_DEBUG"); } double GaussianModeCorr::CalcWeight(BaseFitEvt* evt) { FitEvent* fevt = static_cast(evt); double rw_weight = 1.0; // Get Neutrino if (!fevt->Npart()){ THROW("NO particles found in stack!"); } FitParticle* pnu = fevt->PartInfo(0); if (!pnu){ THROW("NO Starting particle found in stack!"); } int pdgnu = pnu->fPID; FitParticle* plep = fevt->GetHMFSParticle(abs(pdgnu) - 1); if (!plep) return 1.0; TLorentzVector q = pnu->fP - plep->fP; // Extra q0,q3 double q0 = fabs(q.E()) / 1.E3; double q3 = fabs(q.Vect().Mag()) / 1.E3; int initialstate = -1; // Undef if (abs(fevt->Mode) == 2) { int npr = 0; int nne = 0; for (UInt_t j = 0; j < fevt->Npart(); j++) { if ((fevt->PartInfo(j))->fIsAlive) continue; if (fevt->PartInfo(j)->fPID == 2212) npr++; else if (fevt->PartInfo(j)->fPID == 2112) nne++; } // std::cout << "PN State = " << npr << " " << nne << std::endl; if (fevt->Mode == 2 and npr == 1 and nne == 1) { initialstate = 2; } else if (fevt->Mode == 2 and ((npr == 0 and nne == 2) or (npr == 2 and nne == 0))) { initialstate = 1; } } // std::cout << "Got q0 q3 = " << q0 << " " << q3 << std::endl; // Apply weighting if (fApply_CCQE and abs(fevt->Mode) == 1) { if (fDebugStatements) std::cout << "Getting CCQE Weight" << std::endl; double g = GetGausWeight(q0, q3, fGausVal_CCQE); if (g < 1.0) g = 1.0; rw_weight *= g; } if (fApply_2p2h and abs(fevt->Mode) == 2) { if (fDebugStatements) std::cout << "Getting 2p2h Weight" << std::endl; rw_weight *= GetGausWeight(q0, q3, fGausVal_2p2h); } if (fApply_2p2h_PPandNN and abs(fevt->Mode) == 2 and initialstate == 1) { if (fDebugStatements) std::cout << "Getting 2p2h PPandNN Weight" << std::endl; rw_weight *= GetGausWeight(q0, q3, fGausVal_2p2h_PPandNN); } if (fApply_2p2h_NP and abs(fevt->Mode) == 2 and initialstate == 2) { if (fDebugStatements) std::cout << "Getting 2p2h NP Weight" << std::endl; rw_weight *= GetGausWeight(q0, q3, fGausVal_2p2h_NP); } if (fApply_CC1pi and abs(fevt->Mode) >= 11 and abs(fevt->Mode) <= 13) { if (fDebugStatements) std::cout << "Getting CC1pi Weight" << std::endl; rw_weight *= GetGausWeight(q0, q3, fGausVal_CC1pi); } + + // if (fDebugStatements) std::cout << "Returning Weight " << rw_weight << std::endl; return rw_weight; } double GaussianModeCorr::GetGausWeight(double q0, double q3, double vals[]) { // // CCQE Without Suppression // double Norm = 4.82788679036; // double Tilt = 2.3501416116; // double Pq0 = 0.363964889702; // double Wq0 = 0.133976806938; // double Pq3 = 0.431769740224; // double Wq3 = 0.207666663434; // // Also add for CCQE at the end // return (w > 1.0) ? w : 1.0; // // 2p2h with suppression // double Norm = 15.967; // double Tilt = -0.455655; // double Pq0 = 0.214598; // double Wq0 = 0.0291061; // double Pq3 = 0.480194; // double Wq3 = 0.134588; double Norm = vals[kPosNorm]; double Tilt = vals[kPosTilt]; double Pq0 = vals[kPosPq0]; double Wq0 = vals[kPosWq0]; double Pq3 = vals[kPosPq3]; double Wq3 = vals[kPosWq3]; double a = cos(Tilt) * cos(Tilt) / (2 * Wq0 * Wq0); a += sin(Tilt) * sin(Tilt) / (2 * Wq3 * Wq3); double b = - sin(2 * Tilt) / (4 * Wq0 * Wq0); b += sin(2 * Tilt) / (4 * Wq3 * Wq3); double c = sin(Tilt) * sin(Tilt) / (2 * Wq0 * Wq0); c += cos(Tilt) * cos(Tilt) / (2 * Wq3 * Wq3); double w = Norm; w *= exp(-a * (q0 - Pq0) * (q0 - Pq0)); w *= exp(+2.0 * b * (q0 - Pq0) * (q3 - Pq3)); w *= exp(-c * (q3 - Pq3) * (q3 - Pq3)); if (fDebugStatements) { std::cout << "Applied Tilt " << Tilt << " " << cos(Tilt) << " " << sin(Tilt) << std::endl; std::cout << "abc = " << a << " " << b << " " << c << std::endl; std::cout << "Returning " << Norm << " " << Pq0 << " " << Wq0 << " " << Pq3 << " " << Wq3 << " " << w << std::endl; } + if (w != w || isnan(w) || w < 0.0){ + w = 0.0; + } + + if (w < 1.0 and !fAllowSuppression){ + w = 1.0; + } + return w; } void GaussianModeCorr::SetDialValue(std::string name, double val) { SetDialValue(Reweight::ConvDial(name, kCUSTOM), val); } void GaussianModeCorr::SetDialValue(int rwenum, double val) { int curenum = rwenum % 1000; // Check Handled if (!IsHandled(curenum)) return; // CCQE Setting for (int i = kGaussianCorr_CCQE_norm; i <= kGaussianCorr_CCQE_Wq3; i++) { if (i == curenum) { int index = i - kGaussianCorr_CCQE_norm; fGausVal_CCQE[index] = val; fApply_CCQE = true; } } // 2p2h Setting for (int i = kGaussianCorr_2p2h_norm; i <= kGaussianCorr_2p2h_Wq3; i++) { if (i == curenum) { int index = i - kGaussianCorr_2p2h_norm; fGausVal_2p2h[index] = val; fApply_2p2h = true; } } // 2p2h_PPandNN Setting for (int i = kGaussianCorr_2p2h_PPandNN_norm; i <= kGaussianCorr_2p2h_PPandNN_Wq3; i++) { if (i == curenum) { int index = i - kGaussianCorr_2p2h_PPandNN_norm; fGausVal_2p2h_PPandNN[index] = val; fApply_2p2h_PPandNN = true; } } // 2p2h_NP Setting for (int i = kGaussianCorr_2p2h_NP_norm; i <= kGaussianCorr_2p2h_NP_Wq3; i++) { if (i == curenum) { int index = i - kGaussianCorr_2p2h_NP_norm; fGausVal_2p2h_NP[index] = val; fApply_2p2h_NP = true; } } // CC1pi Setting for (int i = kGaussianCorr_CC1pi_norm; i <= kGaussianCorr_CC1pi_Wq3; i++) { if (i == curenum) { int index = i - kGaussianCorr_CC1pi_norm; fGausVal_CC1pi[index] = val; fApply_CC1pi = true; } } + if (curenum == kGaussianCorr_AllowSuppression){ + fAllowSuppression = (val > 0.5); + } + } bool GaussianModeCorr::IsHandled(int rwenum) { int curenum = rwenum % 1000; switch (curenum) { case kGaussianCorr_CCQE_norm: case kGaussianCorr_CCQE_tilt: case kGaussianCorr_CCQE_Pq0: case kGaussianCorr_CCQE_Wq0: case kGaussianCorr_CCQE_Pq3: case kGaussianCorr_CCQE_Wq3: case kGaussianCorr_2p2h_norm: case kGaussianCorr_2p2h_tilt: case kGaussianCorr_2p2h_Pq0: case kGaussianCorr_2p2h_Wq0: case kGaussianCorr_2p2h_Pq3: case kGaussianCorr_2p2h_Wq3: case kGaussianCorr_2p2h_PPandNN_norm: case kGaussianCorr_2p2h_PPandNN_tilt: case kGaussianCorr_2p2h_PPandNN_Pq0: case kGaussianCorr_2p2h_PPandNN_Wq0: case kGaussianCorr_2p2h_PPandNN_Pq3: case kGaussianCorr_2p2h_PPandNN_Wq3: case kGaussianCorr_2p2h_NP_norm: case kGaussianCorr_2p2h_NP_tilt: case kGaussianCorr_2p2h_NP_Pq0: case kGaussianCorr_2p2h_NP_Wq0: case kGaussianCorr_2p2h_NP_Pq3: case kGaussianCorr_2p2h_NP_Wq3: case kGaussianCorr_CC1pi_norm: case kGaussianCorr_CC1pi_tilt: case kGaussianCorr_CC1pi_Pq0: case kGaussianCorr_CC1pi_Wq0: case kGaussianCorr_CC1pi_Pq3: case kGaussianCorr_CC1pi_Wq3: + case kGaussianCorr_AllowSuppression: return true; default: return false; } } diff --git a/src/Reweight/NUISANCEWeightCalcs.h b/src/Reweight/NUISANCEWeightCalcs.h index 95fa64b..15e2c6b 100644 --- a/src/Reweight/NUISANCEWeightCalcs.h +++ b/src/Reweight/NUISANCEWeightCalcs.h @@ -1,100 +1,90 @@ #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/OscWeightEngine.cxx b/src/Reweight/OscWeightEngine.cxx index d5debdb..bcb9292 100644 --- a/src/Reweight/OscWeightEngine.cxx +++ b/src/Reweight/OscWeightEngine.cxx @@ -1,286 +1,329 @@ // 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 . *******************************************************************************/ -#define DEBUG_OSC_WE +//#define DEBUG_OSC_WE #include "OscWeightEngine.h" #include enum nuTypes { kNuebarType = -1, kNumubarType = -2, kNutaubarType = -3, kNueType = 1, kNumuType = 2, kNutauType = 3, }; nuTypes GetNuType(int pdg) { switch (pdg) { case 16: return kNutauType; case 14: return kNumuType; case 12: return kNueType; case -16: return kNutaubarType; case -14: return kNumubarType; case -12: return kNuebarType; default: { THROW("Attempting to convert \"neutrino pdg\": " << pdg); } } } OscWeightEngine::OscWeightEngine() : #ifdef __PROB3PP_ENABLED__ bp(), #endif theta12(0.825), theta13(0.10), theta23(1.0), dm12(7.9e-5), dm23(2.5e-3), dcp(0.0), LengthParam(0xdeadbeef), - TargetNuType(0) { + TargetNuType(0), + ForceFromNuPDG(0) { Config(); } void OscWeightEngine::Config() { std::vector OscParam = Config::QueryKeys("OscParam"); if (OscParam.size() < 1) { ERROR(WRN, "Oscillation parameters specified but no OscParam element " "configuring the experimental characteristics found.\nExpect at " "least . Pausing for " "10..."); sleep(10); return; } if (OscParam[0].Has("baseline_km")) { LengthParamIsZenith = false; LengthParam = OscParam[0].GetD("baseline_km"); constant_density = OscParam[0].Has("matter_density") ? OscParam[0].GetD("matter_density") : 0xdeadbeef; } else if (OscParam[0].Has("detection_zenith_deg")) { LengthParamIsZenith = true; static const double deg2rad = asin(1) / 90.0; LengthParam = cos(OscParam[0].GetD("detection_zenith_deg") * deg2rad); } else { ERROR(WRN, "It appeared that you wanted to set up an oscillation weight " "branch, but it was not correctly configured. You need to specify " "either: detection_zenith_deg or baseline_km attributes on the " "OscParam element, and if baseline_km is specified, you can " "optionally also set matter_density for oscillations through a " "constant matter density. Pausing for 10..."); sleep(10); return; } dm23 = OscParam[0].Has("dm23") ? OscParam[0].GetD("dm23") : dm23; theta23 = OscParam[0].Has("sinsq_theta23") ? OscParam[0].GetD("sinsq_theta23") : theta23; theta13 = OscParam[0].Has("sinsq_theta13") ? OscParam[0].GetD("sinsq_theta13") : theta13; dm12 = OscParam[0].Has("dm12") ? OscParam[0].GetD("dm12") : dm12; theta12 = OscParam[0].Has("sinsq_theta12") ? OscParam[0].GetD("sinsq_theta12") : theta12; dcp = OscParam[0].Has("dcp") ? OscParam[0].GetD("dcp") : dcp; TargetNuType = OscParam[0].Has("TargetNuPDG") ? GetNuType(OscParam[0].GetI("TargetNuPDG")) : 0; + ForceFromNuPDG = OscParam[0].Has("ForceFromNuPDG") + ? GetNuType(OscParam[0].GetI("ForceFromNuPDG")) + : 0; QLOG(FIT, "Configured oscillation weighter:"); if (LengthParamIsZenith) { QLOG(FIT, "Earth density profile with detection cos(zenith) = " << LengthParam); } else { if (constant_density != 0xdeadbeef) { QLOG(FIT, "Constant density with experimental baseline = " << LengthParam); } else { QLOG(FIT, "Vacuum oscillations with experimental baseline = " << LengthParam); } } params[0] = dm23; params[1] = theta23; params[2] = theta13; params[3] = dm12; params[4] = theta12; params[5] = dcp; QLOG(FIT, "\tdm23 : " << params[0]); QLOG(FIT, "\tsinsq_theta23: " << params[1]); QLOG(FIT, "\tsinsq_theta13: " << params[2]); QLOG(FIT, "\tdm12 : " << params[3]); QLOG(FIT, "\tsinsq_theta12: " << params[4]); QLOG(FIT, "\tdcp : " << params[5]); + if (TargetNuType) { + QLOG(FIT, "\tTargetNuType: " << TargetNuType); + } + if (ForceFromNuPDG) { + QLOG(FIT, "\tForceFromNuPDG: " << ForceFromNuPDG); + } + +#ifdef __PROB3PP_ENABLED__ + bp.SetMNS(params[theta12_idx], params[theta13_idx], params[theta23_idx], + params[dm12_idx], params[dm23_idx], params[dcp_idx], 1, true, 2); + bp.DefinePath(LengthParam, 0); + + QLOG(FIT, "\tBaseline : " << (bp.GetBaseline() / 100.0) << " km."); +#endif } void OscWeightEngine::IncludeDial(std::string name, double startval) { #ifdef DEBUG_OSC_WE std::cout << "IncludeDial: " << name << " at " << startval << std::endl; #endif int dial = SystEnumFromString(name); if (!dial) { THROW("OscWeightEngine passed dial: " << name << " that it does not understand."); } params[dial - 1] = startval; } void OscWeightEngine::SetDialValue(int nuisenum, double val) { #ifdef DEBUG_OSC_WE std::cout << "SetDial: " << (nuisenum % 1000) << " at " << val << std::endl; #endif fHasChanged = (params[(nuisenum % 1000) - 1] - val) > std::numeric_limits::epsilon(); params[(nuisenum % 1000) - 1] = val; } void OscWeightEngine::SetDialValue(std::string name, double val) { #ifdef DEBUG_OSC_WE std::cout << "SetDial: " << name << " at " << val << std::endl; #endif int dial = SystEnumFromString(name); if (!dial) { THROW("OscWeightEngine passed dial: " << name << " that it does not understand."); } fHasChanged = (params[dial - 1] - val) > std::numeric_limits::epsilon(); params[dial - 1] = val; } bool OscWeightEngine::IsDialIncluded(std::string name) { return SystEnumFromString(name); } bool OscWeightEngine::IsDialIncluded(int nuisenum) { return ((nuisenum % 1000) > 0) && ((nuisenum % 1000) < 6); } double OscWeightEngine::GetDialValue(std::string name) { int dial = SystEnumFromString(name); if (!dial) { THROW("OscWeightEngine passed dial: " << name << " that it does not understand."); } return params[dial - 1]; } double OscWeightEngine::GetDialValue(int nuisenum) { if (!(nuisenum % 1000) || (nuisenum % 1000) > 6) { THROW("OscWeightEngine passed dial enum: " << (nuisenum % 1000) << " that it does not understand, expected [1,6]."); } return params[(nuisenum % 1000) - 1]; } void OscWeightEngine::Reconfigure(bool silent) { fHasChanged = false; }; bool OscWeightEngine::NeedsEventReWeight() { if (fHasChanged) { return true; } return false; } double OscWeightEngine::CalcWeight(BaseFitEvt* evt) { - if (LengthParam == 0xdeadbeef) { // not configured. - return 1; - } static bool Warned = false; if (evt->probe_E == 0xdeadbeef) { if (!Warned) { ERROR(WRN, "Oscillation weights asked for but using 'litemode' or " "unsupported generator input. Pasuing for 10..."); sleep(10); Warned = true; } return 1; } + + return CalcWeight(evt->probe_E * 1E-3, evt->probe_pdg); +} + +double OscWeightEngine::CalcWeight(double ENu, int PDGNu, int TargetPDGNu) { + if (LengthParam == 0xdeadbeef) { // not configured. + return 1; + } #ifdef __PROB3PP_ENABLED__ - int NuType = GetNuType(evt->probe_pdg); + int NuType = (ForceFromNuPDG != 0) ? ForceFromNuPDG : GetNuType(PDGNu); bp.SetMNS(params[theta12_idx], params[theta13_idx], params[theta23_idx], - params[dm12_idx], params[dm23_idx], params[dcp_idx], - evt->probe_E * 1E-3, true, NuType); + params[dm12_idx], params[dm23_idx], params[dcp_idx], ENu, true, + NuType); int pmt = 0; double prob_weight = 1; + TargetPDGNu = (TargetPDGNu == -1) ? (TargetNuType ? TargetNuType : NuType) + : GetNuType(TargetPDGNu); if (LengthParamIsZenith) { // Use earth density bp.DefinePath(LengthParam, 0); bp.propagate(NuType); pmt = 0; - prob_weight = bp.GetProb(NuType, TargetNuType ? TargetNuType : NuType); + prob_weight = bp.GetProb(NuType, TargetPDGNu); } else { if (constant_density != 0xdeadbeef) { bp.propagateLinear(NuType, LengthParam, constant_density); pmt = 1; - prob_weight = bp.GetProb(NuType, TargetNuType ? TargetNuType : NuType); + prob_weight = bp.GetProb(NuType, TargetPDGNu); } else { pmt = 2; prob_weight = - bp.GetVacuumProb(NuType, TargetNuType ? TargetNuType : NuType, - evt->probe_E * 1E-3, LengthParam); + bp.GetVacuumProb(NuType, TargetPDGNu, ENu * 1E-3, LengthParam); } } #ifdef DEBUG_OSC_WE if (prob_weight != prob_weight) { - THROW("Calculated bad prob weight: " - << prob_weight << "(Osc Type: " << pmt << " -- " << NuType << " -> " - << (TargetNuType ? TargetNuType : NuType) << ")"); + THROW("Calculated bad prob weight: " << prob_weight << "(Osc Type: " << pmt + << " -- " << NuType << " -> " + << TargetPDGNu << ")"); } + if (prob_weight > 1) { + THROW("Calculated bad prob weight: " << prob_weight << "(Osc Type: " << pmt + << " -- " << NuType << " -> " + << TargetPDGNu << ")"); + } + + std::cout << NuType << " -> " << TargetPDGNu << ": " << ENu << " = " + << prob_weight << "%%." << std::endl; #endif return prob_weight; #else return 1; #endif } int OscWeightEngine::SystEnumFromString(std::string const& name) { if (name == "dm23") { return 1; } else if (name == "sinsq_theta23") { return 2; } else if (name == "sinsq_theta13") { return 3; } else if (name == "dm12") { return 4; } else if (name == "sinsq_theta12") { return 5; } else if (name == "dcp") { return 6; } else { return 0; } } + +void OscWeightEngine::Print() { + std::cout << "OscWeightEngine: " << std::endl; + + std::cout << "\t theta12: " << params[theta12_idx] << std::endl; + std::cout << "\t theta13: " << params[theta13_idx] << std::endl; + std::cout << "\t theta23: " << params[theta23_idx] << std::endl; + std::cout << "\t dm12: " << params[dm12_idx] << std::endl; + std::cout << "\t dm23: " << params[dm23_idx] << std::endl; + std::cout << "\t dcp: " << params[dcp_idx] << std::endl; +} diff --git a/src/Reweight/OscWeightEngine.h b/src/Reweight/OscWeightEngine.h index e94ec7f..8cacff7 100644 --- a/src/Reweight/OscWeightEngine.h +++ b/src/Reweight/OscWeightEngine.h @@ -1,126 +1,143 @@ // 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 "FitEvent.h" #include "PhysConst.h" #include "WeightEngineBase.h" #ifdef __PROB3PP_ENABLED__ #include "BargerPropagator.h" #endif #include +#ifdef __PROB3PP_ENABLED__ +class BG : public BargerPropagator { + public: + BG() : BargerPropagator(){}; + double GetBaseline() { return Earth->get_Pathlength(); } +}; +#endif + class OscWeightEngine : public WeightEngineBase { enum params { dm23_idx = 0, theta23_idx, theta13_idx, dm12_idx, theta12_idx, dcp_idx, }; #ifdef __PROB3PP_ENABLED__ - BargerPropagator bp; + BG bp; #endif //******************************* Osc params ****************************** double theta12; double theta13; double theta23; /// The 1-2 mass squared splitting (small) [eV] double dm12; /// The 2-3 mass squared splitting (large) [eV] double dm23; /// The PMNS CP-violating phase double dcp; ///\brief The constant matter density used for simple given baseline /// oscillation [g/cm^3] double constant_density; /// Whether LengthParam corresponds to a Zenith or a baseline. /// /// If we just want to calculate the osc. prob. with a constant matter density /// then this should be false and constant_density should be set /// (or 0 for vacuum prob). bool LengthParamIsZenith; /// Either a path length or a post oscillation zenith angle /// /// N.B. For a beamline that has a dip angle of X degrees, the post /// oscillation zenith angle will be 90+X degrees. double LengthParam; /// Holds current value of oscillation parameters. double params[6]; /// The oscillation target type /// /// If unspecified in the element, it will default to /// disappearance probability. int TargetNuType; + /// The initial neutrino species + /// + /// If unspecified in the element, it will be determined by + /// the incoming events. + int ForceFromNuPDG; + public: OscWeightEngine(); /// Configures oscillation parameters from input xml file. /// /// Osc parameters configured from OscParam XML element as: /// /// /// /// If matter_density and baseline are present, then oscillation probability /// is calculated for a constant matter density. /// If detection_zenith_deg is present, then the baseline and density are /// calculated from the density profile and radius of the earth. /// If none are present, a vacuum oscillation is calculated. /// If TargetNuPDG is unspecified, oscillation will default to /// disappearance probability. void Config(); // Functions requiring Override void IncludeDial(std::string name, double startval); void SetDialValue(int nuisenum, double val); void SetDialValue(std::string name, double val); bool IsDialIncluded(std::string name); bool IsDialIncluded(int nuisenum); double GetDialValue(std::string name); double GetDialValue(int nuisenum); void Reconfigure(bool silent); bool NeedsEventReWeight(); double CalcWeight(BaseFitEvt* evt); + double CalcWeight(double ENu, int PDGNu, int TargetPDGNu = -1); static int SystEnumFromString(std::string const& name); + + void Print(); }; diff --git a/src/Reweight/WeightUtils.cxx b/src/Reweight/WeightUtils.cxx index 6bb4c57..a17eb22 100644 --- a/src/Reweight/WeightUtils.cxx +++ b/src/Reweight/WeightUtils.cxx @@ -1,568 +1,615 @@ #include "WeightUtils.h" +#include "FitLogger.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 "ModeNormEngine.h" +#include "NUISANCESyst.h" #include "OscWeightEngine.h" //******************************************************************** -TF1 FitBase::GetRWConvFunction(std::string type, std::string name) { +TF1 FitBase::GetRWConvFunction(std::string const &type, + std::string const &name) { //******************************************************************** std::string dialfunc = "x"; std::string parType = type; double low = -10000.0; double high = 10000.0; if (parType.find("parameter") == std::string::npos) parType += "_parameter"; std::string line; ifstream card( (GeneralUtils::GetTopLevelDir() + "/parameters/dial_conversion.card") .c_str(), ifstream::in); while (std::getline(card >> std::ws, line, '\n')) { std::vector inputlist = GeneralUtils::ParseToStr(line, " "); // Check the line length if (inputlist.size() < 4) continue; // Check whether this is a comment if (inputlist[0].c_str()[0] == '#') continue; // Check whether this is the correct parameter type if (inputlist[0].compare(parType) != 0) continue; // Check the parameter name if (inputlist[1].compare(name) != 0) continue; // inputlist[2] should be the units... ignore for now dialfunc = inputlist[3]; // High and low are optional, check whether they exist if (inputlist.size() > 4) low = GeneralUtils::StrToDbl(inputlist[4]); if (inputlist.size() > 5) high = GeneralUtils::StrToDbl(inputlist[5]); } TF1 convfunc = TF1((name + "_convfunc").c_str(), dialfunc.c_str(), low, high); return convfunc; } //******************************************************************** -std::string FitBase::GetRWUnits(std::string type, std::string name) { +std::string FitBase::GetRWUnits(std::string const &type, + std::string const &name) { //******************************************************************** std::string unit = "sig."; std::string parType = type; if (parType.find("parameter") == std::string::npos) { parType += "_parameter"; } std::string line; std::ifstream card( (GeneralUtils::GetTopLevelDir() + "/parameters/dial_conversion.card") .c_str(), 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 the correct parameter type if (inputlist[0].compare(parType) != 0) continue; // Check the parameter name if (inputlist[1].compare(name) != 0) continue; unit = inputlist[2]; break; } return unit; } //******************************************************************** -double FitBase::RWAbsToSigma(std::string type, std::string name, double val) { +double FitBase::RWAbsToSigma(std::string const &type, std::string const &name, + double val) { //******************************************************************** TF1 f1 = GetRWConvFunction(type, name); double conv_val = f1.GetX(val); if (fabs(conv_val) < 1E-10) conv_val = 0.0; + + std::cout << "AbsToSigma(" << name << ") = " << val << " -> " << conv_val + << std::endl; return conv_val; } //******************************************************************** -double FitBase::RWSigmaToAbs(std::string type, std::string name, double val) { +double FitBase::RWSigmaToAbs(std::string const &type, std::string const &name, + double val) { //******************************************************************** TF1 f1 = GetRWConvFunction(type, name); double conv_val = f1.Eval(val); return conv_val; } //******************************************************************** -double FitBase::RWFracToSigma(std::string type, std::string name, double val) { +double FitBase::RWFracToSigma(std::string const &type, std::string const &name, + double val) { //******************************************************************** TF1 f1 = GetRWConvFunction(type, name); double conv_val = f1.GetX((val * f1.Eval(0.0))); if (fabs(conv_val) < 1E-10) conv_val = 0.0; return conv_val; } //******************************************************************** -double FitBase::RWSigmaToFrac(std::string type, std::string name, double val) { +double FitBase::RWSigmaToFrac(std::string const &type, std::string const &name, + double val) { //******************************************************************** TF1 f1 = GetRWConvFunction(type, name); double conv_val = f1.Eval(val) / f1.Eval(0.0); return conv_val; } -int FitBase::ConvDialType(std::string type) { +int FitBase::ConvDialType(std::string const &type) { if (!type.compare("neut_parameter")) return kNEUT; else if (!type.compare("niwg_parameter")) return kNIWG; else if (!type.compare("nuwro_parameter")) return kNUWRO; else if (!type.compare("t2k_parameter")) return kT2K; else if (!type.compare("genie_parameter")) return kGENIE; else if (!type.compare("custom_parameter")) return kCUSTOM; else if (!type.compare("norm_parameter")) return kNORM; - else if (!type.compare("modenorm_parameter")) - return kMODENORM; else if (!type.compare("likeweight_parameter")) return kLIKEWEIGHT; else if (!type.compare("spline_parameter")) return kSPLINEPARAMETER; else if (!type.compare("osc_parameter")) return kOSCILLATION; + else if (!type.compare("modenorm_parameter")) + return kMODENORM; else return kUNKNOWN; } std::string FitBase::ConvDialType(int type) { switch (type) { case kNEUT: { return "neut_parameter"; } case kNIWG: { return "niwg_parameter"; } case kNUWRO: { return "nuwro_parameter"; } case kT2K: { return "t2k_parameter"; } case kGENIE: { return "genie_parameter"; } case kNORM: { return "norm_parameter"; } case kCUSTOM: { return "custom_parameter"; } - case kMODENORM: { - return "modenorm_parameter"; - } case kLIKEWEIGHT: { return "likeweight_parameter"; } case kSPLINEPARAMETER: { return "spline_parameter"; } case kOSCILLATION: { return "osc_parameter"; } + case kMODENORM: { + return "modenorm_parameter"; + } default: return "unknown_parameter"; } } -int FitBase::GetDialEnum(std::string type, std::string name) { +int FitBase::GetDialEnum(std::string const &type, std::string const &name) { return FitBase::GetDialEnum(FitBase::ConvDialType(type), name); } -int FitBase::GetDialEnum(int type, std::string name) { +int FitBase::GetDialEnum(int type, std::string const &name) { int offset = type * 1000; - int this_enum = -1; // Not Found + int this_enum = Reweight::kNoDialFound; // Not Found std::cout << "Getting dial enum " << type << " " << name << std::endl; // Select Types switch (type) { // NEUT DIAL TYPE case kNEUT: { #ifdef __NEUT_ENABLED__ int neut_enum = (int)neut::rew::NSyst::FromString(name); if (neut_enum != 0) { this_enum = neut_enum + offset; } #else - this_enum = -2; // Not enabled + this_enum = Reweight::kNoTypeFound; // Not enabled #endif break; } // NIWG DIAL TYPE case kNIWG: { #ifdef __NIWG_ENABLED__ int niwg_enum = (int)niwg::rew::NIWGSyst::FromString(name); if (niwg_enum != 0) { this_enum = niwg_enum + offset; } #else - this_enum = -2; + this_enum = Reweight::kNoTypeFound; #endif break; } // NUWRO DIAL TYPE case kNUWRO: { #ifdef __NUWRO_REWEIGHT_ENABLED__ int nuwro_enum = (int)nuwro::rew::NuwroSyst::FromString(name); if (nuwro_enum > 0) { this_enum = nuwro_enum + offset; } #else - this_enum = -2; + this_enum = Reweight::kNoTypeFound; #endif } // GENIE DIAL TYPE case kGENIE: { #ifdef __GENIE_ENABLED__ int genie_enum = (int)genie::rew::GSyst::FromString(name); if (genie_enum > 0) { this_enum = genie_enum + offset; } #else - this_enum = -2; + this_enum = Reweight::kNoTypeFound; #endif break; } case kCUSTOM: { int custom_enum = 0; // PLACEHOLDER this_enum = custom_enum + offset; break; } // T2K DIAL TYPE case kT2K: { #ifdef __T2KREW_ENABLED__ int t2k_enum = (int)t2krew::T2KSyst::FromString(name); if (t2k_enum > 0) { this_enum = t2k_enum + offset; } #else - this_enum = -2; + this_enum = Reweight::kNoTypeFound; #endif break; } case kNORM: { if (gNormEnums.find(name) == gNormEnums.end()) { gNormEnums[name] = gNormEnums.size() + 1 + offset; } this_enum = gNormEnums[name]; break; } - case kMODENORM: { - size_t us_pos = name.find_first_of('_'); - std::string numstr = name.substr(us_pos + 1); - int mode_num = std::atoi(numstr.c_str()); - LOG(FTL) << "Getting mode num " << mode_num << std::endl; - if (!mode_num) { - ERR(FTL) << "Attempting to parse dial name: \"" << name - << "\" as a mode norm dial but failed." << std::endl; - throw; - } - this_enum = 60 + mode_num + offset; - break; - } - case kLIKEWEIGHT: { if (gLikeWeightEnums.find(name) == gLikeWeightEnums.end()) { gLikeWeightEnums[name] = gLikeWeightEnums.size() + 1 + offset; } this_enum = gLikeWeightEnums[name]; break; } case kSPLINEPARAMETER: { if (gSplineParameterEnums.find(name) == gSplineParameterEnums.end()) { gSplineParameterEnums[name] = gSplineParameterEnums.size() + 1 + offset; } this_enum = gSplineParameterEnums[name]; break; } case kOSCILLATION: { #ifdef __PROB3PP_ENABLED__ int oscEnum = OscWeightEngine::SystEnumFromString(name); if (oscEnum != 0) { this_enum = oscEnum + offset; } #else - this_enum = -2; // Not enabled + this_enum = Reweight::kNoTypeFound; // Not enabled #endif } + case kMODENORM: { + size_t us_pos = name.find_first_of('_'); + std::string numstr = name.substr(us_pos + 1); + int mode_num = std::atoi(numstr.c_str()); + LOG(FTL) << "Getting mode num " << mode_num << std::endl; + if (!mode_num) { + ERR(FTL) << "Attempting to parse dial name: \"" << name + << "\" as a mode norm dial but failed." << std::endl; + throw; + } + this_enum = 60 + mode_num + offset; + break; + } } // If Not Enabled - if (this_enum == -2) { + if (this_enum == Reweight::kNoTypeFound) { ERR(FTL) << "RW Engine not supported for " << FitBase::ConvDialType(type) << std::endl; ERR(FTL) << "Check dial " << name << std::endl; } // If Not Found - if (this_enum == -1) { + if (this_enum == Reweight::kNoDialFound) { ERR(FTL) << "Dial " << name << " not found." << std::endl; } return this_enum; } -int Reweight::ConvDialType(std::string type) { - if (!type.compare("neut_parameter")) - return kNEUT; - else if (!type.compare("niwg_parameter")) - return kNIWG; - else if (!type.compare("nuwro_parameter")) - return kNUWRO; - else if (!type.compare("t2k_parameter")) - return kT2K; - else if (!type.compare("genie_parameter")) - return kGENIE; - else if (!type.compare("norm_parameter")) - return kNORM; - else if (!type.compare("modenorm_parameter")) - return kMODENORM; - else if (!type.compare("custom_parameter")) - return kCUSTOM; - else if (!type.compare("likeweight_parameter")) - return kLIKEWEIGHT; - else if (!type.compare("spline_parameter")) - return kSPLINEPARAMETER; - else if (!type.compare("osc_parameter")) - return kOSCILLATION; - else - return kUNKNOWN; +int Reweight::ConvDialType(std::string const &type) { + return FitBase::ConvDialType(type); } std::string Reweight::ConvDialType(int type) { - switch (type) { - case kNEUT: { - return "neut_parameter"; - } - case kNIWG: { - return "niwg_parameter"; - } - case kNUWRO: { - return "nuwro_parameter"; - } - case kT2K: { - return "t2k_parameter"; - } - case kGENIE: { - return "genie_parameter"; - } - case kNORM: { - return "norm_parameter"; - } - case kCUSTOM: { - return "custom_parameter"; - } - - case kMODENORM: { - return "modenorm_parameter"; - } - case kLIKEWEIGHT: { - return "likeweight_parameter"; - } - case kSPLINEPARAMETER: { - return "spline_parameter"; - } + return FitBase::ConvDialType(type); +} - case kOSCILLATION: { - return "spline_parameter"; - } - default: - return "unknown_parameter"; - } +int Reweight::GetDialType(int type) { + int t = (type / 1000); + return t > kMODENORM ? Reweight::kNoDialFound : t; } +int Reweight::RemoveDialType(int type) { return (type % 1000); } -int Reweight::NEUTEnumFromName(std::string name) { +int Reweight::NEUTEnumFromName(std::string const &name) { #ifdef __NEUT_ENABLED__ int neutenum = (int)neut::rew::NSyst::FromString(name); - return (neutenum > 0) ? neutenum : kNoDialFound; + return (neutenum > 0) ? neutenum : Reweight::kNoDialFound; #else - return kGeneratorNotBuilt; + return Reweight::kGeneratorNotBuilt; #endif } -int Reweight::NIWGEnumFromName(std::string name) { +int Reweight::NIWGEnumFromName(std::string const &name) { #ifdef __NIWG_ENABLED__ int niwgenum = (int)niwg::rew::NIWGSyst::FromString(name); - return (niwgenum != 0) ? niwgenum : kNoDialFound; + return (niwgenum != 0) ? niwgenum : Reweight::kNoDialFound; #else - return kGeneratorNotBuilt; + return Reweight::kGeneratorNotBuilt; #endif } -int Reweight::NUWROEnumFromName(std::string name) { +int Reweight::NUWROEnumFromName(std::string const &name) { #ifdef __NUWRO_REWEIGHT_ENABLED__ int nuwroenum = (int)nuwro::rew::NuwroSyst::FromString(name); - return (nuwroenum > 0) ? nuwroenum : kNoDialFound; + return (nuwroenum > 0) ? nuwroenum : Reweight::kNoDialFound; #else - return kGeneratorNotBuilt; + return Reweight::kGeneratorNotBuilt; #endif } -int Reweight::GENIEEnumFromName(std::string name) { +int Reweight::GENIEEnumFromName(std::string const &name) { #ifdef __GENIE_ENABLED__ int genieenum = (int)genie::rew::GSyst::FromString(name); - return (genieenum > 0) ? genieenum : kNoDialFound; + return (genieenum > 0) ? genieenum : Reweight::kNoDialFound; #else - return kGeneratorNotBuilt; + return Reweight::kGeneratorNotBuilt; #endif } -int Reweight::T2KEnumFromName(std::string name) { +int Reweight::T2KEnumFromName(std::string const &name) { #ifdef __T2KREW_ENABLED__ int t2kenum = (int)t2krew::T2KSyst::FromString(name); - return (t2kenum > 0) ? t2kenum : kNoDialFound; + return (t2kenum > 0) ? t2kenum : Reweight::kNoDialFound; #else - return kGeneratorNotBuilt; + return Reweight::kGeneratorNotBuilt; #endif } -int Reweight::OscillationEnumFromName(std::string name) { +int Reweight::OscillationEnumFromName(std::string const &name) { #ifdef __PROB3PP_ENABLED__ int oscEnum = OscWeightEngine::SystEnumFromString(name); - return (oscEnum > 0) ? oscEnum : kNoDialFound; + return (oscEnum > 0) ? oscEnum : Reweight::kNoDialFound; #else - return kGeneratorNotBuilt; + return Reweight::kGeneratorNotBuilt; #endif } -int Reweight::NUISANCEEnumFromName(std::string name, int type) { +int Reweight::NUISANCEEnumFromName(std::string const &name, int type) { int nuisenum = Reweight::DialList().EnumFromNameAndType(name, type); return nuisenum; } -int Reweight::CustomEnumFromName(std::string name) { +int Reweight::CustomEnumFromName(std::string const &name) { int custenum = Reweight::ConvertNUISANCEDial(name); return custenum; } -int Reweight::ConvDial(std::string name, std::string type, bool exceptions) { +int Reweight::ConvDial(std::string const &name, std::string const &type, + bool exceptions) { return Reweight::ConvDial(name, Reweight::ConvDialType(type), exceptions); } -int Reweight::ConvDial(std::string fullname, int type, bool exceptions) { +int Reweight::ConvDial(std::string const &fullname, int type, bool exceptions) { std::string name = GeneralUtils::ParseToStr(fullname, ",")[0]; // Only use first dial given // Produce offset seperating each type. int offset = type * 1000; - int genenum = kNoDialFound; + int genenum = Reweight::kNoDialFound; switch (type) { case kNEUT: genenum = NEUTEnumFromName(name); break; case kNIWG: genenum = NIWGEnumFromName(name); break; case kNUWRO: genenum = NUWROEnumFromName(name); break; case kGENIE: genenum = GENIEEnumFromName(name); break; case kT2K: genenum = T2KEnumFromName(name); break; case kCUSTOM: genenum = CustomEnumFromName(name); break; case kNORM: - case kMODENORM: case kLIKEWEIGHT: case kSPLINEPARAMETER: case kNEWSPLINE: genenum = NUISANCEEnumFromName(name, type); break; case kOSCILLATION: genenum = OscillationEnumFromName(name); break; + case kMODENORM: + genenum = ModeNormEngine::SystEnumFromString(name); + break; + default: - genenum = kNoTypeFound; + genenum = Reweight::kNoTypeFound; break; } // Throw if required. if (exceptions) { // If Not Enabled - if (genenum == kGeneratorNotBuilt) { + if (genenum == Reweight::kGeneratorNotBuilt) { ERR(FTL) << "RW Engine not supported for " << FitBase::ConvDialType(type) << std::endl; ERR(FTL) << "Check dial " << name << std::endl; throw; } // If no type enabled - if (genenum == kNoTypeFound) { + if (genenum == Reweight::kNoTypeFound) { ERR(FTL) << "Type mismatch inside ConvDialEnum" << std::endl; throw; } // If Not Found - if (genenum == kNoDialFound) { + if (genenum == Reweight::kNoDialFound) { ERR(FTL) << "Dial " << name << " not found." << std::endl; throw; } } // Add offset if no issue int nuisenum = genenum; - if (genenum != kGeneratorNotBuilt and genenum != kNoTypeFound and - genenum != kNoDialFound) { + if ((genenum != Reweight::kGeneratorNotBuilt) && + (genenum != Reweight::kNoTypeFound) && + (genenum != Reweight::kNoDialFound)) { nuisenum += offset; } // Now register dial - // std::cout << "Returning " << nuisenum << std::endl; Reweight::DialList().RegisterDialEnum(name, type, nuisenum); return nuisenum; } std::string Reweight::ConvDial(int nuisenum) { - // GlobalDialList* temp; for (size_t i = 0; i < Reweight::DialList().fAllDialEnums.size(); i++) { if (Reweight::DialList().fAllDialEnums[i] == nuisenum) { return Reweight::DialList().fAllDialNames[i]; } } LOG(FIT) << "Cannot find dial with enum = " << nuisenum << std::endl; return ""; } diff --git a/src/Reweight/WeightUtils.h b/src/Reweight/WeightUtils.h index c2e35ef..c7b044f 100644 --- a/src/Reweight/WeightUtils.h +++ b/src/Reweight/WeightUtils.h @@ -1,144 +1,63 @@ #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" +#include "TF1.h" -enum extra_reweight_types { kOSCILLATION = kLast_generator_event_type }; +enum extra_reweight_types { + kOSCILLATION = kLast_generator_event_type, + kMODENORM +}; namespace FitBase { -TF1 GetRWConvFunction(std::string type, std::string name); -std::string GetRWUnits(std::string type, std::string name); +TF1 GetRWConvFunction(std::string const &type, std::string const &name); +std::string GetRWUnits(std::string const &type, std::string const &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); +double RWSigmaToFrac(std::string const &type, std::string const &name, + double val); +double RWSigmaToAbs(std::string const &type, std::string const &name, + double val); +double RWAbsToSigma(std::string const &type, std::string const &name, + double val); +double RWFracToSigma(std::string const &type, std::string const &name, + double val); -int ConvDialType(std::string type); +int ConvDialType(std::string const &type); std::string ConvDialType(int type); -int GetDialEnum(std::string type, std::string name); -int GetDialEnum(int type, std::string name); +int GetDialEnum(std::string const &type, std::string const &name); +int GetDialEnum(int type, std::string const &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); +int ConvDial(std::string const &name, std::string const &type, + bool exceptions = false); +int ConvDial(std::string const &name, int type, bool exceptions = false); std::string ConvDial(int nuisenum); -int ConvDialType(std::string type); +int ConvDialType(std::string const &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); +int GetDialType(int type); +int RemoveDialType(int type); + +int NEUTEnumFromName(std::string const &name); +int NIWGEnumFromName(std::string const &name); +int NUWROEnumFromName(std::string const &name); +int T2KEnumFromName(std::string const &name); +int GENIEEnumFromName(std::string const &name); +int CustomEnumFromName(std::string const &name); + +int NUISANCEEnumFromName(std::string const &name, int type); +int OscillationEnumFromName(std::string const &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 9d1dc26..ee3e995 100755 --- a/src/Routines/MinimizerRoutines.cxx +++ b/src/Routines/MinimizerRoutines.cxx @@ -1,1510 +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; + fCovar = NULL; + fCovFree = NULL; + fCorrel = NULL; fCorFree = NULL; - fDecomp = NULL; + fDecomp = NULL; fDecFree = NULL; fStrategy = "Migrad,FixAtLimBreak,Migrad"; fRoutines.clear(); fCardFile = ""; fFakeDataInput = ""; - fSampleFCN = NULL; + fSampleFCN = NULL; - fMinimizer = 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"); + fCallFunctor = NULL; + + fAllowedRoutines = + ("Migrad,Simplex,Combined," + "Brute,Fumili,ConjugateFR," + "ConjugatePR,BFGS,BFGS2," + "SteepDesc,GSLSimAn,FixAtLim,FixAtLimBreak," + "Chi2Scan1D,Chi2Scan2D,Contours,ErrorBands," + "DataToys,MCMC"); }; //************************************* -MinimizerRoutines::~MinimizerRoutines() { -//************************************* +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; + 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"); + 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 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"); + if (!key.Has("state")) { + key.SetS("state", "FIX"); } std::string parstate = key.GetS("state"); // Extra limits if (key.Has("low")) { - parlow = key.GetD("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; + LOG(FIT) << "Read " << partype << " : " << parname << " = " << parnom + << " : " << parlow << " < p < " << parhigh << " : " << parstate + << std::endl; } else { - LOG(FIT) << "Read " << partype << " : " - << parname << " = " - << parnom << " : " - << parstate << std::endl; + 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 ); + 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 ); + 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);; + fTypeVals[parname] = FitBase::ConvDialType(partype); + ; fStartVals[parname] = parnom; - fCurVals[parname] = parnom; + fCurVals[parname] = parnom; fErrorVals[parname] = 0.0; - fStateVals[parname] = parstate; + fStateVals[parname] = parstate; bool fixstate = parstate.find("FIX") != std::string::npos; - fFixVals[parname] = fixstate; + fFixVals[parname] = fixstate; fStartFixVals[parname] = fFixVals[parname]; - fMinVals[parname] = parlow; - fMaxVals[parname] = parhigh; + fMinVals[parname] = parlow; + fMaxVals[parname] = parhigh; fStepVals[parname] = parstep; - } // Setup Samples ---------------------------------------------- - std::vector samplekeys = Config::QueryKeys("sample"); + 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"; + std::string sampletype = key.Has("type") ? key.GetS("type") : "DEFAULT"; - double samplenorm = - key.Has("norm") ? key.GetD("norm") : 1.0; + 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 + 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; + fMinVals[normname] = 0.1; + fMaxVals[normname] = 10.0; fStepVals[normname] = 0.5; bool state = sampletype.find("FREE") == std::string::npos; - fFixVals[normname] = state; + 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"); + 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) ); + 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() ); + fMinimizerFCN = new MinimizerFCN(fSampleFCN); + fCallFunctor = new ROOT::Math::Functor(*fMinimizerFCN, fParams.size()); - fSampleFCN->CreateIterationTree( "fit_iterations", FitBase::GetRW() ); + fSampleFCN->CreateIterationTree("fit_iterations", FitBase::GetRW()); return; } - //****************************************** void MinimizerRoutines::SetupFitter(std::string routine) { -//****************************************** + //****************************************** // Make the fitter std::string fitclass = ""; - std::string fittype = ""; + 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"; + 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"; + 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 = ""; } + 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; - fMinimizer = ROOT::Math::Factory::CreateMinimizer(fitclass, fittype); - fMinimizer->SetMaxFunctionCalls(FitPar::Config().GetParI("minimizer.maxcalls")); + 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->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 + // 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); + 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; + 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; + 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 + // 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 + // 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) { -//************************************* +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; + 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 (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")) { - + 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; + << " = " << 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 typestr = FitBase::ConvDialType(fTypeVals[syst]); std::string curunits = "(sig.)"; - double curval = fCurVals[syst]; - double curerr = fErrorVals[syst]; + 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)); + 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; - + 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::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(); + 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]; + 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)); + fCovFree->SetBinContent(freex + 1, freey + 1, + fMinimizer->CovMatrix(i, j)); freey++; } freex++; } - fCorrel = PlotUtils::GetCorrelationPlot(fCovar, "correlation"); - fDecomp = PlotUtils::GetDecompPlot(fCovar, "decomposition"); + 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"); + 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() ); + 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", + fSampleFCN->CreateIterationTree(fParams[i] + "_scan1D_iterations", FitBase::GetRW()); double scanmiddlepoint = fCurVals[fParams[i]]; // Determine N points needed - double limlow = fMinVals[fParams[i]]; + double limlow = fMinVals[fParams[i]]; double limhigh = fMaxVals[fParams[i]]; - double step = fStepVals[fParams[i]]; + double step = fStepVals[fParams[i]]; - int npoints = int( fabs(limhigh - limlow) / (step + 0.) ); + 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); + 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 ); + 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() ); + 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 limlow_i = fMinVals[fParams[i]]; double limhigh_i = fMaxVals[fParams[i]]; - double step_i = fStepVals[fParams[i]]; + double step_i = fStepVals[fParams[i]]; - double limlow_j = fMinVals[fParams[j]]; + double limlow_j = fMinVals[fParams[j]]; double limhigh_j = fMaxVals[fParams[j]]; - double step_j = fStepVals[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; + 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 ); + 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; + 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 ); + 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; + 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; + } 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; + 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 ); + nameVect.push_back(name); - valVect .push_back( fCurVals.at(name) ); + valVect.push_back(fCurVals.at(name)); - errVect .push_back( fErrorVals.at(name) ); + errVect.push_back(fErrorVals.at(name)); - minVect .push_back( fMinVals.at(name) ); + minVect.push_back(fMinVals.at(name)); - maxVect .push_back( fMaxVals.at(name) ); + maxVect.push_back(fMaxVals.at(name)); - startVect .push_back( fStartVals.at(name) ); + startVect.push_back(fStartVals.at(name)); - endfixVect .push_back( fFixVals.at(name) ); + endfixVect.push_back(fFixVals.at(name)); - startfixVect.push_back( fStartFixVals.at(name) ); + startfixVect.push_back(fStartFixVals.at(name)); ipar++; } int NFREE = fMinimizer->NFree(); - int NDIM = fMinimizer->NDim(); + 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 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 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); + 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.SetBinContent(i + 1, minVect.at(i)); minvar.GetXaxis()->SetBinLabel(i + 1, name.c_str()); - maxvar.SetBinContent(i + 1, maxVect.at(i)); + 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.SetBinContent(freecount, minVect.at(i)); minvarfree.GetXaxis()->SetBinLabel(freecount, name.c_str()); - maxvarfree.SetBinContent(freecount, maxVect.at(i)); + 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" - }; + 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()); + 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(); + 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, + 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; } - + 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"); + TDirectory* errorDIR = (TDirectory*)fOutputRootFile->mkdir("error_bands"); errorDIR->cd(); - // Make a second file to store throws + // Make a second file to store throws std::string tempFileName = fOutputFile; - if (tempFileName.find(".root") != std::string::npos) tempFileName.erase(tempFileName.find(".root"), 5); + if (tempFileName.find(".root") != std::string::npos) + tempFileName.erase(tempFileName.find(".root"), 5); tempFileName += ".throws.root"; - TFile* tempfile = new TFile(tempFileName.c_str(),"RECREATE"); + 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"); + TDirectory* nominal = (TDirectory*)tempfile->mkdir("nominal"); nominal->cd(); fSampleFCN->Write(); - - TDirectory* outnominal = (TDirectory*) fOutputRootFile->mkdir("nominal_throw"); + 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(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 ); + 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 + // Now go through the keys in the temporary file and look for TH1D, and TH2D + // plots TIter next(nominal->GetListOfKeys()); - TKey *key; + TKey* key; while ((key = (TKey*)next())) { - TClass *cl = gROOT->GetClass(key->GetClassName()); + TClass* cl = gROOT->GetClass(key->GetClassName()); if (!cl->InheritsFrom("TH1D") and !cl->InheritsFrom("TH2D")) continue; - TH1D *baseplot = (TH1D*)key->ReadObj(); + 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"); + 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()); + 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)); + 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)); + 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]; + 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; + delete[] bincontents; } return; }; - -void MinimizerRoutines::ThrowDataToys(){ +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++){ + 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++){ + 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 new file mode 100644 index 0000000..527be29 --- /dev/null +++ b/src/Routines/Simple_MH_Sampler.h @@ -0,0 +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::GetParI("MCMC.thin"); + thin_ctr = 0; + 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 (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 d33b35e..8e17091 100755 --- a/src/Routines/SystematicRoutines.cxx +++ b/src/Routines/SystematicRoutines.cxx @@ -1,1517 +1,1457 @@ // 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))/35; + // 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->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; }; + +void SystematicRoutines::EigenErrors(){ + + + fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE"); + fOutputRootFile->cd(); + + // Make Covariance + TMatrixDSym* fullcovar = new TMatrixDSym( fParams.size() ); + + // Extract covariance from all loaded ParamPulls + for (PullListConstIter iter = fInputThrows.begin(); + iter != fInputThrows.end(); iter++){ + ParamPull* pull = *iter; + + // Check pull is actualyl Gaussian + std::string pulltype = pull->GetType(); + if (pulltype.find("GAUSTHROW") == std::string::npos){ + THROW("Can only calculate EigenErrors for Gaussian pulls!"); + } + + // Get data and covariances + TH1D dialhist = pull->GetDataHist(); + TH2D covhist = pull->GetFullCovar(); + + // Loop over all dials and compare names + for (int pari = 0; pari < fParams.size(); pari++){ + for (int parj = 0; parj < fParams.size(); parj++){ + + std::string name_pari = fParams[pari]; + std::string name_parj = fParams[parj]; + + // Compare names to those in the pull + for (int pulli = 0; pulli < dialhist.GetNbinsX(); pulli++){ + for (int pullj = 0; pullj < dialhist.GetNbinsX(); pullj++){ + + std::string name_pulli = dialhist.GetXaxis()->GetBinLabel(pulli+1); + std::string name_pullj = dialhist.GetXaxis()->GetBinLabel(pullj+1); + + if (name_pulli == name_pari && name_pullj == name_parj){ + (*fullcovar)[pari][parj] = covhist.GetBinContent(pulli+1, pullj+1); + fCurVals[name_pari] = dialhist.GetBinContent(pulli+1); + fCurVals[name_parj] = dialhist.GetBinContent(pullj+1); + } + + } + } + + } + } + } + + /* + TFile* test = new TFile("testingcovar.root","RECREATE"); + test->cd(); + TH2D* joinedcov = new TH2D("COVAR","COVAR", + fullcovar->GetNrows(), 0.0, float(fullcovar->GetNrows()), + fullcovar->GetNrows(), 0.0, float(fullcovar->GetNrows())); + for (int i = 0; i < fullcovar->GetNrows(); i++){ + for (int j = 0; j < fullcovar->GetNcols(); j++){ + joinedcov->SetBinContent(i+1, j+1, (*fullcovar)[i][j]); + } + } + joinedcov->Write("COVAR"); + test->Close(); + */ + + // Calculator all EigenVectors and EigenValues + TMatrixDSymEigen* eigen = new TMatrixDSymEigen(*fullcovar); + const TVectorD eigenVals = eigen->GetEigenValues(); + const TMatrixD eigenVect = eigen->GetEigenVectors(); + eigenVals.Print(); + eigenVect.Print(); + + TDirectory* outnominal = (TDirectory*) fOutputRootFile->mkdir("nominal"); + outnominal->cd(); + + double *valst = FitUtils::GetArrayFromMap( fParams, fCurVals ); + double chi2 = fSampleFCN->DoEval( valst ); + delete valst; + fSampleFCN->Write(); + + // Loop over all throws + TDirectory* throwsdir = (TDirectory*) fOutputRootFile->mkdir("throws"); + throwsdir->cd(); + + int count = 0; + // Produce all error throws. + for (int i = 0; i < eigenVect.GetNrows(); i++){ + + TDirectory* throwfolder = (TDirectory*)throwsdir->mkdir(Form("throw_%i",count)); + throwfolder->cd(); + + // Get New Parameter Vector + LOG(FIT) << "Parameter Set " << count << std::endl; + for (int j = 0; j < eigenVect.GetNrows(); j++){ + std::string param = fParams[j]; + LOG(FIT) << " " << j << ". " << param << " : " << fCurVals[param] + sqrt(eigenVals[i]) * eigenVect[j][i] << std::endl; + fThrownVals[param] = fCurVals[param] + sqrt(eigenVals[i]) * eigenVect[j][i]; + } + + // Run Eval + double *vals = FitUtils::GetArrayFromMap( fParams, fThrownVals ); + double chi2 = fSampleFCN->DoEval( vals ); + delete vals; + count++; + + fSampleFCN->Write(); + + + throwfolder = (TDirectory*)throwsdir->mkdir(Form("throw_%i",count)); + throwfolder->cd(); + + // Get New Parameter Vector + LOG(FIT) << "Parameter Set " << count << std::endl; + for (int j = 0; j < eigenVect.GetNrows(); j++){ + std::string param = fParams[j]; + LOG(FIT) << " " << j << ". " << param << " : " <DoEval( vals2 ); + delete vals2; + count++; + + // Save the FCN + fSampleFCN->Write(); + + } + + fOutputRootFile->Close(); + fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "UPDATE"); + fOutputRootFile->cd(); + throwsdir = (TDirectory*) fOutputRootFile->Get("throws"); + outnominal = (TDirectory*) fOutputRootFile->Get("nominal"); + + // Loop through Error DIR + TDirectory* outerr = (TDirectory*) fOutputRootFile->mkdir("errors"); + outerr->cd(); + TIter next(outnominal->GetListOfKeys()); + TKey *key; + while ((key = (TKey*)next())) { + + TClass *cl = gROOT->GetClass(key->GetClassName()); + if (!cl->InheritsFrom("TH1D") and !cl->InheritsFrom("TH2D")) continue; + + LOG(FIT) << "Creating error bands for " << key->GetName() << std::endl; + std::string plotname = std::string(key->GetName()); + + if (plotname.find("_EVT") != std::string::npos) continue; + if (plotname.find("_FLUX") != std::string::npos) continue; + if (plotname.find("_FLX") != std::string::npos) continue; + + TH1* baseplot = (TH1D*)key->ReadObj()->Clone(Form("%s_ORIGINAL",key->GetName())); + TH1* errorplot_upper = (TH1D*)baseplot->Clone(Form("%s_ERROR_UPPER",key->GetName())); + TH1* errorplot_lower = (TH1D*)baseplot->Clone(Form("%s_ERROR_LOWER", key->GetName())); + TH1* meanplot = (TH1D*)baseplot->Clone(Form("%s_SET_MEAN", key->GetName())); + TH1* systplot = (TH1D*)baseplot->Clone(Form("%s_SYST", key->GetName())); + TH1* statplot = (TH1D*)baseplot->Clone(Form("%s_STAT", key->GetName())); + TH1* totlplot = (TH1D*)baseplot->Clone(Form("%s_TOTAL", key->GetName())); + + int nbins = 0; + if (cl->InheritsFrom("TH1D")) nbins = ((TH1D*)baseplot)->GetNbinsX(); + else nbins = ((TH1D*)baseplot)->GetNbinsX()* ((TH1D*)baseplot)->GetNbinsY(); + + meanplot->Reset(); + errorplot_upper->Reset(); + errorplot_lower->Reset(); + + for (int j = 0; j < nbins; j++){ + errorplot_upper->SetBinError(j+1, 0.0); + errorplot_lower->SetBinError(j+1, 0.0); + } + + // Loop over throws and calculate mean and error for +- throws + int addcount = 0; + + // Add baseplot first to slightly bias to central value + meanplot->Add(baseplot); + addcount++; + + for (int i = 0; i < count; i++){ + TH1* newplot = (TH1D*) throwsdir->Get(Form("throw_%i/%s",i,plotname.c_str())); + if (!newplot){ + ERR(WRN) << "Cannot find new plot : " << Form("throw_%i/%s",i,plotname.c_str()) << std::endl; + ERR(WRN) << "This plot will not have the correct errors!" << std::endl; + continue; + } + newplot->SetDirectory(0); + nbins = newplot->GetNbinsX(); + + for (int j = 0; j < nbins; j++){ + if (i % 2 == 0){ + // std::cout << plotname<< " : upper " << errorplot_upper->GetBinContent(j+1) << " adding " << pow(baseplot->GetBinContent(j+1) - newplot->GetBinContent(j+1),2) << std::endl; + // std::cout << " -> " << baseplot->GetBinContent(j+1) << " " <GetBinContent(j+1) << std::endl; + errorplot_upper->SetBinContent(j+1, errorplot_upper->GetBinContent(j+1) + + pow(baseplot->GetBinContent(j+1) - newplot->GetBinContent(j+1),2)); + // newplot->Print(); + } else { + // std::cout << plotname << " : lower " << errorplot_lower->GetBinContent(j+1) << " adding " << pow(baseplot->GetBinContent(j+1) - newplot->GetBinContent(j+1),2) << std::endl; + // std::cout << " -> " << baseplot->GetBinContent(j+1) << " " << newplot->GetBinContent(j+1) << std::endl; + errorplot_lower->SetBinContent(j+1, errorplot_lower->GetBinContent(j+1) + + pow(baseplot->GetBinContent(j+1) - newplot->GetBinContent(j+1),2)); + // newplot->Print(); + } + meanplot->SetBinContent(j+1, meanplot->GetBinContent(j+1) + baseplot->GetBinContent(j+1)); + } + delete newplot; + addcount++; + } + + // Get mean Average + for (int j = 0; j < nbins; j++){ + meanplot->SetBinContent(j+1, meanplot->GetBinContent(j+1)/double(addcount)); + } + + for (int j = 0; j < nbins; j++){ + errorplot_upper->SetBinContent(j+1, sqrt(errorplot_upper->GetBinContent(j+1))); + errorplot_lower->SetBinContent(j+1, sqrt(errorplot_lower->GetBinContent(j+1))); + + statplot->SetBinError(j+1, baseplot->GetBinError(j+1) ); + systplot->SetBinError(j+1, (errorplot_upper->GetBinContent(j+1) + errorplot_lower->GetBinContent(j+1))/2.0); + totlplot->SetBinError(j+1, sqrt( pow(statplot->GetBinError(j+1),2) + pow(systplot->GetBinError(j+1),2) ) ); + + meanplot->SetBinError(j+1, sqrt( pow(statplot->GetBinError(j+1),2) + pow(systplot->GetBinError(j+1),2) ) ); + + } + + outerr->cd(); + errorplot_upper->Write(); + errorplot_lower->Write(); + baseplot->Write(); + meanplot->Write(); + + statplot->Write(); + systplot->Write(); + totlplot->Write(); + + delete errorplot_upper; + delete errorplot_lower; + delete baseplot; + delete meanplot; + delete statplot; + delete systplot; + delete totlplot; + } + +} diff --git a/src/Routines/SystematicRoutines.h b/src/Routines/SystematicRoutines.h index 97737aa..b069a4b 100755 --- a/src/Routines/SystematicRoutines.h +++ b/src/Routines/SystematicRoutines.h @@ -1,267 +1,269 @@ // 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 "TMatrixDSymEigen.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(); + + void EigenErrors(); /* 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/Smearceptance/CMakeLists.txt b/src/Smearceptance/CMakeLists.txt index a0f7251..cea1034 100644 --- a/src/Smearceptance/CMakeLists.txt +++ b/src/Smearceptance/CMakeLists.txt @@ -1,54 +1,70 @@ # 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 ISmearcepter.h Smearcepterton.h +EfficiencyApplicator.h ThresholdAccepter.h +TrackedMomentumMatrixSmearer.h +GaussianSmearer.h + +EnergyShuffler.h + +MetaSimpleSmearcepter.h +SmearceptanceUtils.h ) set(IMPLFILES ISmearcepter.cxx Smearcepterton.cxx +EfficiencyApplicator.cxx ThresholdAccepter.cxx +TrackedMomentumMatrixSmearer.cxx +GaussianSmearer.cxx + +EnergyShuffler.cxx + +MetaSimpleSmearcepter.cxx +SmearceptanceUtils.cxx ) set(LIBNAME Smearceptance) 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}") 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/Smearceptance/EfficiencyApplicator.cxx b/src/Smearceptance/EfficiencyApplicator.cxx new file mode 100644 index 0000000..55ab9b3 --- /dev/null +++ b/src/Smearceptance/EfficiencyApplicator.cxx @@ -0,0 +1,388 @@ +// 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 "EfficiencyApplicator.h" + +#include "TEfficiency.h" +#include "TH2.h" +#include "TH3.h" + +//#define DEBUG_EFFAPP + +EfficiencyApplicator::DependVar GetVarType(std::string const &axisvar) { + if (axisvar == "kMomentum") { + return EfficiencyApplicator::kMomentum; + } else if (axisvar == "kKE") { + return EfficiencyApplicator::kKE; + } else if (axisvar == "kTheta") { + return EfficiencyApplicator::kTheta; + } else if (axisvar == "kCosTheta") { + return EfficiencyApplicator::kCosTheta; + } else if (axisvar == "kPhi") { + return EfficiencyApplicator::kPhi; + } + return EfficiencyApplicator::kNoAxis; +} + +TH1 *GetEffHist(TFile *inputFile, std::string const &HistName) { + TH1 *hist = dynamic_cast(inputFile->Get(HistName.c_str())); + if (hist) { + return hist; + } + + TEfficiency *effHist = + dynamic_cast(inputFile->Get(HistName.c_str())); + + if (effHist) { + TH1D *numer = dynamic_cast(effHist->GetCopyPassedHisto()); + TH1D *denom = dynamic_cast(effHist->GetCopyTotalHisto()); + + if (numer && denom) { + numer->Divide(denom); + + denom->SetDirectory(NULL); + delete denom; + + // Gonna be a memory leak, but I'll get over it + numer->SetDirectory(NULL); + return numer; + } + ERROR(FTL, "TEfficiency internal histograms were not TH1Ds."); + } + + THROW("Couldn't get appropriate efficiency object named " + << HistName << " from input file " << inputFile->GetName()); +} + +/// Reads particle efficiency nodes +/// +/// Nodes look like: +/// +/// +/// +/// +/// +/// +void EfficiencyApplicator::SpecifcSetup(nuiskey &nk) { + rand.~TRandom3(); + new (&rand) TRandom3(); + + std::vector effDescriptors = + nk.GetListOfChildNodes("EfficiencyCurve"); + + for (size_t t_it = 0; t_it < effDescriptors.size(); ++t_it) { + std::string inputFileName = effDescriptors[t_it].GetS("InputFile"); + std::string HistName = effDescriptors[t_it].GetS("HistName"); + + TFile inputFile(inputFileName.c_str()); + if (!inputFile.IsOpen()) { + THROW("Couldn't open specified input root file: " << inputFileName); + } + + TH1 *inpHist = GetEffHist(&inputFile, HistName); + if (!inpHist) { + THROW("Couldn't get TH1D named: " << HistName << " from input root file: " + << inputFileName); + } + + int NDims = effDescriptors[t_it].GetI("NDims"); + + if (NDims < 1 || NDims > 3) { + THROW("Read NDims attribute as: " << NDims << ", efficiency curve can " + "currently have between 1 " + "and 3 dimensions."); + } + + EfficiencyApplicator::DependVar XVar = + GetVarType(effDescriptors[t_it].GetS("XAxis")); + double XAxisScale = effDescriptors[t_it].Has("XAxisScaleToInternal") + ? effDescriptors[t_it].GetD("XAxisScaleToInternal") + : 1; + EfficiencyApplicator::DependVar YVar = + NDims > 1 ? GetVarType(effDescriptors[t_it].GetS("YAxis")) + : EfficiencyApplicator::kNoAxis; + double YAxisScale = effDescriptors[t_it].Has("YAxisScaleToInternal") + ? effDescriptors[t_it].GetD("YAxisScaleToInternal") + : 1; + EfficiencyApplicator::DependVar ZVar = + NDims > 2 ? GetVarType(effDescriptors[t_it].GetS("ZAxis")) + : EfficiencyApplicator::kNoAxis; + double ZAxisScale = effDescriptors[t_it].Has("ZAxisScaleToInternal") + ? effDescriptors[t_it].GetD("ZAxisScaleToInternal") + : 1; + + bool Interpolate = effDescriptors[t_it].Has("Interpolate") && + effDescriptors[t_it].GetI("Interpolate"); + + // bool ApplyAsWeight = effDescriptors[t_it].Has("ApplyAsWeight") && + // effDescriptors[t_it].GetI("ApplyAsWeight"); + + std::string pdgs_s = effDescriptors[t_it].GetS("PDG"); + std::vector pdgs_i = GeneralUtils::ParseToInt(pdgs_s, ","); + for (size_t pdg_it = 0; pdg_it < pdgs_i.size(); ++pdg_it) { + if (Efficiencies.count(pdgs_i[pdg_it])) { + ERROR(WRN, "Smearceptor " << ElementName << ":" << InstanceName + << " already has a efficiency for PDG: " + << pdgs_i[pdg_it]); + } + + EffMap em; + em.EffCurve = static_cast(inpHist->Clone()); + em.EffCurve->SetDirectory(NULL); + em.Interpolate = Interpolate; + // em.ApplyAsWeight = ApplyAsWeight; + em.NDims = NDims; + em.DependVars[0] = XVar; + em.DependVars[1] = YVar; + em.DependVars[2] = ZVar; + em.AxisScales[0] = XAxisScale; + em.AxisScales[1] = YAxisScale; + em.AxisScales[2] = ZAxisScale; + + Efficiencies[pdgs_i[pdg_it]] = em; + + QLOG(FIT, + "Added reconstruction efficiency curve for PDG: " << pdgs_i[pdg_it]); + } + } + + SlaveTA.Setup(nk); +} + +RecoInfo *EfficiencyApplicator::Smearcept(FitEvent *fe) { + RecoInfo *ri = new RecoInfo(); + + for (size_t p_it = 0; p_it < fe->NParticles(); ++p_it) { + FitParticle *fp = fe->GetParticle(p_it); +#ifdef DEBUG_EFFAPP + std::cout << std::endl; + std::cout << "[" << p_it << "]: " << fp->PDG() << ", " << fp->Status() + << ", " << fp->E() << " -- KE:" << fp->KE() + << " Mom: " << fp->P3().Mag() << std::flush; +#endif + + if (fp->Status() != kFinalState) { +#ifdef DEBUG_EFFAPP + std::cout << " -- Not final state." << std::flush; +#endif + continue; + } + + if (!Efficiencies.count(fp->PDG())) { + SlaveTA.SmearceptOneParticle(ri, fp +#ifdef DEBUG_THRESACCEPT + , + p_it +#endif + ); + continue; + } + + EffMap &em = Efficiencies[fp->PDG()]; + + double kineProps[3]; + for (Int_t dim_it = 0; dim_it < em.NDims; ++dim_it) { + switch (em.DependVars[dim_it]) { + case kMomentum: { + kineProps[dim_it] = fp->P3().Mag(); + break; + } + case kKE: { + kineProps[dim_it] = fp->KE(); + break; + } + case kTheta: { + kineProps[dim_it] = fp->P3().Theta(); + break; + } + case kCosTheta: { + kineProps[dim_it] = fp->P3().CosTheta(); + break; + } + case kPhi: { + kineProps[dim_it] = fp->P3().Phi(); + break; + } + default: { THROW("Trying to find particle value for a kNoAxis."); } + } + kineProps[dim_it] /= em.AxisScales[dim_it]; + } + + double effProb = 0; + + switch (em.NDims) { + case 1: { + TH1 *hist = em.EffCurve; + if (em.Interpolate && + (hist->GetXaxis()->GetBinCenter(1) < kineProps[0]) && + (hist->GetXaxis()->GetBinCenter(hist->GetXaxis()->GetNbins()) > + kineProps[0])) { + effProb = hist->Interpolate(kineProps[0]); + } else { + Int_t xbin = hist->GetXaxis()->FindFixBin(kineProps[0]); + + if (!xbin || ((hist->GetXaxis()->GetNbins() + 1) == xbin)) { + ERROR(WRN, "Tried to apply effiency but XBin: " + << xbin << " is outside range (/" + << hist->GetXaxis()->GetNbins() << "): Prop " + << kineProps[0] << ", [" + << hist->GetXaxis()->GetBinLowEdge(1) << " -- " + << hist->GetXaxis()->GetBinUpEdge( + hist->GetXaxis()->GetNbins())); + } + + effProb = hist->GetBinContent(xbin); + } + break; + } + case 2: { + TH2 *hist = static_cast(em.EffCurve); + + if (em.Interpolate && + (hist->GetXaxis()->GetBinCenter(1) < kineProps[0]) && + (hist->GetXaxis()->GetBinCenter(hist->GetXaxis()->GetNbins()) > + kineProps[0]) && + (hist->GetYaxis()->GetBinCenter(1) < kineProps[1]) && + (hist->GetYaxis()->GetBinCenter(hist->GetYaxis()->GetNbins()) > + kineProps[1])) { + effProb = hist->Interpolate(kineProps[0], kineProps[1]); + } else { + Int_t xbin = hist->GetXaxis()->FindFixBin(kineProps[0]); + Int_t ybin = hist->GetYaxis()->FindFixBin(kineProps[1]); + + if (!xbin || ((hist->GetXaxis()->GetNbins() + 1) == xbin)) { + ERROR(WRN, "Tried to apply effiency but XBin: " + << xbin << " is outside range (/" + << hist->GetXaxis()->GetNbins() << "): Prop " + << kineProps[0] << ", [" + << hist->GetXaxis()->GetBinLowEdge(1) << " -- " + << hist->GetXaxis()->GetBinUpEdge( + hist->GetXaxis()->GetNbins())); + } + + if (!ybin || ((hist->GetYaxis()->GetNbins() + 1) == ybin)) { + ERROR(WRN, "Tried to apply effiency but XBin: " + << ybin << " is outside range (/" + << hist->GetYaxis()->GetNbins() << "): Prop " + << kineProps[0] << ", [" + << hist->GetYaxis()->GetBinLowEdge(1) << " -- " + << hist->GetYaxis()->GetBinUpEdge( + hist->GetYaxis()->GetNbins())); + } + + effProb = hist->GetBinContent(xbin, ybin); + +#ifdef DEBUG_EFFAPP + std::cout << "\t\t: XProp: " << kineProps[0] + << ", YProp: " << kineProps[1] << " x/y bins: " << xbin + << "/" << ybin << ". Prop ? " << effProb << std::endl; +#endif + } + break; + } + case 3: { + TH3 *hist = static_cast(em.EffCurve); + + if (em.Interpolate && + (hist->GetXaxis()->GetBinCenter(1) < kineProps[0]) && + (hist->GetXaxis()->GetBinCenter(hist->GetXaxis()->GetNbins()) > + kineProps[0]) && + (hist->GetYaxis()->GetBinCenter(1) < kineProps[1]) && + (hist->GetYaxis()->GetBinCenter(hist->GetYaxis()->GetNbins()) > + kineProps[2]) && + (hist->GetZaxis()->GetBinCenter(hist->GetZaxis()->GetNbins()) > + kineProps[2])) { + effProb = hist->Interpolate(kineProps[0], kineProps[1], kineProps[2]); + } else { + Int_t xbin = hist->GetXaxis()->FindFixBin(kineProps[0]); + Int_t ybin = hist->GetYaxis()->FindFixBin(kineProps[1]); + Int_t zbin = hist->GetZaxis()->FindFixBin(kineProps[2]); + + if (!xbin || ((hist->GetXaxis()->GetNbins() + 1) == xbin)) { + ERROR(WRN, "Tried to apply effiency but XBin: " + << xbin << " is outside range (/" + << hist->GetXaxis()->GetNbins() << "): Prop " + << kineProps[0] << ", [" + << hist->GetXaxis()->GetBinLowEdge(1) << " -- " + << hist->GetXaxis()->GetBinUpEdge( + hist->GetXaxis()->GetNbins())); + } + + if (!ybin || ((hist->GetYaxis()->GetNbins() + 1) == ybin)) { + ERROR(WRN, "Tried to apply effiency but XBin: " + << ybin << " is outside range (/" + << hist->GetYaxis()->GetNbins() << "): Prop " + << kineProps[0] << ", [" + << hist->GetYaxis()->GetBinLowEdge(1) << " -- " + << hist->GetYaxis()->GetBinUpEdge( + hist->GetYaxis()->GetNbins())); + } + + if (!zbin || ((hist->GetZaxis()->GetNbins() + 1) == zbin)) { + ERROR(WRN, "Tried to apply effiency but ZBin: " + << zbin << " is outside range (/" + << hist->GetZaxis()->GetNbins() << "): Prop " + << kineProps[0] << ", [" + << hist->GetZaxis()->GetBinLowEdge(1) << " -- " + << hist->GetZaxis()->GetBinUpEdge( + hist->GetZaxis()->GetNbins())); + } + + effProb = hist->GetBinContent(xbin, ybin, zbin); + } + break; + } + } + + bool accepted = (rand.Uniform() < effProb); + + if (accepted) { +#ifdef DEBUG_EFFAPP + std::cout << " -- Reconstructed with probability: " << effProb + << std::flush; +#endif + ri->RecObjMom.push_back(fp->P3()); + ri->RecObjClass.push_back(fp->PDG()); + + continue; + } + +#ifdef DEBUG_EFFAPP + std::cout << " -- Rejected with probability: " << effProb << std::flush; +#endif + + SlaveTA.SmearceptOneParticle(ri, fp +#ifdef DEBUG_THRESACCEPT + , + p_it +#endif + ); + } +#ifdef DEBUG_EFFAPP + std::cout << std::endl; +#endif + +#ifdef DEBUG_EFFAPP + std::cout << "Reconstructed " << ri->RecObjMom.size() << " particles. " + << std::endl; +#endif + return ri; +} diff --git a/src/Smearceptance/ThresholdAccepter.h b/src/Smearceptance/EfficiencyApplicator.h similarity index 63% copy from src/Smearceptance/ThresholdAccepter.h copy to src/Smearceptance/EfficiencyApplicator.h index 761b7c1..4b3abce 100644 --- a/src/Smearceptance/ThresholdAccepter.h +++ b/src/Smearceptance/EfficiencyApplicator.h @@ -1,45 +1,56 @@ // 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 THRESHOLDACCEPTER_HXX_SEEN -#define THRESHOLDACCEPTER_HXX_SEEN +#ifndef EFFICIENCYAPPLICATOR_HXX_SEEN +#define EFFICIENCYAPPLICATOR_HXX_SEEN #include "ISmearcepter.h" +#include "ThresholdAccepter.h" + +#include "TRandom3.h" #include -class ThresholdAccepter : public ISmearcepter { - struct Thresh { - bool ThresholdIsKE; - double ThresholdVal; - }; - struct VisThresh : public Thresh { - bool UseKE; +class EfficiencyApplicator : public ISmearcepter { +public: + enum DependVar { kMomentum, kKE, kTheta, kCosTheta, kPhi, kNoAxis }; +private: + struct EffMap { + TH1 *EffCurve; + bool Interpolate; + // Need to work out how best to apply this. + //bool ApplyAsWeight; + int NDims; + EfficiencyApplicator::DependVar DependVars[3]; + double AxisScales[3]; }; - - std::map ReconThresholds; - std::map VisThresholds; + std::map Efficiencies; void SpecifcSetup(nuiskey &); + TRandom3 rand; + + ThresholdAccepter SlaveTA; + public: RecoInfo *Smearcept(FitEvent *); + ~EfficiencyApplicator(); }; #endif diff --git a/src/Smearceptance/EnergyShuffler.cxx b/src/Smearceptance/EnergyShuffler.cxx new file mode 100644 index 0000000..a4dc6b2 --- /dev/null +++ b/src/Smearceptance/EnergyShuffler.cxx @@ -0,0 +1,157 @@ +#include "EnergyShuffler.h" + +/// Node looks like +/// +/// +/// +/// +void EnergyShuffler::Setup(nuiskey &nk) { + std::vector shuffleDescriptors = nk.GetListOfChildNodes("Shuffler"); + + for (size_t t_it = 0; t_it < shuffleDescriptors.size(); ++t_it) { + if (!shuffleDescriptors[t_it].Has("From") || + !shuffleDescriptors[t_it].Has("Fraction")) { + THROW( + "Shuffler element must have at least the From and Fraction " + "attributes."); + } + std::string from_pdgs_s = shuffleDescriptors[t_it].GetS("From"); + std::vector from_pdgs_i = GeneralUtils::ParseToInt(from_pdgs_s, ","); + + if (!from_pdgs_i.size()) { + THROW("Shuffler element must have at least one From PDG specified."); + } + + std::vector to_pdgs_i; + if (shuffleDescriptors[t_it].Has("To")) { + std::string to_pdgs_s = shuffleDescriptors[t_it].GetS("To"); + to_pdgs_i = GeneralUtils::ParseToInt(to_pdgs_s, ","); + } + + double Fraction = shuffleDescriptors[t_it].GetD("Fraction"); + + for (size_t f_it = 0; f_it < from_pdgs_i.size(); ++f_it) { + ShuffleDescriptor sd; + sd.ToPDGs = to_pdgs_i; + sd.EFraction = Fraction; + ShufflersDescriptors.push_back(std::make_pair(from_pdgs_i[f_it], sd)); + QLOG(FIT, "\tAdded EnergyShuffler from " + << from_pdgs_i[f_it] << " to " << to_pdgs_i.size() + << " particle species at " << sd.EFraction + << " KE fraction.") + } + } +} + +void EnergyShuffler::DoTheShuffle(FitEvent *fe) { + std::map TakenEnergy; + std::map NumParticlesToShare; + // For each particle. + // If in a from: take energy and add it to a sum. + // Count particles of each species. + for (size_t p_it = 0; p_it < fe->NParticles(); ++p_it) { + FitParticle *fp = fe->GetParticle(p_it); + + if (fp->Status() != kFinalState) { + continue; + } + + int PDG = fp->PDG(); + for (size_t sh_it = 0; sh_it < ShufflersDescriptors.size(); ++sh_it) { + ShuffleDescriptor &sd = ShufflersDescriptors[sh_it].second; + + if (std::find(sd.ToPDGs.begin(), sd.ToPDGs.end(), PDG) != + sd.ToPDGs.end()) { // If this is a particle + // that we're giving energy + // to, take note. + if (!NumParticlesToShare.count(sh_it)) { + NumParticlesToShare[sh_it] = 0; + } + NumParticlesToShare[sh_it]++; +#ifdef DEBUG_ESHUFFLER + std::cout << "Found recieving particle in pool " << sh_it << "." + << std::endl; +#endif + } + + if (ShufflersDescriptors[sh_it].first != PDG) { + continue; + } + + double KETaken = sd.EFraction * fp->KE(); + if (!TakenEnergy.count(sh_it)) { + TakenEnergy[sh_it] = 0; + } + TakenEnergy[sh_it] += KETaken; + +#ifdef DEBUG_ESHUFFLER + std::cout << "Taking " << KETaken << " KE from " << fp->PDG() << " (" + << fp << ") with " << fp->KE() << " (mom: " << fp->p() << ")." + << std::endl; +#endif + fe->RemoveKE(p_it, KETaken); + fp = fe->GetParticle(p_it); +#ifdef DEBUG_ESHUFFLER + std::cout << "\t->" << fp->KE() << " (mom: " << fp->p() << ") => " + << sh_it << "." << std::endl; +#endif + } + } + + double LostEnergy = 0; + for (std::map::iterator te_it = TakenEnergy.begin(); + te_it != TakenEnergy.end(); ++te_it) { + double EToGive = te_it->second; + // Get energy share for each 'to' particle + if (NumParticlesToShare.count(te_it->first)) { // If we have any particles + // to share the energy + // between. + +#ifdef DEBUG_ESHUFFLER + std::cout << "Energy from Shuffler " << te_it->first << " " << EToGive + << " shared between " << NumParticlesToShare[te_it->first] + << " particle." << std::endl; +#endif + + EToGive /= double(NumParticlesToShare[te_it->first]); + + } else { + LostEnergy += EToGive; + continue; + } + + ShuffleDescriptor &sd = ShufflersDescriptors[te_it->first].second; + + for (size_t p_it = 0; p_it < fe->NParticles(); ++p_it) { + FitParticle *fp = fe->GetParticle(p_it); + + if (fp->Status() != kFinalState) { + continue; + } + + int PDG = fp->PDG(); + + if (std::find(sd.ToPDGs.begin(), sd.ToPDGs.end(), PDG) == + sd.ToPDGs.end()) { // This shuffler has no energy for this particle + continue; + } + +#ifdef DEBUG_ESHUFFLER + std::cout << "Giving " << EToGive << " KE to " << fp->PDG() << " with " + << fp->KE() << " (mom: " << fp->p() << ")." << std::endl; +#endif + fe->GiveKE(p_it, EToGive); + fp = fe->GetParticle(p_it); +#ifdef DEBUG_ESHUFFLER + std::cout << "\t->" << fp->KE() << " (mom: " << fp->p() << ")." + << std::endl; +#endif + } + } + +#ifdef DEBUG_ESHUFFLER + if (LostEnergy > 0) { + std::cout << "" << LostEnergy << " of KE went nowhere..." << std::endl; + } +#endif +} diff --git a/src/Smearceptance/ThresholdAccepter.h b/src/Smearceptance/EnergyShuffler.h similarity index 64% copy from src/Smearceptance/ThresholdAccepter.h copy to src/Smearceptance/EnergyShuffler.h index 761b7c1..d3a80ba 100644 --- a/src/Smearceptance/ThresholdAccepter.h +++ b/src/Smearceptance/EnergyShuffler.h @@ -1,45 +1,49 @@ // 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 THRESHOLDACCEPTER_HXX_SEEN -#define THRESHOLDACCEPTER_HXX_SEEN +#ifndef ENERGYSHUFFLER_HXX_SEEN +#define ENERGYSHUFFLER_HXX_SEEN #include "ISmearcepter.h" #include -class ThresholdAccepter : public ISmearcepter { - struct Thresh { - bool ThresholdIsKE; - double ThresholdVal; - }; - struct VisThresh : public Thresh { - bool UseKE; - }; +// #define DEBUG_ESHUFFLER - std::map ReconThresholds; - std::map VisThresholds; +/// Tool for shuffles KE between systems. +/// Because it needs to run before an accepter has a chance to throw away +/// particles it should not be an ISmearcepter and instead built into other +/// smearcepters. +class EnergyShuffler { - void SpecifcSetup(nuiskey &); + private: + struct ShuffleDescriptor { + std::vector ToPDGs; + double EFraction; + }; + + std::vector< std::pair > ShufflersDescriptors; public: - RecoInfo *Smearcept(FitEvent *); + void Setup(nuiskey &); + + void DoTheShuffle(FitEvent *); }; #endif diff --git a/src/Smearceptance/GaussianSmearer.cxx b/src/Smearceptance/GaussianSmearer.cxx new file mode 100644 index 0000000..5f57177 --- /dev/null +++ b/src/Smearceptance/GaussianSmearer.cxx @@ -0,0 +1,529 @@ +// 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 "GaussianSmearer.h" + +namespace { +GaussianSmearer::GSmearType GetVarType(std::string const &type) { + if (type == "Absolute") { + return GaussianSmearer::kAbsolute; + } else if (type == "Fractional") { + return GaussianSmearer::kFractional; + } else if (type == "Function") { + return GaussianSmearer::kFunction; + } + return GaussianSmearer::kNoType; +} + +GaussianSmearer::DependVar GetKineType(std::string const &axisvar) { + if (axisvar == "Momentum") { + return GaussianSmearer::kMomentum; + } else if (axisvar == "KE") { + return GaussianSmearer::kKE; + } else if (axisvar == "TEVis") { + return GaussianSmearer::kTEVis; + } else if (axisvar == "KEVis") { + return GaussianSmearer::kKEVis; + } else if (axisvar == "CosTheta") { + return GaussianSmearer::kCosTheta; + } else if (axisvar == "Theta") { + return GaussianSmearer::kTheta; + } + THROW("Failed to parse smear type from \"" << axisvar << "\""); +} + +std::string GetKineTypeName(GaussianSmearer::DependVar dv) { + switch (dv) { + case GaussianSmearer::kMomentum: { + return "Momentum"; + } + case GaussianSmearer::kKE: { + return "KE"; + } + case GaussianSmearer::kTEVis: { + return "TEVis"; + } + case GaussianSmearer::kKEVis: { + return "KEVis"; + } + case GaussianSmearer::kCosTheta: { + return "CosTheta"; + } + case GaussianSmearer::kTheta: { + return "Theta"; + } + default: { THROW("NO VAR!"); } + } +} +} + +/// Nodes look like: +/// Function attribute is given to a TF1, where any "V"s are replaced with the +/// selected kinematic property on an event-by-event basis. e.g Function="{V} + +/// gaus({P1}),..." with P1="0.2", should give the same result as +/// Type="kFractional" and Width="0.2". +/// +/// +/// +void GaussianSmearer::SpecifcSetup(nuiskey &nk) { + rand.~TRandom3(); + new (&rand) TRandom3(); + + std::vector smearDescriptors = nk.GetListOfChildNodes("Smear"); + + for (size_t t_it = 0; t_it < smearDescriptors.size(); ++t_it) { + std::string pdgs_s = smearDescriptors[t_it].GetS("PDG"); + std::vector pdgs_i = GeneralUtils::ParseToInt(pdgs_s, ","); + + double Width = smearDescriptors[t_it].Has("Width") + ? smearDescriptors[t_it].GetD("Width") + : 0xdeadbeef; + + GaussianSmearer::GSmearType Type = + GetVarType(smearDescriptors[t_it].GetS("Type")); + GaussianSmearer::DependVar Kinematics = + GetKineType(smearDescriptors[t_it].GetS("Kinematics")); + bool IsVisSmear = (Kinematics == GaussianSmearer::kKEVis) || + (Kinematics == GaussianSmearer::kTEVis); + + TF1 *sf = NULL; + + if (Type == GaussianSmearer::kFunction) { + std::string funcDescriptor = smearDescriptors[t_it].Has("Function") + ? smearDescriptors[t_it].GetS("Function") + : ""; + if (funcDescriptor.size()) { + std::vector funcP = + GeneralUtils::ParseToStr(funcDescriptor, "$"); + if (funcP.size() != 3) { + THROW( + "Expected Function attribute to contain 3 comma separated " + "entries. e.g. Function=\"1/{V}$$\". "); + } + bool FoundParam; + int pCtr = 1; + std::map PVals; + do { + std::stringstream pv_str(""); + pv_str << "P" << pCtr++; + if (smearDescriptors[t_it].Has(pv_str.str())) { + PVals.insert( + std::make_pair(std::string("{") + pv_str.str() + "}", + smearDescriptors[t_it].GetS(pv_str.str()))); + FoundParam = true; + } else { + FoundParam = false; + } + } while (FoundParam); + + for (std::map::iterator v_it = PVals.begin(); + v_it != PVals.end(); ++v_it) { + funcP[0] = + GeneralUtils::ReplaceAll(funcP[0], v_it->first, v_it->second); + } + + funcP[0] = GeneralUtils::ReplaceAll(funcP[0], "{V}", "[0]"); + QLOG(FIT, "Added smearing func: " + << funcP[0] << ", [" << GeneralUtils::StrToDbl(funcP[1]) + << " -- " << GeneralUtils::StrToDbl(funcP[2]) << "]."); + sf = new TF1("smear_dummy", funcP[0].c_str(), + GeneralUtils::StrToDbl(funcP[1]), + GeneralUtils::StrToDbl(funcP[2])); + } else { + THROW( + "Expected Function attribute with 3 comma separated " + "entries. e.g. Function=\"1/x,,\". "); + } + } + + for (size_t pdg_it = 0; pdg_it < pdgs_i.size(); ++pdg_it) { + if (IsVisSmear && VisGausSmears.count(pdgs_i[pdg_it])) { + ERROR(WRN, + "Smearceptor " + << ElementName << ":" << InstanceName + << " already has a Visible Energy smearing function for PDG: " + << pdgs_i[pdg_it]); + } + + GSmear gs; + + gs.type = Type; + gs.smearVar = Kinematics; + gs.width = Width; + gs.func = sf ? static_cast(sf->Clone()) : NULL; + if (sf) { + std::stringstream ss(""); + ss << "GausSmear" + << "_PDG" << pdgs_i[pdg_it]; + gs.func->SetName(ss.str().c_str()); + } + + if (IsVisSmear) { + VisGausSmears[pdgs_i[pdg_it]] = gs; + } else { + TrackedGausSmears[pdgs_i[pdg_it]].push_back(gs); + } + + QLOG(SAM, "Added gaussian " + << GetKineTypeName(gs.smearVar) + << " smearing function for PDG: " << pdgs_i[pdg_it]); + } + delete sf; + } +} + +void GaussianSmearer::SmearceptOneParticle(RecoInfo *ri, FitParticle *fp +#ifdef DEBUG_GAUSSSMEAR + , + size_t p_it +#endif + ) { +#ifdef DEBUG_GAUSSSMEAR + std::cout << std::endl; + std::cout << "[" << p_it << "]: " << fp->PDG() << ", " << fp->Status() << ", " + << fp->E() << " -- KE:" << fp->KE() << " Mom: " << fp->P3().Mag() + << std::flush; +#endif + + if (fp->Status() != kFinalState) { +#ifdef DEBUG_GAUSSSMEAR + std::cout << " -- Not final state." << std::flush; +#endif + return; + } + + if ((TrackedGausSmears.count(fp->PDG()) + VisGausSmears.count(fp->PDG())) == + 0) { +#ifdef DEBUG_GAUSSSMEAR + std::cout << " -- Undetectable." << std::flush; +#endif + return; + } + + if (TrackedGausSmears.count(fp->PDG())) { + TVector3 ThreeMom = fp->P3(); + for (size_t sm_it = 0; sm_it < TrackedGausSmears[fp->PDG()].size(); + ++sm_it) { + GSmear &sm = TrackedGausSmears[fp->PDG()][sm_it]; + + double kineProp = 0; + + switch (sm.smearVar) { + case GaussianSmearer::kMomentum: { + kineProp = fp->P3().Mag(); + break; + } + case GaussianSmearer::kKE: { + kineProp = fp->KE(); + break; + } + case GaussianSmearer::kCosTheta: { + kineProp = fp->P3().CosTheta(); + break; + } + case GaussianSmearer::kTheta: { + kineProp = fp->P3().Theta(); + break; + } + default: { THROW("Trying to find particle value for a kNoVar."); } + } + + double Smeared; + size_t attempt = 0; + bool ok = false; + while (!ok) { + if (sm.type == GaussianSmearer::kFunction) { + sm.func->SetParameter(0, kineProp); + Smeared = sm.func->GetRandom(); + } else { + double sThrow = rand.Gaus( + 0, sm.width * + ((sm.type == GaussianSmearer::kAbsolute) ? 1 : kineProp)); + Smeared = kineProp + sThrow; + } + switch ( + sm.smearVar) { // Different kinematics have different truncation. + case GaussianSmearer::kMomentum: + case GaussianSmearer::kKE: { + ok = (Smeared > 0); + break; + } + case GaussianSmearer::kCosTheta: { + ok = ((Smeared >= -1) && (Smeared <= 1)); + break; + } + case GaussianSmearer::kTheta: { + ok = true; + break; + } + + default: { THROW("SHOULDN'T BE HERE."); } + } + attempt++; + if (attempt > 1000) { + THROW("Didn't get a good smeared value after " << attempt + << " attempts."); + } + } + + switch (sm.smearVar) { + case GaussianSmearer::kMomentum: { + ThreeMom = (ThreeMom.Unit() * Smeared); + break; + } + case GaussianSmearer::kKE: { + double mass = fp->P4().M(); + double TE = mass + Smeared; + double magP = sqrt(TE * TE - mass * mass); + ThreeMom = (ThreeMom.Unit() * magP); + break; + } + case GaussianSmearer::kCosTheta: { + ThreeMom.SetTheta(acos(Smeared)); + break; + } + case GaussianSmearer::kTheta: { + ThreeMom.SetTheta(Smeared); + break; + } + default: {} + } + } +#ifdef DEBUG_GAUSSSMEAR + std::cout << " -- momentum reconstructed as Mom: " + << ri->RecObjMom.back().Mag() + << ", CT: " << ri->RecObjMom.back().CosTheta() << " from " + << ThreeMom.Mag() << ", " << fp->P3().CosTheta() << " true." + << std::endl; +#endif + ri->RecObjMom.push_back(ThreeMom); + ri->RecObjClass.push_back(fp->PDG()); + } else { // Smear to EVis + + GSmear &sm = VisGausSmears[fp->PDG()]; + + double kineProp = 0; + + switch (sm.smearVar) { + case GaussianSmearer::kKEVis: { + kineProp = fp->KE(); + break; + } + case GaussianSmearer::kTEVis: { + kineProp = fp->E(); + break; + } + default: { THROW("Trying to find particle value for a kNoVar."); } + } + + double Smeared; + if (sm.type == GaussianSmearer::kFunction) { + sm.func->SetParameter(0, kineProp); + Smeared = sm.func->GetRandom(); + } else { + double sThrow = rand.Gaus( + 0, sm.width * + ((sm.type == GaussianSmearer::kAbsolute) ? 1.0 : kineProp)); + Smeared = kineProp + sThrow; + } + Smeared = (Smeared < 0) ? 0 : Smeared; +#ifdef DEBUG_GAUSSSMEAR + std::cout << " -- Saw " << Smeared << " visible energy from " << kineProp + << " available. [PDG: " << fp->PDG() << "]" << std::endl; +#endif + + ri->RecVisibleEnergy.push_back(Smeared); + ri->TrueContribPDGs.push_back(fp->PDG()); + } +#ifdef DEBUG_GAUSSSMEAR + std::cout << std::endl; +#endif +} + +RecoInfo *GaussianSmearer::Smearcept(FitEvent *fe) { + RecoInfo *ri = new RecoInfo(); + + for (size_t p_it = 0; p_it < fe->NParticles(); ++p_it) { + FitParticle *fp = fe->GetParticle(p_it); + SmearceptOneParticle(ri, fp +#ifdef DEBUG_GAUSSSMEAR + , + p_it +#endif + ); + } + + return ri; +} + +void GaussianSmearer::SmearceptOneParticle(TVector3 &RecObjMom, + int RecObjClass) { + if (!TrackedGausSmears.count(RecObjClass)) { + return; + } + TVector3 ThreeMom = RecObjMom; + TVector3 OriginalKP = ThreeMom; + for (size_t sm_it = 0; sm_it < TrackedGausSmears[RecObjClass].size(); + ++sm_it) { + GSmear &sm = TrackedGausSmears[RecObjClass][sm_it]; + + double kineProp = 0; + + switch (sm.smearVar) { + case GaussianSmearer::kMomentum: { + kineProp = RecObjMom.Mag(); + break; + } + case GaussianSmearer::kKE: { + double mass = PhysConst::GetMass(RecObjClass) * 1.0E3; + kineProp = sqrt(RecObjMom.Mag2() + mass * mass) - mass; + break; + } + case GaussianSmearer::kCosTheta: { + kineProp = OriginalKP.CosTheta(); + break; + } + case GaussianSmearer::kTheta: { + kineProp = OriginalKP.Theta(); + break; + } + default: { THROW("Trying to find particle value for a kNoVar."); } + } + + double Smeared; + bool ok = false; + int attempt = 0; + while (!ok) { + if (sm.type == GaussianSmearer::kFunction) { + sm.func->SetParameter(0, kineProp); + Smeared = sm.func->GetRandom(); + } else { + double sThrow = rand.Gaus( + 0, sm.width * + ((sm.type == GaussianSmearer::kAbsolute) ? 1.0 : kineProp)); + Smeared = kineProp + sThrow; +#ifdef DEBUG_GAUSSSMEAR + std::cout << "*** [" << attempt << "] Gaus(0," + << (sm.width * (sm.type == GaussianSmearer::kAbsolute) + ? 1 + : kineProp) + << "[" << sm.width << "]) = " << sThrow << ": " << kineProp + << " -> " << Smeared << std::endl; +#endif + } + switch (sm.smearVar) { // Different kinematics have different truncation. + case GaussianSmearer::kMomentum: + case GaussianSmearer::kKE: { + ok = (Smeared > 0); + break; + } + case GaussianSmearer::kCosTheta: { + ok = ((Smeared >= -1) && (Smeared <= 1)); + break; + } + case GaussianSmearer::kTheta: { + ok = true; + break; + } + default: { THROW("SHOULDN'T BE HERE."); } + } + attempt++; + if (attempt > 1000) { + THROW("Didn't get a good smeared value after " << attempt + << " attempts."); + } + } + + switch (sm.smearVar) { + case GaussianSmearer::kMomentum: { + ThreeMom = (ThreeMom.Unit() * Smeared); + break; + } + case GaussianSmearer::kKE: { + double mass = PhysConst::GetMass(RecObjClass) * 1.0E3; + double TE = mass + Smeared; + double magP = sqrt(TE * TE - mass * mass); + ThreeMom = (ThreeMom.Unit() * magP); + break; + } + case GaussianSmearer::kCosTheta: { + ThreeMom.SetTheta(acos(Smeared)); + break; + } + case GaussianSmearer::kTheta: { + ThreeMom.SetTheta(Smeared); + break; + } + default: {} + } + } + RecObjMom = ThreeMom; + +#ifdef DEBUG_GAUSSSMEAR + std::cout << " -- momentum reconstructed as Mom: " << RecObjMom.Mag() + << ", CT: " << RecObjMom.CosTheta() << " from " << OriginalKP.Mag() + << ", " << OriginalKP.CosTheta() << " true." << std::endl; +#endif +} + +void GaussianSmearer::SmearceptOneParticle(double &RecVisibleEnergy, + int TrueContribPDG) { + if (!VisGausSmears.count(TrueContribPDG)) { + return; + } + GSmear &sm = VisGausSmears[TrueContribPDG]; + double kineProp = RecVisibleEnergy; + + double Smeared; + if (sm.type == GaussianSmearer::kFunction) { + sm.func->SetParameter(0, kineProp); + Smeared = sm.func->GetRandom(); + } else { + double sThrow = rand.Gaus( + 0, + sm.width * ((sm.type == GaussianSmearer::kAbsolute) ? 1.0 : kineProp)); + Smeared = kineProp + sThrow; + } + Smeared = (Smeared < 0) ? 0 : Smeared; +#ifdef DEBUG_GAUSSSMEAR + std::cout << " -- Saw " << Smeared << " visible energy from " << kineProp + << " available. [PDG: " << TrueContribPDG << "]" << std::endl; +#endif + + RecVisibleEnergy = Smeared; +} + +void GaussianSmearer::SmearRecoInfo(RecoInfo *ri) { + // Smear tracked particles + for (size_t p_it = 0; p_it < ri->RecObjMom.size(); ++p_it) { + SmearceptOneParticle(ri->RecObjMom[p_it], ri->RecObjClass[p_it]); + } + + for (size_t ve_it = 0; ve_it < ri->RecVisibleEnergy.size(); ++ve_it) { + SmearceptOneParticle(ri->RecVisibleEnergy[ve_it], + ri->TrueContribPDGs[ve_it]); + } + +#ifdef DEBUG_GAUSSSMEAR + std::cout << std::endl; +#endif +} diff --git a/src/Smearceptance/ThresholdAccepter.h b/src/Smearceptance/GaussianSmearer.h similarity index 52% copy from src/Smearceptance/ThresholdAccepter.h copy to src/Smearceptance/GaussianSmearer.h index 761b7c1..8add0cf 100644 --- a/src/Smearceptance/ThresholdAccepter.h +++ b/src/Smearceptance/GaussianSmearer.h @@ -1,45 +1,67 @@ // 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 THRESHOLDACCEPTER_HXX_SEEN -#define THRESHOLDACCEPTER_HXX_SEEN +#ifndef GAUSSIANSMEARER_HXX_SEEN +#define GAUSSIANSMEARER_HXX_SEEN #include "ISmearcepter.h" #include -class ThresholdAccepter : public ISmearcepter { - struct Thresh { - bool ThresholdIsKE; - double ThresholdVal; - }; - struct VisThresh : public Thresh { - bool UseKE; +// #define DEBUG_GAUSSSMEAR + +class GaussianSmearer : public ISmearcepter { + public: + enum GSmearType { kAbsolute, kFractional, kFunction, kNoType }; + enum DependVar { kMomentum, kKE, kKEVis, kTEVis, kCosTheta, kTheta, kNoVar }; + + private: + struct GSmear { + GSmearType type; + DependVar smearVar; + double width; + TF1 *func; }; - std::map ReconThresholds; - std::map VisThresholds; + std::map > TrackedGausSmears; + std::map VisGausSmears; + + TRandom3 rand; void SpecifcSetup(nuiskey &); public: RecoInfo *Smearcept(FitEvent *); + + void SmearceptOneParticle(RecoInfo *ri, FitParticle *fp +#ifdef DEBUG_GAUSSSMEAR + , + size_t p_it +#endif + ); + /// Helper method for using this class as a component in a more complex + /// smearer + void SmearRecoInfo(RecoInfo *); + + void SmearceptOneParticle(TVector3 &RecObjMom, int RecObjClass); + + void SmearceptOneParticle(double &RecVisibleEnergy, int TrueContribPDGs); }; #endif diff --git a/src/Smearceptance/Hist2DSlice.cxx b/src/Smearceptance/Hist2DSlice.cxx new file mode 100644 index 0000000..f5674de --- /dev/null +++ b/src/Smearceptance/Hist2DSlice.cxx @@ -0,0 +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 . +*******************************************************************************/ + +#include "Hist2DSlice.h" + +Int_t Hist2DSlice::GetNbinsX() { return Bins.size(); } +double Hist2DSlice::GetBinContent_Index(size_t i) { return Bins[i].second; } +double Hist2DSlice::GetBinNumber_Index(size_t i) { return Bins[i].first; } +double Hist2DSlice::GetBinContent_BinNum(Int_t i); +double Hist2DSlice::GetMaximum() { return Max; } + +Hist2DSlice::Hist2DSlice(TH2D const *Hist, Int_t YBinNum) { + std::stringstream ss(""); + ss << Hist->GetName() << "_yslice_" << YBinNum; + Slice = new TH1D(ss.str().c_str(),"",); + Slice->SetDirectory(NULL); + for (Int_t i = 0; i < (Hist->GetXaxis()->GetNbins() + 2); ++i) { + Int_t MatrixBin = Hist->GetBin(i, YBinNum); + Float_t cont = Hist->GetBinContent(MatrixBin); + if (cont <= 0) { + continue; + } + Bins.push_back(std::make_pair(i, cont)); + Max = std::max(Max, Bins.back().second); + } + + NOrigBinsX = Hist->GetXaxis()->GetNbins(); + return GetNbinsX(); +} + +Float_t Hist2DSlice::GetBinContent_BinNum(Int_t binnum) { + for (size_t i = 0; i < Bins.size(); ++i) { + if (Bins[i].first == binnum) { + return Bins[i].second; + } + } + return 0; +} diff --git a/src/Smearceptance/ThresholdAccepter.h b/src/Smearceptance/Hist2DSlice.h similarity index 66% copy from src/Smearceptance/ThresholdAccepter.h copy to src/Smearceptance/Hist2DSlice.h index 761b7c1..8a70120 100644 --- a/src/Smearceptance/ThresholdAccepter.h +++ b/src/Smearceptance/Hist2DSlice.h @@ -1,45 +1,43 @@ // 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 THRESHOLDACCEPTER_HXX_SEEN -#define THRESHOLDACCEPTER_HXX_SEEN +#ifndef HIST2DSLICE_HXX_SEEN +#define HIST2DSLICE_HXX_SEEN -#include "ISmearcepter.h" +class Hist2DSlice { + TH1D *Slice; -#include + bool IsSparse; + std::vector > SparseBins; + double Max; + Int_t NOrigBinsX; -class ThresholdAccepter : public ISmearcepter { - struct Thresh { - bool ThresholdIsKE; - double ThresholdVal; - }; - struct VisThresh : public Thresh { - bool UseKE; - }; - - std::map ReconThresholds; - std::map VisThresholds; - - void SpecifcSetup(nuiskey &); + Int_t GetNbinsX(); + double GetBinContent_Index(size_t i); + double GetBinNumber_Index(size_t i); + double GetBinContent_BinNum(Int_t i); + double GetMaximum(); public: - RecoInfo *Smearcept(FitEvent *); + Hist2DSlice(TH2D const *Hist, Int_t YBinNum); + Int_t ThrowBin(TRandom3 *); + double ThrowXValue(TRandom3 *); }; #endif diff --git a/src/Smearceptance/ISmearcepter.h b/src/Smearceptance/ISmearcepter.h index 88f4279..9fb683b 100644 --- a/src/Smearceptance/ISmearcepter.h +++ b/src/Smearceptance/ISmearcepter.h @@ -1,67 +1,87 @@ // 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 ISMEARCEPTER_HXX_SEEN #define ISMEARCEPTER_HXX_SEEN #include "FitEvent.h" #include "NuisKey.h" #include "TVector3.h" #include #include /// Base reconstructed information that a smearcepter should fill. /// Smearcepters may allocate and return instances of RecoInfo subclasses. struct RecoInfo { RecoInfo() : RecObjMom(), RecObjClass(), RecVisibleEnergy(0), - TrueContribPDGs(){}; + TrueContribPDGs(), + Weight(1){}; /// Reconstructed 3-momentum std::vector RecObjMom; ///\brief 'Class' of a reconstructed object. Might be a PDG particle code, or /// some smearer-defined classification like MIP track/EMShower/... std::vector RecObjClass; /// The visible energy not left by fully reconstructed tracks std::vector RecVisibleEnergy; /// The true pdgs of particles that contributed to the visible energy std::vector TrueContribPDGs; + + double Weight; }; class ISmearcepter { protected: std::string ElementName; std::string InstanceName; public: void Setup(nuiskey &); virtual void SpecifcSetup(nuiskey &) = 0; std::string GetName() { return InstanceName; } std::string GetElementName() { return ElementName; } virtual RecoInfo *Smearcept(FitEvent *) = 0; + /// Helper method for using this class as a component in a more complex + /// smearer + virtual void SmearRecoInfo(RecoInfo *) { + THROW("Smearcepter: " << ElementName + << " doesn't implement SmearRecoInfo."); + ; + } }; +template +ISmearcepter* BuildSmearcepter(nuiskey& nk) { + ISmearcepter* rtn = new T(); + rtn->Setup(nk); + return rtn; +} + +typedef ISmearcepter* (*SmearceptionFactory_fcn)(nuiskey&); + + #endif diff --git a/src/Smearceptance/MetaSimpleSmearcepter.cxx b/src/Smearceptance/MetaSimpleSmearcepter.cxx new file mode 100644 index 0000000..eac85e9 --- /dev/null +++ b/src/Smearceptance/MetaSimpleSmearcepter.cxx @@ -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 . +*******************************************************************************/ +#include "EfficiencyApplicator.h" +#include "GaussianSmearer.h" +#include "ThresholdAccepter.h" +#include "TrackedMomentumMatrixSmearer.h" +#include "VisECoalescer.h" + +#include "MetaSimpleSmearcepter.h" + +void MetaSimpleSmearcepter::SpecifcSetup(nuiskey &nk) { + std::map factories; + + factories["ThresholdAccepter"] = &BuildSmearcepter; + factories["EfficiencyApplicator"] = &BuildSmearcepter; + factories["GaussianSmearer"] = &BuildSmearcepter; + factories["VisECoalescer"] = &BuildSmearcepter; + factories["TrackedMomentumMatrixSmearer"] = + &BuildSmearcepter; + + std::vector smearcepters = nk.GetListOfChildNodes(); + for (size_t smear_it = 0; smear_it < smearcepters.size(); ++smear_it) { + std::string const &smearType = smearcepters[smear_it].GetElementName(); + + if (smearType == "EnergyShuffler") { + ES = new EnergyShuffler(); + ES->Setup(smearcepters[smear_it]); + continue; + } + + if (!factories.count(smearType)) { + ERROR(WRN, "No known smearer accepts elements named: \"" << smearType + << "\""); + continue; + } + + Smearcepters.push_back(factories[smearType](smearcepters[smear_it])); + + QLOG(FIT, "MetaSimpleSmearcepter adopted child smearcepter: " + << Smearcepters.back()->GetName() + << " of type: " << Smearcepters.back()->GetElementName()); + } + NSmearcepters = Smearcepters.size(); +} +RecoInfo *MetaSimpleSmearcepter::Smearcept(FitEvent *fe) { + if (ES) { + ES->DoTheShuffle(fe); + } + RecoInfo *ri = NULL; + for (size_t sm_it = 0; sm_it < NSmearcepters; ++sm_it) { + if (!sm_it) { + ri = Smearcepters[sm_it]->Smearcept(fe); + } else { + Smearcepters[sm_it]->SmearRecoInfo(ri); + } + } + return ri; +} diff --git a/src/Smearceptance/ThresholdAccepter.h b/src/Smearceptance/MetaSimpleSmearcepter.h similarity index 76% copy from src/Smearceptance/ThresholdAccepter.h copy to src/Smearceptance/MetaSimpleSmearcepter.h index 761b7c1..422800e 100644 --- a/src/Smearceptance/ThresholdAccepter.h +++ b/src/Smearceptance/MetaSimpleSmearcepter.h @@ -1,45 +1,43 @@ // 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 THRESHOLDACCEPTER_HXX_SEEN -#define THRESHOLDACCEPTER_HXX_SEEN +#ifndef MetaSimpleSmearcepter_HXX_SEEN +#define MetaSimpleSmearcepter_HXX_SEEN #include "ISmearcepter.h" +#include "EnergyShuffler.h" + #include -class ThresholdAccepter : public ISmearcepter { - struct Thresh { - bool ThresholdIsKE; - double ThresholdVal; - }; - struct VisThresh : public Thresh { - bool UseKE; - }; - - std::map ReconThresholds; - std::map VisThresholds; +class MetaSimpleSmearcepter : public ISmearcepter { + + private: + size_t NSmearcepters; + std::vector Smearcepters; + + EnergyShuffler *ES; void SpecifcSetup(nuiskey &); public: RecoInfo *Smearcept(FitEvent *); }; #endif diff --git a/src/Smearceptance/SmearceptanceUtils.cxx b/src/Smearceptance/SmearceptanceUtils.cxx new file mode 100644 index 0000000..bd00b75 --- /dev/null +++ b/src/Smearceptance/SmearceptanceUtils.cxx @@ -0,0 +1,284 @@ +// 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 "SmearceptanceUtils.h" + +#include "TDecompSVD.h" + +#include "FitLogger.h" + +namespace SmearceptanceUtils { + +double Smear1DProp(TH2D *mapping, double TrueProp, TRandom3 *rnjesus) { + bool myrand = false; + if (!rnjesus) { + rnjesus = new TRandom3(); + myrand = true; + } + + if (myrand) { + delete rnjesus; + } + THROW("NIMPLEMENTED"); + return 0; +} + +TVectorD SVDInverseSolve(TVectorD *inp, TMatrixD *mapping) { + TDecompSVD svd(*mapping); + bool ok; + + TVectorD c_svd = svd.Solve(*inp, ok); + if (!ok) { + THROW("Failed to solve SVD matrix equation."); + } + return c_svd; +} + +TVectorD SVDInverseSolve(TH1D *inp, TMatrixD *mapping) { + TVectorD inp_v = GetVector(inp); + return SVDInverseSolve(&inp_v, mapping); +} + +TVectorD SVDInverseSolve(TH1D *inp, TH2D *mapping) { + TMatrixD mat(mapping->GetXaxis()->GetNbins(), + mapping->GetYaxis()->GetNbins()); + + for (Int_t xb_it = 0; xb_it < mapping->GetXaxis()->GetNbins(); ++xb_it) { + for (Int_t yb_it = 0; yb_it < mapping->GetYaxis()->GetNbins(); ++yb_it) { + mat[xb_it][yb_it] = mapping->GetBinContent(xb_it + 1, yb_it + 1); + } + } + return SVDInverseSolve(inp, &mat); +} + +TH2D *SVDGetInverse(TH2D *mapping, int NToTruncate) { + TMatrixD mat = GetMatrix(mapping); + + if (mat.GetNcols() > mat.GetNrows()) { + THROW("Trying to invert a " << mat.GetNrows() << "x" << mat.GetNcols() + << " matrix."); + } + + TH2D *inverse = dynamic_cast(mapping->Clone()); + inverse->SetName("inverse"); + inverse->Reset(); + + TDecompSVD svd(mat); + svd.Decompose(); + + if (NToTruncate) { + TVectorD Sig(svd.GetSig()); + TMatrixD U(svd.GetU()); + TMatrixD V(svd.GetV()); + if (svd.GetV().TestBit(TMatrixD::kTransposed)) { + THROW("ARGHH"); + } + TMatrixD V_T = V.Transpose(V); + + TMatrixD Sig_TruncM(U.GetNrows(), V.GetNrows()); + for (Int_t i = 0; i < U.GetNrows(); ++i) { + for (Int_t j = 0; j < V.GetNrows(); ++j) { + Sig_TruncM[i][j] = + ((i != j) || (i >= (Sig.GetNrows() - NToTruncate))) ? 0 : Sig[i]; + } + } + + TMatrixD Trunc = U * Sig_TruncM * V_T; + + svd.~TDecompSVD(); + new (&svd) TDecompSVD(Trunc); + } + + TMatrixD inv = svd.Invert(); + if (fabs(inv[mapping->GetXaxis()->GetNbins() / 2] + [mapping->GetXaxis()->GetNbins() / 2] - + mat[mapping->GetXaxis()->GetNbins() / 2] + [mapping->GetXaxis()->GetNbins() / 2]) < + std::numeric_limits::epsilon()) { + THROW("Failed to SVD invert matrix."); + } + + for (Int_t xb_it = 0; xb_it < inverse->GetXaxis()->GetNbins(); ++xb_it) { + for (Int_t yb_it = 0; yb_it < inverse->GetYaxis()->GetNbins(); ++yb_it) { + inverse->SetBinContent(xb_it + 1, yb_it + 1, inv[yb_it][xb_it]); + } + } + + return inverse; +} + +void GetSVDDecomp(TH2D *mapping, TVectorD &Sig, TMatrixD &U, TMatrixD &V) { + TMatrixD mat = GetMatrix(mapping); + + TDecompSVD svd(mat); + + U.ResizeTo(svd.GetU()); + U = svd.GetU(); + + V.ResizeTo(svd.GetV()); + V = svd.GetU(); + + Sig.ResizeTo(svd.GetSig()); + Sig = svd.GetSig(); +} + +TVectorD GetVector(TH1D *inp) { + TVectorD vec(inp->GetXaxis()->GetNbins()); + + for (Int_t xb_it = 0; xb_it < inp->GetXaxis()->GetNbins(); ++xb_it) { + vec[xb_it] = inp->GetBinContent(xb_it + 1); + } + return vec; +} +TVectorD GetErrorVector(TH1D *inp) { + TVectorD vec(inp->GetXaxis()->GetNbins()); + + for (Int_t xb_it = 0; xb_it < inp->GetXaxis()->GetNbins(); ++xb_it) { + vec[xb_it] = inp->GetBinError(xb_it + 1); + } + return vec; +} +TMatrixD GetMatrix(TH2D *inp) { + TMatrixD mat(inp->GetYaxis()->GetNbins(), inp->GetXaxis()->GetNbins()); + + for (Int_t xb_it = 0; xb_it < inp->GetXaxis()->GetNbins(); ++xb_it) { + for (Int_t yb_it = 0; yb_it < inp->GetYaxis()->GetNbins(); ++yb_it) { + mat[yb_it][xb_it] = inp->GetBinContent(xb_it + 1, yb_it + 1); + } + } + return mat; +} + +TH1D *GetTH1FromVector(TVectorD const &inp, TH1D *templ) { + TH1D *hist; + if (templ) { + hist = static_cast(templ->Clone()); + hist->Reset(); + hist->SetName("vectHist"); + } else { + hist = new TH1D("vectHist", "", inp.GetNrows(), 0, inp.GetNrows()); + } + hist->SetDirectory(NULL); + + for (Int_t xb_it = 0; xb_it < inp.GetNrows(); ++xb_it) { + hist->SetBinContent(xb_it + 1, inp[xb_it]); + } + + return hist; +} + +TH2D *GetTH2FromMatrix(TMatrixD const &inp, TH2D *templ) { + TH2D *hist; + if (templ) { + hist = static_cast(templ->Clone()); + hist->Reset(); + hist->SetName("matHist"); + } else { + hist = new TH2D("matHist", "", inp.GetNcols(), 0, inp.GetNcols(), + inp.GetNrows(), 0, inp.GetNrows()); + } + hist->SetDirectory(NULL); + + for (Int_t xb_it = 0; xb_it < inp.GetNcols(); ++xb_it) { + for (Int_t yb_it = 0; yb_it < inp.GetNrows(); ++yb_it) { + hist->SetBinContent(xb_it + 1, yb_it + 1, inp[yb_it][xb_it]); + } + } + return hist; +} + +TVectorD ThrowVectFromHist(TH1D *inp, TRandom3 *rnjesus, bool allowNeg) { + TVectorD vec(inp->GetXaxis()->GetNbins()); + + for (Int_t xb_it = 0; xb_it < inp->GetXaxis()->GetNbins(); ++xb_it) { + size_t attempt = 0; + do { + if (attempt > 1000) { + THROW("Looks like we aren't getting anywhere with this bin: " + << inp->GetBinContent(xb_it + 1) << " +- " + << inp->GetBinError(xb_it + 1)); + } + vec[xb_it] = inp->GetBinContent(xb_it + 1) + + inp->GetBinError(xb_it + 1) * rnjesus->Gaus(); + attempt++; + } while ((!allowNeg) && (vec[xb_it] < 0)); + } + return vec; +} + +void PushTH1ThroughMatrixWithErrors(TH1D *inp, TH1D *oup, TMatrixD &response, + size_t NToys, bool allowNeg) { + TRandom3 rnjesus; + + oup->Reset(); + + TVectorD Mean(oup->GetXaxis()->GetNbins()); + TVectorD RMS(oup->GetXaxis()->GetNbins()); + std::vector Toys; + Toys.reserve(NToys); + double NToysFact = 1.0 / double(NToys); + + for (size_t t_it = 0; t_it < NToys; ++t_it) { + TVectorD Toy = ThrowVectFromHist(inp, &rnjesus, allowNeg); + TVectorD UnfoldToy = response * Toy; + + for (Int_t bi_it = 0; bi_it < oup->GetXaxis()->GetNbins(); ++bi_it) { + Mean[bi_it] += UnfoldToy[bi_it] * NToysFact; + } + Toys.push_back(UnfoldToy); + } + + for (size_t t_it = 0; t_it < NToys; ++t_it) { + for (Int_t bi_it = 0; bi_it < oup->GetXaxis()->GetNbins(); ++bi_it) { + RMS[bi_it] += (Mean[bi_it] - Toys[t_it][bi_it]) * + (Mean[bi_it] - Toys[t_it][bi_it]) * NToysFact; + } + } + + for (Int_t bi_it = 0; bi_it < oup->GetXaxis()->GetNbins(); ++bi_it) { + oup->SetBinContent(bi_it + 1, Mean[bi_it]); + oup->SetBinError(bi_it + 1, sqrt(RMS[bi_it])); + } +} + +TH2D * SwapXYTH2D(TH2D *templ) { + TH2D *Swapped = new TH2D( + (std::string(templ->GetName()) + "_c").c_str(), "", + templ->GetYaxis()->GetNbins(), templ->GetYaxis()->GetXbins()->GetArray(), + templ->GetXaxis()->GetNbins(), templ->GetXaxis()->GetXbins()->GetArray()); + Swapped->Reset(); + + Swapped->SetDirectory(NULL); + + + std::string title = ";"; + title += templ->GetYaxis()->GetTitle(); + title += ";"; + title += templ->GetXaxis()->GetTitle(); + Swapped->SetTitle(title.c_str()); + + for (Int_t x_it = 0; x_it < templ->GetXaxis()->GetNbins() + 2; ++x_it) { + for (Int_t y_it = 0; y_it < templ->GetYaxis()->GetNbins() + 2; ++y_it) { + Swapped->SetBinContent(y_it, x_it, templ->GetBinContent(x_it, y_it)); + Swapped->SetBinError(y_it, x_it, templ->GetBinError(x_it, y_it)); + } + } + return Swapped; +} +} diff --git a/src/Smearceptance/SmearceptanceUtils.h b/src/Smearceptance/SmearceptanceUtils.h new file mode 100644 index 0000000..0f67848 --- /dev/null +++ b/src/Smearceptance/SmearceptanceUtils.h @@ -0,0 +1,46 @@ +// 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 "TH2D.h" +#include "TMatrixD.h" +#include "TRandom3.h" +#include "TVectorD.h" + +namespace SmearceptanceUtils { + +double Smear1DProp(TH2D *, double TrueProp, TRandom3 *rand = NULL); + +TVectorD SVDInverseSolve(TVectorD *inp, TMatrixD *mapping); +TVectorD SVDInverseSolve(TH1D *inp, TMatrixD *mapping); +TVectorD SVDInverseSolve(TH1D *inp, TH2D *mapping); +TH2D *SVDGetInverse(TH2D *mapping, int NToTruncate=0); +void GetSVDDecomp(TH2D *mapping, TVectorD &Sig, TMatrixD &U, TMatrixD &V); + +TVectorD GetVector(TH1D *inp); +TVectorD GetErrorVector(TH1D *inp); +TMatrixD GetMatrix(TH2D *inp); +TH1D *GetTH1FromVector(TVectorD const &inp, TH1D *templ = NULL); +TH2D *GetTH2FromMatrix(TMatrixD const &inp, TH2D *templ = NULL); + +TVectorD ThrowVectFromHist(TH1D *inp, TRandom3 *rnjesus, bool allowNeg); +void PushTH1ThroughMatrixWithErrors(TH1D *inp, TH1D *oup, TMatrixD &response, + size_t NToys, bool allowNeg); + +TH2D *SwapXYTH2D(TH2D *templ); +} diff --git a/src/Smearceptance/Smearcepterton.cxx b/src/Smearceptance/Smearcepterton.cxx index b68b205..5db2e91 100644 --- a/src/Smearceptance/Smearcepterton.cxx +++ b/src/Smearceptance/Smearcepterton.cxx @@ -1,76 +1,338 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "Smearcepterton.h" +#include "EfficiencyApplicator.h" +#include "GaussianSmearer.h" +#include "MetaSimpleSmearcepter.h" #include "ThresholdAccepter.h" +#include "TrackedMomentumMatrixSmearer.h" +#include "VisECoalescer.h" #include -template -ISmearcepter* BuildSmearcepter(nuiskey& nk) { - ISmearcepter* rtn = new T(); - rtn->Setup(nk); - return rtn; +#ifdef __USE_DYNSAMPLES__ + +#include "TRegexp.h" + +#include + +// linux +#include + +DynamicSmearceptorFactory::DynamicSmearceptorFactory() + : NSmearceptors(0), NManifests(0) { + LoadPlugins(); + QLOG(FIT, "Loaded " << NSmearceptors << " from " << NManifests + << " shared object libraries."); +} +DynamicSmearceptorFactory* DynamicSmearceptorFactory::glblDSF = NULL; +DynamicSmearceptorFactory::PluginManifest::~PluginManifest() { + for (size_t i_it = 0; i_it < Instances.size(); ++i_it) { + (*(DSF_DestroySmearceptor))(Instances[i_it]); + } +} +std::string EnsureTrailingSlash(std::string const& inp) { + if (!inp.length()) { + return "/"; + } + if (inp[inp.length() - 1] == '/') { + return inp; + } + return inp + "/"; +} +void DynamicSmearceptorFactory::LoadPlugins() { + std::vector SearchDirectories; + + if (Config::HasPar("dynamic_smearceptor.path")) { + SearchDirectories = GeneralUtils::ParseToStr( + Config::GetParS("dynamic_smearceptor.path"), ":"); + } + + char const* envPath = getenv("NUISANCE_DS_PATH"); + if (envPath) { + std::vector envPaths = GeneralUtils::ParseToStr(envPath, ":"); + for (size_t ep_it = 0; ep_it < envPaths.size(); ++ep_it) { + SearchDirectories.push_back(envPaths[ep_it]); + } + } + + if (!SearchDirectories.size()) { + char const* pwdPath = getenv("PWD"); + if (pwdPath) { + SearchDirectories.push_back(pwdPath); + } + } + + for (size_t sp_it = 0; sp_it < SearchDirectories.size(); ++sp_it) { + std::string dirpath = EnsureTrailingSlash(SearchDirectories[sp_it]); + + QLOG(FIT, "Searching for dynamic smearceptor manifests in: " << dirpath); + + Ssiz_t len = 0; + DIR* dir; + struct dirent* ent; + dir = opendir(dirpath.c_str()); + if (dir != NULL) { + TRegexp matchExp("*.so", true); + while ((ent = readdir(dir)) != NULL) { + if (matchExp.Index(TString(ent->d_name), &len) != Ssiz_t(-1)) { + QLOG(FIT, "\tFound shared object: " + << ent->d_name << " checking for relevant methods..."); + + void* dlobj = + dlopen((dirpath + ent->d_name).c_str(), RTLD_NOW | RTLD_GLOBAL); + char const* dlerr_cstr = dlerror(); + std::string dlerr; + if (dlerr_cstr) { + dlerr = dlerr_cstr; + } + + if (dlerr.length()) { + ERROR(WRN, "\tDL Load Error: " << dlerr); + continue; + } + + PluginManifest plgManif; + plgManif.dllib = dlobj; + plgManif.soloc = (dirpath + ent->d_name); + + plgManif.DSF_NSmearceptors = reinterpret_cast( + dlsym(dlobj, "DSF_NSmearceptors")); + + dlerr = ""; + dlerr_cstr = dlerror(); + if (dlerr_cstr) { + dlerr = dlerr_cstr; + } + + if (dlerr.length()) { + ERROR(WRN, "\tFailed to load symbol \"DSF_NSmearceptors\" from " + << (dirpath + ent->d_name) << ": " << dlerr); + dlclose(dlobj); + continue; + } + + plgManif.DSF_GetSmearceptorName = + reinterpret_cast( + dlsym(dlobj, "DSF_GetSmearceptorName")); + + dlerr = ""; + dlerr_cstr = dlerror(); + if (dlerr_cstr) { + dlerr = dlerr_cstr; + } + + if (dlerr.length()) { + ERROR(WRN, + "\tFailed to load symbol \"DSF_GetSmearceptorName\" from " + << (dirpath + ent->d_name) << ": " << dlerr); + dlclose(dlobj); + continue; + } + + plgManif.DSF_GetSmearceptor = + reinterpret_cast( + dlsym(dlobj, "DSF_GetSmearceptor")); + + dlerr = ""; + dlerr_cstr = dlerror(); + if (dlerr_cstr) { + dlerr = dlerr_cstr; + } + + if (dlerr.length()) { + ERROR(WRN, "\tFailed to load symbol \"DSF_GetSmearceptor\" from " + << (dirpath + ent->d_name) << ": " << dlerr); + dlclose(dlobj); + continue; + } + + plgManif.DSF_DestroySmearceptor = + reinterpret_cast( + dlsym(dlobj, "DSF_DestroySmearceptor")); + + dlerr = ""; + dlerr_cstr = dlerror(); + if (dlerr_cstr) { + dlerr = dlerr_cstr; + } + + if (dlerr.length()) { + ERROR(WRN, "Failed to load symbol \"DSF_DestroySmearceptor\" from " + << (dirpath + ent->d_name) << ": " << dlerr); + dlclose(dlobj); + continue; + } + + plgManif.NSmearceptors = (*(plgManif.DSF_NSmearceptors))(); + QLOG(FIT, "\tSuccessfully loaded dynamic smearceptor manifest: " + << plgManif.soloc << ". Contains " + << plgManif.NSmearceptors << " smearceptors."); + + for (size_t smp_it = 0; smp_it < plgManif.NSmearceptors; ++smp_it) { + char const* smp_name = (*(plgManif.DSF_GetSmearceptorName))(smp_it); + if (!smp_name) { + THROW("Could not load smearceptor " + << smp_it << " / " << plgManif.NSmearceptors << " from " + << plgManif.soloc); + } + + if (Smearceptors.count(smp_name)) { + ERROR(WRN, "Already loaded a smearceptor named: \"" + << smp_name << "\". cannot load duplciates. This " + "smearceptor will be skipped."); + continue; + } + + plgManif.SmearceptorsProvided.push_back(smp_name); + Smearceptors[smp_name] = std::make_pair(plgManif.soloc, smp_it); + QLOG(FIT, "\t\t" << smp_name); + } + + if (plgManif.SmearceptorsProvided.size()) { + Manifests[plgManif.soloc] = plgManif; + + NSmearceptors += plgManif.SmearceptorsProvided.size(); + NManifests++; + } else { + dlclose(dlobj); + } + } + } + closedir(dir); + } else { + ERROR(WRN, "Tried to open non-existant directory."); + } + } +} +DynamicSmearceptorFactory& DynamicSmearceptorFactory::Get() { + if (!glblDSF) { + glblDSF = new DynamicSmearceptorFactory(); + } + return *glblDSF; } +void DynamicSmearceptorFactory::Print() { + std::map > ManifestSmearceptors; -typedef ISmearcepter* (*SmearceptionFactory_fcn)(nuiskey&); + for (std::map >::iterator smp_it = + Smearceptors.begin(); + smp_it != Smearceptors.end(); ++smp_it) { + if (!ManifestSmearceptors.count(smp_it->second.first)) { + ManifestSmearceptors[smp_it->second.first] = std::vector(); + } + ManifestSmearceptors[smp_it->second.first].push_back(smp_it->first); + } + + QLOG(FIT, "Dynamic smearceptor manifest: "); + for (std::map >::iterator m_it = + ManifestSmearceptors.begin(); + m_it != ManifestSmearceptors.end(); ++m_it) { + QLOG(FIT, "\tLibrary " << m_it->first << " contains: "); + for (size_t s_it = 0; s_it < m_it->second.size(); ++s_it) { + QLOG(FIT, "\t\t" << m_it->second[s_it]); + } + } +} +bool DynamicSmearceptorFactory::HasSmearceptor(std::string const& name) { + return Smearceptors.count(name); +} +bool DynamicSmearceptorFactory::HasSmearceptor(nuiskey& smearceptorkey) { + return HasSmearceptor(smearceptorkey.GetElementName()); +} +ISmearcepter* DynamicSmearceptorFactory::CreateSmearceptor( + nuiskey& smearceptorkey) { + if (!HasSmearceptor(smearceptorkey)) { + ERROR(WRN, "Asked to load unknown smearceptor: \"" + << smearceptorkey.GetElementName() << "\"."); + return NULL; + } + + std::pair smearceptor = + Smearceptors[smearceptorkey.GetElementName()]; + QLOG(SAM, "\tLoading smearceptor " << smearceptor.second << " from " + << smearceptor.first); + + ISmearcepter* smear = (*(Manifests[smearceptor.first].DSF_GetSmearceptor))( + smearceptor.second, &smearceptorkey); + return smear; +} + +DynamicSmearceptorFactory::~DynamicSmearceptorFactory() { Manifests.clear(); } + +#endif Smearcepterton* Smearcepterton::_inst = NULL; Smearcepterton& Smearcepterton::Get() { if (!_inst) { _inst = new Smearcepterton(); } return *_inst; } Smearcepterton::Smearcepterton() { InitialiserSmearcepters(); } void Smearcepterton::InitialiserSmearcepters() { // hard coded list of tag name -> smearcepter factories, add here to add your // own. std::map factories; factories["ThresholdAccepter"] = &BuildSmearcepter; + factories["EfficiencyApplicator"] = &BuildSmearcepter; + factories["GaussianSmearer"] = &BuildSmearcepter; + factories["TrackedMomentumMatrixSmearer"] = + &BuildSmearcepter; + factories["VisECoalescer"] = &BuildSmearcepter; + factories["MetaSimpleSmearcepter"] = &BuildSmearcepter; std::vector smearcepterBlocks = Config::QueryKeys("smearcepters"); for (size_t smearB_it = 0; smearB_it < smearcepterBlocks.size(); ++smearB_it) { std::vector smearcepters = smearcepterBlocks[smearB_it].GetListOfChildNodes(); - for (size_t smear_it = 0; smear_it < smearcepterBlocks.size(); ++smear_it) { + for (size_t smear_it = 0; smear_it < smearcepters.size(); ++smear_it) { std::string const& smearType = smearcepters[smear_it].GetElementName(); - if (!factories.count(smearType)) { - ERROR(WRN, "No known smearer accepts elements named: \"" << smearType - << "\""); - continue; + ISmearcepter* smearer = NULL; + if (DynamicSmearceptorFactory::Get().HasSmearceptor(smearType)) { + smearer = DynamicSmearceptorFactory::Get().CreateSmearceptor( + smearcepters[smear_it]); + } else { + if (!factories.count(smearType)) { + ERROR(WRN, "No known smearer accepts elements named: \"" << smearType + << "\""); + continue; + } + smearer = factories[smearType](smearcepters[smear_it]); } - ISmearcepter* smearer = factories[smearType](smearcepters[smear_it]); + if(!smearer){ + THROW("Failed to load smearceptor."); + } Smearcepters[smearer->GetName()] = smearer; QLOG(FIT, "Configured smearer named: " << smearer->GetName() << " of type: " << smearer->GetElementName()); } } } diff --git a/src/Smearceptance/Smearcepterton.h b/src/Smearceptance/Smearcepterton.h index ea6027a..f5c6fc5 100644 --- a/src/Smearceptance/Smearcepterton.h +++ b/src/Smearceptance/Smearcepterton.h @@ -1,51 +1,112 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #ifndef SMEARCEPTERTON_HXX_SEEN #define SMEARCEPTERTON_HXX_SEEN #include "FitLogger.h" #include "ISmearcepter.h" #include #include + +#ifdef __USE_DYNSAMPLES__ +/// Expect each .so containing smearceptors to supply 4 c-style methods. +/// int DSF_NSmearceptors(); +/// char const * DSF_GetSmearceptorName(int); +/// ISmearcepter* DSF_GetSmearceptor(int, nuiskey *); +/// void DSF_DestroySmearceptor(ISmearcepter *); +class DynamicSmearceptorFactory { + size_t NSmearceptors; + size_t NManifests; + + DynamicSmearceptorFactory(); + + static DynamicSmearceptorFactory* glblDSF; + + typedef int (*DSF_NSmearceptors_ptr)(void); + typedef char const* (*DSF_GetSmearceptorName_ptr)(int); + typedef ISmearcepter* (*DSF_GetSmearceptor_ptr)(int, nuiskey *); + typedef void (*DSF_DestroySmearceptor_ptr)(ISmearcepter*); + + struct PluginManifest { + void* dllib; + + DSF_NSmearceptors_ptr DSF_NSmearceptors; + DSF_GetSmearceptorName_ptr DSF_GetSmearceptorName; + DSF_GetSmearceptor_ptr DSF_GetSmearceptor; + DSF_DestroySmearceptor_ptr DSF_DestroySmearceptor; + + std::string soloc; + std::vector Instances; + std::vector SmearceptorsProvided; + size_t NSmearceptors; + ~PluginManifest(); + }; + + std::map Manifests; + std::map > Smearceptors; + + void LoadPlugins(); + + public: + static DynamicSmearceptorFactory& Get(); + + void Print(); + + bool HasSmearceptor(std::string const& name); + bool HasSmearceptor(nuiskey& smearceptorkey); + + ISmearcepter* CreateSmearceptor(nuiskey& smearceptorkey); + + ~DynamicSmearceptorFactory(); +}; + +#endif + /// Singleton handling the loading and configuring of known smearcepters. class Smearcepterton { Smearcepterton(); void InitialiserSmearcepters(); static Smearcepterton *_inst; std::map Smearcepters; public: static Smearcepterton &Get(); - ISmearcepter &GetSmearcepter(std::string const & name) { + ISmearcepter &GetSmearcepter(std::string const &name) { if (!Smearcepters.count(name) || !Smearcepters[name]) { + ERROR(FTL, "Known smearcepters:"); + for (std::map::iterator sm_it = + Smearcepters.begin(); + sm_it != Smearcepters.end(); ++sm_it) { + ERROR(FTL, "\t" << sm_it->first); + } THROW("No smearcepter named: \"" << name << "\" defined."); } return *Smearcepters[name]; } }; #endif diff --git a/src/Smearceptance/ThresholdAccepter.cxx b/src/Smearceptance/ThresholdAccepter.cxx index 1f7b6f6..adc7239 100644 --- a/src/Smearceptance/ThresholdAccepter.cxx +++ b/src/Smearceptance/ThresholdAccepter.cxx @@ -1,197 +1,330 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "ThresholdAccepter.h" -// #define DEBUG_THRESACCEPT +namespace { +ThresholdAccepter::KineVar GetKineType(nuiskey &nk) { + if (nk.Has("RecoThresholdMomentum_MeV")) { + return ThresholdAccepter::kMomentum; + } else if (nk.Has("RecoThresholdKE_MeV")) { + return ThresholdAccepter::kKE; + } else if (nk.Has("RecoThresholdCosTheta_Max")) { + return ThresholdAccepter::kCosTheta_Max; + } else if (nk.Has("RecoThresholdCosTheta_Min")) { + return ThresholdAccepter::kCosTheta_Min; + } else if (nk.Has("RecoThresholdAbsCosTheta_Max")) { + return ThresholdAccepter::kAbsCosTheta_Max; + } else if (nk.Has("RecoThresholdAbsCosTheta_Min")) { + return ThresholdAccepter::kAbsCosTheta_Min; + } else { + THROW("Cannot determine the threshold type for Smearcepter element."); + } + return ThresholdAccepter::kNoVar; +} + +std::string GetKineTypeName(ThresholdAccepter::KineVar kv) { + switch (kv) { + case ThresholdAccepter::kMomentum: + return "Momentum"; + case ThresholdAccepter::kKE: + return "KE"; + case ThresholdAccepter::kCosTheta_Max: + return "CosTheta_Max"; + case ThresholdAccepter::kCosTheta_Min: + return "CosTheta_Min"; + case ThresholdAccepter::kAbsCosTheta_Max: + return "AbsCosTheta_Max"; + case ThresholdAccepter::kAbsCosTheta_Min: + return "CosTheta_Min"; + default: + return "NoVar"; + } +} + +double GetKineThreshold(nuiskey &nk, ThresholdAccepter::KineVar kv) { + switch (kv) { + case ThresholdAccepter::kMomentum: + return nk.GetD("RecoThresholdMomentum_MeV"); + case ThresholdAccepter::kKE: + return nk.GetD("RecoThresholdKE_MeV"); + case ThresholdAccepter::kCosTheta_Max: + return nk.GetD("RecoThresholdCosTheta_Max"); + case ThresholdAccepter::kCosTheta_Min: + return nk.GetD("RecoThresholdCosTheta_Min"); + case ThresholdAccepter::kAbsCosTheta_Max: + return nk.GetD("RecoThresholdAbsCosTheta_Max"); + case ThresholdAccepter::kAbsCosTheta_Min: + return nk.GetD("RecoThresholdAbsCosTheta_Min"); + default: + return 0; + } +} + +double GetKineVal(FitParticle *fp, ThresholdAccepter::Thresh &rt) { + switch (rt.ThresholdType) { + case ThresholdAccepter::kMomentum: + return fp->P3().Mag(); + case ThresholdAccepter::kKE: + return fp->KE(); + case ThresholdAccepter::kCosTheta_Max: + return fp->P3().CosTheta(); + case ThresholdAccepter::kCosTheta_Min: + return fp->P3().CosTheta(); + case ThresholdAccepter::kAbsCosTheta_Max: + return fabs(fp->P3().CosTheta()); + case ThresholdAccepter::kAbsCosTheta_Min: + return fabs(fp->P3().CosTheta()); + default: + return 0; + } +} + +bool PassesThreshold(FitParticle *fp, ThresholdAccepter::Thresh &rt) { + switch (rt.ThresholdType) { + case ThresholdAccepter::kMomentum: + return (fp->P3().Mag() > rt.ThresholdVal); + case ThresholdAccepter::kKE: + return (fp->KE() > rt.ThresholdVal); + case ThresholdAccepter::kCosTheta_Max: + return (fp->P3().CosTheta() < rt.ThresholdVal); + case ThresholdAccepter::kCosTheta_Min: + return (fp->P3().CosTheta() > rt.ThresholdVal); + case ThresholdAccepter::kAbsCosTheta_Max: + return (fabs(fp->P3().CosTheta()) < rt.ThresholdVal); + case ThresholdAccepter::kAbsCosTheta_Min: + return (fabs(fp->P3().CosTheta()) > rt.ThresholdVal); + default: + return 0; + } +} +} /// Reads particle threshold nodes /// /// Nodes look like: /// /// -/// -/// -/// +/// +/// +/// +/// +/// /// void ThresholdAccepter::SpecifcSetup(nuiskey &nk) { std::vector recoThresholdDescriptors = nk.GetListOfChildNodes("RecoThreshold"); for (size_t t_it = 0; t_it < recoThresholdDescriptors.size(); ++t_it) { std::string pdgs_s = recoThresholdDescriptors[t_it].GetS("PDG"); std::vector pdgs_i = GeneralUtils::ParseToInt(pdgs_s, ","); for (size_t pdg_it = 0; pdg_it < pdgs_i.size(); ++pdg_it) { - if (ReconThresholds.count(pdgs_i[pdg_it])) { - ERROR(WRN, "Smearceptor " << ElementName << ":" << InstanceName - << " already has a threshold for PDG: " - << pdgs_i[pdg_it]); - } Thresh t; - if (recoThresholdDescriptors[t_it].Has("RecoThresholdKE_MeV")) { - t.ThresholdIsKE = true; - t.ThresholdVal = - recoThresholdDescriptors[t_it].GetD("RecoThresholdKE_MeV"); - } else if (recoThresholdDescriptors[t_it].Has("RecoThresholdMom_MeV")) { - t.ThresholdIsKE = false; - t.ThresholdVal = - recoThresholdDescriptors[t_it].GetD("RecoThresholdMom_MeV"); - } else { - ERROR(WRN, "Smearceptor " - << ElementName << ":" << InstanceName - << " cannot find threshold information for PDG: " - << pdgs_i[pdg_it]); - continue; - } + t.ThresholdType = GetKineType(recoThresholdDescriptors[t_it]); + t.ThresholdVal = + GetKineThreshold(recoThresholdDescriptors[t_it], t.ThresholdType); - ReconThresholds[pdgs_i[pdg_it]] = t; + ReconThresholds[pdgs_i[pdg_it]].push_back(t); - QLOG(SAM, - "Added reconstruction threshold of MeV " - << ReconThresholds[pdgs_i[pdg_it]].ThresholdVal << " " - << (ReconThresholds[pdgs_i[pdg_it]].ThresholdIsKE ? "KE" : "Mom") - << ", for PDG: " << pdgs_i[pdg_it]); + QLOG(FIT, "Added reconstruction threshold of type: " + << ReconThresholds[pdgs_i[pdg_it]].back().ThresholdVal + << " " + << GetKineTypeName( + ReconThresholds[pdgs_i[pdg_it]].back().ThresholdType) + << ", for PDG: " << pdgs_i[pdg_it]); } } std::vector visThresholdDescriptors = nk.GetListOfChildNodes("VisThreshold"); for (size_t t_it = 0; t_it < visThresholdDescriptors.size(); ++t_it) { std::string pdgs_s = visThresholdDescriptors[t_it].GetS("PDG"); std::vector pdgs_i = GeneralUtils::ParseToInt(pdgs_s, ","); for (size_t pdg_it = 0; pdg_it < pdgs_i.size(); ++pdg_it) { if (VisThresholds.count(pdgs_i[pdg_it])) { ERROR(WRN, "Smearceptor " << ElementName << ":" << InstanceName << " already has a threshold for PDG: " << pdgs_i[pdg_it]); } VisThresh vt; + vt.UseKE = visThresholdDescriptors[t_it].Has("Contrib") + ? (visThresholdDescriptors[t_it].GetS("Contrib") == "K") + : false; + vt.Fraction = visThresholdDescriptors[t_it].Has("Fraction") + ? visThresholdDescriptors[t_it].GetD("Fraction") + : 1; if (visThresholdDescriptors[t_it].Has("VisThresholdKE_MeV")) { - vt.ThresholdIsKE = true; + vt.ThresholdType = ThresholdAccepter::kKE; vt.ThresholdVal = visThresholdDescriptors[t_it].GetD("VisThresholdKE_MeV"); - vt.UseKE = (visThresholdDescriptors[t_it].GetS("Contrib") == "K"); - } else if (visThresholdDescriptors[t_it].Has("VisThresholdMom_MeV")) { - vt.ThresholdIsKE = false; + } else if (visThresholdDescriptors[t_it].Has( + "VisThresholdMomentum_MeV")) { + vt.ThresholdType = ThresholdAccepter::kMomentum; vt.ThresholdVal = - visThresholdDescriptors[t_it].GetD("VisThresholdMom_MeV"); - vt.UseKE = (visThresholdDescriptors[t_it].GetS("Contrib") == "K"); + visThresholdDescriptors[t_it].GetD("VisThresholdMomentum_MeV"); + ; } else { ERROR(WRN, "Smearceptor " << ElementName << ":" << InstanceName << " cannot find threshold information for PDG: " << pdgs_i[pdg_it]); continue; } VisThresholds[pdgs_i[pdg_it]] = vt; - QLOG(SAM, + QLOG(FIT, "Added visibility threshold of MeV " << VisThresholds[pdgs_i[pdg_it]].ThresholdVal << " " - << (VisThresholds[pdgs_i[pdg_it]].ThresholdIsKE ? "KE" : "Mom") + << GetKineTypeName(VisThresholds[pdgs_i[pdg_it]].ThresholdType) << ", for PDG: " << pdgs_i[pdg_it] << ". If visible, particle deposits: " << (VisThresholds[pdgs_i[pdg_it]].UseKE ? "KE" : "TE")); } } } -RecoInfo *ThresholdAccepter::Smearcept(FitEvent *fe) { - RecoInfo *ri = new RecoInfo(); +void ThresholdAccepter::SmearceptOneParticle(RecoInfo *ri, FitParticle *fp +#ifdef DEBUG_THRESACCEPT + , + size_t p_it +#endif + ) { +#ifdef DEBUG_THRESACCEPT + std::cout << std::endl; + std::cout << "[" << p_it << " = " << fp << "]: " << fp->PDG() << ", " + << fp->Status() << ", " << fp->E() << " -- KE:" << fp->KE() + << " Mom: " << fp->P3().Mag() << std::flush; +#endif - for (size_t p_it = 0; p_it < fe->NParticles(); ++p_it) { - FitParticle *fp = fe->GetParticle(p_it); + if (fp->Status() != kFinalState) { #ifdef DEBUG_THRESACCEPT - std::cout << std::endl; - std::cout << "[" << p_it << "]: " << fp->PDG() << ", " << fp->Status() - << ", " << fp->E() << " -- KE:" << fp->KE() - << " Mom: " << fp->P3().Mag() << std::flush; + std::cout << " -- Not final state." << std::flush; #endif + return; + } - if (fp->Status() != kFinalState) { + if ((ReconThresholds.count(fp->PDG()) + VisThresholds.count(fp->PDG())) == + 0) { #ifdef DEBUG_THRESACCEPT - std::cout << " -- Not final state." << std::flush; + std::cout << " -- Undetectable." << std::flush; #endif - continue; - } + return; + } - if (!ReconThresholds.count(fp->PDG())) { + // If no reco thresholds it should fall through to EVis + bool Passes = ReconThresholds[fp->PDG()].size(); + bool FailEnergyThresh = !ReconThresholds[fp->PDG()].size(); + for (size_t rt_it = 0; rt_it < ReconThresholds[fp->PDG()].size(); ++rt_it) { + bool Passed = PassesThreshold(fp, ReconThresholds[fp->PDG()][rt_it]); + if (!Passed) { +#ifdef DEBUG_THRESACCEPT + std::cout << "\n\t -- Rejected. (" + << GetKineTypeName( + ReconThresholds[fp->PDG()][rt_it].ThresholdType) + << " Threshold: " + << ReconThresholds[fp->PDG()][rt_it].ThresholdVal << " | " + << GetKineVal(fp, ReconThresholds[fp->PDG()][rt_it]) << ")" + << std::flush; + if ((ReconThresholds[fp->PDG()][rt_it].ThresholdType == + ThresholdAccepter::kMomentum) || + (ReconThresholds[fp->PDG()][rt_it].ThresholdType == + ThresholdAccepter::kKE)) { + FailEnergyThresh = true; + } +#endif + } else { #ifdef DEBUG_THRESACCEPT - std::cout << " -- Undetectable." << std::flush; + std::cout << "\n\t -- Accepted. (" + << GetKineTypeName( + ReconThresholds[fp->PDG()][rt_it].ThresholdType) + << " Threshold: " + << ReconThresholds[fp->PDG()][rt_it].ThresholdVal << " | " + << GetKineVal(fp, ReconThresholds[fp->PDG()][rt_it]) << ")" + << std::flush; #endif - continue; } + Passes = Passes && Passed; + } - if ((ReconThresholds[fp->PDG()].ThresholdIsKE && - (ReconThresholds[fp->PDG()].ThresholdVal < - fp->KE())) // Above KE-style threshold - || (!ReconThresholds[fp->PDG()].ThresholdIsKE && - (ReconThresholds[fp->PDG()].ThresholdVal < - fp->P3().Mag())) // Above mom-style threshold - ) { + if (Passes) { #ifdef DEBUG_THRESACCEPT - std::cout << " -- Reconstructed. (" - << (ReconThresholds[fp->PDG()].ThresholdIsKE ? "KE" : "Mom") - << ": " << ReconThresholds[fp->PDG()].ThresholdVal << ")" - << std::flush; + std::cout << " -- Reconstructed." << std::flush; #endif - ri->RecObjMom.push_back(fp->P3()); - ri->RecObjClass.push_back(fp->PDG()); + ri->RecObjMom.push_back(fp->P3()); + ri->RecObjClass.push_back(fp->PDG()); - continue; - } + return; + } else if (!FailEnergyThresh) { +#ifdef DEBUG_THRESACCEPT + std::cout << " -- Failed non-Energy threshold, no chance for EVis." + << std::flush; +#endif + return; + } - if ((VisThresholds[fp->PDG()].ThresholdIsKE && - (VisThresholds[fp->PDG()].ThresholdVal < - fp->KE())) // Above KE-style threshold - || (!VisThresholds[fp->PDG()].ThresholdIsKE && - (VisThresholds[fp->PDG()].ThresholdVal < - fp->P3().Mag())) // Above mom-style threshold - ) { + if (((VisThresholds[fp->PDG()].ThresholdType == ThresholdAccepter::kKE) && + (VisThresholds[fp->PDG()].ThresholdVal < + fp->KE())) // Above KE-style threshold + || ((VisThresholds[fp->PDG()].ThresholdType == + ThresholdAccepter::kMomentum) && + (VisThresholds[fp->PDG()].ThresholdVal < + fp->P3().Mag())) // Above mom-style threshold + ) { #ifdef DEBUG_THRESACCEPT - std::cout << " -- Contributed to VisE. (" - << (VisThresholds[fp->PDG()].ThresholdIsKE ? "KE" : "Mom") - << ": " << VisThresholds[fp->PDG()].ThresholdVal << ")" - << std::flush; + std::cout << " -- Contributed to VisE. (" + << GetKineTypeName(VisThresholds[fp->PDG()].ThresholdType) << ": " + << VisThresholds[fp->PDG()].ThresholdVal << ")" << std::flush; #endif - ri->RecVisibleEnergy.push_back(VisThresholds[fp->PDG()].UseKE ? fp->KE() - : fp->E()); - ri->TrueContribPDGs.push_back(fp->PDG()); + ri->RecVisibleEnergy.push_back( + VisThresholds[fp->PDG()].Fraction * + (VisThresholds[fp->PDG()].UseKE ? fp->KE() : fp->E())); + ri->TrueContribPDGs.push_back(fp->PDG()); - continue; - } + return; + } else { #ifdef DEBUG_THRESACCEPT std::cout << " -- Rejected. " - << "Reco: (" - << (ReconThresholds[fp->PDG()].ThresholdIsKE ? "KE" : "Mom") - << ": " << ReconThresholds[fp->PDG()].ThresholdVal << ")" << " Vis: (" - << (VisThresholds[fp->PDG()].ThresholdIsKE ? "KE" : "Mom") << ": " + << GetKineTypeName(VisThresholds[fp->PDG()].ThresholdType) << ": " << VisThresholds[fp->PDG()].ThresholdVal << ")" << std::flush; #endif } +} + +RecoInfo *ThresholdAccepter::Smearcept(FitEvent *fe) { + RecoInfo *ri = new RecoInfo(); + + for (size_t p_it = 0; p_it < fe->NParticles(); ++p_it) { + FitParticle *fp = fe->GetParticle(p_it); + SmearceptOneParticle(ri, fp +#ifdef DEBUG_THRESACCEPT + , + p_it +#endif + ); + } #ifdef DEBUG_THRESACCEPT std::cout << std::endl; #endif return ri; } diff --git a/src/Smearceptance/ThresholdAccepter.h b/src/Smearceptance/ThresholdAccepter.h index 761b7c1..cefc33e 100644 --- a/src/Smearceptance/ThresholdAccepter.h +++ b/src/Smearceptance/ThresholdAccepter.h @@ -1,45 +1,66 @@ // 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 THRESHOLDACCEPTER_HXX_SEEN #define THRESHOLDACCEPTER_HXX_SEEN +// #define DEBUG_THRESACCEPT + #include "ISmearcepter.h" #include class ThresholdAccepter : public ISmearcepter { + + public: + enum KineVar { + kMomentum, + kKE, + kCosTheta_Max, + kCosTheta_Min, + kAbsCosTheta_Max, + kAbsCosTheta_Min, + kNoVar + }; + struct Thresh { - bool ThresholdIsKE; + KineVar ThresholdType; double ThresholdVal; }; struct VisThresh : public Thresh { bool UseKE; + double Fraction; }; - std::map ReconThresholds; + private: + std::map > ReconThresholds; std::map VisThresholds; void SpecifcSetup(nuiskey &); public: + void SmearceptOneParticle(RecoInfo *ri, FitParticle *fp +#ifdef DEBUG_THRESACCEPT + , size_t p_it +#endif + ); RecoInfo *Smearcept(FitEvent *); }; #endif diff --git a/src/Smearceptance/TrackedMomentumMatrixSmearer.cxx b/src/Smearceptance/TrackedMomentumMatrixSmearer.cxx new file mode 100644 index 0000000..1a03865 --- /dev/null +++ b/src/Smearceptance/TrackedMomentumMatrixSmearer.cxx @@ -0,0 +1,416 @@ +// 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 "TrackedMomentumMatrixSmearer.h" + +namespace { +TrackedMomentumMatrixSmearer::DependVar GetVarType(std::string const &axisvar) { + if (axisvar == "Momentum") { + return TrackedMomentumMatrixSmearer::kMomentum; + } else if (axisvar == "KE") { + return TrackedMomentumMatrixSmearer::kKE; + } else if (axisvar == "TE") { + return TrackedMomentumMatrixSmearer::kTE; + } + return TrackedMomentumMatrixSmearer::kNoVar; +} +} + +TH1D const *TrackedMomentumMatrixSmearer::SmearMap::GetRecoSlice(double val) { + if ((val < RecoSlices.front().first.first) || + (val > RecoSlices.back().first.second)) { + ERROR(WRN, + "Kinematic property: " << val << ", not within smearable range: [" + << RecoSlices.front().first.first << " -- " + << RecoSlices.back().first.second << "]."); + return NULL; + } + + int L = 0, U = RecoSlices.size(); + + while (true) { + if (U == L) { + return RecoSlices[L].second; + } + int R = (U - L); + int m = L + (R / 2); + + if (val <= RecoSlices[m].first.first) { + U = m - 1; + continue; + } + if (val > RecoSlices[m].first.second) { + L = m + 1; + continue; + } + if ((val > RecoSlices[m].first.first) && + (val <= RecoSlices[m].first.second)) { + return RecoSlices[m].second; + } + THROW("Binary smearing search failed. Check logic."); + } +} + +TH1D *GetMapSlice(TH2D *mp, int SliceBin, bool AlongX) { + int NBins = (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetNbins(); + int NOtherBins = (AlongX ? mp->GetYaxis() : mp->GetXaxis())->GetNbins(); + if (SliceBin >= NOtherBins) { + THROW("Asked for slice " << SliceBin << " but the " << (AlongX ? 'Y' : 'X') + << " axis only has " << NOtherBins); + } + + if ((AlongX ? mp->GetXaxis() : mp->GetYaxis())->IsVariableBinSize() && + ((NBins + 1) != + (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetXbins()->GetSize())) { + THROW( + "Attemping to take binning slice of variable binning, but NBins+1 != " + "NBinEdges: " + << (NBins + 1) << " != " + << (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetXbins()->GetSize()); + } + + std::stringstream ss(""); + ss << mp->GetName() << (AlongX ? 'Y' : 'X') << "Slice_" << SliceBin; + std::stringstream st(""); + st << mp->GetTitle() << ";" + << (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetTitle() << ";" + << "Count"; + TH1D *Ret; + if ((AlongX ? mp->GetXaxis() : mp->GetYaxis())->IsVariableBinSize()) { + Ret = new TH1D( + ss.str().c_str(), st.str().c_str(), NBins, + (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetXbins()->GetArray()); + } else { + Ret = new TH1D(ss.str().c_str(), st.str().c_str(), NBins, + (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetXmin(), + (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetXmax()); + } + + for (int bi_it = 0; bi_it < NBins + 2; ++bi_it) { + int X = AlongX ? bi_it : SliceBin + 1; + int Y = AlongX ? SliceBin + 1 : bi_it; + int GBin = mp->GetBin(X, Y); + Ret->SetBinContent(bi_it, mp->GetBinContent(GBin)); + Ret->SetBinError(bi_it, mp->GetBinError(GBin)); + } + +#ifdef DEBUG_MATSMEAR + std::cout << "Took slice: " << SliceBin << " spanning [" + << Ret->GetXaxis()->GetBinLowEdge(1) << " -- " + << Ret->GetXaxis()->GetBinUpEdge(Ret->GetXaxis()->GetNbins()) + << "] (Orignal span [" + << (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetBinLowEdge(1) + << " -- " + << (AlongX ? mp->GetXaxis() : mp->GetYaxis()) + ->GetBinUpEdge( + (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetNbins()) + << "]) " << (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetXmin() + << " -- " << (AlongX ? mp->GetXaxis() : mp->GetYaxis())->GetXmax() + << " IsVBin: " + << (AlongX ? mp->GetXaxis() : mp->GetYaxis())->IsVariableBinSize() + << std::endl; +#endif + + Ret->SetDirectory(NULL); + return Ret; +} + +void TrackedMomentumMatrixSmearer::SmearMap::SetSlicesFromMap(TH2D *map, + bool TruthIsY) { + int NSlices = (TruthIsY ? map->GetYaxis() : map->GetXaxis())->GetNbins(); + + for (Int_t TrueSlice_it = 0; TrueSlice_it < NSlices; ++TrueSlice_it) { + std::pair BinEdges; + BinEdges.first = (TruthIsY ? map->GetYaxis() : map->GetXaxis()) + ->GetBinLowEdge(TrueSlice_it + 1); + BinEdges.second = (TruthIsY ? map->GetYaxis() : map->GetXaxis()) + ->GetBinUpEdge(TrueSlice_it + 1); + + TH1D *slice = GetMapSlice(map, TrueSlice_it, TruthIsY); + + RecoSlices.push_back(std::make_pair(BinEdges, slice)); + } + QLOG(FIT, "\tAdded " << RecoSlices.size() << " reco slices."); +} + +/// Reads particle efficiency nodes +/// +/// Nodes look like: +/// +/// +/// +void TrackedMomentumMatrixSmearer::SpecifcSetup(nuiskey &nk) { + std::vector effDescriptors = nk.GetListOfChildNodes("SmearMatrix"); + + for (size_t t_it = 0; t_it < effDescriptors.size(); ++t_it) { + std::string inputFileName = effDescriptors[t_it].GetS("InputFile"); + std::string HistName = effDescriptors[t_it].GetS("HistName"); + bool YIsTrue = effDescriptors[t_it].Has("YIsTrue") + ? effDescriptors[t_it].GetI("YIsTrue") + : true; + + double UnitsScale = effDescriptors[t_it].Has("MatrixToInternal") + ? effDescriptors[t_it].GetD("MatrixToInternal") + : 1; + + TFile inputFile(inputFileName.c_str()); + if (!inputFile.IsOpen()) { + THROW("Couldn't open specified input root file: " << inputFileName); + } + + TH2D *inpHist = dynamic_cast(inputFile.Get(HistName.c_str())); + if (!inpHist) { + THROW("Couldn't get TH2D named: " << HistName << " from input root file: " + << inputFileName); + } + + TrackedMomentumMatrixSmearer::DependVar var = + GetVarType(effDescriptors[t_it].GetS("Kinematics")); + + std::string pdgs_s = effDescriptors[t_it].GetS("PDG"); + std::vector pdgs_i = GeneralUtils::ParseToInt(pdgs_s, ","); + for (size_t pdg_it = 0; pdg_it < pdgs_i.size(); ++pdg_it) { + if (ParticleMappings.count(pdgs_i[pdg_it])) { + ERROR(WRN, "Smearceptor " << ElementName << ":" << InstanceName + << " already has a smearing for PDG: " + << pdgs_i[pdg_it]); + } + + SmearMap sm; + sm.SetSlicesFromMap(inpHist, YIsTrue); + sm.SmearVar = var; + sm.UnitsScale = UnitsScale; + + ParticleMappings[pdgs_i[pdg_it]] = sm; + + QLOG(FIT, "Added smearing map for PDG: " << pdgs_i[pdg_it]); + } + } + SlaveGS.Setup(nk); +} + +RecoInfo *TrackedMomentumMatrixSmearer::Smearcept(FitEvent *fe) { + RecoInfo *ri = new RecoInfo(); + + for (size_t p_it = 0; p_it < fe->NParticles(); ++p_it) { + FitParticle *fp = fe->GetParticle(p_it); +#ifdef DEBUG_MATSMEAR + std::cout << std::endl; + std::cout << "[" << p_it << "]: " << fp->PDG() << ", " << fp->Status() + << ", " << fp->E() << " -- KE:" << fp->KE() + << " Mom: " << fp->P3().Mag() << std::flush; +#endif + + if (fp->Status() != kFinalState) { +#ifdef DEBUG_MATSMEAR + std::cout << " -- Not final state." << std::flush; +#endif + continue; + } + + if (!ParticleMappings.count(fp->PDG())) { + SlaveGS.SmearceptOneParticle(ri, fp +#ifdef DEBUG_GAUSSSMEAR + , + p_it +#endif + ); + continue; + } + + SmearMap &sm = ParticleMappings[fp->PDG()]; + double kineProp = 0; + + switch (sm.SmearVar) { + case kMomentum: { + kineProp = fp->P3().Mag(); + break; + } + case kKE: { + kineProp = fp->KE(); + break; + } + case kTE: { + kineProp = fp->E(); + break; + } + default: { THROW("Trying to find particle value for a kNoAxis."); } + } + + TH1 const *recoDistrib = sm.GetRecoSlice(kineProp / sm.UnitsScale); + +#ifdef DEBUG_MATSMEAR + std::cout << " -- Got slice spanning [" + << recoDistrib->GetXaxis()->GetBinLowEdge(1) << " -- " + << recoDistrib->GetXaxis()->GetBinUpEdge( + recoDistrib->GetXaxis()->GetNbins()) + << "]" << std::endl; +#endif + + if (!recoDistrib) { +#ifdef DEBUG_MATSMEAR + std::cout << " -- outside smearable range." << std::flush; +#endif + continue; + } + + if (recoDistrib->Integral() == 0) { + ERROR(WRN, "True slice has no reconstructed events. Not smearing.") + continue; + } + + double Smeared = recoDistrib->GetRandom() * sm.UnitsScale; +#ifdef DEBUG_MATSMEAR + std::cout << "GotRandom: " << Smeared << ", MPV: " + << recoDistrib->GetXaxis()->GetBinCenter( + recoDistrib->GetMaximumBin()) * + sm.UnitsScale + << std::endl; +#endif + + switch (sm.SmearVar) { + case kMomentum: { + ri->RecObjMom.push_back(fp->P3().Unit() * Smeared); + +#ifdef DEBUG_MATSMEAR + std::cout << " -- Smeared: " << fp->p() << " -> " << Smeared << "." + << std::flush; +#endif + + break; + } + case kKE: { + double mass = fp->P4().M(); + double TE = mass + Smeared; + double magP = sqrt(TE * TE - mass * mass); + + ri->RecObjMom.push_back(fp->P3().Unit() * magP); + +#ifdef DEBUG_MATSMEAR + std::cout << " -- Smeared: " << fp->KE() << " (mass: " << mass + << ") -> " << Smeared + << ". Smear Mom: " << ri->RecObjMom.back().Mag() << "." + << std::flush; +#endif + break; + } + case kTE: { + double mass = fp->P4().M(); + double TE = Smeared; + double magP = sqrt(TE * TE - mass * mass); + + ri->RecObjMom.push_back(fp->P3().Unit() * magP); + +#ifdef DEBUG_MATSMEAR + std::cout << " -- Smeared: " << fp->E() << " (mass: " << mass + << ") -> " << Smeared + << ". Smear Mom: " << ri->RecObjMom.back().Mag() << "." + << std::flush; +#endif + break; + } + default: {} + } +#ifdef DEBUG_MATSMEAR + std::cout << " -- momentum reconstructed as " << ri->RecObjMom.back().Mag() + << "." << std::endl; +#endif + if (ri->RecObjMom.back().Mag() != ri->RecObjMom.back().Mag()) { + ERROR(WRN, "Invalid particle built."); + ri->RecObjMom.pop_back(); + +#include "TCanvas.h" + TCanvas *Test = new TCanvas("c1", ""); + static_cast(recoDistrib->Clone())->Draw(); + Test->SaveAs("Fail.png"); + delete Test; + THROW("ARGH"); + } else { + ri->RecObjClass.push_back(fp->PDG()); + } + } +#ifdef DEBUG_MATSMEAR + std::cout << std::endl; +#endif + return ri; +} + +void TrackedMomentumMatrixSmearer::SmearRecoInfo(RecoInfo *ri) { + for (size_t p_it = 0; p_it < ri->RecObjMom.size(); ++p_it) { + if (!ParticleMappings.count(ri->RecObjClass[p_it])) { + SlaveGS.SmearceptOneParticle(ri->RecObjMom[p_it], ri->RecObjClass[p_it]); + continue; + } + SmearMap &sm = ParticleMappings[ri->RecObjClass[p_it]]; + double kineProp = 0; + + switch (sm.SmearVar) { + case kMomentum: { + kineProp = ri->RecObjMom[p_it].Mag(); + break; + } + case kKE: { + double mass = PhysConst::GetMass(ri->RecObjClass[p_it]) * 1E3; + kineProp = sqrt(ri->RecObjMom[p_it].Mag2() + mass * mass) - mass; + break; + } + case kTE: { + double mass = PhysConst::GetMass(ri->RecObjClass[p_it]) * 1E3; + kineProp = sqrt(ri->RecObjMom[p_it].Mag2() + mass * mass); + break; + } + default: { THROW("Trying to find particle value for a kNoAxis."); } + } + TH1 const *recoDistrib = sm.GetRecoSlice(kineProp / sm.UnitsScale); + if (!recoDistrib) { + continue; + } + + if (recoDistrib->Integral() == 0) { + ERROR(WRN, "True slice has no reconstructed events. Not smearing.") + continue; + } + + double Smeared = recoDistrib->GetRandom() * sm.UnitsScale; + + switch (sm.SmearVar) { + case kMomentum: { + ri->RecObjMom[p_it] = ri->RecObjMom[p_it].Unit() * Smeared; + break; + } + case kKE: { + double mass = PhysConst::GetMass(ri->RecObjClass[p_it]) * 1E3; + double TE = mass + Smeared; + double magP = sqrt(TE * TE - mass * mass); + ri->RecObjMom[p_it] = ri->RecObjMom[p_it].Unit() * magP; + break; + } + case kTE: { + double mass = PhysConst::GetMass(ri->RecObjClass[p_it]) * 1E3; + double TE = Smeared; + double magP = sqrt(TE * TE - mass * mass); + ri->RecObjMom[p_it] = ri->RecObjMom[p_it].Unit() * magP; + break; + } + default: {} + } + } +} diff --git a/src/Smearceptance/TrackedMomentumMatrixSmearer.h b/src/Smearceptance/TrackedMomentumMatrixSmearer.h new file mode 100644 index 0000000..c84698c --- /dev/null +++ b/src/Smearceptance/TrackedMomentumMatrixSmearer.h @@ -0,0 +1,72 @@ +// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +/******************************************************************************* +* This file is part of NUISANCE. +* +* NUISANCE is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* NUISANCE is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NUISANCE. If not, see . +*******************************************************************************/ + +#ifndef TRACKEDMOMENTUMMATRIXSMEARER_HXX_SEEN +#define TRACKEDMOMENTUMMATRIXSMEARER_HXX_SEEN + +#include "ISmearcepter.h" + +#include "GaussianSmearer.h" + +#include "TRandom3.h" +#include "TH2D.h" +#include "TH1D.h" + +#include +#include + +// #define DEBUG_MATSMEAR + +class TrackedMomentumMatrixSmearer : public ISmearcepter { + public: + enum DependVar { kMomentum, kKE, kTE, kNoVar }; + + private: + class SmearMap { + /// Input True -> Reco mapping. + std::vector, TH1D *> > RecoSlices; + + public: + TH1D const *GetRecoSlice(double val); + void SetSlicesFromMap(TH2D *, bool TruthIsY); + /// Particle variable to smear: Momentum/KE + /// + /// In the future should be able to smear multi-kinematic property + /// distributions, but requires the definition of axis mappings that I + /// cannot be bothered with at this second. + TrackedMomentumMatrixSmearer::DependVar SmearVar; + + double UnitsScale; + }; + std::map ParticleMappings; + + GaussianSmearer SlaveGS; + + void SpecifcSetup(nuiskey &); + + public: + /// Will reject any particle that is not known about. + RecoInfo *Smearcept(FitEvent *); + /// Helper method for using this class as a component in a more complex + /// smearer + void SmearRecoInfo(RecoInfo *); + ~TrackedMomentumMatrixSmearer(); +}; + +#endif diff --git a/src/Smearceptance/VisECoalescer.h b/src/Smearceptance/VisECoalescer.h new file mode 100644 index 0000000..a56610a --- /dev/null +++ b/src/Smearceptance/VisECoalescer.h @@ -0,0 +1,61 @@ +// 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 VISECOALESCER_HXX_SEEN +#define VISECOALESCER_HXX_SEEN + +#include "ISmearcepter.h" + +#include + +///Stacks all VisE deposits from particles of the same PDG +class VisECoalescer : public ISmearcepter { + private: + void SpecifcSetup(nuiskey &) {} + + public: + RecoInfo *Smearcept(FitEvent *) { + THROW("VisECoalescer cannot act as an accepter"); + } + + /// Helper method for using this class as a component in a more complex + /// smearer + void SmearRecoInfo(RecoInfo *ri) { + std::map TotalSpeciesVisE; + + for (size_t ve_it = 0; ve_it < ri->RecVisibleEnergy.size(); ++ve_it) { + if (!TotalSpeciesVisE.count(ri->TrueContribPDGs[ve_it])) { + TotalSpeciesVisE[ri->TrueContribPDGs[ve_it]] = 0; + } + TotalSpeciesVisE[ri->TrueContribPDGs[ve_it]] += + ri->RecVisibleEnergy[ve_it]; + } + + ri->RecVisibleEnergy.clear(); + ri->TrueContribPDGs.clear(); + + for (std::map::iterator ve_it = TotalSpeciesVisE.begin(); + ve_it != TotalSpeciesVisE.end(); ++ve_it) { + ri->TrueContribPDGs.push_back(ve_it->first); + ri->RecVisibleEnergy.push_back(ve_it->second); + } + } +}; + +#endif diff --git a/src/Smearceptance/smearceptance.md b/src/Smearceptance/smearceptance.md new file mode 100644 index 0000000..b876ded --- /dev/null +++ b/src/Smearceptance/smearceptance.md @@ -0,0 +1,273 @@ +# NUISANCE Smearceptance + +1. Introduction +2. Quickstart: Applying thresholds +3. Included smearcepters +4. Writing your own + +## 1. Introduction +A generalised 'Fast MC' interface for NUISANCE. Smearers, accepters, and +smearcepters can be written and configured to mock up the effects of using a +'realistic' detection techniques on any input event format that NUISANCE can +read. A simple example of this would be a threshold accepter, which lets the +user define charged particle tracking thresholds for different types of final +state particles. These thresholds would be applied so that any downstream +analysis can only see particles above threshold. + +The eventual aim of such a module would be to expand the use of NUISANCE as a +data-release platform so that analysers could add their +reconstruction-level/uncorrected results, along with the information to +forward-fold, or 'smearcept' theory inputs for comparison and model tuning. It +is not currently clear that this is feasible, but it is an interesting +possibility. + +The current use cases include generating fake data for different types of +detector technology, running simple mock experiments as a first gauge of +potential sensitivities, and simple model overlays for uncorrected data from +both nu-A and e-A scattering experiments. + +The interface is designed to be abstract, and very simple. With any real data +and analyses, the devil is often in the detail and it is likely that tailored +Smearcepters would have to be written for each analysis. However, a number of +examples and simple smearcepters already exist and are useful for applying +thresholds, multi-dimensional efficiency curves, and simple detector smearing +effects. + +## 2. Quickstart: Applying thresholds + +Steps to acceptance: +* Write a smearcepter card file, `WaterCherenkovThresholds.xml`: +```xml + + + + + + + + +``` +* Produce a smeared event summary tree: +`$ nuissmear -i InputVector.root -c WaterCherenkovThresholds.xml -t WCThresh -o WaterCherenkov_summary.root` +* Draw plots from the event tree: +`[root] FlatTree_VARS->Draw("EISLep_true:EISLep_LepHad_rec >> (100,0,2000,100,0,2000)","Weight*(flagCCINC_rec==1)","COLZ")` + +The branchs in the event summary tree are described in detail the class +documentation of `src/MCStudies/Smearceptance_Tester.cxx` + +## 3. Included smearcepters + +### General + +Smearcepters are defined in a NUISANCE xml configuration file within a tag of +the `` root element named ``. Any number can be defined, +and each should be distinctly named with a `Name=""` attribute. + +An example XML tag is shown below that highlights some of the notation used in +this section. +```xml + +``` +* `AB` and `AC` are both valid attribute names, at least one of which is a +required attribute. +* `D` is an optional attribute. +* `` is an example attribute value. +* The attribute `E` must take either the value `F` or `G`. + +### ThresholdAccepter + +Applies tracking and visible energy thresholds to an input vector. + +#### Full example +```xml + + + + + + + + + + + + + + + +``` + +#### Details +A tracking threshold can be placed on a particles production zenith angle by +the element: +* `` +* `` + +Tracking and visible energy threshold values can be applied by the following +elements: +* Particle momentum: Use `<[Reco|Vis]Threshold PDG="" [Reco|Vis]ThresholdMomentum_MeV="" (Contrib="[T|K]" Fraction="") />` +* Particle kinetic energy: Use `<[Reco|Vis]Threshold PDG="" [Reco|Vis]ThresholdKE_MeV="" (Contrib="[T|K]" Fraction="") />` + +When defining visible energy thresholds, the additional attributes +`Contrib="[,K]"` and `Fraction=""` can be specified to detail whether +the energy deposit contribution comes from the particle total or kinetic energy +only and what fraction of that deposit is visible. The deposited energy defaults +to the particle total energy and the fraction defaults to 1. + +If a particle kinematics do not exceed a momentum or kinetic energy threshold +for tracking they are tested against the visible energy deposit threshold. If a +particle is rejected due to an angular threshold, it is not allowed to deposit +energy. + +Multiple thresholds can target the same input PDG, however it is undefined +behavior to use more than one energy/momentum tracking threshold, or use both +`Abs` and non-`Abs` zenith angle cuts. + +*N.B.* If a PDG code is encountered for which there are no defined thresholds, +it is not accepted. + +### GaussianSmearer + +Documentation to follow. Sorry. + +### EfficiencyApplicator + +Applies tracking efficiencies from one, two, or three dimensional efficiencies +passed in as input. + +#### Full example +```xml + + + + + + + + + +``` +#### Details + +Each `` tag requires at least: +* `PDG="<211,-211>"`: The particle IDs to apply this efficiency to. +* `InputFile=""`: The location of the ROOT file containing the +efficiency histogram. +* `HistName=""`: The name (may include directories) of the `TH1` or +`TEfficiency` that describes the efficiency. +* `NDims="[1|2|3]"`: The number of kinematic axes for the efficiency curve. +* `XAxis="[kMomentum|kKE|kCosTheta|kTheta|kPhi]"`: The kinematic variable +spanned by the first dimension of the efficiency histogram. + +optional attributes: +* `YAxis="[kMomentum|kKE|kCosTheta|kTheta|kPhi]"`: The kinematic variable +spanned by the second dimension of the efficiency histogram. +* `ZAxis="[kMomentum|kKE|kCosTheta|kTheta|kPhi]"`: The kinematic variable +spanned by the third dimension of the efficiency histogram. +* `Interpolate="[true|false]"`: Whether to use TH1:Interpolate or to take the +bin-averaged efficiency. +* `[X|Y|Z]AxisScaleToInternal=""`: A scale factor to translate the axes +to the internal NUISANCE units (MeV and radians). *e.g.* Use +`XAxisScaleToInternal="1E3"` if the input histogram uses kinetic energy in units +of GeV. + +An `EfficiencyApplicator` Can also contain `` and +`` tags, as described in `ThresholdAccepter`. Particles that are +rejected due to inefficiency get passed to a configured `ThresholdAccepter` +instance. *N.B.* it is unlikely that you want to have an `` tag +and a `` tag for the same PDG. However, it is possible that +particles that failed to be tracked, left some visible energy. + +### GaussianSmearer + +Applies simple smearing to tracked particle kinematics or visible energy deposits. + +#### Full example +```xml + + + + + +``` +#### Details + +Each `` tag requires at least: +* `PDG="<211,-211>"`: The particle IDs to apply this smearing to. +* `Type="[Fractional|Absolute|Function]"`: The type of smearer to use. `Fractional` and `Absolute` use a Gaussian smearer. For `Fractional` the Gaussian width is set to `*ParticleKinematicPropertyValue` and for Absolute it is simple ``. +* `Kinematics="[KE|Momentum|TEVis|KEVis|Theta|CosTheta]"`: The particle kinematics to smear. For the majority of practical uses, where an accepter is also in use, `TEVis` and `KEVis` produce the same results. As only a single property smearer can be used per PDG, the use of `Theta` and `CosTheta` are of very limited use. + +Additional attributes that depend on the value of the `Type` attribute are as follows: +* `Width=""`: The width of the Gaussian used for `Fractional` or `Absolute` type smearers. +* `Function=""`: The function to throw the smeared values from for `Function` type smearers. The example function here should give the same result as ``. +* `P[1|2|3|...]=""`: Extra parameters to replace in the `Function` attribute value. *e.g.*: ``. Mostly just for clarity. An element can contain any number of numbered parameters, but they must be numbered in increasing order. + +### TrackedMomentumMatrixSmearer + +Applies momentum or kinetic energy smearing to tracked particles. + +#### Full example +```xml + + + + +``` +#### Details + +Each `` tag requires at least: +* `PDG="<211,-211>"`: The particle IDs to apply this smearing to. +* `InputFile=""`: The root file that contains the input smearing matrix. +* `HistName=""`: The name of the histogram within in the input root file. Can be located within a subdirectory of the TFile. +* `Kinematics="[KE|TE|Momentum]"`: The kinematics to smear. +* `MatrixToInternal=""`: The scale factor used to scale the units used in the smearing matrix to MeV. +* YIsTrue="[1|0]": Whether the Y or X axis of the input histogram denotes the true kinematic property axis. + +The `` element can also contain any number of `` element, which are used for PDG codes that do not have a `` element. Their behavior is as in ``. As this smearer can only smear tracked particles, using `` elements to add visible energy smearing is the expected use case. + +### VisECoalescer + +### EnergyShuffler + +### MetaSimpleSmearcepter + +#### Full example + +```xml + + + + + + + + + + +