diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3a0988b..4033ef1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,176 +1,182 @@
 cmake_minimum_required (VERSION 2.6 FATAL_ERROR)
 
 project(ExternalDataFitter)
 
 enable_language(Fortran)
 
 set (ExtFit_VERSION_MAJOR 1)
 set (ExtFit_VERSION_MINOR 0) #The q+1'th letter of the alphabet
 set (ExtFit_VERSION_REVISION 0)
 
 set (ExtFit_VERSION_STRING "v${ExtFit_VERSION_MAJOR}r${ExtFit_VERSION_MINOR}")
 if(${ExtFit_VERSION_REVISION} STRGREATER "0")
   set (ExtFit_VERSION_STRING "${ExtFit_VERSION_STRING}p${ExtFit_VERSION_REVISION}")
 endif()
 
 set (VERBOSE TRUE)
 
 set (CMAKE_SKIP_BUILD_RPATH TRUE)
 
 if(NOT DEFINED NOTEST OR NOT NOTEST)
   enable_testing()
 endif()
 
 include(${CMAKE_SOURCE_DIR}/cmake/cmessage.cmake)
 
 if(NOT DEFINED USE_NEUT AND
   NOT DEFINED USE_NuWro AND
   NOT DEFINED USE_GENIE AND
   NOT DEFINED USE_T2K AND
   NOT DEFINED USE_NIWG AND
   NOT DEFINED USE_GiBUU AND
   NOT DEFINED USE_NUANCE)
   cmessage(FATAL_ERROR "No reweight engines requested. Configure with at least "
     "one of -DUSE_{NEUT,NuWro,GENIE,NIWG,T2K,GiBUU,NUANCE}.")
 else()
   cmessage(STATUS "Generator Input Support:
   		  NEUT:${USE_NEUT},
   		  NuWro:${USE_NuWro},
 		  GENIE:${USE_GENIE},
 		  NIWG:${USE_NIWG},
   		  GiBUU:${USE_GiBUU},
 		  NUANCE:${USE_NUANCE}")
 endif()
 
 #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()
 
 cmessage(STATUS "CMAKE_INSTALL_PREFIX: \"${CMAKE_INSTALL_PREFIX}\"")
 
 if(CMAKE_BUILD_TYPE STREQUAL "")
   set(CMAKE_BUILD_TYPE DEBUG)
 elseif(NOT DEFINED CMAKE_BUILD_TYPE)
   set(CMAKE_BUILD_TYPE DEBUG)
 endif()
 
 cmessage(STATUS "CMAKE_BUILD_TYPE: \"${CMAKE_BUILD_TYPE}\"")
 
 ################################################################################
 #                            Check Dependencies
 ################################################################################
 
 ##################################  ROOT  ######################################
 include(${CMAKE_SOURCE_DIR}/cmake/ROOTSetup.cmake)
 
 ############################  Reweight Engines  ################################
 include(${CMAKE_SOURCE_DIR}/cmake/ReweightEnginesSetup.cmake)
 
 ############################### GiBUU + NUANCE  ####################################
 
 if(DEFINED USE_EXP AND USE_EXP)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DINMEMORYEVENTCLASS")
 endif()
 
 if(DEFINED USE_GiBUU AND USE_GiBUU)
   cmessage(STATUS "Included GiBUU")
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__GiBUU_ENABLED__")
   include(${CMAKE_SOURCE_DIR}/cmake/GiBUUSetup.cmake)
 endif()
 
 if(DEFINED USE_NUANCE AND USE_NUANCE)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D__NUANCE_ENABLED__")
 endif()
 
 #################################  Pythia6  ####################################
 include(${CMAKE_SOURCE_DIR}/cmake/pythia6Setup.cmake)
 
 ################################## COMPILER ####################################
 include(${CMAKE_SOURCE_DIR}/cmake/c++CompilerSetup.cmake)
 
 ################################################################################
 
 ################################# gperftools ###################################
 
 include(${CMAKE_SOURCE_DIR}/cmake/gperfSetup.cmake)
 
 ################################### doxygen ###################################
 
 include(${CMAKE_SOURCE_DIR}/cmake/docsSetup.cmake)
 
 ###############################################################################
 
 set(MINCODE
   Routines
   FCN)
 
 set(CORE
   MCStudies
+  Genie
   FitBase
+  InputHandler
   Splines
   Reweight
   Utils
   #Devel
   )
 
 
 ###############
 # Allow compilation against single experiment folder
 # Add later..
 ##############
 
 set(EXPERIMENTS
   ANL
   ArgoNeuT
   BEBC
   BNL
   Electron
   FNAL
   GGM
   K2K
   MINERvA
   MiniBooNE
   T2K)
 
 set(EXP_INCLUDE_DIRECTORIES)
 
 foreach(edir ${EXPERIMENTS})
   set(EXP_INCLUDE_DIRECTORIES ${EXP_INCLUDE_DIRECTORIES};${CMAKE_SOURCE_DIR}/src/${edir})
 endforeach()
 cmessage(STATUS "Included experiments: ${EXP_INCLUDE_DIRECTORIES}")
 
 foreach(mdir ${MINCODE})
   cmessage (STATUS "Configuring directory: src/${mdir}")
   add_subdirectory(src/${mdir})
 endforeach()
 
 foreach(edir ${EXPERIMENTS})
   cmessage (STATUS "Configuring directory: src/${edir}")
   add_subdirectory(src/${edir})
 endforeach()
 
 foreach(cdir ${CORE})
   cmessage (STATUS "Configuring directory: src/${cdir}")
   add_subdirectory(src/${cdir})
 endforeach()
 
 cmessage(STATUS "Module targets:  ${MODULETargets}")
 
 add_subdirectory(app)
 add_subdirectory(src/Tests)
 
 configure_file(cmake/setup.sh.in
   "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/setup.sh" @ONLY)
 install(FILES
   "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/setup.sh" DESTINATION
   ${CMAKE_INSTALL_PREFIX})
 
+
 install(PROGRAMS
   "${PROJECT_SOURCE_DIR}/scripts/nuiscardgen" DESTINATION
   bin)
 
+install(PROGRAMS
+  "${PROJECT_SOURCE_DIR}/scripts/nuissamples" DESTINATION
+  bin)
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index 36fa5fe..952bca5 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -1,132 +1,134 @@
 # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 ################################################################################
 #    This file is part of NUISANCE.
 #
 #    NUISANCE is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
 #    (at your option) any later version.
 #
 #    NUISANCE is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #    GNU General Public License for more details.
 #
 #    You should have received a copy of the GNU General Public License
 #    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 ################################################################################
 
 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/Utils)
 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(${EXP_INCLUDE_DIRECTORIES})
 
 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()
 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(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()
 
 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()
 
 # PREPARE NUWRO
 # Commented out for the time being until it is finished..
 #if(USE_NuWro)
 #  add_executable(PrepareNuwro PrepareNuwro.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)
diff --git a/app/PrepareGENIE.cxx b/app/PrepareGENIE.cxx
index 39b4e8c..e0be761 100644
--- a/app/PrepareGENIE.cxx
+++ b/app/PrepareGENIE.cxx
@@ -1,365 +1,367 @@
 #include <stdio.h>
 #include <stdlib.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     = "";
 
 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);
 
 int main(int argc, char* argv[]) {
 
   ParseOptions(argc, argv);
 
   if (gFlagMerge) RunGENIEMerger(gInputFiles, 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;
 
   tn->SetBranchAddress("gmcrec", &genientpl);
 
   // Get Flux Hist
   std::vector<std::string> 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);
     
   
       // 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<std::string, TH1D*> modexsec;
   std::map<std::string, TH1D*> modecount;
   std::vector<std::string> genieids;
   std::vector<std::string> targetids;
   std::vector<std::string> interids;
 
 
   // Loop over all events
   for (int i = 0; i < nevt; i++) {
     tn->GetEntry(i);
 
     StopTalking();
     EventRecord& event = *(genientpl->event);
     GHepParticle* neu = event.Probe();
     StartTalking();
 
     // Get XSec From Spline
     GHepRecord genie_record = static_cast<GHepRecord>(event);
     double xsec = (genie_record.XSec() / (1E-38 * genie::units::cm2));
 
     // Parse Interaction String
     std::string mode = genie_record.Summary()->AsString();
     std::vector<std::string> modevec = GeneralUtils::ParseToStr(mode, ";");
     std::string targ  = ( modevec[0] + ";" + modevec[1] );
     std::string inter = mode;
 
     // Fill lists of Unique IDS
     if (std::find(targetids.begin(), targetids.end(), targ)
         == targetids.end()) {
       targetids.push_back(targ);
     }
 
     if (std::find(interids.begin(), interids.end(), inter)
         == interids.end()) {
       interids.push_back(inter);
     }
 
     // Create entries Mode Maps
     if (modexsec.find(mode) == modexsec.end()) {
       genieids.push_back(mode);
 
       modexsec[mode] = (TH1D*)xsechist->Clone();
       modecount[mode] = (TH1D*)xsechist->Clone();
     }
 
     // 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
   // 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<std::string, TH1D*> modeavg;
 
 
   TDirectory* inddir = (TDirectory*) outputfile->Get("IndividualGENIESplines");
   if (!inddir) inddir = (TDirectory*)outputfile->mkdir("IndividualGENIESplines");
   inddir->cd();
 
   // Loop over GENIE ID's and get MEC count
   int MECcount = 0;
   bool MECcorrect = FitPar::Config().GetParB("CorrectGENIEMECNorm");
   for (UInt_t i = 0; i < genieids.size(); i++) {
     if (genieids[i].find("MEC") != std::string::npos){
       MECcount++;
     }
   }
   LOG(FIT) << "Found " << MECcount << " repeated MEC instances." << std::endl;
 
 
   for (UInt_t i = 0; i < genieids.size(); i++) {
     std::string mode = genieids[i];
 
     modexsec[mode]->Write(  (mode + "_summed_xsec").c_str() , TObject::kOverwrite);
     modecount[mode]->Write( (mode + "_summed_evt").c_str()  , TObject::kOverwrite);
 
     //Form extra avg xsec map -> Reconstructed spline
     modeavg[mode] = (TH1D*)modexsec[mode]->Clone();
     modeavg[mode]->Divide(modecount[mode]);
 
     if (MECcorrect && (mode.find("MEC") != std::string::npos)){
       modeavg[mode]->Scale(1.0 / double(MECcount) );
     }
 
     modeavg[mode]->Write( (mode + "_rec_spline").c_str() , TObject::kOverwrite);
   }
 
   TDirectory* targdir = (TDirectory*) outputfile->Get("TargetGENIESplines");
   if (!targdir) targdir = (TDirectory*) outputfile->mkdir("TargetGENIESplines");
   targdir->cd();
 
   LOG(FIT) << "Getting Target Splines" << std::endl;
   // For each target save a total spline
   std::map<std::string, TH1D*> targetsplines;
 
   for (uint i = 0; i < targetids.size(); i++) {
     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<std::string> 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<std::string, TH1D*>::iterator iter = targetsplines.begin();
          iter != targetsplines.end(); iter++) {
       std::string targstr = iter->first;
       TH1D* xsec = iter->second;
 
       if (targstr.find(targpdg) != std::string::npos) {
         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;
   */
 
 }
 
 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;
 }
diff --git a/cmake/c++CompilerSetup.cmake b/cmake/c++CompilerSetup.cmake
index 65d5193..9146ca0 100644
--- a/cmake/c++CompilerSetup.cmake
+++ b/cmake/c++CompilerSetup.cmake
@@ -1,71 +1,71 @@
 # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 ################################################################################
 #    This file is part of NUISANCE.
 #
 #    NUISANCE is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
 #    (at your option) any later version.
 #
 #    NUISANCE is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #    GNU General Public License for more details.
 #
 #    You should have received a copy of the GNU General Public License
 #    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 ################################################################################
 
 set(CXX_WARNINGS "-Wall ") #-Wextra")
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CXX_WARNINGS}")
 
 if(DEFINED USE_EXP AND USE_EXP)
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
 endif()
 
 
-set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O2")
+set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O3")
 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(CMAKE_LINK_FLAGS "${CMAKE_LINK_FLAGS} ")
 set(CMAKE_DEPENDLIB_FLAGS "${ROOT_LD_FLAGS}")
 
 if(NOT ${RWENGINE_LINKER_FLAGS} STREQUAL "")
   set(CMAKE_DEPENDLIB_FLAGS "${CMAKE_DEPENDLIB_FLAGS} ${RWENGINE_LINKER_FLAGS}")
 endif()
 
 if (DEFINED USE_MYPERFTOOLS AND USE_MYPERFTOOLS)
 #  add_dependencies(gperftools libunwind)
   set(CMAKE_CXX_FLAGS "-fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free ${CMAKE_CXX_FLAGS}")
   set(CMAKE_LINK_FLAGS "${CMAKE_LINK_FLAGS} -ltcmalloc_and_profiler")
   cmessage(STATUS "Using google performance libraries")
 endif()
 
 if(DEFINED USE_EXP AND USE_EXP)
   set(CMAKE_LINK_FLAGS "${CMAKE_LINK_FLAGS}")
 endif()
 
 if(DEFINED USE_OPENMP AND USE_OPENMP)
   set(CMAKE_C_FLAGS "-fopenmp ${CMAKE_C_FLAGS}")
   set(CMAKE_CXX_FLAGS "-fopenmp ${CMAKE_CXX_FLAGS} -D__USE_OPENMP__")
   set(CMAKE_DEPENDLIB_FLAGS "-lgomp ${CMAKE_DEPENDLIB_FLAGS}")
 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/doc/Doxyfile.in b/doc/Doxyfile.in
index 8454238..005d4ef 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         = "@ExtFit_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
 
 # 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
 
 # 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
 
 # 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
 
 # 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
 
 # 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 <command> <input-file>, where <command> is the value of
 # the FILE_VERSION_FILTER tag, and <input-file> 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
 
 # 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
 
 # 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 <filter> <input-file>, where <filter>
 # is the value of the INPUT_FILTER tag, and <input-file> 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
 
 # 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
 # <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
 
 QHP_CUST_FILTER_ATTRS  =
 
 # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's
 # filter section matches.
 # <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
 
 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
 
 # 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      = YES
+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 76f4bdd..2a7bde0 100644
--- a/parameters/config.xml
+++ b/parameters/config.xml
@@ -1,169 +1,175 @@
 <nuisance>
 <!-- # ###################################################### -->
 <!-- # NUISANCE CONFIGURATION OPTIONS -->
 <!-- # This file is read in by default at runtime -->
 <!-- # If you want to override on a case by case bases use -q at runtime -->
 <!-- # ###################################################### -->
 
 <!-- # MAIN Configs -->
 <!-- # ###################################################### -->
 
 <!-- # Logger goes from -->
 <!-- # 1 Quiet -->
 <!-- # 2 Fitter -->
 <!-- # 3 Samples -->
 <!-- # 4 Reconfigure Loops -->
 <!-- # 5 Every Event print out (SHOUT) -->
 <!-- # -1 DEBUGGING -->
 <config verbosity='5'/>
 <config VERBOSITY='5'/>
 
 <!-- # ERROR goes from -->
 <!-- # 0 NONE -->
 <!-- # 1 FATAL -->
 <!-- # 2 WARN -->
 <config ERROR='2'/>
 <config TRACE='1'/>
 
 <config cores='2' />
 <config spline_test_throws='50' />
 <config spline_cores='6' />
 <config spline_chunks='10' />
 <config spline_procchunk='-1' />
 
 <config Electron_NThetaBins='4' />
 <config Electron_NEnergyBins='4' />
 <config Electron_ThetaWidth='2.0' />
 <config Electron_EnergyWidth='0.10' />
 
+<config RemoveFSIParticles='0' />
+<config RemoveUndefParticles='0' />
+<config RemoveNuclearParticles='0'/>
+<config logging.FitEvent.cxx='1' />
+
 <!-- # Input Configs -->
 <!-- # ###################################################### -->
 
 <!-- # Default Requirements file for the externalDataFitter Package -->
 <!-- # MAX Events : -1 is no cut. Events will be scaled automatically to give good xsec predictions. -->
 <config input.maxevents='-1'/>
 <config MAXEVENTS='-1'/>
 <config input.MAXEVENTS='-1'/>
 <config includeemptystackhists='0'/>
 <!-- # Turn on/off event manager -->
 <!-- # EventManager enables us to only loop number of events once for multiple projections of the same measurements -->
 <!-- # e.g. MiniBooNE CC1pi+ Q2 and MiniBooNE CC1pi+ Tmu would ordinarily require 2 reconfigures, but with this enabled it requires only one -->
 <config input.eventmanager='1'/>
 <config EventManager='1'/>
 
 <!-- # Event Directories -->
 <!-- # Can setup default directories and use @EVENT_DIR/path to link to it -->
 <config EVENT_DIR='/data2/stowell/NIWG/'/>
 <config NEUT_EVENT_DIR='/data2/stowell/NIWG/neut/fit_samples_neut5.3.3/'/>
 <config GENIE_EVENT_DIR='/data2/stowell/NIWG/genie/fit_samples_R.2.10.0/'/>
 <config NUWRO_EVENT_DIR='/data2/stowell/NIWG/nuwro/fit_samples/'/>
 <config GIBUU_EVENT_DIR='/data/GIBUU/DIR/'/>
+<config SaveNuWroExtra='0' />
 
 <!-- # In PrepareGENIE the reconstructed splines can be saved into the file -->
 <config save_genie_splines='1'/>
 
 <!-- # In InputHandler the option to regenerate NuWro flux/xsec plots is available -->
 <!-- # Going to move this to its own app soon -->
 <config input.regen_nuwro_plots='0'/>
 
 <!-- # DEVEL CONFIG OPTION, don't touch! -->
-<config CacheSize='50000000'/>
+<config CacheSize='5000000'/>
 
 <!-- # ReWeighting Configuration Options -->
 <!-- # ###################################################### -->
 
 <!-- # Set absolute twkdial for parameters -->
 <config params.setabstwk='0'/>
 
 <!-- # Convert Dials in output statements using dial conversion card -->
 <config convert_dials='0'/>
 
 <!-- # Make RW Calculations be quiet -->
 <config params.silentweighting='0'/>
 
 <!-- # Vetos can be used to specify RW dials NOT to be loaded in -->
 <!-- # Useful if one specific one has an issue -->
 <config FitWeight.fNIWGRW_veto=''/>
 <config FitWeight.fNuwroRW_veto=''/>
 <config FitWeight.fNeutRW_veto=''/>
 <config FitWeight.fGenieRW_veto=''/>
 
 
 <!-- # Output Options -->
 <!-- # ###################################################### -->
 
 <!-- # Save Nominal prediction with all rw engines at default -->
 <config savenominal='0'/>
 
 <!-- # Save prefit with values at starting values -->
 <config saveprefit='0'/>
 
 <!-- # Here's the full list of drawing options -->
 <!-- # See src/FitBase/Measurement1D::Write for more info -->
 <!-- #config drawopts DATA/MC/EVT/FINE/RATIO/MODES/SHAPE/RESIDUAL/MATRIX/FLUX/MASK/MAP -->
 <!-- #config drawopts DATA/MC -->
 <config drawopts='DATA/MC/EVT/FINE/RATIO/MODES/SHAPE/FLUX/XSEC/MASK/COV/INCOV/DECOMP/CANVPDG/CANVMC'/>
 
 <!-- # Save the shape scaling applied with option SHAPE into the main MC hist -->
 <config saveshapescaling='0'/>
 
 <config CorrectGENIEMECNorm='1'/>
 
 <!-- # Set style of 1D output histograms -->
 <config linecolour='1'/>
 <config linestyle='1'/>
 <config linewidth='1'/>
 
 <!-- # For GenericFlux -->
 <config isLiteMode='0'/>
 
 <!-- # Statistical Options -->
 <!-- # ###################################################### -->
 
 <!-- # Add MC Statistical error to likelihoods -->
 <config statutils.addmcerror='0'/>
 
 <!-- # NUISMIN Configurations -->
 <!-- # ###################################################### -->
 
 <config minimizer.maxcalls='1000000'/>
 <config minimizer.maxiterations='1000000'/>
 <config minimizer.tolerance='0.001'/>
 
 <!-- # Number of events required in low stats routines -->
 <config minimizer.lowstatevents='25000'/>
 
 
 <!-- # Error band generator configs -->
 <!-- # ###################################################### -->
 
 <!-- # For -f ErrorBands creates error bands for given measurements -->
 <!-- # How many throws do we want (The higher the better precision) -->
 <config error_throws='250'/>
 
 <!-- # Are we throwing uniform or according to Gaussian? -->
 <!-- # Only use uniform if wanting to study the limits of a dial. -->
 <config error_uniform='0'/>
 <config WriteSeperateStacks='1'/>
 
 <!-- # Other Individual Case Configs -->
 <!-- # ###################################################### -->
 
 <!-- # Covariance throw options for fake data studies with MiniBooNE data. -->
 <config thrown_covariance='FULL'/>
 <config throw_mc_stat='0.0'/>
 <config throw_diag_syst='0'/>
 <config throw_corr_syst='0'/>
 <config throw_mc_stat='0'/>
 
 <!-- # Apply a shift to the muon momentum before calculation of Q2 -->
 <config muon_momentum_shift='0.0'/>
 <config muon_momentum_throw='0'/>
 
 <!-- # MINERvA Specific Configs -->
 <config MINERvA_XSec_CCinc_2DEavq3_nu.hadron_cut='0'/>
 <config MINERvA_CCinc_XSec_2DEavq3_nu.useq3true='0'/>
 <config Modes.split_PN_NN='0'/>
 <config SignalReconfigures='0'/>
 
 </nuisance>
diff --git a/src/FCN/listsamples.sh b/scripts/nuissamples
similarity index 100%
rename from src/FCN/listsamples.sh
rename to scripts/nuissamples
diff --git a/src/ANL/._CMakeLists.txt~ b/src/ANL/._CMakeLists.txt~
new file mode 100644
index 0000000..89a44f4
Binary files /dev/null and b/src/ANL/._CMakeLists.txt~ differ
diff --git a/src/ANL/CMakeLists.txt b/src/ANL/CMakeLists.txt
index 951e989..564e292 100644
--- a/src/ANL/CMakeLists.txt
+++ b/src/ANL/CMakeLists.txt
@@ -1,136 +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 <http://www.gnu.org/licenses/>.
 ################################################################################
 set(IMPLFILES
 ANL_CCQE_Evt_1DQ2_nu.cxx
 ANL_CCQE_XSec_1DEnu_nu.cxx
 
 ANL_CC1npip_Evt_1DcosmuStar_nu.cxx
 ANL_CC1npip_Evt_1Dppi_nu.cxx
 ANL_CC1npip_Evt_1DQ2_nu.cxx
 ANL_CC1npip_XSec_1DEnu_nu.cxx
 
 ANL_CC1pi0_Evt_1DcosmuStar_nu.cxx
 ANL_CC1pi0_Evt_1DQ2_nu.cxx
 ANL_CC1pi0_XSec_1DEnu_nu.cxx
 
 ANL_CC1ppip_Evt_1DcosmuStar_nu.cxx
 ANL_CC1ppip_Evt_1Dppi_nu.cxx
 ANL_CC1ppip_Evt_1DQ2_nu.cxx
 ANL_CC1ppip_Evt_1Dthpr_nu.cxx
 ANL_CC1ppip_XSec_1DEnu_nu.cxx
 ANL_CC1ppip_XSec_1DQ2_nu.cxx
 ANL_CC1ppip_Evt_1DcosthAdler_nu.cxx
 ANL_CC1ppip_Evt_1Dphi_nu.cxx
 
 ANL_NC1npip_Evt_1Dppi_nu.cxx
 
 ANL_NC1ppim_XSec_1DEnu_nu.cxx
 ANL_NC1ppim_Evt_1DcosmuStar_nu.cxx
 
 ANL_CC2pi_1pim1pip_XSec_1DEnu_nu.cxx
 ANL_CC2pi_1pim1pip_Evt_1Dpmu_nu.cxx
 ANL_CC2pi_1pim1pip_Evt_1Dppim_nu.cxx
 ANL_CC2pi_1pim1pip_Evt_1Dppip_nu.cxx
 ANL_CC2pi_1pim1pip_Evt_1Dpprot_nu.cxx
 
 ANL_CC2pi_1pip1pi0_XSec_1DEnu_nu.cxx
 ANL_CC2pi_1pip1pi0_Evt_1Dpmu_nu.cxx
 ANL_CC2pi_1pip1pi0_Evt_1Dppi0_nu.cxx
 ANL_CC2pi_1pip1pi0_Evt_1Dppip_nu.cxx
 ANL_CC2pi_1pip1pi0_Evt_1Dpprot_nu.cxx
 
 ANL_CC2pi_1pip1pip_XSec_1DEnu_nu.cxx
 ANL_CC2pi_1pip1pip_Evt_1Dpmu_nu.cxx
 ANL_CC2pi_1pip1pip_Evt_1Dpneut_nu.cxx
 ANL_CC2pi_1pip1pip_Evt_1DppipHigh_nu.cxx
 ANL_CC2pi_1pip1pip_Evt_1DppipLow_nu.cxx
 )
 
 set(HEADERFILES
 ANL_CCQE_Evt_1DQ2_nu.h
 ANL_CCQE_XSec_1DEnu_nu.h
 
 ANL_CC1npip_Evt_1DcosmuStar_nu.h
 ANL_CC1npip_Evt_1Dppi_nu.h
 ANL_CC1npip_Evt_1DQ2_nu.h
 ANL_CC1npip_XSec_1DEnu_nu.h
 
 ANL_CC1pi0_Evt_1DcosmuStar_nu.h
 ANL_CC1pi0_Evt_1DQ2_nu.h
 ANL_CC1pi0_XSec_1DEnu_nu.h
 
 ANL_CC1ppip_Evt_1DcosmuStar_nu.h
 ANL_CC1ppip_Evt_1Dppi_nu.h
 ANL_CC1ppip_Evt_1DQ2_nu.h
 ANL_CC1ppip_Evt_1Dthpr_nu.h
 ANL_CC1ppip_XSec_1DEnu_nu.h
 ANL_CC1ppip_XSec_1DQ2_nu.h
 ANL_CC1ppip_Evt_1DcosthAdler_nu.h
 ANL_CC1ppip_Evt_1Dphi_nu.h
 
 ANL_NC1npip_Evt_1Dppi_nu.h
 
 ANL_NC1ppim_XSec_1DEnu_nu.h
 ANL_NC1ppim_Evt_1DcosmuStar_nu.h
 
 ANL_CC2pi_1pim1pip_XSec_1DEnu_nu.h
 ANL_CC2pi_1pim1pip_Evt_1Dpmu_nu.h
 ANL_CC2pi_1pim1pip_Evt_1Dppim_nu.h
 ANL_CC2pi_1pim1pip_Evt_1Dppip_nu.h
 ANL_CC2pi_1pim1pip_Evt_1Dpprot_nu.h
 
 ANL_CC2pi_1pip1pi0_XSec_1DEnu_nu.h
 ANL_CC2pi_1pip1pi0_Evt_1Dpmu_nu.h
 ANL_CC2pi_1pip1pi0_Evt_1Dppi0_nu.h
 ANL_CC2pi_1pip1pi0_Evt_1Dppip_nu.h
 ANL_CC2pi_1pip1pi0_Evt_1Dpprot_nu.h
 
 ANL_CC2pi_1pip1pip_XSec_1DEnu_nu.h
 ANL_CC2pi_1pip1pip_Evt_1Dpmu_nu.h
 ANL_CC2pi_1pip1pip_Evt_1Dpneut_nu.h
 ANL_CC2pi_1pip1pip_Evt_1DppipHigh_nu.h
 ANL_CC2pi_1pip1pip_Evt_1DppipLow_nu.h
 )
 
 set(LIBNAME expANL)
 
 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(${RWENGINE_INCLUDE_DIRECTORIES})
 
 include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
+include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler)
+include_directories(${CMAKE_SOURCE_DIR}/src/Genie)
 include_directories(${CMAKE_SOURCE_DIR}/src/Reweight)
 include_directories(${CMAKE_SOURCE_DIR}/src/Splines)
 include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
 
 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/ArgoNeuT/CMakeLists.txt b/src/ArgoNeuT/CMakeLists.txt
index ad53bc6..52157fc 100644
--- a/src/ArgoNeuT/CMakeLists.txt
+++ b/src/ArgoNeuT/CMakeLists.txt
@@ -1,61 +1,63 @@
 # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 ################################################################################
 #    This file is part of NUISANCE.
 #
 #    NUISANCE is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
 #    (at your option) any later version.
 #
 #    NUISANCE is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #    GNU General Public License for more details.
 #
 #    You should have received a copy of the GNU General Public License
 #    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 ################################################################################
 set(IMPLFILES
 ArgoNeuT_CCInc_XSec_1Dpmu_antinu.cxx
 ArgoNeuT_CCInc_XSec_1Dpmu_nu.cxx
 ArgoNeuT_CCInc_XSec_1Dthetamu_antinu.cxx
 ArgoNeuT_CCInc_XSec_1Dthetamu_nu.cxx
 )
 
 set(HEADERFILES
 ArgoNeuT_CCInc_XSec_1Dpmu_antinu.h
 ArgoNeuT_CCInc_XSec_1Dpmu_nu.h
 ArgoNeuT_CCInc_XSec_1Dthetamu_antinu.h
 ArgoNeuT_CCInc_XSec_1Dthetamu_nu.h
 )
 
 set(LIBNAME expArgoNeuT)
 
 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(${RWENGINE_INCLUDE_DIRECTORIES})
 
 include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
+include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler)
+include_directories(${CMAKE_SOURCE_DIR}/src/Genie)
 include_directories(${CMAKE_SOURCE_DIR}/src/Reweight)
 include_directories(${CMAKE_SOURCE_DIR}/src/Splines)
 include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
 
 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})
 
 # Add Extra Links
 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/BEBC/CMakeLists.txt b/src/BEBC/CMakeLists.txt
index c7e4278..0682d6f 100644
--- a/src/BEBC/CMakeLists.txt
+++ b/src/BEBC/CMakeLists.txt
@@ -1,72 +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 <http://www.gnu.org/licenses/>.
 ################################################################################
 set(IMPLFILES
 BEBC_CC1npim_XSec_1DEnu_antinu.cxx
 BEBC_CC1npim_XSec_1DQ2_antinu.cxx
 BEBC_CC1npip_XSec_1DEnu_nu.cxx
 BEBC_CC1npip_XSec_1DQ2_nu.cxx
 BEBC_CC1pi0_XSec_1DEnu_nu.cxx
 BEBC_CC1pi0_XSec_1DQ2_nu.cxx
 BEBC_CC1ppim_XSec_1DEnu_antinu.cxx
 BEBC_CC1ppim_XSec_1DQ2_antinu.cxx
 BEBC_CC1ppip_XSec_1DEnu_nu.cxx
 BEBC_CC1ppip_XSec_1DQ2_nu.cxx
 BEBC_CCQE_XSec_1DQ2_nu.cxx
 )
 
 set(HEADERFILES
 BEBC_CC1npim_XSec_1DEnu_antinu.h
 BEBC_CC1npim_XSec_1DQ2_antinu.h
 BEBC_CC1npip_XSec_1DEnu_nu.h
 BEBC_CC1npip_XSec_1DQ2_nu.h
 BEBC_CC1pi0_XSec_1DEnu_nu.h
 BEBC_CC1pi0_XSec_1DQ2_nu.h
 BEBC_CC1ppim_XSec_1DEnu_antinu.h
 BEBC_CC1ppim_XSec_1DQ2_antinu.h
 BEBC_CC1ppip_XSec_1DEnu_nu.h
 BEBC_CC1ppip_XSec_1DQ2_nu.h
 BEBC_CCQE_XSec_1DQ2_nu.h
 )
 
 set(LIBNAME expBEBC)
 
 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(${RWENGINE_INCLUDE_DIRECTORIES})
 
 include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
+include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler)
+include_directories(${CMAKE_SOURCE_DIR}/src/Genie)
 include_directories(${CMAKE_SOURCE_DIR}/src/Reweight)
 include_directories(${CMAKE_SOURCE_DIR}/src/Splines)
 include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
 
 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/BNL/CMakeLists.txt b/src/BNL/CMakeLists.txt
index a1a8adf..e92b5e1 100644
--- a/src/BNL/CMakeLists.txt
+++ b/src/BNL/CMakeLists.txt
@@ -1,70 +1,72 @@
 # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 ################################################################################
 #    This file is part of NUISANCE.
 #
 #    NUISANCE is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
 #    (at your option) any later version.
 #
 #    NUISANCE is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #    GNU General Public License for more details.
 #
 #    You should have received a copy of the GNU General Public License
 #    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 ################################################################################
 set(IMPLFILES
 BNL_CC1npip_Evt_1DQ2_nu.cxx
 BNL_CC1npip_XSec_1DEnu_nu.cxx
 BNL_CC1pi0_Evt_1DQ2_nu.cxx
 BNL_CC1pi0_XSec_1DEnu_nu.cxx
 BNL_CC1ppip_Evt_1DQ2_nu.cxx
 BNL_CC1ppip_XSec_1DEnu_nu.cxx
 BNL_CCQE_Evt_1DQ2_nu.cxx
 BNL_CCQE_XSec_1DEnu_nu.cxx
 BNL_CC1ppip_Evt_1DcosthAdler_nu.cxx
 BNL_CC1ppip_Evt_1Dphi_nu.cxx
 )
 
 set(HEADERFILES
 BNL_CC1npip_Evt_1DQ2_nu.h
 BNL_CC1npip_XSec_1DEnu_nu.h
 BNL_CC1pi0_Evt_1DQ2_nu.h
 BNL_CC1pi0_XSec_1DEnu_nu.h
 BNL_CC1ppip_Evt_1DQ2_nu.h
 BNL_CC1ppip_XSec_1DEnu_nu.h
 BNL_CCQE_Evt_1DQ2_nu.h
 BNL_CCQE_XSec_1DEnu_nu.h
 BNL_CC1ppip_Evt_1DcosthAdler_nu.h
 BNL_CC1ppip_Evt_1Dphi_nu.h
 )
 
 set(LIBNAME expBNL)
 
 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(${RWENGINE_INCLUDE_DIRECTORIES})
 
 include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
+include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler)
+include_directories(${CMAKE_SOURCE_DIR}/src/Genie)
 include_directories(${CMAKE_SOURCE_DIR}/src/Reweight)
 include_directories(${CMAKE_SOURCE_DIR}/src/Splines)
 include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
 
 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/Electron/CMakeLists.txt b/src/Electron/CMakeLists.txt
index e7e8450..c9abb0d 100644
--- a/src/Electron/CMakeLists.txt
+++ b/src/Electron/CMakeLists.txt
@@ -1,53 +1,55 @@
 # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 ################################################################################
 #    This file is part of NUISANCE.
 #
 #    NUISANCE is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
 #    (at your option) any later version.
 #
 #    NUISANCE is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #    GNU General Public License for more details.
 #
 #    You should have received a copy of the GNU General Public License
 #    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 ################################################################################
 set(IMPLFILES
 ElectronScattering_DurhamData.cxx
 )
 
 set(HEADERFILES
 ElectronScattering_DurhamData.h
 )
 
 
 set(LIBNAME expElectron)
 
 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(${RWENGINE_INCLUDE_DIRECTORIES})
 
 include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
+include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler)
+include_directories(${CMAKE_SOURCE_DIR}/src/Genie)
 include_directories(${CMAKE_SOURCE_DIR}/src/Reweight)
 include_directories(${CMAKE_SOURCE_DIR}/src/Splines)
 include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
 
 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/Electron/ElectronScattering_DurhamData.cxx b/src/Electron/ElectronScattering_DurhamData.cxx
index 92af8aa..7a8c300 100644
--- a/src/Electron/ElectronScattering_DurhamData.cxx
+++ b/src/Electron/ElectronScattering_DurhamData.cxx
@@ -1,436 +1,436 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
 #include "ElectronScattering_DurhamData.h"
 
 //********************************************************************
 ElectronScattering_DurhamData::ElectronScattering_DurhamData(nuiskey samplekey) {
 //********************************************************************
 
   // Sample overview ---------------------------------------------------
   std::string descrip = "Electron Scattering Durham Data sample. \n" \
                         "Target: Multiple \n" \
                         "Flux: Energy should match data being handled \n" \
                         "Signal: Any event with an electron in the final state \n";
   fSettings = LoadSampleSettings(samplekey);
   fSettings.SetDescription(descrip);
   fSettings.DefineAllowedSpecies("electron");
   fSettings.SetTitle("Electron");
   fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG/NORM/MASK", "FIX/DIAG");
   fSettings.SetXTitle("q0");
   fSettings.SetYTitle("#sigma");
   // fIsRawEvents = true;
 
   FinaliseSampleSettings();
 
   // Plot Setup -------------------------------------------------------
   SetDataFromName(fSettings.GetS("name"));
   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;
 
 
   std::cout << "Event Integral = " << GetEventHistogram()->Integral("width") << std::endl;
   std::cout << "Flux Integral = " << TotalIntegratedFlux("width") << " " << fZLowLim << " " << fZHighLim << std::endl;
   std::cout << "DAngle = " << dangle << std::endl;
   std::cout << "sigscale = " << sigscale << std::endl;
   std::cout << "fZCenter = " << fZCenter << std::endl;
 
   // Finish up
   FinaliseMeasurement();
 };
 
 //********************************************************************
 void ElectronScattering_DurhamData::SetDataFromName(std::string name) {
 //********************************************************************
 
   // Data Should be given in the format
   // Electron_Z_A_Energy_Theta_Source
   std::vector<std::string> splitstring = GeneralUtils::ParseToStr(name, "_");
   std::string zstring = splitstring[1];
   std::string astring = splitstring[2];
   std::string estring = splitstring[3];
   std::string tstring = splitstring[4];
   std::string sstring = splitstring[5];
 
   fYCenter = GeneralUtils::StrToDbl(tstring);
   fZCenter = GeneralUtils::StrToDbl(estring);
 
   // Create effective E and Theta bin Edges
   std::vector<double> thetabinedges;
   std::vector<double> ebinedges;
 
   int nthetabins    = FitPar::Config().GetParI("Electron_NThetaBins");
   int nebins        = FitPar::Config().GetParI("Electron_NEnergyBins");
   double thetawidth = FitPar::Config().GetParD("Electron_ThetaWidth");
   double ewidth     = FitPar::Config().GetParD("Electron_EnergyWidth");
 
   for (int i = -nthetabins; i <= nthetabins; i++) {
     thetabinedges.push_back( fYCenter + thetawidth * (double(i)) );
   }
   for (int i = -nebins; i <= nebins; i++) {
     double newval = fZCenter + ewidth * (double(i));
 
     if (newval < 0.0) newval = 0.0;
     if (newval < GetEventHistogram()->GetXaxis()->GetXmin()) newval = GetEventHistogram()->GetXaxis()->GetXmin();
     if (newval > GetEventHistogram()->GetXaxis()->GetXmax()) newval = GetEventHistogram()->GetXaxis()->GetXmax();
     if (std::find(ebinedges.begin(), ebinedges.end(), newval) != ebinedges.end()) continue;
     ebinedges.push_back(newval);
   }
 
   // Determine target
   std::string target = "";
   if (!zstring.compare("6") && !astring.compare("12")) target = "12C.dat";
   else {
     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);
   int i = 0;
 
   std::vector<double> pointx;
   std::vector<double> errorx;
   std::vector<double> pointy;
   std::vector<double> errory;
   double scalef = 1.E-38 * 1.E5;
 
   while (std::getline(mask >> std::ws, line, '\n')) {
     // std::cout << "Line = " << line << std::endl;
     if (line.empty()) continue;
 
     std::vector<std::string> lineentries = GeneralUtils::ParseToStr(line, " ");
     // std::cout << "Checking : " << line << std::endl;
     if (zstring.compare(lineentries[0])) continue;
     if (astring.compare(lineentries[1])) continue;
     if (estring.compare(lineentries[2])) continue;
     if (tstring.compare(lineentries[3])) continue;
     if (sstring.compare(lineentries[7])) continue;
 
     std::cout << "Registering data point : " << line << std::endl;
     std::cout << "Adding Graph Point : " <<  GeneralUtils::StrToDbl(lineentries[4]) << " " << GeneralUtils::StrToDbl(lineentries[5]) << std::endl;
 
     // Loop through x and y points and find a place to insert
     if (pointx.empty()) {
       pointx.push_back(GeneralUtils::StrToDbl(lineentries[4]));
       errorx.push_back(0.0);
       pointy.push_back(GeneralUtils::StrToDbl(lineentries[5]) * scalef);
       errory.push_back(GeneralUtils::StrToDbl(lineentries[6]) * scalef);
 
     } else {
       for (size_t j = 0; j < pointx.size(); j++) {
 
         if (GeneralUtils::StrToDbl(lineentries[4]) < pointx[j] && j == 0) {
           std::cout << "Inserting at start point iterator " << std::endl;
           pointx.insert(pointx.begin() + j, GeneralUtils::StrToDbl(lineentries[4]));
           errorx.insert(errorx.begin() + j, 0.0);
           pointy.insert(pointy.begin() + j, GeneralUtils::StrToDbl(lineentries[5]) * scalef);
           errory.insert(errory.begin() + j, GeneralUtils::StrToDbl(lineentries[6]) * scalef);
           break;
 
         } else if (GeneralUtils::StrToDbl(lineentries[4]) > pointx[j] && j == pointx.size() - 1) {
           std::cout << "Pushing back data point " << std::endl;
           pointx.push_back(GeneralUtils::StrToDbl(lineentries[4]));
           errorx.push_back(0.0);
           pointy.push_back(GeneralUtils::StrToDbl(lineentries[5]) * scalef);
           errory.push_back(GeneralUtils::StrToDbl(lineentries[6]) * scalef);
           break;
 
         } else if (GeneralUtils::StrToDbl(lineentries[4]) > pointx[j - 1] && GeneralUtils::StrToDbl(lineentries[4]) < pointx[j]) {
           std::cout << "Inserting at point iterator = " << j << std::endl;
 
           pointx.insert(pointx.begin() + j, GeneralUtils::StrToDbl(lineentries[4]));
           errorx.insert(errorx.begin() + j, 0.0);
           pointy.insert(pointy.begin() + j, GeneralUtils::StrToDbl(lineentries[5]) * scalef);
           errory.insert(errory.begin() + j, GeneralUtils::StrToDbl(lineentries[6]) * scalef);
           break;
         }
       }
 
 
 
     }
 
     // pointx.push_back(GeneralUtils::StrToDbl(lineentries[4]));
     // errorx.push_back(0.0);
     // pointy.push_back(GeneralUtils::StrToDbl(lineentries[5]));
     // errory.push_back(GeneralUtils::StrToDbl(lineentries[6]));
 
     i++;
   }
 
-  for (int i  = 0; i < pointx.size(); i++) {
+  for (uint i  = 0; i < pointx.size(); i++) {
     std::cout << "Q0 Point " << i << " = " << pointx[i] << std::endl;
   }
 
 
   fDataGraph = new TGraphErrors(pointx.size(), &pointx[0], &pointy[0], &errorx[0], &errory[0]);
   fDataGraph->SetNameTitle((fName + "_data_GRAPH").c_str(), (fName + "_data_GRAPH").c_str());
 
 
 // Now form an effective data and mc histogram
   std::vector<double> q0binedges;
   const double* x = fDataGraph->GetX();
 
 // Loop over graph and get mid way point between each data point.
   for (int i = 0; i < fDataGraph->GetN(); i++) {
     std::cout << "X Point = " << x[i] << std::endl;
 
     if (i == 0) {
       // First point set lower width as half distance to point above
       q0binedges.push_back(x[0] - ((x[1] - x[0]) / 2.0));
     } else if (i == fDataGraph->GetN() - 1) {
       // Last point set upper width as half distance to point above.
       q0binedges.push_back(x[i] - ((x[i] - x[i - 1]) / 2.0));
       q0binedges.push_back(x[i] + ((x[i] - x[i - 1]) / 2.0));
     } else {
       // Set half distance to point below
       q0binedges.push_back(x[i] - ((x[i] - x[i - 1]) / 2.0));
     }
   }
 
 // Bubble Sort
 
 
 
 
-  for (int i  = 0; i < q0binedges.size(); i++) {
+  for (uint i  = 0; i < q0binedges.size(); i++) {
     std::cout << "Q0 Edge " << i << " = " << q0binedges[i] << std::endl;
   }
 
-  for (int i  = 0; i < ebinedges.size(); i++) {
+  for (uint i  = 0; i < ebinedges.size(); i++) {
     std::cout << "e Edge " << i << " = " << ebinedges[i] << std::endl;
   }
-  for (int i  = 0; i < thetabinedges.size(); i++) {
+  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);
 }
 
 
 //********************************************************************
 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;
 
   // std::cout << "Got Event " << q0 << " " << theta << " " << E << std::endl;
 
   return;
 };
 
 //********************************************************************
 bool ElectronScattering_DurhamData::isSignal(FitEvent * event) {
 //********************************************************************
 
   if (event->NumFSParticle(11) == 0)
     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;
 
   if (fXVar < fXLowLim or fXVar > fXHighLim) return false;
   if (fYVar < fYLowLim or fYVar > fYHighLim) return false;
   if (fZVar < fZLowLim or fZVar > fZHighLim) 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/CMakeLists.txt b/src/FCN/CMakeLists.txt
index fe8db94..274ee82 100644
--- a/src/FCN/CMakeLists.txt
+++ b/src/FCN/CMakeLists.txt
@@ -1,70 +1,72 @@
 # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 ################################################################################
 #    This file is part of NUISANCE.
 #
 #    NUISANCE is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
 #    (at your option) any later version.
 #
 #    NUISANCE is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #    GNU General Public License for more details.
 #
 #    You should have received a copy of the GNU General Public License
 #    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 ################################################################################
 set(IMPLFILES
 JointFCN.cxx
 SampleList.cxx
 )
 
 set(HEADERFILES
 JointFCN.h
 MinimizerFCN.h
 SampleList.h
 )
 
 set(LIBNAME FCN)
 
 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(${RWENGINE_INCLUDE_DIRECTORIES})
 include_directories(${EXP_INCLUDE_DIRECTORIES})
 
 include_directories(${CMAKE_SOURCE_DIR}/src/Reweight)
 include_directories(${CMAKE_SOURCE_DIR}/src/Splines)
 include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
 include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
+include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler)
+include_directories(${CMAKE_SOURCE_DIR}/src/Genie)
 
 include_directories(${CMAKE_SOURCE_DIR}/src/ANL)
 include_directories(${CMAKE_SOURCE_DIR}/src/BNL)
 include_directories(${CMAKE_SOURCE_DIR}/src/FNAL)
 include_directories(${CMAKE_SOURCE_DIR}/src/GGM)
 include_directories(${CMAKE_SOURCE_DIR}/src/MINERvA)
 include_directories(${CMAKE_SOURCE_DIR}/src/MiniBooNE)
 include_directories(${CMAKE_SOURCE_DIR}/src/T2K)
 include_directories(${CMAKE_SOURCE_DIR}/src/Electron)
 include_directories(${CMAKE_SOURCE_DIR}/src/MCStudies)
 include_directories(${CMAKE_SOURCE_DIR}/src/FCN)
 
 
 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/FCN/JointFCN.cxx b/src/FCN/JointFCN.cxx
index b984da8..61cc4de 100755
--- a/src/FCN/JointFCN.cxx
+++ b/src/FCN/JointFCN.cxx
@@ -1,1035 +1,1034 @@
 #include "JointFCN.h"
 #include <stdio.h>
 #include "FitUtils.h"
 
 // //***************************************************
 // JointFCN::JointFCN(std::string cardfile, TFile* outfile) {
 //   //***************************************************
 
 //   fOutputDir = gDirectory;
 //   FitPar::Config().out = outfile;
 
 //   fCardFile = cardfile;
 
 //   LoadSamples(fCardFile);
 
 //   fCurIter = 0;
 //   fMCFilled = false;
 
 //   fOutputDir->cd();
 
 //   fIterationTree = NULL;
 //   fDialVals = NULL;
 //   fNDials = 0;
 
 //   fUsingEventManager = FitPar::Config().GetParB("EventManager");
 //   fOutputDir->cd();
 // };
 
 
 JointFCN::JointFCN(TFile* outfile) {
 
   fOutputDir = gDirectory;
   if (outfile)
     FitPar::Config().out = outfile;
 
   std::vector<nuiskey> samplekeys =  Config::QueryKeys("sample");
   LoadSamples(samplekeys);
 
   std::vector<nuiskey> covarkeys =  Config::QueryKeys("covar");
   LoadPulls(covarkeys);
 
   fCurIter = 0;
   fMCFilled = false;
 
   fIterationTree = NULL;
   fDialVals = NULL;
   fNDials = 0;
 
   fUsingEventManager = FitPar::Config().GetParB("EventManager");
   fOutputDir->cd();
 
 }
 
 JointFCN::JointFCN(std::vector<nuiskey> samplekeys, TFile* outfile) {
 
   fOutputDir = gDirectory;
   if (outfile)
     FitPar::Config().out = outfile;
 
   LoadSamples(samplekeys);
 
   fCurIter = 0;
   fMCFilled = false;
 
   fOutputDir->cd();
 
   fIterationTree = NULL;
   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 tree! " << endl;
+  LOG(FIT) << " Creating new iteration tree! " << std::endl;
   if (fIterationTree && !name.compare(fIterationTree->GetName())) {
     fIterationTree->Reset();
     return;
   }
 
   fIterationTree = new TTree(name.c_str(), name.c_str());
 
   // Setup Main Branches
   fIterationTree->Branch("total_likelihood", &fLikelihood,
                          "total_likelihood/D");
   fIterationTree->Branch("total_ndof", &fNDOF, "total_ndof/I");
 
   // Setup Sample Arrays
   int ninputs = fSamples.size() + fPulls.size();
   fSampleLikes = new double[ninputs];
   fSampleNDOF = new int[ninputs];
   fNDOF = GetNDOF();
 
   // Setup Sample Branches
   int count = 0;
   for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
        iter++) {
     MeasurementBase* exp = *iter;
 
     std::string name = exp->GetName();
     std::string liketag = name + "_likelihood";
     std::string ndoftag = name + "_ndof";
 
     fIterationTree->Branch(liketag.c_str(), &fSampleLikes[count],
                            (liketag + "/D").c_str());
     fIterationTree->Branch(ndoftag.c_str(), &fSampleNDOF[count],
                            (ndoftag + "/D").c_str());
 
     count++;
   }
 
   for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) {
     ParamPull* pull = *iter;
 
     std::string name = pull->GetName();
     std::string liketag = name + "_likelihood";
     std::string ndoftag = name + "_ndof";
 
     fIterationTree->Branch(liketag.c_str(), &fSampleLikes[count],
                            (liketag + "/D").c_str());
     fIterationTree->Branch(ndoftag.c_str(), &fSampleNDOF[count],
                            (ndoftag + "/D").c_str());
 
     count++;
   }
 
   // Add Dial Branches
   std::vector<std::string> dials = rw->GetDialNames();
   fNDials = dials.size();
   fDialVals = new double[fNDials];
 
   for (int i = 0; i < fNDials; i++) {
     fIterationTree->Branch(dials[i].c_str(), &fDialVals[i],
                            (dials[i] + "/D").c_str());
   }
 }
 
 //***************************************************
 void JointFCN::DestroyIterationTree() {
   //***************************************************
 
   if (!fIterationTree) {
     delete fIterationTree;
   }
 }
 
 //***************************************************
 void JointFCN::WriteIterationTree() {
   //***************************************************
 
   if (!fIterationTree) {
-    ERR(FTL) << "Can't save empty iteration tree!" << endl;
+    ERR(FTL) << "Can't save empty iteration tree!" << std::endl;
     throw;
   }
   fIterationTree->Write();
 }
 
 //***************************************************
 void JointFCN::FillIterationTree(FitWeight* rw) {
   //***************************************************
 
   if (!fIterationTree) {
-    ERR(FTL) << "Trying to fill iteration_tree when it is NULL!" << endl;
+    ERR(FTL) << "Trying to fill iteration_tree when it is NULL!" << std::endl;
     throw;
   }
 
   rw->GetAllDials(fDialVals, fNDials);
   fIterationTree->Fill();
 }
 
 //***************************************************
 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();
 
   // 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
   fNDOF = totaldof;
 
   return totaldof;
 }
 
 //***************************************************
 double JointFCN::GetLikelihood() {
   //***************************************************
 
-  LOG(MIN) << std::left << std::setw(43) << "Getting likelihoods..." << " : " << "-2logL" << endl;
+  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();
 
     // Save seperate likelihoods
     if (fIterationTree) {
       fSampleLikes[count] = newlike;
     }
 
-    LOG(MIN) << "-> " << std::left << std::setw(40) << exp->GetName() << " : " << newlike << endl;
+    LOG(MIN) << "-> " << std::left << std::setw(40) << exp->GetName() << " : " << newlike << 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;
 
   return like;
 };
 
 void JointFCN::LoadSamples(std::vector<nuiskey> samplekeys) {
 
   LOG(MIN) << "Loading Samples : " << samplekeys.size() << std::endl;
   for (size_t i = 0; i < samplekeys.size(); i++) {
     nuiskey key = samplekeys[i];
 
     // Get Sample Options
     std::string samplename = key.GetS("name");
     std::string samplefile = key.GetS("input");
     std::string sampletype = key.GetS("type");
     std::string fakeData = "";
 
     LOG(MIN) << "Loading Sample : " << samplename << std::endl;
 
     fOutputDir->cd();
     MeasurementBase* NewLoadedSample
       = SampleUtils::CreateSample(key);
 
     if (!NewLoadedSample) {
       ERR(FTL) << "Could not load sample provided: " << samplename << std::endl;
       ERR(FTL) << "Check spelling with that in src/FCN/SampleList.cxx"
-               << endl;
+               << std::endl;
       throw;
     } else {
       fSamples.push_back(NewLoadedSample);
     }
   }
 }
 
 void JointFCN::LoadPulls(std::vector<nuiskey> pullkeys) {
 
   for (size_t i = 0; i < pullkeys.size(); i++) {
     nuiskey key = pullkeys[i];
 
     std::string pullname = key.GetS("name");
     std::string pullfile = key.GetS("input");
     std::string pulltype = key.GetS("type");
 
     fOutputDir->cd();
     fPulls.push_back(new ParamPull(pullname, pullfile, pulltype));
 
   }
 
   //     // Sample Inputs
 //     if (!samplevect[0].compare("covar") || !samplevect[0].compare("pulls") ||
 //         !samplevect[0].compare("throws")) {
 //       // Get all inputs
 //       std::string name = samplevect[1];
 //       std::string files = samplevect[2];
 //       std::string type = "DEFAULT";
 
 //       if (samplevect.size() > 3) {
 //         type = samplevect[3];
 //       } else if (!samplevect[0].compare("pull")) {
 //         type = "GAUSPULL";
 //       } else if (!samplevect[0].compare("throws")) {
 //         type = "GAUSTHROWS";
 //       }
 
 //       // Create Pull Class
 //       LOG(MIN) << "Loading up pull term: " << name << " << " << files << " ("
 //                << type << ")" << std::endl;
 //       std::string fakeData = "";
 //       fOutputDir->cd();
 //       fPulls.push_back(new ParamPull(name, files, type));
 //     }
 
 
 
 }
 
 
 // //***************************************************
 // void JointFCN::LoadSamples(std::string cardinput)
 // //***************************************************
 // {
 //   LOG(MIN) << "Initializing Samples" << std::endl;
 
 //   // Read the card file here and load objects
 //   std::string line;
 //   std::ifstream card(cardinput.c_str(), ifstream::in);
 
 //   // Make sure they are created in correct working DIR
 //   fOutputDir->cd();
 
 //   while (std::getline(card >> std::ws, line, '\n')) {
 //     // Skip Empties
 //     if (line.c_str()[0] == '#') continue;
 //     if (line.empty()) continue;
 
 //     // Parse line
 //     std::vector<std::string> samplevect = GeneralUtils::ParseToStr(line, " ");
 
 //     // Sample Inputs
 //     if (!samplevect[0].compare("sample")) {
 //       // Get all inputs
 //       std::string name = samplevect[1];
 //       std::string files = samplevect[2];
 //       std::string type = "DEFAULT";
 //       if (samplevect.size() > 3) type = samplevect[3];
 
 //       // Create Sample Class
 //       LOG(MIN) << "Loading up sample: " << name << " << " << files << " ("
 //                << type << ")" << std::endl;
 //       std::string fakeData = "";
 //       fOutputDir->cd();
 //       MeasurementBase* NewLoadedSample = SampleUtils::CreateSample(name, files, type,
 //                                          fakeData, FitBase::GetRW());
 
 //       if (!NewLoadedSample) {
 //         ERR(FTL) << "Could not load sample provided: " << name << std::endl;
 //         ERR(FTL) << "Check spelling with that in src/FCN/SampleList.cxx"
-//                  << endl;
+//                  << std::endl;
 //         throw;
 //       } else {
 //         fSamples.push_back(NewLoadedSample);
 //       }
 //     }
 
 //     // Sample Inputs
 //     if (!samplevect[0].compare("covar") || !samplevect[0].compare("pulls") ||
 //         !samplevect[0].compare("throws")) {
 //       // Get all inputs
 //       std::string name = samplevect[1];
 //       std::string files = samplevect[2];
 //       std::string type = "DEFAULT";
 
 //       if (samplevect.size() > 3) {
 //         type = samplevect[3];
 //       } else if (!samplevect[0].compare("pull")) {
 //         type = "GAUSPULL";
 //       } else if (!samplevect[0].compare("throws")) {
 //         type = "GAUSTHROWS";
 //       }
 
 //       // Create Pull Class
 //       LOG(MIN) << "Loading up pull term: " << name << " << " << files << " ("
 //                << type << ")" << std::endl;
 //       std::string fakeData = "";
 //       fOutputDir->cd();
 //       fPulls.push_back(new ParamPull(name, files, type));
 //     }
 //   }
 //   card.close();
 // };
 
 //***************************************************
 void JointFCN::ReconfigureSamples(bool fullconfig) {
   //***************************************************
 
   int starttime = time(NULL);
-  LOG(REC) << "Starting Reconfigure iter. " << this->fCurIter << endl;
+  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" << endl;
+           << time(NULL) - starttime << "s" << std::endl;
 
   fCurIter++;
 }
 
 //***************************************************
 void JointFCN::ReconfigureSignal() {
   //***************************************************
   this->ReconfigureSamples(false);
 }
 
 //***************************************************
 void JointFCN::ReconfigureAllEvents() {
   //***************************************************
   FitBase::GetRW()->Reconfigure();
   FitBase::EvtManager().ResetWeightFlags();
   ReconfigureSamples(true);
 }
 
 std::vector<InputHandlerBase*> JointFCN::GetInputList() {
 
   std::vector<InputHandlerBase*> InputList;
   fIsAllSplines = true;
 
   MeasListConstIter iterSam = fSamples.begin();
   for (; iterSam != fSamples.end(); iterSam++) {
     MeasurementBase* exp = (*iterSam);
 
     std::vector<MeasurementBase*> subsamples = exp->GetSubSamples();
     for (size_t i = 0; i < subsamples.size(); i++) {
 
       InputHandlerBase* inp = subsamples[i]->GetInput();
       if (std::find(InputList.begin(), InputList.end(), inp) ==  InputList.end()) {
 
         if (subsamples[i]->GetInput()->GetType() != kSPLINEPARAMETER) fIsAllSplines = false;
 
         InputList.push_back(subsamples[i]->GetInput());
 
       }
     }
   }
 
 
 
   return InputList;
 }
 
 std::vector<MeasurementBase*> JointFCN::GetSubSampleList() {
 
   std::vector<MeasurementBase*> SampleList;
 
   MeasListConstIter iterSam = fSamples.begin();
   for (; iterSam != fSamples.end(); iterSam++) {
     MeasurementBase* exp = (*iterSam);
 
     std::vector<MeasurementBase*> subsamples = exp->GetSubSamples();
     for (size_t i = 0; i < subsamples.size(); i++) {
       SampleList.push_back(subsamples[i]);
     }
   }
 
   return SampleList;
 }
 
 
 //***************************************************
 void JointFCN::ReconfigureUsingManager() {
 //***************************************************
 
   // 'Slow' Event Manager Reconfigure
   LOG(REC) << "Event Manager Reconfigure" << std::endl;
   int timestart = time(NULL);
 
   // Reset all samples
   MeasListConstIter iterSam = fSamples.begin();
   for (; iterSam != fSamples.end(); iterSam++) {
     MeasurementBase* exp = (*iterSam);
     exp->ResetAll();
   }
 
   // If we are siving signal, reset all containers.
   bool savesignal = (FitPar::Config().GetParB("SignalReconfigures"));
   std::cout << " Save Signal = " << savesignal << std::endl;
   //  sleep(5);
 
   if (savesignal) {
     // Reset all of our event signal vectors
     fSignalEventBoxes.clear();
     fSignalEventFlags.clear();
     fSampleSignalFlags.clear();
     fSignalEventSplines.clear();
 
   }
 
   // Make sure we have a list of inputs
   if (fInputList.empty()) {
     fInputList = GetInputList();
     fSubSampleList = GetSubSampleList();
   }
 
 
   // If all inputs are splines make sure the readers are told
   // they need to be reconfigured.
   std::vector<InputHandlerBase*>::iterator inp_iter = fInputList.begin();
 
   if (fIsAllSplines) {
     for (; inp_iter != fInputList.end(); inp_iter++) {
       InputHandlerBase* curinput = (*inp_iter);
 
       // Tell reader in each BaseEvent it needs a Reconfigure next weight calc.
       BaseFitEvt* curevent = curinput->FirstBaseEvent();
       if (curevent->fSplineRead) {
         curevent->fSplineRead->SetNeedsReconfigure(true);
       }
     }
   }
 
   // MAIN INPUT LOOP ====================
 
   int fillcount = 0;
   int inputcount = 0;
   inp_iter = fInputList.begin();
 
   // Loop over each input in manager
   for (; inp_iter != fInputList.end(); inp_iter++) {
     InputHandlerBase* curinput = (*inp_iter);
 
     // Get event information
     FitEvent* curevent = curinput->FirstNuisanceEvent();
+    curinput->CreateCache();
+
     int i = 0;
     int nevents = curinput->GetNEvents();
     int countwidth = nevents / 20;
 
     // 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;
+         // std::cout << "RWWeight = " << curevent->RWWeight  << " " << curevent->InputWeight << std::endl;
 
 
       // Logging
       if (LOG_LEVEL(REC)) {
         if (i % countwidth == 0) {
           LOG(REC) << "Processed " << i << " events. [M, W] = [" << curevent->Mode << ", " << rwweight << "]" << std::endl;
         }
       }
 
       // Setup flag for if signal found in at least one sample
       bool foundsignal = false;
 
       // Create a new signal bitset for this event
       std::vector<bool> signalbitset(fSubSampleList.size());
 
       // Create a new signal box vector for this event
       std::vector<MeasurementVariableBox*> signalboxes;
 
       // Start measurement iterator
       size_t measitercount = 0;
       std::vector<MeasurementBase*>::iterator meas_iter = fSubSampleList.begin();
 
       // Loop over all subsamples (sub in JointMeas)
       for (; meas_iter != fSubSampleList.end(); meas_iter++) {
         MeasurementBase* curmeas = (*meas_iter);
 
         // Compare input pointers, to current input, skip if not.
         // Pointer tells us if it matches without doing ID checks.
         if (curinput != curmeas->GetInput()) {
 
           if (savesignal) {
             // Set bit to 0 as definitely not signal
             signalbitset[measitercount] = 0;
           }
 
           // Count up what measurement we are on.
           measitercount++;
 
           // Skip sample as input not signal.
           continue;
         }
 
 
         // Fill events for matching inputs.
         MeasurementVariableBox* box = curmeas->FillVariableBox(curevent);
 
         bool signal = curmeas->isSignal(curevent);
         curmeas->SetSignal(signal);
         curmeas->FillHistograms(rwweight);
 
         // If its Signal tally up fills
         if (signal) {
           fillcount++;
         }
 
         // If we are saving signal/splines fill the bitset
         if (savesignal) {
           signalbitset[measitercount] = signal;
         }
 
         // If signal save a clone of the event box for use later.
         if (savesignal and signal) {
           foundsignal = true;
           signalboxes.push_back( box->CloneSignalBox() );
         }
 
         // Keep track of Measurement we are on.
         measitercount++;
       }
 
 
       // Once we've filled the measurements, if saving signal
       // push back if any sample flagged this event as signal
       if (savesignal) {
         fSignalEventFlags.push_back(foundsignal);
       }
 
       // Save the vector of signal boxes for this event
       if (savesignal and foundsignal) {
         fSignalEventBoxes.push_back(signalboxes);
         fSampleSignalFlags.push_back(signalbitset);
       }
 
 
       // If all inputs are splines we can save the spline coefficients
       // for fast in memory reconfigures later.
       if (fIsAllSplines and savesignal and foundsignal) {
 
         // Make temp vector to push back with
         std::vector<float> coeff;
         for (size_t l = 0; l < (UInt_t)curevent->fSplineRead->GetNPar(); l++) {
           coeff.push_back( curevent->fSplineCoeff[l] );
         }
 
         // Push back to signal event splines. Kept in sync with fSignalEventBoxes size.
-        int splinecount = fSignalEventSplines.size();
+        // int splinecount = fSignalEventSplines.size();
         fSignalEventSplines.push_back(coeff);
 
         // if (splinecount % 1000 == 0) {
         // std::cout << "Pushed Back Coeff " << splinecount << " : ";
         // for (size_t l = 0; l < fSignalEventSplines[splinecount].size(); l++) {
         // std::cout << " " << fSignalEventSplines[splinecount][l];
         // }
         // std::cout << std::endl;
         // }
 
       }
 
       // Clean up vectors once done with this event
       signalboxes.clear();
       signalbitset.clear();
 
       // Iterate to the next event.
       curevent = curinput->NextNuisanceEvent();
       i++;
     }
 
+    curinput->RemoveCache();
+
     // Keep track of what input we are on.
     inputcount++;
   }
 
   // End of Event Loop ===============================
 
 
   // Now event loop is finished loop over all Measurements
   // Converting Binned events to XSec Distributions
   iterSam = fSamples.begin();
   for (; iterSam != fSamples.end(); iterSam++) {
     MeasurementBase* exp = (*iterSam);
     exp->ConvertEventRates();
   }
 
   // Print out statements on approximate memory usage for profiling.
   LOG(REC) << "Filled " << fillcount << " signal events." << std::endl;
   if (savesignal) {
     int mem = ( //sizeof(fSignalEventBoxes) +
                 // fSignalEventBoxes.size() * sizeof(fSignalEventBoxes.at(0)) +
                 sizeof(MeasurementVariableBox1D) * fillcount) * 1E-6;
     LOG(REC) << " -> Saved " << fillcount << " signal boxes for faster access. (~" << mem << " MB)" << std::endl;
     if (fIsAllSplines and !fSignalEventSplines.empty()) {
       int splmem = sizeof(float) * fSignalEventSplines.size() * fSignalEventSplines[0].size() * 1E-6;
       LOG(REC) << " -> Saved " << fillcount << " " << fSignalEventSplines.size() << " spline sets into memory. (~" << splmem << " MB)" << std::endl;
     }
   }
 
   LOG(REC) << "Time taken ReconfigureUsingManager() : " << time(NULL) - timestart << std::endl;
 
   // End of reconfigure
   return;
 };
 
 
 //***************************************************
 void JointFCN::ReconfigureFastUsingManager() {
 //***************************************************
 
-  LOG(FIT) << " -> Doing FAST using manager"<< std::endl;
+  LOG(FIT) << " -> Doing FAST using manager" << std::endl;
   // Get Start time for profilling
   int timestart = time(NULL);
 
   // Reset all samples
   MeasListConstIter iterSam = fSamples.begin();
   for (; iterSam != fSamples.end(); iterSam++) {
     MeasurementBase* exp = (*iterSam);
     exp->ResetAll();
   }
 
   // Check for saved variables if not do a full reconfigure.
   if (fSignalEventFlags.empty()) {
     ERR(WRN) << "Signal Flags Empty! Using normal manager." << std::endl;
     ReconfigureUsingManager();
     return;
   }
 
   bool fFillNuisanceEvent = FitPar::Config().GetParB("FullEventOnSignalReconfigure");
 
   // Setup fast vector iterators.
   std::vector<bool>::iterator inpsig_iter = fSignalEventFlags.begin();
   std::vector< std::vector<MeasurementVariableBox*> >::iterator box_iter = fSignalEventBoxes.begin();
   std::vector< std::vector<float> >::iterator spline_iter = fSignalEventSplines.begin();
   std::vector< std::vector<bool> >::iterator samsig_iter = fSampleSignalFlags.begin();
   int splinecount = 0;
 
   // Setup stuff for logging
   int fillcount = 0;
   int nevents = fSignalEventFlags.size();
   int countwidth = nevents / 500;
 
   // If All Splines tell splines they need a reconfigure.
   std::vector<InputHandlerBase*>::iterator inp_iter = fInputList.begin();
   if (fIsAllSplines) {
     LOG(REC) << "All Spline Inputs so using fast spline loop." << std::endl;
     for (; inp_iter != fInputList.end(); inp_iter++) {
       InputHandlerBase* curinput = (*inp_iter);
 
       // Tell each fSplineRead in BaseFitEvent to reconf next weight calc
       BaseFitEvt* curevent = curinput->FirstBaseEvent();
       if (curevent->fSplineRead) curevent->fSplineRead->SetNeedsReconfigure(true);
     }
   }
 
 
   // Loop over all possible spline inputs
-  int coreeventcount = 0;
-  double* coreeventweights;
+  double* coreeventweights = new double[fSignalEventBoxes.size()];
   splinecount = 0;
 
-  if (fIsAllSplines) {
-    coreeventweights = new double[fSignalEventSplines.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 (int iinput = 0; iinput < fInputList.size(); iinput++) {
+  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;
 
         // #pragma omp atomic
-        coreeventweights[splinecount] = rwweight;
-
+        if (fIsAllSplines) {
+          coreeventweights[splinecount] = rwweight;
+        }
         if (splinecount % countwidth == 0) {
           LOG(REC) << "Processed " << splinecount << " event weights." << std::endl;
         }
 
 
         // #pragma omp atomic
         splinecount++;
       }
 
       // #pragma omp atomic
       sigcount++;
 
     }
   }
   LOG(SAM) << "Processed event weights." << std::endl;
 
 
   // #pragma omp barrier
 
   // Reset Iterators
   inpsig_iter = fSignalEventFlags.begin();
   spline_iter = fSignalEventSplines.begin();
   box_iter = fSignalEventBoxes.begin();
   samsig_iter = fSampleSignalFlags.begin();
   int nsplineweights = splinecount;
   splinecount = 0;
 
 
   // Start of Fast Event Loop ============================
 
   // Start input iterators
   // Loop over number of inputs
   for (int ispline = 0; ispline < nsplineweights; ispline++) {
     double rwweight = coreeventweights[ispline];
 
     // Get iterators for this event
     std::vector<bool>::iterator subsamsig_iter = (*samsig_iter).begin();
     std::vector<MeasurementVariableBox*>::iterator subbox_iter = (*box_iter).begin();
 
     // Loop over all sub measurements.
     std::vector<MeasurementBase*>::iterator meas_iter = fSubSampleList.begin();
     for (; meas_iter != fSubSampleList.end(); meas_iter++, subsamsig_iter++) {
       MeasurementBase* curmeas = (*meas_iter);
 
       // If event flagged as signal for this sample fill from the box.
       if (*subsamsig_iter) {
         curmeas->SetSignal(true);
         curmeas->FillHistogramsFromBox((*subbox_iter), rwweight);
 
         // Move onto next box if there is one.
         subbox_iter++;
         fillcount++;
       }
     }
 
     if (ispline % countwidth == 0) {
       LOG(REC) << "Filled " << ispline << " sample weights." << std::endl;
     }
 
     // Iterate over the main signal event containers.
     samsig_iter++;
     box_iter++;
     spline_iter++;
     splinecount++;
 
   }
   // End of Fast Event Loop ===================
 
   LOG(SAM) << "Filled sample distributions." << std::endl;
 
   // Now loop over all Measurements
   // Convert Binned events
   iterSam = fSamples.begin();
   for (; iterSam != fSamples.end(); iterSam++) {
     MeasurementBase* exp = (*iterSam);
     exp->ConvertEventRates();
   }
 
   // Cleanup coreeventweights
   if (fIsAllSplines) {
     delete coreeventweights;
   }
 
   // Print some reconfigure profiling.
   LOG(REC) << "Filled " << fillcount << " signal events." << std::endl;
   LOG(REC) << "Time taken ReconfigureFastUsingManager() : " << time(NULL) - timestart << std::endl;
 }
 
 //***************************************************
 void JointFCN::Write() {
   //***************************************************
 
   // Loop over individual experiments and call Write
-  LOG(MIN) << "Writing each of the data classes..." << endl;
+  LOG(MIN) << "Writing each of the data classes..." << std::endl;
   for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
        iter++) {
     MeasurementBase* exp = *iter;
     exp->Write();
   }
 
   // Save Pull Terms
   for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) {
     ParamPull* pull = *iter;
     pull->Write();
   }
 
   if (FitPar::Config().GetParB("EventManager")) {
     // Get list of inputs
     std::map<int, InputHandlerBase*> fInputs = FitBase::EvtManager().GetInputs();
     std::map<int, InputHandlerBase*>::const_iterator iterInp;
 
     for (iterInp = fInputs.begin(); iterInp != fInputs.end(); iterInp++) {
       InputHandlerBase* input = (iterInp->second);
 
       input->GetFluxHistogram()->Write();
       input->GetXSecHistogram()->Write();
       input->GetEventHistogram()->Write();
     }
   }
 };
 
 //***************************************************
 void JointFCN::SetFakeData(std::string fakeinput) {
   //***************************************************
 
-  LOG(MIN) << "Setting fake data from " << fakeinput << endl;
+  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;
 }
diff --git a/src/FNAL/CMakeLists.txt b/src/FNAL/CMakeLists.txt
index 2fca73f..b87633d 100644
--- a/src/FNAL/CMakeLists.txt
+++ b/src/FNAL/CMakeLists.txt
@@ -1,60 +1,62 @@
 # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 ################################################################################
 #    This file is part of NUISANCE.
 #
 #    NUISANCE is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
 #    (at your option) any later version.
 #
 #    NUISANCE is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #    GNU General Public License for more details.
 #
 #    You should have received a copy of the GNU General Public License
 #    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 ################################################################################
 set(IMPLFILES
 FNAL_CC1ppip_Evt_1DQ2_nu.cxx
 FNAL_CC1ppip_XSec_1DEnu_nu.cxx
 FNAL_CC1ppip_XSec_1DQ2_nu.cxx
 FNAL_CCQE_Evt_1DQ2_nu.cxx
 FNAL_CC1ppim_XSec_1DEnu_antinu.cxx
 )
 
 set(HEADERFILES
 FNAL_CC1ppim_XSec_1DEnu_antinu.h
 FNAL_CC1ppip_Evt_1DQ2_nu.h
 FNAL_CC1ppip_XSec_1DEnu_nu.h
 FNAL_CC1ppip_XSec_1DQ2_nu.h
 FNAL_CCQE_Evt_1DQ2_nu.h
 )
 
 set(LIBNAME expFNAL)
 
 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(${RWENGINE_INCLUDE_DIRECTORIES})
 
 include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
+include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler)
+include_directories(${CMAKE_SOURCE_DIR}/src/Genie)
 include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
 include_directories(${CMAKE_SOURCE_DIR}/src/Reweight)
 include_directories(${CMAKE_SOURCE_DIR}/src/Splines)
 
 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/FitBase/CMakeLists.txt b/src/FitBase/CMakeLists.txt
index 4631d6d..b4c7df3 100644
--- a/src/FitBase/CMakeLists.txt
+++ b/src/FitBase/CMakeLists.txt
@@ -1,111 +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 <http://www.gnu.org/licenses/>.
 ################################################################################
 set(IMPLFILES
 ParamPull.cxx
-BaseFitEvt.cxx
-FitParticle.cxx
-Measurement1D.cxx
 EventManager.cxx
+Measurement1D.cxx
 Measurement2D.cxx
-FitEvent.cxx
 JointMeas1D.cxx
 MeasurementBase.cxx
-GeneratorUtils.cxx
-StdHepEvt.cxx
 TemplateMeas1D.cxx
-InputUtils.cxx
-NEUTInputHandler.cxx
-GENIEInputHandler.cxx
-NuWroInputHandler.cxx
-GIBUUInputHandler.cxx
-NUANCEInputHandler.cxx
-NuanceEvent.cxx
 SampleSettings.cxx
-FitEventInputHandler.cxx
-SplineInputHandler.cxx
 MeasurementVariableBox.cxx
 MeasurementVariableBox2D.cxx
 MeasurementVariableBox1D.cxx
 CustomVariableBoxes.h
-GeneratorInfoBase.h
-InputTypes.h
-GNUISANCEFlux.cxx
-GNUISANCEMCJDriver.cxx
-HepMCTextInputHandler.cxx
 )
 
 set(HEADERFILES
 ParamPull.h
-NuanceEvent.h
-BaseFitEvt.h    FitEvent.h     JointMeas1D.h    Measurement2D.h
-EventManager.h  FitParticle.h      MeasurementBase.h   Measurement1D.h GeneratorUtils.h StdHepEvt.h TemplateMeas1D.h
-InputUtils.h
-NEUTInputHandler.h
-HepMCTextInputHandler.h
-GENIEInputHandler.h
-NuWroInputHandler.h
-InputHandler2.h
-GIBUUInputHandler.h
-NUANCEInputHandler.h
+JointMeas1D.h    
+Measurement2D.h
+EventManager.h
+MeasurementBase.h   
+Measurement1D.h 
+TemplateMeas1D.h
 SampleSettings.h
-FitEventInputHandler.h
-SplineInputHandler.h
 MeasurementVariableBox.h
 MeasurementVariableBox2D.h
 MeasurementVariableBox1D.h
 CustomVariableBoxes.h
-GeneratorInfoBase.h
-GNUISANCEFlux.h
-GNUISANCEMCJDriver.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(${RWENGINE_INCLUDE_DIRECTORIES})
 
 if (USE_GENIE)
    include_directories(${GENIE_INCLUDES}/Apps)
    include_directories(${GENIE_INCLUDES}/FluxDrivers)
    include_directories(${GENIE_INCLUDES}/EVGDrivers)
 endif()
 
+include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler)
 include_directories(${CMAKE_SOURCE_DIR}/src/Reweight)
 include_directories(${CMAKE_SOURCE_DIR}/src/Splines)
 include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
 include_directories(${CMAKE_CURRENT_SOURCE_DIR})
 
 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/FitBase/CustomVariableBoxes.h b/src/FitBase/CustomVariableBoxes.h
index 1dd3e2b..8bb8b41 100644
--- a/src/FitBase/CustomVariableBoxes.h
+++ b/src/FitBase/CustomVariableBoxes.h
@@ -1,21 +1,21 @@
 #ifndef CUSTOM_VARIABLES_BOX_H
 #define CUSTOM_VARIABLES_BOX_H
 
 #include "MeasurementVariableBox.h"
 #include "MeasurementVariableBox1D.h"
 #include "MeasurementVariableBox2D.h"
 
 /*!
  *  \addtogroup FitBase
  *  @{
  */
 
 /// Custom box used to also save Q2 for each event.
 class Q2VariableBox1D : public MeasurementVariableBox1D {
 public:
 	inline Q2VariableBox1D() { Reset(); };
 	inline void Reset() {	fQ2 = -999.9; }
 	double fQ2;
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/FitBase/EventManager.h b/src/FitBase/EventManager.h
index 1a7364d..d3df579 100644
--- a/src/FitBase/EventManager.h
+++ b/src/FitBase/EventManager.h
@@ -1,76 +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 <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
 #ifndef EVENTMANAGER_H
 #define EVENTMANAGER_H
 
-#include "InputHandler2.h"
+#include "InputHandler.h"
 #include "FitWeight.h"
 #include "InputUtils.h"
-
+#include "InputFactory.h"
 // This class is menat to manage one input file for many distributions
 class EventManager {
  public:
   static EventManager& Get(void);
 
   FitWeight* GetRW();
   void SetRW(FitWeight* rw);
 
   InputHandlerBase* GetInput(int id);
   FitEvent* GetEvent(int id, int i);
   double GetEventWeight(int id, int i);
   InputHandlerBase* AddInput(std::string handle, std::string infile);
   void ResetWeightFlags();
   int GetInputID(std::string infile);
 
   std::map< int, InputHandlerBase* > GetInputs();
 
  protected:
   EventManager();
   ~EventManager();
 
   static EventManager* m_evtmgrInstance;
 
   FitWeight* fRW;
   std::map< std::string, int > fid;
   std::map< int, InputHandlerBase* > finputs;
   std::map< int, std::vector< bool > > frwneeded;
   std::map< int, std::vector< double > > calc_rw;
 
 };
 
 
 namespace FitBase {
 
   inline
   EventManager& EvtManager(){ return EventManager::Get(); };
   inline
   FitWeight* GetRW(){ return EvtManager().GetRW(); };
   inline
   void SetRW(FitWeight* rw){ EvtManager().SetRW(rw); };
   inline
   int GetInputID(std::string infile){ return EvtManager().GetInputID(infile); };
   inline
   InputHandlerBase* GetInput(int infile){ return EvtManager().GetInput(infile); };
   inline
   InputHandlerBase* AddInput(std::string handle, std::string infile){ return EvtManager().AddInput(handle, infile); };
 
 
 }
 #endif
diff --git a/src/FitBase/FitEventInputHandler.cxx b/src/FitBase/FitEventInputHandler.cxx
deleted file mode 100644
index 5287224..0000000
--- a/src/FitBase/FitEventInputHandler.cxx
+++ /dev/null
@@ -1,152 +0,0 @@
-#include "FitEventInputHandler.h"
-
-FitEventInputHandler::FitEventInputHandler(std::string const& handle, std::string const& rawinputs){
-
-	// Run a joint input handling
-	fName = handle;
-	jointinput = false;
-	jointindexswitch = 0;
-
-	// Form list of all inputs, remove brackets if required.
-	std::vector<std::string> inputs = GeneralUtils::ParseToStr(rawinputs, ",");
-	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);
-	}
-    for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) {
-      LOG(SAM) << "\t -> Found input file: " << inputs[inp_it] << std::endl;
-    }
-
-    // Setup the TChain
-	fFitEventTree = new TChain("nuisance_events");
-	
-    // Loop over all inputs and grab flux, eventhist, and nevents
-    // Also add it to the TChain
-    int evtcounter = 0;
-    if (inputs.size() > 1) jointinput = true;
-    for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) {
-
-    	// Add to TChain
-    	fFitEventTree->Add( inputs[inp_it].c_str() );
-
-    	// Open File for histogram access
-    	TFile* inp_file = new TFile(inputs[inp_it].c_str(),"READ");
-
-    	// Get Flux/Event hist
-    	TH1D* fluxhist  = (TH1D*)inp_file->Get(
-    			(PlotUtils::GetObjectWithName(inp_file, "nuisance_fluxhist")).c_str());
-    	TH1D* eventhist = (TH1D*)inp_file->Get(
-    			(PlotUtils::GetObjectWithName(inp_file, "nuisance_eventhist")).c_str());
-
-    	// Get N events
-    	TTree* neuttree = (TTree*)inp_file->Get("nuisance_events");
-    	int nevents = neuttree->GetEntries();
-
-    	// Push into individual input vectors
-    	jointfluxinputs.push_back( (TH1D*) fluxhist->Clone() );
-    	jointeventinputs.push_back( (TH1D*) eventhist->Clone() );
-
-    	jointindexlow.push_back(evtcounter);
-    	jointindexhigh.push_back(evtcounter + nevents);
-    	evtcounter += nevents;
-
-    	// Add to the total flux/event hist
-    	if (!fFluxHist) fFluxHist = (TH1D*) fluxhist->Clone();
-    	else fFluxHist->Add(fluxhist);
-
-    	if (!fEventHist) fEventHist = (TH1D*) eventhist->Clone();
-    	else fEventHist->Add(eventhist);
-
-	}
-
-	// Setup NEvents and the FitEvent
-    fNEvents = fFitEventTree->GetEntries();
-    fEventType = kINPUTFITEVENT;
-    fNUISANCEEvent = new FitEvent();
-    fNUISANCEEvent->SetInputFitEvent();
-    fNUISANCEEvent->HardReset();
-    fNUISANCEEvent->SetBranchAddress(fFitEventTree);
-
-    fBaseEvent = static_cast<BaseFitEvt*>(fNUISANCEEvent);
-
-
-    // Normalise event histograms for relative flux contributions.
-    for (size_t i = 0; i < jointeventinputs.size(); i++) { 
-    	TH1D* eventhist = (TH1D*) jointeventinputs.at(i)->Clone();
-
-    	double scale = double(fNEvents) / fEventHist->Integral("width");
-    	scale *= eventhist->Integral("width");
-    	scale /= double(jointindexhigh[i] - jointindexlow[i]);
-
-    	jointindexscale .push_back(scale);
-    }
-    
-    fEventHist->SetNameTitle((fName + "_EVT").c_str(), (fName + "_EVT").c_str());
-    fFluxHist->SetNameTitle((fName + "_FLUX").c_str(), (fName + "_FLUX").c_str());
-    
-    fFitEventTree->SetCacheEntryRange(0,fNEvents);
-    fFitEventTree->AddBranchToCache("*",1);
-    fFitEventTree->SetCacheSize(FitPar::Config().GetParI("CacheSize"));
-
-};
-
-
-FitEvent* FitEventInputHandler::GetNuisanceEvent(const UInt_t entry){
-
-	// Return NULL if out of bounds
-  if (entry >= (UInt_t)fNEvents) return NULL;
-
-	// Reset all variables before tree read
-	fNUISANCEEvent->ResetEvent();
-
-	// Read NUISANCE Tree
-	fFitEventTree->GetEntry(entry);
-	
-	// Setup Input scaling for joint inputs
-	if (jointinput){
-		fNUISANCEEvent->InputWeight = fNUISANCEEvent->SavedRWWeight * fNUISANCEEvent->InputWeight * GetInputWeight(entry);
-	} else {
-		fNUISANCEEvent->InputWeight = fNUISANCEEvent->SavedRWWeight * fNUISANCEEvent->InputWeight;
-	}
-
-	return fNUISANCEEvent;
-}
-
-
-double FitEventInputHandler::GetInputWeight(int entry){
-
-	// Find Switch Scale
-	while( entry < jointindexlow[jointindexswitch] ||
-	       entry >= jointindexhigh[jointindexswitch] ){
-		jointindexswitch++;
-
-		// Loop Around
-		if (jointindexswitch == jointindexlow.size()){ 
-			jointindexswitch = 0;
-		}
-	}
-	return jointindexscale[jointindexswitch];
-};
-
-
-BaseFitEvt* FitEventInputHandler::GetBaseEvent(const UInt_t entry){
-
-	// Read entry from TTree to fill NEUT Vect in BaseFitEvt;
-	fFitEventTree->GetEntry(entry);
-	// fBaseEvent->eventid = entry;
-	
-	// Set joint scaling if required
-	if (jointinput){
-		fNUISANCEEvent->InputWeight = fNUISANCEEvent->SavedRWWeight * fNUISANCEEvent->InputWeight * GetInputWeight(entry);
-	} else {
-		fNUISANCEEvent->InputWeight = fNUISANCEEvent->SavedRWWeight * fNUISANCEEvent->InputWeight;
-	}
-
-	return fBaseEvent;
-}
-
-void FitEventInputHandler::Print(){}
-
-	
diff --git a/src/FitBase/FitEventInputHandler.h b/src/FitBase/FitEventInputHandler.h
deleted file mode 100644
index 87c9957..0000000
--- a/src/FitBase/FitEventInputHandler.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef FITEVENT_INPUTHANDLER_H
-#define FITEVENT_INPUTHANDLER_H
-
-#include "InputHandler2.h"
-#include "FitEvent.h"
-#include "PlotUtils.h"
-
-class FitEventInputHandler : public InputHandlerBase {
-public:
-
-	FitEventInputHandler(std::string const& handle, std::string const& rawinputs);
-	~FitEventInputHandler(){};
-
-	FitEvent* GetNuisanceEvent(const UInt_t entry);
-	double GetInputWeight(int entry);
-	BaseFitEvt* GetBaseEvent(const UInt_t entry);
-	void Print();
-
-	bool save_extra;
-	TChain* fFitEventTree;
-};
-
-#endif
diff --git a/src/FitBase/GENIEInputHandler.h b/src/FitBase/GENIEInputHandler.h
deleted file mode 100644
index 0279e99..0000000
--- a/src/FitBase/GENIEInputHandler.h
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef GENIEINPUTHANDLER_H
-#define GENIEINPUTHANDLER_H
-#include "InputHandler2.h"
-#include "PlotUtils.h"
-
-#ifdef __GENIE_ENABLED__
-#include "Conventions/Units.h"
-#include "EVGCore/EventRecord.h"
-#include "GHEP/GHepRecord.h"
-#include "Ntuple/NtpMCEventRecord.h"
-using namespace genie;
-#endif
-
-
-class GENIEInputHandler : public InputHandlerBase {
-public:
-
-	GENIEInputHandler(std::string const& handle, std::string const& rawinputs);
-	~GENIEInputHandler(){};
-
-	FitEvent* GetNuisanceEvent(const UInt_t entry);
-	void CalcNUISANCEKinematics();
-	double GetInputWeight(int entry);
-	BaseFitEvt* GetBaseEvent(const UInt_t entry);
-	void Print();
-
-#ifdef __GENIE_ENABLED__
-	int GetGENIEParticleStatus(genie::GHepParticle* part, int mode=0);
-	int ConvertGENIEReactionCode(GHepRecord* gheprec);
-#endif
-	
-#ifdef __GENIE_ENABLED__
-	  GHepRecord* fGenieGHep;
-	  NtpMCEventRecord* fGenieNtpl;
-#endif
-
-	TChain* fGENIETree;
-};
-
-#endif
diff --git a/src/FitBase/GIBUUInputHandler.h b/src/FitBase/GIBUUInputHandler.h
deleted file mode 100644
index b773a00..0000000
--- a/src/FitBase/GIBUUInputHandler.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef GIBUUINPUTHANDLER_H
-#define GIBUUINPUTHANDLER_H
-#ifdef __GiBUU_ENABLED__
-#include "InputHandler2.h"
-#include "PlotUtils.h"
-
-class GIBUUInputHandler : public InputHandlerBase {
-public:
-
-	GIBUUInputHandler(std::string const& handle, std::string const& rawinputs);
-	~GIBUUInputHandler(){};
-
-	FitEvent* GetNuisanceEvent(const UInt_t entry);
-	int GetGIBUUParticleStatus(int status, int pdg);
-	void CalcNUISANCEKinematics();
-	double GetInputWeight(int entry);
-	BaseFitEvt* GetBaseEvent(const UInt_t entry);
-	void Print();
-
-	GiBUUStdHepReader* fGiReader;
-	TChain* fGIBUUTree;
-	std::vector<TH1D*> fFluxList;
-};
-#endif
-#endif
\ No newline at end of file
diff --git a/src/FitBase/GNUISANCEFlux.cxx b/src/FitBase/GNUISANCEFlux.cxx
deleted file mode 100644
index 816e686..0000000
--- a/src/FitBase/GNUISANCEFlux.cxx
+++ /dev/null
@@ -1,304 +0,0 @@
-#ifdef __GEVGEN_ENABLED__
-//____________________________________________________________________________
-/*
- Copyright (c) 2003-2016, GENIE Neutrino MC Generator Collaboration
- For the full text of the license visit http://copyright.genie-mc.org
- or see $GENIE/LICENSE
-
- Author: Costas Andreopoulos <costas.andreopoulos \at stfc.ac.uk>
-         University of Liverpool & STFC Rutherford Appleton Lab - July 04, 2005
-
- For the class documentation see the corresponding header file.
-
- Important revisions after version 2.0.0 :
-
- @ Feb 22, 2011 - JD
-   Implemented dummy versions of the new GFluxI::Clear, GFluxI::Index and 
-   GFluxI::GenerateWeighted methods needed for pre-generation of flux
-   interaction probabilities in GMCJDriver.
-
-*/
-//____________________________________________________________________________
-
-#include <cassert>
-#include <algorithm>
-
-#include <TH1D.h>
-#include <TF1.h>
-#include <TVector3.h>
-
-#include "Conventions/Constants.h"
-#include "GNUISANCEFlux.h"
-#include "Messenger/Messenger.h"
-#include "Numerical/RandomGen.h"
-#include "PDG/PDGCodeList.h"
-#include "Utils/PrintUtils.h"
-
-#include "FluxDrivers/GFluxDriverFactory.h"
-FLUXDRIVERREG4(genie,flux,GNUISANCEFlux,genie::flux::GNUISANCEFlux)
-
-using namespace genie;
-using namespace genie::constants;
-using namespace genie::flux;
-
-//____________________________________________________________________________
-GNUISANCEFlux::GNUISANCEFlux()
-{
-  this->Initialize();
-}
-//___________________________________________________________________________
-GNUISANCEFlux::~GNUISANCEFlux()
-{
-  this->CleanUp();
-}
-//___________________________________________________________________________
-bool GNUISANCEFlux::GenerateNext(void)
-{
-  //-- Reset previously generated neutrino code / 4-p / 4-x
-  this->ResetSelection();
-
-  //-- Generate an energy from the 'combined' spectrum histogram
-  //   and compute the momentum vector
-  if (!fTotSpectrum) AddAllFluxes();
-
-  std::cout << "fTotSpectrum = " << fTotSpectrum << std::endl;
-  std::cout << "TotalSpectrum Integral = " << fTotSpectrum->Integral() << std::endl;
-
-  double Ev = (double) fTotSpectrum->GetRandom();
-
-  TVector3 p3(*fDirVec); // momentum along the neutrino direction
-  p3.SetMag(Ev);         // with |p|=Ev
-
-  fgP4.SetPxPyPzE(p3.Px(), p3.Py(), p3.Pz(), Ev);
-
-  //-- Select a neutrino species from the flux fractions at the
-  //   selected energy
-  fgPdgC = (*fPdgCList)[this->SelectNeutrino(Ev)];
-
-  //-- Compute neutrino 4-x
-
-  if(fRt <= 0) {
-    fgX4.SetXYZT(0.,0.,0.,0.);
-  } 
-  else {
-    // Create a vector (vec) that points to a random position at a disk
-    // of radius Rt passing through the origin, perpendicular to the
-    // input direction.
-    TVector3 vec0(*fDirVec);           // vector along the input direction
-    TVector3 vec = vec0.Orthogonal();  // orthogonal vector
-
-    double psi = this->GeneratePhi();  // rndm angle [0,2pi]
-    double Rt  = this->GenerateRt();   // rndm R [0,Rtransverse]
-
-    vec.Rotate(psi,vec0); // rotate around original vector
-    vec.SetMag(Rt);       // set new norm
-
-    // Set the neutrino position as beam_spot + vec
-    double x = fBeamSpot->X() + vec.X();
-    double y = fBeamSpot->Y() + vec.Y();
-    double z = fBeamSpot->Z() + vec.Z();
-
-    fgX4.SetXYZT(x,y,z,0.);
-  }
-
-  LOG("Flux", pINFO) << "Generated neutrino pdg-code: " << fgPdgC;
-  LOG("Flux", pINFO)
-        << "Generated neutrino p4: " << utils::print::P4AsShortString(&fgP4);
-  LOG("Flux", pINFO)
-             << "Generated neutrino x4: " << utils::print::X4AsString(&fgX4);
-
-  return true;
-}
-//___________________________________________________________________________
-void GNUISANCEFlux::Clear(Option_t * opt)
-{
-// Dummy clear method needed to conform to GFluxI interface 
-//
-  LOG("Flux", pERROR) << 
-      "No Clear(Option_t * opt) method implemented for opt: "<< opt;
-}
-//___________________________________________________________________________
-void GNUISANCEFlux::GenerateWeighted(bool gen_weighted)
-{
-// Dummy implementation needed to conform to GFluxI interface
-//
-  LOG("Flux", pERROR) << 
-      "No GenerateWeighted(bool gen_weighted) method implemented for " << 
-      "gen_weighted: " << gen_weighted;
-}
-//___________________________________________________________________________
-void GNUISANCEFlux::Initialize(void)
-{
-  LOG("Flux", pNOTICE) << "Initializing GNUISANCEFlux driver";
-
-  fMaxEv       = 0;
-  fPdgCList    = new PDGCodeList;
-  fTotSpectrum = 0;
-  fDirVec      = 0;
-  fBeamSpot    = 0;
-  fRt          =-1;
-  fRtDep       = 0;
-
-  this->ResetSelection();
-  this->SetRtDependence("x");
-  //eg, other example: this->SetRtDependence("pow(x,2)");
-}
-//___________________________________________________________________________
-void GNUISANCEFlux::ResetSelection(void)
-{
-// initializing running neutrino pdg-code, 4-position, 4-momentum
-  fgPdgC = 0;
-  fgP4.SetPxPyPzE (0.,0.,0.,0.);
-  fgX4.SetXYZT    (0.,0.,0.,0.);
-}
-//___________________________________________________________________________
-void GNUISANCEFlux::CleanUp(void)
-{
-  LOG("Flux", pNOTICE) << "Cleaning up...";
-
-  if (fDirVec     ) delete fDirVec;
-  if (fBeamSpot   ) delete fBeamSpot;
-  if (fPdgCList   ) delete fPdgCList;
-  //  if (fTotSpectrum) delete fTotSpectrum;
-  if (fRtDep      ) delete fRtDep;
-
-  unsigned int nspectra = fSpectrum.size();
-  for(unsigned int i = 0; i < nspectra; i++) {
-     TH1D * spectrum = fSpectrum[i];
-     delete spectrum;
-     spectrum = 0;
-  }
-}
-//___________________________________________________________________________
-void GNUISANCEFlux::SetNuDirection(const TVector3 & direction)
-{
-  if(fDirVec) delete fDirVec;
-  fDirVec = new TVector3(direction);
-}
-//___________________________________________________________________________
-void GNUISANCEFlux::SetBeamSpot(const TVector3 & spot)
-{
-  if(fBeamSpot) delete fBeamSpot;
-  fBeamSpot = new TVector3(spot);
-}
-//___________________________________________________________________________
-void GNUISANCEFlux::SetTransverseRadius(double Rt)
-{
-  LOG ("Flux", pNOTICE) << "Setting R[transverse] = " << Rt;
-  fRt = Rt;
-
-  if(fRtDep) fRtDep->SetRange(0,Rt);
-}
-//___________________________________________________________________________
-void GNUISANCEFlux::AddEnergySpectrum(int nu_pdgc, TH1D * spectrum)
-{
-  LOG("Flux", pNOTICE) << "Adding flux spectrum for pdg = " << nu_pdgc;
-
-  fPdgCList->push_back(nu_pdgc);
-
-  bool accepted = (count(fPdgCList->begin(),fPdgCList->end(),nu_pdgc) == 1);
-  if(!accepted) {
-     LOG ("Flux", pWARN)
-            << "The pdg-code isn't recognized and the spectrum was ignored";
-  } else {
-     fSpectrum.push_back(spectrum);
-
-     int    nb  = spectrum->GetNbinsX();
-     Axis_t max = spectrum->GetBinLowEdge(nb)+spectrum->GetBinWidth(nb);
-     fMaxEv = TMath::Max(fMaxEv, (double)max);
-
-     LOG("Flux", pNOTICE) 
-          << "Updating maximum energy of flux particles to: " << fMaxEv;
-
-     //     this->AddAllFluxes(); // update combined flux
-  }
-
-}
-//___________________________________________________________________________
-void GNUISANCEFlux::SetRtDependence(string rdep)
-{
-// Set the (functional form of) Rt dependence as string, eg "x*x+sin(x)"
-// You do not need to set this method. The default behaviour is to generate
-// flux neutrinos uniformly over the area of the cylinder's cross section.
-
-  if(fRtDep) delete fRtDep;
-
-  fRtDep = new TF1("rdep", rdep.c_str(), 0,fRt);
-}
-//___________________________________________________________________________
-void GNUISANCEFlux::AddAllFluxes(void)
-{
-  LOG("Flux", pNOTICE) << "Computing combined flux";
-
-  //if(fTotSpectrum) delete fTotSpectrum;
-
-  vector<TH1D *>::const_iterator spectrum_iter;
-
-  unsigned int inu=0;
-  for(spectrum_iter = fSpectrum.begin();
-                       spectrum_iter != fSpectrum.end(); ++spectrum_iter) {
-     TH1D * spectrum = *spectrum_iter;
-
-     if(inu==0) { fTotSpectrum = new TH1D(*spectrum); }
-     else       { fTotSpectrum->Add(spectrum);        }
-
-     LOG("Flux",pNOTICE) << "Added spectrum ";
-     inu++;
-  }
-  LOG("Flux", pNOTICE) << "Flux Pointer = " << fTotSpectrum;
-  LOG("Flux", pNOTICE) << "Total flux integral = " << fTotSpectrum->Integral();
-}
-//___________________________________________________________________________
-int GNUISANCEFlux::SelectNeutrino(double Ev)
-{
-  const unsigned int n = fPdgCList->size();
-  double fraction[n];
-
-  vector<TH1D *>::const_iterator spectrum_iter;
-
-  unsigned int inu=0;
-  for(spectrum_iter = fSpectrum.begin();
-                       spectrum_iter != fSpectrum.end(); ++spectrum_iter) {
-     TH1D * spectrum = *spectrum_iter;
-     fraction[inu++] = spectrum->GetBinContent(spectrum->FindBin(Ev));
-  }
-
-  double sum = 0;
-  for(inu = 0; inu < n; inu++) {
-     sum += fraction[inu];
-     fraction[inu] = sum;
-     LOG("Flux", pDEBUG) << "SUM-FRACTION(0->" << inu <<") = " << sum;
-  }
-
-  RandomGen * rnd = RandomGen::Instance();
-  double R = sum * rnd->RndFlux().Rndm();
-
-  LOG("Flux", pDEBUG) << "R e [0,SUM] = " << R;
-
-  for(inu = 0; inu < n; inu++) {if ( R < fraction[inu] ) return inu;}
-
-  LOG("Flux", pERROR) << "Could not select a neutrino species";
-  assert(false);
-
-  return -1;
-}
-//___________________________________________________________________________
-double GNUISANCEFlux::GeneratePhi(void) const
-{
-  RandomGen * rnd = RandomGen::Instance();
-  double phi = 2.*kPi * rnd->RndFlux().Rndm(); // [0,2pi]
-  return phi;
-}
-//___________________________________________________________________________
-double GNUISANCEFlux::GenerateRt(void) const
-{
-  double Rt = fRtDep->GetRandom(); // rndm R [0,Rtransverse]
-  return Rt;
-}
-//___________________________________________________________________________
-TH1D* GNUISANCEFlux::GetTotalSpectrum(void){
-  //  if (fTotSpectrum) delete fTotSpectrum;
-  this->AddAllFluxes();
-  return fTotSpectrum;
-}
-#endif
diff --git a/src/FitBase/GNUISANCEFlux.h b/src/FitBase/GNUISANCEFlux.h
deleted file mode 100644
index 841f72f..0000000
--- a/src/FitBase/GNUISANCEFlux.h
+++ /dev/null
@@ -1,103 +0,0 @@
-#ifdef __GEVGEN_ENABLED__
-//____________________________________________________________________________
-/*!
-
-\class   genie::flux::GNUISANCEFlux
-
-\brief   A generic GENIE flux driver. 
-         Generates a 'cylindrical' neutrino beam along the input direction, 
-         with the input transverse radius and centered at the input position.
-         The energies are generated from the input energy spectrum (TH1D).
-         Multiple neutrino species can be generated (you will need to supply
-         an energy spectrum for each).
-
-\author  Costas Andreopoulos <costas.andreopoulos \at stfc.ac.uk>
-         University of Liverpool & STFC Rutherford Appleton Lab
-
-\created July 4, 2005
-
-\cpright  Copyright (c) 2003-2016, GENIE Neutrino MC Generator Collaboration
-          For the full text of the license visit http://copyright.genie-mc.org
-          or see $GENIE/LICENSE
-*/
-//____________________________________________________________________________
-
-#ifndef _G_NUISANCE_FLUX_H_
-#define _G_NUISANCE_FLUX_H_
-
-#include <string>
-#include <vector>
-
-#include <TLorentzVector.h>
-
-#include "EVGDrivers/GFluxI.h"
-
-class TH1D;
-class TF1;
-class TVector3;
-
-using std::string;
-using std::vector;
-
-namespace genie {
-namespace flux  {
-
-class GNUISANCEFlux: public GFluxI {
-
-public :
-  GNUISANCEFlux();
- ~GNUISANCEFlux();
-
-  // methods specific to this flux object
-  void SetNuDirection      (const TVector3 & direction);
-  void SetBeamSpot         (const TVector3 & spot);
-  void SetTransverseRadius (double Rt);
-  void AddEnergySpectrum   (int nu_pdgc, TH1D * spectrum);
-  void SetRtDependence     (string rdep);
-
-  // methods implementing the GENIE GFluxI interface
-  const PDGCodeList &    FluxParticles (void) { return *fPdgCList; }
-  double                 MaxEnergy     (void) { return  fMaxEv;    }
-  bool                   GenerateNext  (void);
-  int                    PdgCode       (void) { return  fgPdgC;    }
-  double                 Weight        (void) { return  1.0;       }
-  const TLorentzVector & Momentum      (void) { return  fgP4;      }
-  const TLorentzVector & Position      (void) { return  fgX4;      }
-  bool                   End           (void) { return  false;     }
-  long int               Index         (void) { return -1;         }
-  void                   Clear            (Option_t * opt);
-  void                   GenerateWeighted (bool gen_weighted);
-
-  TH1D* GetTotalSpectrum();
-  inline vector<TH1D*> GetSpectrum(){ return fSpectrum; };
-  void   AddAllFluxes      (void);
-
-private:
-
-  // private methods
-  void   Initialize        (void);
-  void   CleanUp           (void);
-  void   ResetSelection    (void);
-  int    SelectNeutrino    (double Ev);
-  double GeneratePhi       (void) const;
-  double GenerateRt        (void) const;
-
-  // private data members
-  double         fMaxEv;       ///< maximum energy
-  PDGCodeList *  fPdgCList;    ///< list of neutrino pdg-codes
-  int            fgPdgC;       ///< running generated nu pdg-code
-  TLorentzVector fgP4;         ///< running generated nu 4-momentum
-  TLorentzVector fgX4;         ///< running generated nu 4-position
-  vector<TH1D *> fSpectrum;    ///< flux = f(Ev), 1/neutrino species
-  TH1D *         fTotSpectrum; ///< combined flux = f(Ev)
-  TVector3 *     fDirVec;      ///< neutrino direction
-  TVector3 *     fBeamSpot;    ///< beam spot position
-  double         fRt;          ///< transverse size of neutrino beam
-  TF1 *          fRtDep;       ///< transverse radius dependence
-};
-
-} // flux namespace
-} // genie namespace
-
-#endif // _G_TH1_CYLICDRICAL_FLUX_H_
-#endif
diff --git a/src/FitBase/GNUISANCEMCJDriver.cxx b/src/FitBase/GNUISANCEMCJDriver.cxx
deleted file mode 100644
index faf3f88..0000000
--- a/src/FitBase/GNUISANCEMCJDriver.cxx
+++ /dev/null
@@ -1,1372 +0,0 @@
-#ifdef __GEVGEN_ENABLED__
-//____________________________________________________________________________
-/*
- Copyright (c) 2003-2016, GENIE Neutrino MC Generator Collaboration
- For the full text of the license visit http://copyright.genie-mc.org
- or see $GENIE/LICENSE
-
- Author: Costas Andreopoulos <costas.andreopoulos \at stfc.ac.uk>
-         University of Liverpool & STFC Rutherford Appleton Lab 
-
- For the class documentation see the corresponding header file.
-
- Important revisions after version 2.0.0 :
- @ Feb 08, 2008 - CA
-   Modified the global probability scale to be the maximum amongst the maximum
-   interaction probabilities for each neutrino (rather than the sum of maximum
-   probabilities). The modified probability scale still gives unbiased event
-   generation & reduces the 'no-interaction' probability.
- @ Feb 14, 2008 - CA
-   Significant speed improvements - Most of the rejected flux neutrinos, are
-   rejected before having them propagated through the detector geometry 
-   (flux neutrinos are pre-selected using the maximum path-lengths / for most
-   realistic fluxes -high energy tail, low energy peak- most of the selection
-   inefficiency is caused not because the path-lengths are not close the max
-   possible ones, but because the energy is not close to the max possible one).
-   Also some speed improvement was gained by properly using the total cross
-   section splines (before, han repeatedly summing-up the
-   The driver does not assert that _each_ flux neutrino generation & geometry
-   navigation will be succesfull - In the rare event that this may happen, it
-   prints an err mesg and tries again. In next revision I will limit the 
-   number of successive trials something may go wrong to prevent the driver
-   from hanging in truly problematic cases.
-   The driver was adapted to handle flux drivers that -at some point- may stop
-   generating more flux neutrinos (eg because they read flux neutrinos by 
-   looping over a beam simulation ntuple and they reached its last entry).
-   Code was appropriately restructured and some methods have been renamed.
- @ Feb 29, 2008 - CA
-   Modified the InteractionProbability() to calculate absolute interaction
-   probabilities. Added NFluxNeutrinos() and GlobProbScale() to get the
-   number of neutrinos thrown by the flux driver towards the geometry and
-   the global interaction probability scale so as to be able to calculate
-   event sample normalization factors.
- @ Jan 15, 2009 - CA
-   Stopped GMCJDriver from initializing the unphysical event mask so as not
-   to overwrite the values that each GEVGDriver obtains from the environment.
- @ Jan 16, 2009 - CA
-   Added methods to return pointers to the flux and geometry drivers.
- @ Mar 11, 2009 - CA
-   In GenerateEvent1Try() handle failure to generate kinematics. Added sanity
-   check on the no interaction probability.
- @ Mar 04, 2010 - CA
-   Remove unused FilterUnphysical(TBits) method. Now set exclusively via the
-   GUNPHYSMASK env.var.
- @ Apr 15, 2010 - CA
-   Fix unit error in ComputeEventProbability() - Reported by Corey Reed.
-   The probability stored at the output event was wrong but this doesn't
-   affect any of the existing applications as this number wasn't actually
-   used anywhere.
- @ Dec 07, 2010 - CA
-   Don't use a fixed bin size in ComputeProbScales() as this was causing 
-   errors for low energy applications. Addresses a problem reported by
-   Joachim Kopp.
- @ Feb 22, 2011 - JD
-   Added a number of new methods to allow pre-calculation of exact flux 
-   interaction probabilities for a given set of flux neutrinos from the 
-   flux driver. See the comments for the new LoadFluxProbabilities, 
-   SaveFluxProbabilities, PreCalcFluxProbabilities and PreSelectEvents 
-   methods for details. Using these methods mean that there is no need 
-   to generate maximum path lengths as instead use the exact interaction 
-   probabilities to pre-select. This can result in very significant speed 
-   increases (between factor of 5 and ~300) for event generation over complex
-   detector geometries and with realistic flux drivers. See 
-   src/support/t2k/EvGen/gT2KEvGen.cxx for an example of how to use.
- @ Mar, 7, 2011 - JD
-   Store sum totals of the flux interaction probabilities for various neutrino 
-   type in a map relating pdg code to total interaction probability. Also add
-   public getter method so that this can be used in applications to work out
-   expected event rates. See gT2KEvGen.cxx for an example of how to do this. 
-   Also save the PDG code for each entry in the flux interaction probabilities 
-   tree. 
- @ Mar, 11, 2011 - JD 
-   Set the directory of fFluxIntTree to the output file fFluxIntProbFile if
-   saving it later. This is so that it is incrementally saved and fixes bug
-   where getting std::bad_alloc when trying to Write large trees 
-   fFluxIntProbFile.   
- @ Jan 31, 2013 - CA
-   Added SetEventGeneratorList(string listname). $GEVGL var no longer in use.
- @ Feb 01, 2013 - CA
-   The GUNPHYSMASK env. var is no longer used. Added SetUnphysEventMask(const 
-   TBits &). Input is propagated accordingly.
- @ Feb 06, 2013 - CA
-   Fix small problem introduced with recent changes.
-   In PopulateEventGenDriverPool() calls to GEVGDriver::SetEventGeneratorList()
-   and GEVGDriver::Configure() were reversed. Problem reported by W.Huelsnitz.
- @ July 15, 2014 - HG
-   Incorporated code provided by Jason Koskinen - IceCube
-   Modified ComputeProbScales to evalulate the cross sections at both the high
-   and low edges of the energy bin when calculating the max interaction 
-   probability.
-*/
-//____________________________________________________________________________
-
-#include <cassert>
-
-#include <TVector3.h>
-#include <TSystem.h>
-#include <TStopwatch.h>
-
-#include "Algorithm/AlgConfigPool.h"
-#include "Conventions/GBuild.h"
-#include "Conventions/Constants.h"
-#include "Conventions/Units.h"
-#include "Conventions/Controls.h"
-#include "EVGCore/EventRecord.h"
-#include "EVGDrivers/GMCJDriver.h"
-#include "GNUISANCEMCJDriver.h"
-
-#include "EVGDrivers/GEVGDriver.h"
-#include "EVGDrivers/GEVGPool.h"
-#include "EVGDrivers/GFluxI.h"
-#include "EVGDrivers/GeomAnalyzerI.h"
-#include "GHEP/GHepFlags.h"
-#include "GHEP/GHepParticle.h"
-#include "Interaction/InitialState.h"
-#include "Messenger/Messenger.h"
-#include "Numerical/RandomGen.h"
-#include "Numerical/Spline.h"
-#include "PDG/PDGUtils.h"
-#include "Utils/PrintUtils.h"
-#include "Utils/XSecSplineList.h"
-#include "Conventions/Constants.h"
-
-using namespace genie;
-using namespace genie::constants;
-
-//____________________________________________________________________________
-GNUISANCEMCJDriver::GNUISANCEMCJDriver()
-{
-  this->InitJob();
-}
-//___________________________________________________________________________
-GNUISANCEMCJDriver::~GNUISANCEMCJDriver()
-{
-  if(fUnphysEventMask) delete fUnphysEventMask;
-  if (fGPool) delete fGPool;
-
-  map<int,TH1D*>::iterator pmax_iter = fPmax.begin();
-  for( ; pmax_iter != fPmax.end(); ++pmax_iter) {
-    TH1D * pmax = pmax_iter->second;
-    if(pmax) {
-      delete pmax; pmax = 0;
-    }
-  }
-  fPmax.clear();
-
-  if(fFluxIntTree) delete fFluxIntTree;
-  if(fFluxIntProbFile) delete fFluxIntProbFile;
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::SetEventGeneratorList(string listname)
-{
-  LOG("GNUISANCEMCJDriver", pNOTICE)
-       << "Setting event generator list: " << listname;
-
-  fEventGenList = listname;
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::SetUnphysEventMask(const TBits & mask)
-{
-  *fUnphysEventMask = mask;
-
-  LOG("GNUISANCEMCJDriver", pNOTICE)
-    << "Setting unphysical event mask (bits: " << GHepFlags::NFlags() - 1
-    << " -> 0) : " << *fUnphysEventMask;
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::UseFluxDriver(GFluxI * flux_driver)
-{
-  fFluxDriver = flux_driver;
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::UseGeomAnalyzer(GeomAnalyzerI * geom_analyzer)
-{
-  fGeomAnalyzer = geom_analyzer;
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::UseSplines(bool useLogE)
-{
-  fUseSplines = true;
-  fUseLogE    = useLogE;
-}
-//___________________________________________________________________________
-bool GNUISANCEMCJDriver::UseMaxPathLengths(string xml_filename)
-{
-// If you supply the maximum path lengths for all materials in your geometry
-// (eg for ROOT/GEANT geometries they can be computed running GENIE's gmxpl 
-// application, see $GENIE/src/stdapp/gMaxPathLengths.cxx ) you can speed up 
-// the driver init phase by quite a bit (especially for complex geometries).
-
-  fMaxPlXmlFilename = xml_filename;
-
-  bool is_accessible = !(gSystem->AccessPathName(fMaxPlXmlFilename.c_str()));
-
-  if ( is_accessible ) fUseExtMaxPl = true;
-  else {
-    fUseExtMaxPl = false;
-    LOG("GNUISANCEMCJDriver", pWARN)
-      << "UseMaxPathLengths could not find file: \"" << xml_filename << "\"";
-  }
-  return fUseExtMaxPl;
-
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::KeepOnThrowingFluxNeutrinos(bool keep_on)
-{
-  LOG("GNUISANCEMCJDriver", pNOTICE)
-        << "Keep on throwing flux neutrinos till one interacts? : "
-                             << utils::print::BoolAsYNString(keep_on);
-  fKeepThrowingFluxNu = keep_on;
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::ForceSingleProbScale()
-{
-// Use a single probability scale. That generates unweighted events.
-// (Note that generating unweighted event kinematics is a different thing)
-//
-  fGenerateUnweighted = true;
-
-  LOG("GNUISANCEMCJDriver", pNOTICE)
-    << "GNUISANCEMCJDriver will generate un-weighted events. "
-    << "Note: That does not force unweighted event kinematics!";
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::PreSelectEvents(bool preselect)
-{
-// Set whether to pre-select events based on a max-path lengths file. This
-// should be turned off if using pre-generated interaction probabilities 
-// calculated from a given flux file.
-  fPreSelect = preselect;
-}
-//___________________________________________________________________________
-bool GNUISANCEMCJDriver::PreCalcFluxProbabilities(void)
-{
-// Loop over complete set of flux entries satisfying input config options 
-// (such as neutrino type) and save the interaction probability in a tree 
-// relating flux index (entry number in input flux tree) to interaction 
-// probability. If a pre-generated flux interaction probability tree has 
-// already been loaded then just returns true. Also save tree to a TFile
-// for use in later jobs if flag is set 
-//
-  bool success = true;
- 
-  bool save_to_file = fFluxIntProbFile == 0 && fFluxIntFileName.size()>0;
-
-  // Clear map storing sum(fBrFluxWeight*fBrFluxIntProb) for each neutrino pdg
-  fSumFluxIntProbs.clear();
-
-  // check if already loaded flux interaction probs using LoadFluxProbTree
-  if(fFluxIntTree){
-    LOG("GNUISANCEMCJDriver", pNOTICE) << 
-         "Skipping pre-generation of flux interaction probabilities - "<<
-         "using pre-generated file";
-    success = true;
-  }
-  // otherwise create them on the fly now 
-  else {
-
-    if(save_to_file){
-      fFluxIntProbFile = new TFile(fFluxIntFileName.c_str(), "CREATE");
-      if(fFluxIntProbFile->IsZombie()){
-        LOG("GNUISANCEMCJDriver", pFATAL) << "Cannot overwrite an existing file. Exiting!";
-        exit(1);
-      } 
-    } 
-  
-    // Create the tree to store flux probs
-    fFluxIntTree = new TTree(fFluxIntTreeName.c_str(), 
-                         "Tree storing pre-calculated flux interaction probs"); 
-    fFluxIntTree->Branch("FluxIndex", &fBrFluxIndex, "FluxIndex/I");
-    fFluxIntTree->Branch("FluxIntProb", &fBrFluxIntProb, "FluxIntProb/D");
-    fFluxIntTree->Branch("FluxEnu", &fBrFluxEnu, "FluxEnu/D"); 
-    fFluxIntTree->Branch("FluxWeight", &fBrFluxWeight, "FluxWeight/D"); 
-    fFluxIntTree->Branch("FluxPDG", &fBrFluxPDG, "FluxPDG/I"); 
-    // Associate to file otherwise get std::bad_alloc when writing large trees 
-    if(save_to_file) fFluxIntTree->SetDirectory(fFluxIntProbFile); 
- 
-    fFluxDriver->GenerateWeighted(true);
-  
-    fGlobPmax = 1.0; // Force ComputeInteractionProbabilities to return absolute value
-  
-    // Loop over flux entries and calculate interaction probabilities
-    TStopwatch stopwatch; 
-    stopwatch.Start();
-    long int first_index = -1;
-    bool first_loop = true;
-    // loop until at end of flux ntuple
-    while(fFluxDriver->End() == false){ 
-
-      // get the next flux neutrino
-      bool gotnext = fFluxDriver->GenerateNext(); 
-      if(!gotnext){
-        LOG("GNUISANCEMCJDriver", pWARN) << "*** Couldn't generate next flux ray! ";
-        continue;
-      }
-
-      // stop if completed a full cycle (this check is necessary as fluxdriver
-      // may be set to loop over more than one cycle before reaching end) 
-      bool already_been_here = first_loop ? false : first_index == fFluxDriver->Index();
-      if(already_been_here) break; 
-   
-      // compute the path lengths for current flux neutrino 
-      if(this->ComputePathLengths() == false){ success = false; break;}
-  
-      // compute and store the interaction probability 
-      double psum = this->ComputeInteractionProbabilities(false /*Based on actual PLs*/);
-      assert(psum+controls::kASmallNum > 0.);
-      fBrFluxIntProb = psum;
-      fBrFluxIndex   = fFluxDriver->Index();
-      fBrFluxEnu     = fFluxDriver->Momentum().E();
-      fBrFluxWeight  = fFluxDriver->Weight();
-      fBrFluxPDG     = fFluxDriver->PdgCode();
-      fFluxIntTree->Fill();
-
-      // store the first index so know when have cycled exactly once
-      if(first_loop){
-        first_index = fFluxDriver->Index();
-        first_loop = false;
-      }
-    } // flux loop
-    stopwatch.Stop();            
-    LOG("GNUISANCEMCJDriver", pNOTICE)
-                    << "Finished pre-calculating flux interaction probabilities. "
-                    << "Total CPU time to process "<< fFluxIntTree->GetEntries()
-                    << " entries: "<< stopwatch.CpuTime();
-
-    // reset the flux driver so can be used at next stage. N.B. This 
-    // should also reset flux driver to throw de-weighted flux neutrinos
-    fFluxDriver->Clear("CycleHistory");
-  }
-
-  // If successfully calculated/loaded interaction probabilities then set global
-  // probability scale and, if requested, save tree to output file
-  if(success){
-    fGlobPmax = 0.0;
-    double safety_factor = 1.01;
-    for(int i = 0; i< fFluxIntTree->GetEntries(); i++){
-      fFluxIntTree->GetEntry(i);
-      // Check have non-negative probabilities
-      assert(fBrFluxIntProb+controls::kASmallNum > 0.0);
-      assert(fBrFluxWeight+controls::kASmallNum > 0.0);
-      // Update the global maximum
-      fGlobPmax = TMath::Max(fGlobPmax, fBrFluxIntProb*safety_factor); 
-      // Update the sum of fBrFluxIntProb*fBrFluxWeight for different species
-      if(fSumFluxIntProbs.find(fBrFluxPDG) == fSumFluxIntProbs.end()){
-        fSumFluxIntProbs[fBrFluxPDG] = 0.0;
-      }
-      fSumFluxIntProbs[fBrFluxPDG] += fBrFluxIntProb * fBrFluxWeight;
-    }
-    LOG("GNUISANCEMCJDriver", pNOTICE) <<
-        "Updated global probability scale to fGlobPmax = "<< fGlobPmax; 
-
-    if(save_to_file){
-      LOG("GNUISANCEMCJDriver", pNOTICE) <<
-          "Saving pre-generated interaction probabilities to file: "<<
-          fFluxIntProbFile->GetName();
-      fFluxIntProbFile->cd();
-      fFluxIntTree->Write();
-    }
-
-    // Also build index for use later
-    if(fFluxIntTree->BuildIndex("FluxIndex") != fFluxIntTree->GetEntries()){
-      LOG("GNUISANCEMCJDriver", pFATAL) << 
-          "Cannot build index using branch \"FluxIndex\" for flux prob tree!"; 
-      exit(1);
-    } 
- 
-    // Now that have pre-generated flux probabilities need to trun off event 
-    // preselection as this is only advantages when using max path lengths
-    this->PreSelectEvents(false);
-
-    LOG("GNUISANCEMCJDriver", pNOTICE) << "Successfully generated/loaded pre-calculate flux interaction probabilities";
-  }
-  // Otherwise clean up
-  else if(fFluxIntTree){ 
-    delete fFluxIntTree; 
-    fFluxIntTree = 0;
-  }
-  
-  // Return whether have successfully pre-calculated flux interaction probabilities
-  return success;
-}
-//___________________________________________________________________________
-bool GNUISANCEMCJDriver::LoadFluxProbabilities(string filename)
-{
-// Load a pre-generated set of flux interaction probabilities from an external
-// file. This is recommended when using large flux files (>100k entries) as  
-// for these the time to calculate the interaction probabilities can exceed 
-// ~20 minutes. After loading the input tree we call PreCalcFluxProbabilities
-// to check that has successfully loaded
-//
-  if(fFluxIntProbFile){
-    LOG("GNUISANCEMCJDriver", pWARN) 
-     << "Can't load flux interaction prob file as one is already loaded"; 
-    return false;
-  }
-
-  fFluxIntProbFile = new TFile(filename.c_str(), "OPEN");
-
-  if(fFluxIntProbFile){
-    fFluxIntTree = dynamic_cast<TTree*>(fFluxIntProbFile->Get(fFluxIntTreeName.c_str())); 
-    if(fFluxIntTree){
-      bool set_addresses = 
-        fFluxIntTree->SetBranchAddress("FluxIntProb", &fBrFluxIntProb) >= 0 &&
-        fFluxIntTree->SetBranchAddress("FluxIndex", &fBrFluxIndex) >= 0 &&
-        fFluxIntTree->SetBranchAddress("FluxPDG", &fBrFluxPDG) >= 0 &&
-        fFluxIntTree->SetBranchAddress("FluxWeight", &fBrFluxWeight) >= 0 &&
-        fFluxIntTree->SetBranchAddress("FluxEnu", &fBrFluxEnu) >= 0; 
-      if(set_addresses){ 
-        // Finally check that can use them
-        if(this->PreCalcFluxProbabilities()) {
-          LOG("GNUISANCEMCJDriver", pNOTICE) 
-           << "Successfully loaded pre-generated flux interaction probabilities";
-          return true;
-        }
-      }
-      // If cannot load then delete tree 
-      LOG("GNUISANCEMCJDriver", pERROR) << 
-          "Cannot find expected branches in input flux probability tree!"; 
-      delete fFluxIntTree; fFluxIntTree = 0; 
-    }
-    else LOG("GNUISANCEMCJDriver", pERROR) 
-          << "Cannot find tree: "<< fFluxIntTreeName.c_str();
-  }
-     
-  LOG("GNUISANCEMCJDriver", pWARN)
-     << "Unable to load flux interaction probabilities file";
-  return false;
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::SaveFluxProbabilities(string outfilename)
-{
-// Configue the flux driver to save the calculated flux interaction
-// probabilities to the specified output file name for use in later jobs. See
-// the LoadFluxProbTree method for how they are fed into a later job. 
-//
-  fFluxIntFileName = outfilename;
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::Configure(bool calc_prob_scales)
-{
-  LOG("GNUISANCEMCJDriver", pNOTICE)
-     << utils::print::PrintFramedMesg("Configuring GNUISANCEMCJDriver");
-
-  // Get the list of neutrino types from the input flux driver and the list
-  // of target materials from the input geometry driver
-  this->GetParticleLists();
-
-  // Ask the input GFluxI for the max. neutrino energy (to compute Pmax)
-  this->GetMaxFluxEnergy();
-
-  // Create all possible initial states and for each one initialize, 
-  // configure & store an GEVGDriver event generation driver object.
-  // Once an 'initial state' has been selected from the input flux / geom,
-  // the responsibility for generating the neutrino interaction will be
-  // delegated to one of these drivers.
-  this->PopulateEventGenDriverPool();
-
-  // If the user wants to use cross section splines in order to speed things
-  // up, then coordinate spline creation from all GEVGDriver objects pushed 
-  // into GEVGPool. This will create all xsec splines needed for all (enabled)
-  // processes that can be simulated involving the particles in the input flux 
-  // and geometry. 
-  // Spline creation will be skipped for every spline that has been pre-loaded 
-  // into the the XSecSplineList.
-  // Once more it is noted that computing cross section splines is a huge 
-  // overhead. The user is encouraged to generate them in advance and load
-  // them into the XSecSplineList
-  this->BootstrapXSecSplines();
-
-  // Create cross section splines describing the total interaction xsec
-  // for a given initial state (Create them by summing all xsec splines
-  // for each possible initial state)
-  this->BootstrapXSecSplineSummation();
-
-  if(calc_prob_scales){
-    // Ask the input geometry driver to compute the max. path length for each
-    // material in the list of target materials (or load a precomputed list)
-    this->GetMaxPathLengthList();
-
-    // Compute the max. interaction probability to scale all interaction
-    // probabilities to be computed by this driver
-    this->ComputeProbScales();
-  }
-  LOG("GNUISANCEMCJDriver", pNOTICE) << "Finished configuring GNUISANCEMCJDriver\n\n";
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::InitJob(void)
-{
-  fEventGenList       = "Default";  // <-- set of event generators to be loaded by this driver
-
-  fUnphysEventMask = new TBits(GHepFlags::NFlags()); //<-- unphysical event mask
-  //fUnphysEventMask->ResetAllBits(true);
-  for(unsigned int i = 0; i < GHepFlags::NFlags(); i++) {
-   fUnphysEventMask->SetBitNumber(i, true);
-  }
-
-  fFluxDriver         = 0;     // <-- flux driver
-  fGeomAnalyzer       = 0;     // <-- geometry driver
-  fGPool              = 0;     // <-- pool of GEVGDriver event generation drivers
-  fEmax               = 0;     // <-- maximum neutrino energy
-  fMaxPlXmlFilename   = "";    // <-- XML file with external path lengths
-  fUseExtMaxPl        = false;
-  fUseSplines         = false;
-  fNFluxNeutrinos     = 0;     // <-- number of flux neutrinos thrown so far
-
-  fGlobPmax           = 0;     // <-- maximum interaction probability (global prob scale)
-  fPmax.clear();               // <-- maximum interaction probability per neutrino & per energy bin
-
-  fGenerateUnweighted = false; // <-- default opt to generate weighted events
-  fPreSelect          = true;  // <-- default to use pre-selection based on maximum path lengths 
-
-  fSelTgtPdg          = 0;
-  fCurEvt             = 0;
-  fCurVtx.SetXYZT(0.,0.,0.,0.);
-
-  fFluxIntProbFile    = 0; 
-  fFluxIntTreeName    = "gFlxIntProb";
-  fFluxIntFileName    = "";
-  fFluxIntTree        = 0;
-  fBrFluxIntProb      = -1.;
-  fBrFluxIndex        = -1;
-  fBrFluxEnu          = -1.;       
-  fBrFluxWeight       = -1.;
-  fBrFluxPDG          = 0;
-  fSumFluxIntProbs.clear();
-
-  // Throw as many flux neutrinos as necessary till one has interacted
-  // so that GenerateEvent() never  returns NULL (except when in error)
-  this->KeepOnThrowingFluxNeutrinos(true);
-
-  // Allow the selected GEVGDriver to go into recursive mode and regenerate
-  // an interaction that turns out to be unphysical.
-  //TBits unphysmask(GHepFlags::NFlags());
-  //unphysmask.ResetAllBits(false); 
-  //this->FilterUnphysical(unphysmask);
-
-  // Force early initialization of singleton objects that are typically
-  // would be initialized at their first use later on.
-  // This is purely cosmetic and I do it to send the banner and some prolific
-  // initialization printout at the top.
-  assert( Messenger::Instance()     );
-  assert( AlgConfigPool::Instance() );
-
-  // Autoload splines (from the XML file pointed at the $GSPLOAD env. var.,
-  // if the env. var. has been set);
-  XSecSplineList * xspl = XSecSplineList::Instance();
-  xspl->AutoLoad();
-
-  // Clear the target and neutrino lists
-  fNuList.clear();
-  fTgtList.clear();
-
-  // Clear the maximum path length list
-  fMaxPathLengths.clear();
-  fCurPathLengths.clear();
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::GetParticleLists(void)
-{
-  // Get the list of flux neutrinos from the flux driver
-  LOG("GNUISANCEMCJDriver", pNOTICE)
-                    << "Asking the flux driver for its list of neutrinos";
-  fNuList = fFluxDriver->FluxParticles();
-
-  LOG("GNUISANCEMCJDriver", pNOTICE) << "Flux particles: " << fNuList;
-
-  // Get the list of target materials from the geometry driver
-  LOG("GNUISANCEMCJDriver", pNOTICE)
-                  << "Asking the geometry driver for its list of targets";
-  fTgtList = fGeomAnalyzer->ListOfTargetNuclei();
-
-  LOG("GNUISANCEMCJDriver", pNOTICE) << "Target materials: " << fTgtList;
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::GetMaxPathLengthList(void)
-{
-  if(fUseExtMaxPl) {
-     LOG("GNUISANCEMCJDriver", pNOTICE)
-       << "Loading external max path-length list for input geometry from "
-       << fMaxPlXmlFilename;
-     fMaxPathLengths.LoadFromXml(fMaxPlXmlFilename);
-
-  } else {
-     LOG("GNUISANCEMCJDriver", pNOTICE)
-       << "Querying the geometry driver to compute the max path-length list";
-     fMaxPathLengths = fGeomAnalyzer->ComputeMaxPathLengths();
-  }
-  // Print maximum path lengths & neutrino energy
-  LOG("GNUISANCEMCJDriver", pNOTICE)
-     << "Maximum path length list: " << fMaxPathLengths;
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::GetMaxFluxEnergy(void)
-{
-  LOG("GNUISANCEMCJDriver", pNOTICE)
-     << "Querying the flux driver for the maximum energy of flux neutrinos";
-  fEmax = fFluxDriver->MaxEnergy();
-
-  LOG("GNUISANCEMCJDriver", pNOTICE) 
-     << "Maximum flux neutrino energy = " << fEmax << " GeV";
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::PopulateEventGenDriverPool(void)
-{
-  LOG("GNUISANCEMCJDriver", pDEBUG)
-       << "Creating GEVGPool & adding a GEVGDriver object per init-state";
-
-  if (fGPool) delete fGPool;
-  fGPool = new GEVGPool;
-
-  PDGCodeList::const_iterator nuiter;
-  PDGCodeList::const_iterator tgtiter;
-
-  for(nuiter = fNuList.begin(); nuiter != fNuList.end(); ++nuiter) {
-   for(tgtiter = fTgtList.begin(); tgtiter != fTgtList.end(); ++tgtiter) {
-
-     int target_pdgc   = *tgtiter;
-     int neutrino_pdgc = *nuiter;
-
-     InitialState init_state(target_pdgc, neutrino_pdgc);
-
-     LOG("GNUISANCEMCJDriver", pNOTICE)
-       << "\n\n ---- Creating a GEVGDriver object configured for init-state: "
-       << init_state.AsString() << " ----\n\n";
-
-     GEVGDriver * evgdriver = new GEVGDriver;
-     evgdriver->SetEventGeneratorList(fEventGenList); // specify list of generators
-     evgdriver->Configure(init_state);
-     evgdriver->UseSplines(); // check if all splines needed are loaded
-
-     LOG("GNUISANCEMCJDriver", pDEBUG) << "Adding new GEVGDriver object to GEVGPool";
-     fGPool->insert( GEVGPool::value_type(init_state.AsString(), evgdriver) );
-   } // targets
-  } // neutrinos
-
-  LOG("GNUISANCEMCJDriver", pNOTICE)
-             << "All necessary GEVGDriver object were pushed into GEVGPool\n";
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::BootstrapXSecSplines(void)
-{
-// Bootstrap cross section spline generation by the event generation drivers
-// that handle each initial state.
-
-  if(!fUseSplines) return;
-
-  LOG("GNUISANCEMCJDriver", pNOTICE) 
-    << "Asking event generation drivers to compute all needed xsec splines";
-
-  PDGCodeList::const_iterator nuiter;
-  PDGCodeList::const_iterator tgtiter;
-  for(nuiter = fNuList.begin(); nuiter != fNuList.end(); ++nuiter){
-     for(tgtiter = fTgtList.begin(); tgtiter != fTgtList.end(); ++tgtiter) {
-       int target_pdgc   = *tgtiter;
-       int neutrino_pdgc = *nuiter;
-       InitialState init_state(target_pdgc, neutrino_pdgc);
-       LOG("GNUISANCEMCJDriver", pINFO)
-           << "Computing all splines needed for init-state: "
-           << init_state.AsString();
-       GEVGDriver * evgdriver = fGPool->FindDriver(init_state);
-       evgdriver->CreateSplines(-1,-1,fUseLogE);
-     } // targets
-  } // neutrinos
-  LOG("GNUISANCEMCJDriver", pINFO) << "Finished creating cross section splines\n";
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::BootstrapXSecSplineSummation(void)
-{
-// Sum-up the cross section splines for all the interaction that can be
-// simulated for each initial state
-
-  LOG("GNUISANCEMCJDriver", pNOTICE)
-    << "Summing-up splines to get total cross section for each init state";
-
-  GEVGPool::iterator diter;
-  for(diter = fGPool->begin(); diter != fGPool->end(); ++diter) {
-    string       init_state = diter->first;
-    GEVGDriver * evgdriver  = diter->second;
-    assert(evgdriver);
-    LOG("GNUISANCEMCJDriver", pNOTICE)
-             << "**** Summing xsec splines for init-state = " << init_state;
-
-    Range1D_t rE = evgdriver->ValidEnergyRange();
-    if (fEmax>rE.max || fEmax<rE.min)
-      LOG("GNUISANCEMCJDriver",pFATAL)
-        << " rE (validEnergyRange) [" << rE.min << "," << rE.max << "] "
-        << " fEmax " << fEmax;
-    assert(fEmax<rE.max && fEmax>rE.min);
-
-    // decide the energy range for the sum spline - extend the spline a little
-    // bit above the maximum beam energy (but below the maximum valid energy)
-    // to avoid the evaluation of the cubic spline around the viscinity of
-    // knots with zero y values (although the GENIE Spline object handles it)
-    double dE  = fEmax/10.;
-    double min = rE.min;
-    double max = (fEmax+dE < rE.max) ? fEmax+dE : rE.max;
-    evgdriver->CreateXSecSumSpline(100,min,max,true);
-  }
-  LOG("GNUISANCEMCJDriver", pNOTICE)
-     << "Finished summing all interaction xsec splines per initial state";
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::ComputeProbScales(void)
-{
-// Computing interaction probability scales.
-// To minimize the numbers or trials before choosing a neutrino+target init
-// state for generating an event (note: each trial means selecting a flux 
-// neutrino, navigating it through the detector to compute path lengths, 
-// computing  interaction probabilities for each material and so on...) 
-// a set of probability scales can be used for different neutrino species 
-// and at different energy bins. 
-// A global probability scale is also being constructed for keeping the correct 
-// proportions between differect flux neutrino species or flux neutrinos of 
-// different energies.
-
-  LOG("GNUISANCEMCJDriver", pNOTICE)
-    << "Computing the max. interaction probability (probability scale)";
-
-  // clean up global probability scale and maximum probabilties per neutrino
-  // type & energy bin
-  {
-    fGlobPmax = 0;
-    map<int,TH1D*>::iterator pmax_iter = fPmax.begin();
-    for( ; pmax_iter != fPmax.end(); ++pmax_iter) {
-      TH1D * pmax = pmax_iter->second;
-      if(pmax) {
-        delete pmax; pmax = 0;    
-      }
-    }
-    fPmax.clear();
-  }
-
-  // for maximum interaction probability vs E /for given geometry/ I will
-  // be using 300 bins up to the maximum energy for the input flux
-  // double de   = fEmax/300.;//djk june 5, 2013
-  double de   = fEmax/300.;//djk june 5, 2013
-  double emin = 0.0;
-  double emax = fEmax + de;
-  int n = 1 + (int) ((emax-emin)/de);
-
-  PDGCodeList::const_iterator nuiter;
-  PDGCodeList::const_iterator tgtiter;
-
-  // loop over all neutrino types generated by the flux driver
-  for(nuiter = fNuList.begin(); nuiter != fNuList.end(); ++nuiter) {
-    int neutrino_pdgc = *nuiter;
-    TH1D * pmax_hst = new TH1D("pmax_hst",
-             "max interaction probability vs E | geom",n,emin,emax);
-    pmax_hst->SetDirectory(0);
-
-    // loop over energy bins
-    for(int ie = 1; ie <= pmax_hst->GetNbinsX(); ie++) {
-      double EvLow  = pmax_hst->GetBinCenter(ie) - 0.5*pmax_hst->GetBinWidth(ie); 
-      double EvHigh = pmax_hst->GetBinCenter(ie) + 0.5*pmax_hst->GetBinWidth(ie); 
-      //double Ev = pmax_hst->GetBinCenter(ie);
-
-       // loop over targets in input geometry, form initial state and compute
-       // the sum of maximum interaction probabilities at the current energy bin
-       //
-       for(tgtiter = fTgtList.begin(); tgtiter != fTgtList.end(); ++tgtiter) {
-         int target_pdgc = *tgtiter;
-
-         InitialState init_state(target_pdgc, neutrino_pdgc);
-
-         LOG("GNUISANCEMCJDriver", pDEBUG)
-           << "Computing Pmax for init-state: " << init_state.AsString() << " E from " << EvLow << "-" << EvHigh;
-
-         // get the appropriate driver
-         GEVGDriver * evgdriver = fGPool->FindDriver(init_state);
-
-         // get xsec sum over all modelled processes for given neutrino+target)
-         double sxsecLow  = evgdriver->XSecSumSpline()->Evaluate(EvLow);
-	 double sxsecHigh = evgdriver->XSecSumSpline()->Evaluate(EvHigh);
-
-         // get max{path-length x density}
-         double plmax = fMaxPathLengths.PathLength(target_pdgc);
-
-         // compute/store the max interaction probabiity (for given energy)
-         int A = pdg::IonPdgCodeToA(target_pdgc);
-         double pmaxLow  = this->InteractionProbability(sxsecLow, plmax, A);
-         double pmaxHigh = this->InteractionProbability(sxsecHigh, plmax, A);
-
-	 double pmax = pmaxHigh;
-	 if ( pmaxLow > pmaxHigh){
-	   pmax = pmaxLow;
-	   LOG("GNUISANCEMCJDriver", pWARN)
-	     << "Lower energy neutrinos have a higher probability of interacting than those at higher energy."
-	     << " pmaxLow(E=" << EvLow << ")=" << pmaxLow << " and " << " pmaxHigh(E=" << EvHigh << ")=" << pmaxHigh;
-	 }
-
-         pmax_hst->SetBinContent(ie, pmax_hst->GetBinContent(ie) + pmax);
-
-         LOG("GNUISANCEMCJDriver", pDEBUG)
-           << "Pmax[" << init_state.AsString() << ", Ev from " << EvLow << "-" << EvHigh << "] = " << pmax;
-       } // targets
-
-       pmax_hst->SetBinContent(ie, 1.2 * pmax_hst->GetBinContent(ie));
-
-       LOG("GNUISANCEMCJDriver", pINFO)
-	 << "Pmax[nu=" << neutrino_pdgc << ", Ev from " << EvLow << "-" << EvHigh << "] = "
-          <<  pmax_hst->GetBinContent(ie);
-    } // E
-
-    fPmax.insert(map<int,TH1D*>::value_type(neutrino_pdgc,pmax_hst));
-  } // nu
-
-  // Compute global probability scale
-  // Sum Probabilities {
-  //   all neutrinos, all targets, @  max path length, @ max energy}
-  //
-  {
-    for(nuiter = fNuList.begin(); nuiter != fNuList.end(); ++nuiter) {
-      int neutrino_pdgc = *nuiter;
-      map<int,TH1D*>::const_iterator pmax_iter = fPmax.find(neutrino_pdgc);
-      assert(pmax_iter != fPmax.end());
-      TH1D * pmax_hst = pmax_iter->second;
-      assert(pmax_hst);
-//    double pmax = pmax_hst->GetBinContent(pmax_hst->FindBin(fEmax));
-      double pmax = pmax_hst->GetMaximum();
-      assert(pmax>0);        
-//    fGlobPmax += pmax;
-      fGlobPmax = TMath::Max(pmax, fGlobPmax); // ?;
-    }
-    LOG("GNUISANCEMCJDriver", pNOTICE) << "*** Probability scale = " << fGlobPmax;
-  }
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::InitEventGeneration(void)
-{
-  fCurPathLengths.clear();
-  fCurEvt    = 0;
-  fSelTgtPdg = 0;
-  fCurVtx.SetXYZT(0.,0.,0.,0.);
-}
-//___________________________________________________________________________
-EventRecord * GNUISANCEMCJDriver::GenerateEvent(void)
-{
-  LOG("GNUISANCEMCJDriver", pNOTICE) << "Generating next event...";
-
-  this->InitEventGeneration();
-
-  while(1) {
-    bool flux_end = fFluxDriver->End();
-    if(flux_end) {
-       LOG("GNUISANCEMCJDriver", pNOTICE) 
-           << "No more neutrinos can be thrown by the flux driver";
-       return 0;
-    }
-
-    EventRecord * event = this->GenerateEvent1Try();
-    if(event) return event;
-
-    if(fKeepThrowingFluxNu) {
-         LOG("GNUISANCEMCJDriver", pNOTICE)
-             << "Flux neutrino didn't interact - Trying the next one...";
-         continue;
-    }
-    break;
-  } // (w(1)
-
-  LOG("GNUISANCEMCJDriver", pINFO) << "Returning NULL event!";
-  return 0;
-}
-//___________________________________________________________________________
-EventRecord * GNUISANCEMCJDriver::GenerateEvent1Try(void)
-{
-// attempt generating a neutrino interaction by firing a single flux neutrino
-//
-  RandomGen * rnd = RandomGen::Instance();
-
-  double Pno=0, Psum=0;
-  double R = rnd->RndEvg().Rndm();
-  LOG("GNUISANCEMCJDriver", pDEBUG) << "Rndm [0,1] = " << R;
-
-  // Generate a neutrino using the input GFluxI & get current pdgc/p4/x4
-  bool flux_ok = this->GenerateFluxNeutrino();
-  if(!flux_ok) {
-     LOG("GNUISANCEMCJDriver", pERROR) 
-        << "** Rejecting current flux neutrino (flux driver err)";
-     return 0;
-  }
-
-  // Compute the interaction probabilities assuming max. path lengths
-  // and decide whether the neutrino would interact -- 
-  // Many flux neutrinos should be rejected here, drastically reducing 
-  // the number of neutrinos that I need to propagate through the 
-  // actual detector geometry (this is skipped when using 
-  // pre-calculated flux interaction probabilities)
-  if(fPreSelect) {
-       LOG("GNUISANCEMCJDriver", pNOTICE) 
-          << "Computing interaction probabilities for max. path lengths";
-
-       Psum = this->ComputeInteractionProbabilities(true /* <- max PL*/);
-       Pno  = 1-Psum;
-       LOG("GNUISANCEMCJDriver", pNOTICE)
-          << "The no-interaction probability (max. path lengths) is: " 
-          << 100*Pno << " %";
-       if(Pno<0.) {
-           LOG("GNUISANCEMCJDriver", pFATAL) 
-             << "Negative no-interaction probability! (P = " << 100*Pno << " %)"
-             << " Particle E=" << fFluxDriver->Momentum().E() << " type=" << fFluxDriver->PdgCode() << "Psum=" << Psum;
-           gAbortingInErr=true;
-           exit(1);
-       }
-       if(R>=1-Pno) {
-  	   LOG("GNUISANCEMCJDriver", pNOTICE)  
-              << "** Rejecting current flux neutrino";
-	   return 0;
-       }
-  } // preselect 
-
-  bool pl_ok = false;
-
-
-  // If possible use pre-generated flux neutrino interaction probabilities 
-  if(fFluxIntTree){
-    Psum = this->PreGenFluxInteractionProbability(); 
-  }         
-  // Else compute them in the usual manner
-  else {
-    // Compute (pathLength x density x weight fraction) for all materials
-    // in the input geometry, for the neutrino generated by the flux driver
-    pl_ok = this->ComputePathLengths();
-    if(!pl_ok) {
-       LOG("GNUISANCEMCJDriver", pERROR) 
-          << "** Rejecting current flux neutrino (err computing path-lengths)";
-       return 0;
-    }
-    if(fCurPathLengths.AreAllZero()) {
-       LOG("GNUISANCEMCJDriver", pNOTICE) 
-          << "** Rejecting current flux neutrino (misses generation volume)";
-       return 0;
-    }
-    Psum = this->ComputeInteractionProbabilities(false /* <- actual PL */);
-  }
-
-
-  if(TMath::Abs(Psum) < controls::kASmallNum){
-    LOG("GNUISANCEMCJDriver", pNOTICE)
-       << "** Rejecting current flux neutrino (has null interaction probability)";
-    return 0;
-  } 
-
-  // Now decide whether the current neutrino interacts
-  Pno  = 1-Psum;
-  LOG("GNUISANCEMCJDriver", pNOTICE)
-     << "The actual 'no interaction' probability is: " << 100*Pno << " %";
-  if(Pno<0.) {
-      LOG("GNUISANCEMCJDriver", pFATAL) 
-         << "Negative no interactin probability! (P = " << 100*Pno << " %)";
-
-      // print info about what caused the problem
-      int                    nupdg = fFluxDriver -> PdgCode  ();
-      const TLorentzVector & nup4  = fFluxDriver -> Momentum ();
-      const TLorentzVector & nux4  = fFluxDriver -> Position ();
-
-      LOG("GNUISANCEMCJDriver", pWARN)
-        << "\n [-] Problematic neutrino: "
-        << "\n  |----o PDG-code   : " << nupdg
-        << "\n  |----o 4-momentum : " << utils::print::P4AsString(&nup4)
-        << "\n  |----o 4-position : " << utils::print::X4AsString(&nux4)
-        << "\n Emax : " << fEmax;
-
-      LOG("GNUISANCEMCJDriver", pWARN)
-        << "\n Problematic path lengths:" << fCurPathLengths;
-
-      LOG("GNUISANCEMCJDriver", pWARN)
-        << "\n Maximum path lengths:" << fMaxPathLengths;
-
-      exit(1);
-  }
-  if(R>=1-Pno) {
-     LOG("GNUISANCEMCJDriver", pNOTICE) 
-        << "** Rejecting current flux neutrino";
-     return 0;
-  }
-
-  //
-  // The flux neutrino interacts! 
-  //
-
-  // Calculate path lengths for first time and check potential mismatch if 
-  // used pre-generated flux interaction probabilities
-  if(fFluxIntTree){
-    pl_ok = this->ComputePathLengths(); 
-    if(!pl_ok) { 
-      LOG("GNUISANCEMCJDriver", pFATAL) << "** Cannot calculate path lenths!"; 
-      exit(1); 
-    }  
-    double Psum_curr = this->ComputeInteractionProbabilities(false /* <- actual PL */);
-    bool mismatch = TMath::Abs(Psum-Psum_curr) > controls::kASmallNum;    
-    if(mismatch){
-      LOG("GNUISANCEMCJDriver", pFATAL) << 
-          "** Mismatch between pre-calculated and current interaction "<<
-          "probabilities!";
-      exit(1);
-    }
-  }
-
-  // Select a target material
-  fSelTgtPdg = this->SelectTargetMaterial(R);
-  if(fSelTgtPdg==0) {
-     LOG("GNUISANCEMCJDriver", pERROR) 
-        << "** Rejecting current flux neutrino (failed to select tgt!)";
-     return 0;
-  }
-
-  // Ask the GEVGDriver object to select and generate an interaction and
-  // its kinematics for the selected initial state & neutrino 4-momentum
-  this->GenerateEventKinematics();
-  if(!fCurEvt) {
-     LOG("GNUISANCEMCJDriver", pWARN) 
-        << "** Couldn't generate kinematics for selected interaction";
-     return 0;
-  }
-
-  // Generate an 'interaction position' in the selected material (in the
-  // detector coord system), along the direction of nup4 & set it 
-  this->GenerateVertexPosition();
-
-  // Set the event probability (probability for this event to happen given
-  // the detector setup & the selected flux neutrino)
-  // Note for users: 
-  // The above probability is stored at GHepRecord::Probability()
-  // For normalization purposes make sure that you take into account the
-  // GHepRecord::Weight() -if event generation is weighted-, and
-  // GFluxI::Weight() -if beam simulation is weighted-.
-  this->ComputeEventProbability();
-
-  return fCurEvt;
-}
-//___________________________________________________________________________
-bool GNUISANCEMCJDriver::GenerateFluxNeutrino(void)
-{
-// Ask the neutrino flux driver to generate a flux neutrino and make sure
-// that things look ok...
-//
-  LOG("GNUISANCEMCJDriver", pNOTICE) << "Generating a flux neutrino";
-
-  bool ok = fFluxDriver->GenerateNext();
-  if(!ok) {
-     LOG("GNUISANCEMCJDriver", pERROR)
-         << "*** The flux driver couldn't generate a flux neutrino!!";
-     return false;
-  }
-
-  fNFluxNeutrinos++;
-  int                    nupdg = fFluxDriver -> PdgCode  ();
-  const TLorentzVector & nup4  = fFluxDriver -> Momentum ();
-  const TLorentzVector & nux4  = fFluxDriver -> Position ();
-
-  LOG("GNUISANCEMCJDriver", pNOTICE)
-     << "\n [-] Generated flux neutrino: "
-     << "\n  |----o PDG-code   : " << nupdg
-     << "\n  |----o 4-momentum : " << utils::print::P4AsString(&nup4)
-     << "\n  |----o 4-position : " << utils::print::X4AsString(&nux4);
-
-  if(nup4.Energy() > fEmax) {
-     LOG("GNUISANCEMCJDriver", pFATAL)
-       << "\n *** Flux driver error ***"
-       << "\n Generated flux v with E = " << nup4.Energy() << " GeV"
-       << "\n Max v energy (declared by flux driver) = " << fEmax << " GeV"
-       << "\n My interaction probability scaling is invalidated!!";
-     return false;
-  }
-  if(!fNuList.ExistsInPDGCodeList(nupdg)) {
-     LOG("GNUISANCEMCJDriver", pFATAL)
-       << "\n *** Flux driver error ***"
-       << "\n Generated flux v with pdg = " << nupdg
-       << "\n It does not belong to the declared list of flux neutrinos"
-       << "\n I was not configured to handle this!!";
-     return false;
-  }
-  return true;
-}
-//___________________________________________________________________________
-bool GNUISANCEMCJDriver::ComputePathLengths(void)
-{
-// Ask the geometry driver to compute (pathLength x density x weight frac.)
-// for all detector materials for the neutrino generated by the flux driver
-// and make sure that things look ok...
-
-  fCurPathLengths.clear();
-
-  const TLorentzVector & nup4  = fFluxDriver -> Momentum ();
-  const TLorentzVector & nux4  = fFluxDriver -> Position ();
-
-  fCurPathLengths = fGeomAnalyzer->ComputePathLengths(nux4, nup4);
-
-  LOG("GNUISANCEMCJDriver", pNOTICE) << fCurPathLengths;
-
-  if(fCurPathLengths.size() == 0) {
-     LOG("GNUISANCEMCJDriver", pFATAL)
-       << "\n *** Geometry driver error ***"
-       << "\n Got an empty PathLengthList - No material found in geometry?";
-     return false;
-  }
-
-  if(fCurPathLengths.AreAllZero()) {
-         LOG("GNUISANCEMCJDriver", pNOTICE)
-                 << "current flux v doesn't cross any geometry material...";
-  }
-  return true;
-}
-//___________________________________________________________________________
-double GNUISANCEMCJDriver::ComputeInteractionProbabilities(bool use_max_path_length)
-{
-  LOG("GNUISANCEMCJDriver", pNOTICE)
-       << "Computing relative interaction probabilities for each material";
-
-  // current flux neutrino code & 4-p
-  int                    nupdg = fFluxDriver->PdgCode();
-  const TLorentzVector & nup4  = fFluxDriver->Momentum();
-
-  fCurCumulProbMap.clear();
-
-  const PathLengthList & path_length_list = 
-        (use_max_path_length) ? fMaxPathLengths : fCurPathLengths;
-
-  double probsum=0;
-  PathLengthList::const_iterator pliter;
-
-  for(pliter = path_length_list.begin();
-                            pliter != path_length_list.end(); ++pliter) {
-     int    mpdg  = pliter->first;            // material PDG code
-     double pl    = pliter->second;           // density x path-length
-     int    A     = pdg::IonPdgCodeToA(mpdg);
-     double xsec  = 0.;                       // sum of xsecs for all modelled processes for given init state
-     double prob  = 0.;                       // interaction probability
-     double probn = 0.;                       // normalized interaction probability
-
-     // find the GEVGDriver object that is handling the current init state
-     InitialState init_state(mpdg, nupdg);
-     GEVGDriver * evgdriver = fGPool->FindDriver(init_state);
-     if(!evgdriver) {
-       LOG("GNUISANCEMCJDriver", pFATAL)
-        << "\n * The MC Job driver isn't properly configured!"
-        << "\n * No event generation driver could be found for init state: " 
-        << init_state.AsString();
-       exit(1);
-     }
-     // compute the interaction xsec and probability (if path-length>0)
-     if(pl>0.) {
-        const Spline * totxsecspl = evgdriver->XSecSumSpline();
-        if(!totxsecspl) {
-            LOG("GNUISANCEMCJDriver", pFATAL)
-              << "\n * The MC Job driver isn't properly configured!"
-              << "\n * Couldn't retrieve total cross section spline for init state: " 
-              << init_state.AsString();
-            exit(1);
-        } else {
-            xsec = totxsecspl->Evaluate( nup4.Energy() );
-        }
-        prob = this->InteractionProbability(xsec,pl,A);
-        LOG("GNUISANCEMCJDriver", pDEBUG)
-          << " (xsec, pl, A)=(" << xsec << "," << pl << "," << A << ")";
-
-        // scale the interaction probability to the maximum one so as not
-        // to have to throw few billions of flux neutrinos before getting
-        // an interaction...
-        double pmax = 0;
-        if(fGenerateUnweighted) pmax = fGlobPmax;
-        else {
-           map<int,TH1D*>::const_iterator pmax_iter = fPmax.find(nupdg);
-           assert(pmax_iter != fPmax.end());
-           TH1D * pmax_hst = pmax_iter->second;
-           assert(pmax_hst);
-           int    ie   = pmax_hst->FindBin(nup4.Energy());
-           pmax = pmax_hst->GetBinContent(ie);
-        }
-        assert(pmax>0);        
-        LOG("GNUISANCEMCJDriver", pDEBUG)
-          << "Pmax=" << pmax;
-        probn = prob/pmax;
-     }
-#ifdef __GENIE_LOW_LEVEL_MESG_ENABLED__
-     LOG("GNUISANCEMCJDriver", pNOTICE)
-         << "tgt: " << mpdg << " -> TotXSec = "
-         << xsec/units::cm2 << " cm^2, Norm.Prob = " << 100*probn << "%";
-#endif
-
-     probsum += probn;
-     fCurCumulProbMap.insert(map<int,double>::value_type(mpdg,probsum));
-  }
-  return probsum;
-}
-//___________________________________________________________________________
-int GNUISANCEMCJDriver::SelectTargetMaterial(double R)
-{
-// Pick a target material using the pre-computed interaction probabilities
-// for a flux neutrino that has already been determined that interacts
-
-  LOG("GNUISANCEMCJDriver", pNOTICE) << "Selecting target material";
-  int tgtpdg = 0;
-  map<int,double>::const_iterator probiter = fCurCumulProbMap.begin();
-  for( ; probiter != fCurCumulProbMap.end(); ++probiter) {
-     double prob = probiter->second;
-     if(R<prob) {
-        tgtpdg = probiter->first;
-        LOG("GNUISANCEMCJDriver", pNOTICE) 
-          << "Selected target material = " << tgtpdg;
-        return tgtpdg;
-     }
-  }
-  LOG("GNUISANCEMCJDriver", pERROR)
-     << "Could not select target material for an interacting neutrino";
-  return 0;
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::GenerateEventKinematics(void)
-{
-  int                    nupdg = fFluxDriver->PdgCode();
-  const TLorentzVector & nup4  = fFluxDriver->Momentum();
-
-  // Find the GEVGDriver object that generates interactions for the
-  // given initial state (neutrino + target)
-  InitialState init_state(fSelTgtPdg, nupdg);
-  GEVGDriver * evgdriver = fGPool->FindDriver(init_state);
-  if(!evgdriver) {
-     LOG("GNUISANCEMCJDriver", pFATAL)
-       << "No GEVGDriver object for init state: " << init_state.AsString();
-     exit(1);
-  }
-
-  // propagate current unphysical event mask 
-  evgdriver->SetUnphysEventMask(*fUnphysEventMask);
-
-  // Ask the GEVGDriver object to select and generate an interaction for
-  // the selected initial state & neutrino 4-momentum
-  LOG("GNUISANCEMCJDriver", pNOTICE)
-          << "Asking the selected GEVGDriver object to generate an event";
-  fCurEvt = evgdriver->GenerateEvent(nup4);
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::GenerateVertexPosition(void)
-{
-  // Generate an 'interaction position' in the selected material, along
-  // the direction of nup4
-  LOG("GNUISANCEMCJDriver", pNOTICE)
-     << "Asking the geometry analyzer to generate a vertex";
-
-  const TLorentzVector & p4 = fFluxDriver->Momentum ();
-  const TLorentzVector & x4 = fFluxDriver->Position ();
-
-  const TVector3 & vtx = fGeomAnalyzer->GenerateVertex(x4, p4, fSelTgtPdg);
-
-  TVector3 origin(x4.X(), x4.Y(), x4.Z());
-  origin-=vtx; // computes vector dr = origin - vtx
-
-  double dL = origin.Mag();
-  double c  = kLightSpeed /(units::meter/units::second);
-  double dt = dL/c;
-
-  LOG("GNUISANCEMCJDriver", pNOTICE)
-     << "|vtx - origin|: dL = " << dL << " m, dt = " << dt << " sec";
-
-  fCurVtx.SetXYZT(vtx.x(), vtx.y(), vtx.z(), x4.T() + dt);
-
-  fCurEvt->SetVertex(fCurVtx);
-}
-//___________________________________________________________________________
-void GNUISANCEMCJDriver::ComputeEventProbability(void)
-{
-// Compute event probability for the given flux neutrino & detector geometry
-
-  // get interaction cross section
-  double xsec = fCurEvt->XSec();
-
-  // get path length in detector along v direction for specified target material
-  PathLengthList::const_iterator pliter = fCurPathLengths.find(fSelTgtPdg);
-  double path_length = pliter->second;
-
-  // get target material mass number
-  int A = pdg::IonPdgCodeToA(fSelTgtPdg);
-
-  // calculate interaction probability
-  double P = this->InteractionProbability(xsec, path_length, A);
-
-  //
-  // get weight for selected event
-  //
-
-  GHepParticle * nu = fCurEvt->Probe();
-  int    nu_pdg = nu->Pdg();
-  double Ev     = nu->P4()->Energy();
- 
-  double weight = 1.0;
-  if(!fGenerateUnweighted) {
-     map<int,TH1D*>::const_iterator pmax_iter = fPmax.find(nu_pdg);
-     assert(pmax_iter != fPmax.end());
-     TH1D * pmax_hst = pmax_iter->second;
-     assert(pmax_hst);
-     double pmax = pmax_hst->GetBinContent(pmax_hst->FindBin(Ev));
-     assert(pmax>0);
-     weight = pmax/fGlobPmax;
-  }
-
-  // set probability & update weight
-  fCurEvt->SetProbability(P);
-  fCurEvt->SetWeight(weight * fCurEvt->Weight());
-}
-//___________________________________________________________________________
-double GNUISANCEMCJDriver::InteractionProbability(double xsec, double pL, int A)
-{
-// P = Na   (Avogadro number,                 atoms/mole) *
-//     1/A  (1/mass number,                   mole/gr)    *
-//     xsec (total interaction cross section, cm^2)       *
-//     pL   (density-weighted path-length,    gr/cm^2)
-//
-  xsec = xsec / units::cm2; 
-  pL   = pL   * ((units::kilogram/units::m2)/(units::gram/units::cm2));
-
-  return kNA*(xsec*pL)/A;
-}
-//___________________________________________________________________________
-double GNUISANCEMCJDriver::PreGenFluxInteractionProbability()
-{
-// Return the pre-computed interaction probability for the current flux 
-// neutrino index (entry number in flux file). Exit if not possible as 
-// using meaningless interaction probability leads to incorrect physics 
-//
-  if(!fFluxIntTree){
-    LOG("GNUISANCEMCJDriver", pERROR) << 
-         "Cannot get pre-computed flux interaction probability as no tree!";
-    exit(1);
-  }
-
-  assert(fFluxDriver->Index() >= 0); // Check trying to find meaningfull index
-
-  // Check if can find relevant entry and no mismatch in energies -->
-  // using correct pre-gen interaction prob file
-  bool found_entry = fFluxIntTree->GetEntryWithIndex(fFluxDriver->Index()) > 0;
-  bool enu_match = false;
-  if(found_entry){
-    double rel_err = fBrFluxEnu-fFluxDriver->Momentum().E();
-    if(fBrFluxEnu > controls::kASmallNum) rel_err /= fBrFluxEnu;
-    enu_match = TMath::Abs(rel_err)<controls::kASmallNum;
-    if(enu_match == false){
-      LOG("GNUISANCEMCJDriver", pERROR) << 
-           "Mismatch between: Enu_curr  = "<< fFluxDriver->Momentum().E() <<
-           ", Enu_pre_gen = "<< fBrFluxEnu;
-    } 
-  }
-  else {
-    LOG("GNUISANCEMCJDriver", pERROR) << "Cannot find flux entry in interaction prob tree!";
-  }
-
-  // Exit if not successful
-  bool success = found_entry && enu_match;
-  if(!success){
-    LOG("GNUISANCEMCJDriver", pFATAL) << 
-         "Cannot find pre-generated interaction probability! Check you "<<
-         "are using the correct pre-generated interaction prob file "   <<
-         "generated using current flux input file with same input "     <<
-         "config (same geom TopVol, neutrino species list)";
-    exit(1);
-  }
-  assert(fGlobPmax+controls::kASmallNum>0.0);
-  return fBrFluxIntProb/fGlobPmax; 
-}
-//___________________________________________________________________________
-#endif
diff --git a/src/FitBase/GNUISANCEMCJDriver.h b/src/FitBase/GNUISANCEMCJDriver.h
deleted file mode 100644
index 3d7e4f9..0000000
--- a/src/FitBase/GNUISANCEMCJDriver.h
+++ /dev/null
@@ -1,145 +0,0 @@
-//____________________________________________________________________________
-/*!
-
-\class    genie::GMCJDriver
-
-\brief    A GENIE `MC Job Driver'. Can be used for setting up complicated event 
-          generation cases involving detailed flux descriptions and detector 
-          geometry descriptions.
-
-\author   Costas Andreopoulos <costas.andreopoulos \at stfc.ac.uk>
-          University of Liverpool & STFC Rutherford Appleton Lab
-
-\created  May 25, 2005
-
-\cpright  Copyright (c) 2003-2016, GENIE Neutrino MC Generator Collaboration
-          For the full text of the license visit http://copyright.genie-mc.org
-          or see $GENIE/LICENSE
-*/
-//____________________________________________________________________________
-
-#ifndef _GENIE_NUISANCE_MC_JOB_DRIVER_H_
-#define _GENIE_NUISANCE_MC_JOB_DRIVER_H_
-#ifdef __GEVGEN_ENABLED__
-
-#include <string>
-#include <map>
-
-#include <TH1D.h>
-#include <TLorentzVector.h>
-#include <TFile.h>
-#include <TTree.h>
-#include <TBits.h>
-
-#include "EVGDrivers/PathLengthList.h"
-#include "PDG/PDGCodeList.h"
-#include "EVGDrivers/GEVGPool.h"
-
-using std::string;
-using std::map;
-
-namespace genie {
-
-class EventRecord;
-class GFluxI;
-class GeomAnalyzerI;
-class GENIE;
-//class GEVGPool;
-
-class GNUISANCEMCJDriver {
-
-public :
-  GNUISANCEMCJDriver();
- ~GNUISANCEMCJDriver();
-
-  // configure MC job
-  void SetEventGeneratorList       (string listname);
-  void SetUnphysEventMask          (const TBits & mask);
-  void UseFluxDriver               (GFluxI * flux);
-  void UseGeomAnalyzer             (GeomAnalyzerI * geom);
-  void UseSplines                  (bool useLogE = true);
-  bool UseMaxPathLengths           (string xml_filename);
-  void KeepOnThrowingFluxNeutrinos (bool keep_on);
-  void ForceSingleProbScale        (void);
-  void PreSelectEvents             (bool preselect = true);
-  bool PreCalcFluxProbabilities    (void);
-  bool LoadFluxProbabilities       (string filename);
-  void SaveFluxProbabilities       (string outfilename);
-  void Configure                   (bool calc_prob_scales = true);
-  GEVGPool* GetConfigPool(void){return this->fGPool;};
-
-  // generate single neutrino event for input flux & geometry
-  EventRecord * GenerateEvent (void);
-
-  // info needed for computing the generated sample normalization
-  double   GlobProbScale  (void) const { return fGlobPmax;                  }
-  long int NFluxNeutrinos (void) const { return (long int) fNFluxNeutrinos; }
-  map<int, double> SumFluxIntProbs(void) const { return fSumFluxIntProbs;   }
-
-  // input flux and geometry drivers
-  const GFluxI &        FluxDriver      (void) const { return *fFluxDriver;   }
-  const GeomAnalyzerI & GeomAnalyzer    (void) const { return *fGeomAnalyzer; }
-  GFluxI *              FluxDriverPtr   (void) const { return  fFluxDriver;   } 
-  GeomAnalyzerI *       GeomAnalyzerPtr (void) const { return  fGeomAnalyzer; }
-
-  // private methods:
-  void          InitJob                         (void);
-  void          InitEventGeneration             (void);
-  void          GetParticleLists                (void);
-  void          GetMaxPathLengthList            (void);
-  void          GetMaxFluxEnergy                (void);
-  void          PopulateEventGenDriverPool      (void);
-  void          BootstrapXSecSplines            (void);
-  void          BootstrapXSecSplineSummation    (void);
-  void          ComputeProbScales               (void);
-  EventRecord * GenerateEvent1Try               (void);
-  bool          GenerateFluxNeutrino            (void);
-  bool          ComputePathLengths              (void);
-  double	ComputeInteractionProbabilities (bool use_max_path_length);
-  int           SelectTargetMaterial            (double R);
-  void          GenerateEventKinematics         (void);
-  void          GenerateVertexPosition          (void);
-  void          ComputeEventProbability         (void);
-  double        InteractionProbability          (double xsec, double pl, int A);
-  double        PreGenFluxInteractionProbability(void);
-
-  // private data members:
-  GEVGPool *      fGPool;              ///< A pool of GEVGDrivers properly configured event generation drivers / one per init state
-  GFluxI *        fFluxDriver;         ///< [input] neutrino flux driver
-  GeomAnalyzerI * fGeomAnalyzer;       ///< [input] detector geometry analyzer
-  double          fEmax;               ///< [declared by the flux driver] maximum neutrino energy 
-  PDGCodeList     fNuList;             ///< [declared by the flux driver] list of neutrino codes 
-  PDGCodeList     fTgtList;            ///< [declared by the geom driver] list of target codes 
-  PathLengthList  fMaxPathLengths;     ///< [declared by the geom driver] maximum path length list 
-  PathLengthList  fCurPathLengths;     ///< [current] path length list for current flux neutrino
-  TLorentzVector  fCurVtx;             ///< [current] interaction vertex
-  EventRecord *   fCurEvt;             ///< [current] generated event
-  int             fSelTgtPdg;          ///< [current] selected target material PDG code
-  map<int,double> fCurCumulProbMap;    ///< [current] cummulative interaction probabilities
-  double          fNFluxNeutrinos;     ///< [current] number of flux nuetrinos fired by the flux driver so far 
-  map<int,TH1D*>  fPmax;               ///< [computed at init] interaction probability scale /neutrino /energy for given geometry
-  double          fGlobPmax;           ///< [computed at init] global interaction probability scale for given flux & geometry
-  string          fEventGenList;       ///< [config] list of event generators loaded by this driver (what used to be the $GEVGL setting)
-  TBits *         fUnphysEventMask;    ///< [config] controls whether unphysical events are returned (what used to be the $GUNPHYSMASK setting)
-  string          fMaxPlXmlFilename;   ///< [config] input file with max density-weighted path lengths for all materials
-  bool            fUseExtMaxPl;        ///< [config] using external max path length estimate?
-  bool            fUseSplines;         ///< [config] compute all needed & not-loaded splines at init
-  bool            fUseLogE;            ///< [config] build splines = f(logE) (rather than f(E)) ?
-  bool            fKeepThrowingFluxNu; ///< [config] keep firing flux neutrinos till one of them interacts
-  bool            fGenerateUnweighted; ///< [config] force single probability scale?
-  bool            fPreSelect;          ///< [config] set whether to pre-select events using max interaction paths 
-  TFile*          fFluxIntProbFile;    ///< [input] pre-generated flux interaction probability file
-  TTree*          fFluxIntTree;        ///< [computed-or-loaded] pre-computed flux interaction probabilities (expected tree name is "gFlxIntProbs")
-  double          fBrFluxIntProb;      ///< flux interaction probability (set to branch:"FluxIntProb")
-  int             fBrFluxIndex;        ///< corresponding entry in flux input tree (set to address of branch:"FluxEntry")
-  double          fBrFluxEnu;          ///< corresponding flux P4 (set to address of branch:"FluxP4") 
-  double          fBrFluxWeight;       ///< corresponding flux weight (set to address of branch: "FluxWeight") 
-  int             fBrFluxPDG;          ///< corresponding flux pdg code (set to address of branch: "FluxPDG") 
-  string          fFluxIntFileName;    ///< whether to save pre-generated flux tree for use in later jobs
-  string          fFluxIntTreeName;    ///< name for tree holding flux probabilities 
-  map<int, double> fSumFluxIntProbs;   ///< map where the key is flux pdg code and the value is sum of fBrFluxWeight * fBrFluxIntProb for all these flux neutrinos 
-};
-
-}      // genie namespace
-#endif // _GENIE_MC_JOB_DRIVER_H_
-#endif
diff --git a/src/FitBase/GeneratorUtils.cxx b/src/FitBase/GeneratorUtils.cxx
deleted file mode 100644
index 975a6e2..0000000
--- a/src/FitBase/GeneratorUtils.cxx
+++ /dev/null
@@ -1,1067 +0,0 @@
-// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
-
-/*******************************************************************************
-*    This file is part of NUISANCE.
-*
-*    NUISANCE is free software: you can redistribute it and/or modify
-*    it under the terms of the GNU General Public License as published by
-*    the Free Software Foundation, either version 3 of the License, or
-*    (at your option) any later version.
-*
-*    NUISANCE is distributed in the hope that it will be useful,
-*    but WITHOUT ANY WARRANTY; without even the implied warranty of
-*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*    GNU General Public License for more details.
-*
-*    You should have received a copy of the GNU General Public License
-*    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
-*******************************************************************************/
-
-#include <iostream>
-
-#include "GeneratorUtils.h"
-#include "FitLogger.h"
-
-// TODO, Make a generator variables box, and keep an original particle stack when OrderStack is called.
-
-namespace GeneratorUtils {
-
-  const std::string NEUT_TreeName = "neuttree";
-  const std::string NuWro_TreeName = "treeout";
-  const std::string GENIE_TreeName = "gtree";
-  const std::string GiBUU_TreeName = "giRooTracker";
-}
-
-#ifdef __NEUT_ENABLED__
-void GeneratorUtils::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" << 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
-
-#ifdef __NIWG_ENABLED__
-niwg::rew::NIWGEvent * GeneratorUtils::GetNIWGEvent(NeutVect* nvect)
-{
-  niwg::rew::NIWGEvent * fDummyNIWGEvent = NULL;
-
-  fDummyNIWGEvent = new niwg::rew::NIWGEvent();
-  fDummyNIWGEvent->detid = 1;   // MiniBooNE (apply CCQE LowE variations)
-  fDummyNIWGEvent->neutmode = nvect->Mode;
-  fDummyNIWGEvent->targetA = nvect->TargetA;
-  fDummyNIWGEvent->recenu_ccqe_sk = -1;
-  if (nvect->Ibound==0) fDummyNIWGEvent->targetA = 1;//RT: identifies as H, rather than O16
-
-  // Fill initial particle stack
-  for (int ip=0; ip<nvect->Npart(); ++ip) {
-
-    niwg::rew::NIWGPartStack fDummyPartStack;
-
-    fDummyPartStack.p = (nvect->PartInfo(ip)->fP)*0.001;  // Convert to GeV
-
-    fDummyPartStack.pdg = nvect->PartInfo(ip)->fPID;
-    fDummyPartStack.chase = nvect->PartInfo(ip)->fIsAlive;
-    fDummyPartStack.parent = nvect->ParentIdx(ip)-1;       // WARNING: this needs to be tested with a NeutRoot file
-
-    fDummyNIWGEvent->part_stack.push_back(fDummyPartStack);
-  }
-  fDummyNIWGEvent->CalcKinematics();
-
-  return fDummyNIWGEvent;
-}
-#endif // neut enabled
-
-
-#ifdef __NUWRO_ENABLED__
-//***************************************************
-int GeneratorUtils::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 (e->nof (proton_pdg))
-		return -51;
-	      else if (e->nof (neutron_pdg))
-		return -52;	// sprawdzam dodatkowo ?
-	    }
-	}
-      else			// oddziaływanie z neutrinem
-	{
-	  if (e->flag.cc)
-	    return 1;
-	  else
-	    {
-	      if (e->nof (proton_pdg))
-		return 51;
-	      else if (e->nof (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 =
-	e->nof (pion_pdg) + e->nof (pion_plus_pdg) + e->nof (pion_minus_pdg);
-      liczba_kaonow = e->nof (kaon_pdg) + e->nof (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 (e->nof (neutron_pdg) && e->nof (pion_minus_pdg))
-		    return -11;
-		  if (e->nof (neutron_pdg) && e->nof (pion_pdg))
-		    return -12;
-		  if (e->nof (proton_pdg) && e->nof (pion_minus_pdg))
-		    return -13;
-		}
-	      else
-		{
-		  if (e->nof (proton_pdg))
-		    {
-		      if (e->nof (pion_minus_pdg))
-			return -33;
-		      else if (e->nof (pion_pdg))
-			return -32;
-		    }
-		  else if (e->nof (neutron_pdg))
-		    {
-		      if (e->nof (pion_plus_pdg))
-			return -34;
-		      else if (e->nof (pion_pdg))
-			return -31;
-		    }
-		}
-	    }
-	  else			// oddziaływanie z neutrinem
-	    {
-	      if (e->flag.cc)
-		{
-		  if (e->nof (proton_pdg) && e->nof (pion_plus_pdg))
-		    return 11;
-		  if (e->nof (proton_pdg) && e->nof (pion_pdg))
-		    return 12;
-		  if (e->nof (neutron_pdg) && e->nof (pion_plus_pdg))
-		    return 13;
-		}
-	      else
-		{
-		  if (e->nof (proton_pdg))
-		    {
-		      if (e->nof (pion_minus_pdg))
-			return 33;
-		      else if (e->nof (pion_pdg))
-			return 32;
-		    }
-		  else if (e->nof (neutron_pdg))
-		    {
-		      if (e->nof (pion_plus_pdg))
-			return 34;
-		      else if (e->nof (pion_pdg))
-			return 31;
-		    }
-		}
-	    }
-	}
-
-      if (e->nof (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 (e->nof (neutron_pdg))
-		    return -42;
-		  else if (e->nof (proton_pdg))
-		    return -43;	// sprawdzam dodatkowo ?
-		}
-	    }
-	  else			// oddziaływanie z neutrinem
-	    {
-	      if (e->flag.cc)
-		return 22;
-	      else
-		{
-		  if (e->nof (neutron_pdg))
-		    return 42;
-		  else if (e->nof (proton_pdg))
-		    return 43;
-		}
-	    }
-	}
-
-      if (e->nof (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 && e->nof (kaon_pdg))
-		return -23;
-	      else
-		{
-		  if (e->nof (kaon_pdg))
-		    return -44;
-		  else if (e->nof (kaon_plus_pdg))
-		    return -45;
-		}
-	    }
-	  else			// oddziaływanie z neutrinem
-	    {
-	      if (e->flag.cc && e->nof (kaon_plus_pdg))
-		return 23;
-	      else
-		{
-		  if (e->nof (kaon_pdg))
-		    return 44;
-		  else if (e->nof (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 && e->nof (pion_minus_pdg))
-		return -16;
-	      else if (e->nof (pion_pdg))
-		return -36;
-	    }
-	  else			// oddziaływanie z neutrinem
-	    {
-	      if (e->flag.cc && e->nof (pion_plus_pdg))
-		return 16;
-	      else if (e->nof (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;
-}
-
-
-#endif
-
-
-#ifdef __NUANCE_ENABLED__
-int GeneratorUtils::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;
-
-}
-#endif
-
-/*
-// 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";
-*/
diff --git a/src/FitBase/GeneratorUtils.h b/src/FitBase/GeneratorUtils.h
deleted file mode 100644
index 28d9287..0000000
--- a/src/FitBase/GeneratorUtils.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
-
-/*******************************************************************************
-*    This file is part of NUISANCE.
-*
-*    NUISANCE is free software: you can redistribute it and/or modify
-*    it under the terms of the GNU General Public License as published by
-*    the Free Software Foundation, either version 3 of the License, or
-*    (at your option) any later version.
-*
-*    NUISANCE is distributed in the hope that it will be useful,
-*    but WITHOUT ANY WARRANTY; without even the implied warranty of
-*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*    GNU General Public License for more details.
-*
-*    You should have received a copy of the GNU General Public License
-*    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
-*******************************************************************************/
-
-#ifndef GENERATOR_UTILS_H
-#define GENERATOR_UTILS_H
-
-#ifdef __NEUT_ENABLED__
-#include "nefillverC.h"
-#include "necardC.h"
-#include "neutmodelC.h"
-#include "neutparamsC.h"
-#include "neworkC.h"
-#include "fsihistC.h"
-#include "neutcrsC.h"
-#include "neutvect.h"
-#include "neutpart.h"
-#include "neutfsipart.h"
-#include "neutfsivert.h"
-#include "neutrootTreeSingleton.h"
-#include "NModeDefn.h"
-#include "NSyst.h"
-#include "NFortFns.h" // Contains all the NEUT common blocks
-#endif
-
-#ifdef __NEUT_NUCFSI_ENABLED__
-#include "nucleonfsihistC.h"
-#include "neutnucfsivert.h"
-#include "neutnucfsistep.h"
-#endif
-
-
-#ifdef __NIWG_ENABLED__
-#include "NIWGEvent.h"
-#include "NIWGSyst.h"
-#endif
-
-#ifdef __NUWRO_ENABLED__
-#include "event1.h"
-#endif
-
-#include "NuanceEvent.h"
-
-namespace GeneratorUtils {
-
-  extern const std::string NEUT_TreeName;
-#ifdef __NEUT_ENABLED__
-  void FillNeutCommons(NeutVect* nvect);
-#endif
-
-#ifdef __NIWG_ENABLED__
-  niwg::rew::NIWGEvent* GetNIWGEvent(NeutVect* nvect);
-#endif
-
-  extern const std::string NuWro_TreeName;
-#ifdef __NUWRO_ENABLED__
-  int ConvertNuwroMode (event * e);
-#endif
-
-#ifdef __NUANCE_ENABLED__
-  int ConvertNuanceMode(NuanceEvent * evt);
-#endif
-
-  extern const std::string GENIE_TreeName;
-  extern const std::string GiBUU_TreeName;
-};
-#endif
diff --git a/src/FitBase/InputHandler2.h b/src/FitBase/InputHandler2.h
deleted file mode 100644
index 2de4759..0000000
--- a/src/FitBase/InputHandler2.h
+++ /dev/null
@@ -1,189 +0,0 @@
-#ifndef INPUTHANDLER2_H
-#define INPUTHANDLER2_H
-
-#include "TH1D.h"
-#include "FitEvent.h"
-#include "BaseFitEvt.h"
-
-class InputHandlerBase {
-public:
-  InputHandlerBase() {
-    fName = "";
-    fFluxHist = NULL;
-    fEventHist = NULL;
-    fNEvents = 0;
-    fNUISANCEEvent = NULL;
-    fBaseEvent = NULL;
-  };
-  ~InputHandlerBase() {};
-
-  virtual FitEvent* GetNuisanceEvent(const UInt_t entry) = 0;
-  virtual BaseFitEvt* GetBaseEvent(const UInt_t entry) = 0;
-  virtual void Print(){};
-
-  inline int GetNEvents(void) { return fNEvents; }
-  inline TH1D* GetFluxHistogram(void) {return fFluxHist;};
-  inline TH1D* GetEventHistogram(void) {return fEventHist;};
-  inline std::string GetName(void) {return fName;};
-  inline int GetType(void) {return fEventType;};
-
-  inline TH1D* GetXSecHistogram(void) {
-    fXSecHist = (TH1D*)fFluxHist->Clone();
-    fXSecHist->Divide(fEventHist);
-    return fXSecHist;
-  };
-
-//********************************************************************
-  inline double PredictedEventRate(double low, double high,
-                                   std::string intOpt) {
-    //********************************************************************
-
-    int minBin = fFluxHist->GetXaxis()->FindBin(low);
-    int maxBin = fFluxHist->GetXaxis()->FindBin(high);
-
-    return fEventHist->Integral(minBin, maxBin + 1, intOpt.c_str());
-  };
-
-  //********************************************************************
-  inline double TotalIntegratedFlux(double low = -9999.9, double high = -9999.9,
-                                    std::string intOpt="") {
-    //********************************************************************
-
-    std::cout << "Getting Total Integrated Flux Between : " << low << " - " << high << std::endl;
-
-    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;
-    }
-
-    std::cout << "Getting Between Bins " << minBin << " " << maxBin << std::endl;
-    // If we are within a single bin
-    if (minBin == maxBin) {
-      std::cout << "Getting minBin == maxBin " << std::endl;
-      // Get the contained fraction of the single bin's width
-      return ((high - low) / fFluxHist->GetXaxis()->GetBinWidth(minBin)) *
-             fFluxHist->Integral(minBin, minBin, intOpt.c_str());
-    }
-
-    double lowBinUpEdge = fFluxHist->GetXaxis()->GetBinUpEdge(minBin);
-    double highBinLowEdge = fFluxHist->GetXaxis()->GetBinLowEdge(maxBin);
-
-    double lowBinfracIntegral =
-      ((lowBinUpEdge - low) / fFluxHist->GetXaxis()->GetBinWidth(minBin)) *
-      fFluxHist->Integral(minBin, minBin, intOpt.c_str());
-    double highBinfracIntegral =
-      ((high - highBinLowEdge) / fFluxHist->GetXaxis()->GetBinWidth(maxBin)) *
-      fFluxHist->Integral(maxBin, maxBin, intOpt.c_str());
-
-    // If they are neighbouring bins
-    if ((minBin + 1) == maxBin) {
-      std::cout << "Get lowfrac + highfrac" << std::endl;
-      // Get the contained fraction of the two bin's width
-      return lowBinfracIntegral + highBinfracIntegral;
-    }
-
-    std::cout << "Returning highBinFracIntegral and LowBinFracIntegral " << std::endl;
-    // If there are filled bins between them
-    return lowBinfracIntegral + highBinfracIntegral +
-           fFluxHist->Integral(minBin + 1, maxBin - 1, intOpt.c_str());
-    // return fFluxHist->Integral(minBin + 1, maxBin - 1, intOpt.c_str());
-  }
-
-
-  std::vector<TH1*> GetFluxList(void) { return std::vector<TH1*>(1, fFluxHist); };
-  std::vector<TH1*> GetEventList(void) { return std::vector<TH1*>(1, fEventHist); };
-  std::vector<TH1*> GetXSecList(void) { return std::vector<TH1*>(1, GetXSecHistogram()); };
-
-  virtual FitEvent* FirstNuisanceEvent() {
-    fCurrentIndex = 0;
-    return GetNuisanceEvent(fCurrentIndex);
-  };
-
-
-
-  virtual FitEvent* NextNuisanceEvent() {
-    fCurrentIndex++;
-
-    if (jointinput and fMaxEvents != -1) {
-      while ( fCurrentIndex < jointindexlow[jointindexswitch] ||
-              fCurrentIndex >= jointindexhigh[jointindexswitch] ) {
-        jointindexswitch++;
-
-        // Loop Around
-        if (jointindexswitch == jointindexlow.size()) {
-          jointindexswitch = 0;
-        }
-      }
-
-
-      if (fCurrentIndex > jointindexlow[jointindexswitch] + jointindexallowed[jointindexswitch]) {
-        fCurrentIndex = jointindexlow[jointindexswitch];
-      }
-    }
-
-    return GetNuisanceEvent(fCurrentIndex);
-  };
-
-
-  virtual BaseFitEvt* FirstBaseEvent() {
-    fCurrentIndex = 0;
-    return GetBaseEvent(fCurrentIndex);
-  };
-
-  virtual BaseFitEvt* NextBaseEvent() {
-    fCurrentIndex++;
-
-    if (jointinput and fMaxEvents != -1) {
-      while ( fCurrentIndex < jointindexlow[jointindexswitch] ||
-              fCurrentIndex >= jointindexhigh[jointindexswitch] ) {
-        jointindexswitch++;
-
-        // Loop Around
-        if (jointindexswitch == jointindexlow.size()) {
-          jointindexswitch = 0;
-        }
-      }
-
-
-      if (fCurrentIndex > jointindexlow[jointindexswitch] + jointindexallowed[jointindexswitch]) {
-        fCurrentIndex = jointindexlow[jointindexswitch];
-      }
-    }
-
-    return GetBaseEvent(fCurrentIndex);
-  };
-
-
-
-
-  std::vector<TH1D*> jointfluxinputs;
-  std::vector<TH1D*> jointeventinputs;
-  std::vector<int> jointindexlow;
-  std::vector<int> jointindexhigh;
-  std::vector<int> jointindexallowed;
-  size_t jointindexswitch;
-  bool jointinput;
-  std::vector<double> jointindexscale;
-
-  std::string fName;
-  TH1D* fFluxHist;
-  TH1D* fEventHist;
-  TH1D* fXSecHist;
-  int fNEvents;
-  int fMaxEvents;
-  FitEvent* fNUISANCEEvent;
-  BaseFitEvt* fBaseEvent;
-  int fEventType;
-  int fCurrentIndex;
-};
-
-
-
-
-#endif
\ No newline at end of file
diff --git a/src/FitBase/JointMeas1D.cxx b/src/FitBase/JointMeas1D.cxx
index 2a0f2d2..46226ac 100644
--- a/src/FitBase/JointMeas1D.cxx
+++ b/src/FitBase/JointMeas1D.cxx
@@ -1,2183 +1,2209 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This ile is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 #include "JointMeas1D.h"
 
 
 //********************************************************************
 JointMeas1D::JointMeas1D(void) {
 //********************************************************************
 
   // XSec Scalings
   fScaleFactor = -1.0;
   fCurrentNorm = 1.0;
 
   // Histograms
   fDataHist = NULL;
   fDataTrue = NULL;
 
   fMCHist = NULL;
   fMCFine = NULL;
   fMCWeighted = NULL;
 
   fMaskHist = NULL;
 
   // Covar
   covar = NULL;
   fFullCovar = NULL;
 
   fCovar  = NULL;
   fInvert = NULL;
   fDecomp = NULL;
 
   // Fake Data
   fFakeDataInput = "";
   fFakeDataFile  = NULL;
 
   // Options
   fDefaultTypes = "FIX/FULL/CHI2";
   fAllowedTypes =
     "FIX,FREE,SHAPE/FULL,DIAG/CHI2/NORM/ENUCORR/Q2CORR/ENU1D/MASK";
 
   fIsFix = false;
   fIsShape = false;
   fIsFree = false;
   fIsDiag = false;
   fIsFull = false;
   fAddNormPen = false;
   fIsMask = false;
   fIsChi2SVD = false;
   fIsRawEvents = false;
   fIsDifXSec = false;
   fIsEnu1D = false;
 
   // Inputs
   fInput = NULL;
   fRW = NULL;
 
   // Extra Histograms
   fMCHist_Modes = NULL;
 
   for (std::vector<MeasurementBase*>::const_iterator iter = fSubChain.begin();
        iter != fSubChain.end(); iter++) {
     MeasurementBase* exp = *iter;
     if (exp) delete exp;
   }
   fSubChain.clear();
 
   // Flags for Joint Measurements
   fIsRatio = false;
   fIsSummed = false;
   fSaveSubMeas = false;
 
   fIsJoint = true;
 
 }
 
 
 //********************************************************************
 void JointMeas1D::SetupDefaultHist() {
   //********************************************************************
 
   // Setup fMCHist
   fMCHist = (TH1D*)fDataHist->Clone();
   fMCHist->SetNameTitle((fName + "_MC").c_str(),
                         (fName + "_MC" + fPlotTitles).c_str());
 
   // Setup fMCFine
   Int_t nBins = fMCHist->GetNbinsX();
   fMCFine = new TH1D(
     (fName + "_MC_FINE").c_str(), (fName + "_MC_FINE" + fPlotTitles).c_str(),
     nBins * 6, fMCHist->GetBinLowEdge(1), fMCHist->GetBinLowEdge(nBins + 1));
 
   fMCStat = (TH1D*)fMCHist->Clone();
   fMCStat->Reset();
 
   fMCHist->Reset();
   fMCFine->Reset();
 
   // Setup the NEUT Mode Array
   PlotUtils::CreateNeutModeArray((TH1D*)fMCHist, (TH1**)fMCHist_PDG);
   PlotUtils::ResetNeutModeArray((TH1**)fMCHist_PDG);
 
   // Setup bin masks using sample name
   if (fIsMask) {
     std::string maskloc = FitPar::Config().GetParDIR(fName + ".mask");
     if (maskloc.empty()) {
       maskloc = FitPar::GetDataBase() + "/masks/" + fName + ".mask";
     }
 
     SetBinMask(maskloc);
   }
 
   fMCHist_Modes = new TrueModeStack( (fName + "_MODES").c_str(), ("True Channels"), fMCHist);
   SetAutoProcessTH1(fMCHist_Modes);
 
   return;
 }
 
 
 //********************************************************************
 JointMeas1D::~JointMeas1D(void) {
 //********************************************************************
 
   if (fDataHist)   delete fDataHist;
   if (fDataTrue)   delete fDataTrue;
   if (fMCHist)     delete fMCHist;
   if (fMCFine)     delete fMCFine;
   if (fMCWeighted) delete fMCWeighted;
   if (fMaskHist)   delete fMaskHist;
   if (covar)       delete covar;
   if (fFullCovar)  delete fFullCovar;
   if (fCovar)      delete fCovar;
   if (fInvert)     delete fInvert;
   if (fDecomp)     delete fDecomp;
 
   for (std::vector<MeasurementBase*>::const_iterator iter = fSubChain.begin();
        iter != fSubChain.end(); iter++) {
     MeasurementBase* exp = *iter;
     if (exp) delete exp;
   }
   fSubChain.clear();
 
 
 
 }
 
 //********************************************************************                                                                                                                                                                     
 SampleSettings JointMeas1D::LoadSampleSettings(nuiskey samplekey){
 //********************************************************************                                                                                                                                                                      
   SampleSettings s = MeasurementBase::LoadSampleSettings(samplekey);
 
   // Parse Inputs                                                                                                                                                                                                                          
   fSubInFiles.clear();
 
   std::vector<std::string> entries = GeneralUtils::ParseToStr(s.GetS("input"), ";");
 
   if (entries.size() < 2) {
     ERR(FTL) << "Joint measurement expected to recieve at least two semi-colon "
              "separated input files, but recieved: \""
              << s.GetS("input") << "\"" << std::endl;
     throw;
   }
 
   std::vector<std::string> first_file_descriptor =
     GeneralUtils::ParseToStr(entries.front(), ":");
 
   if (first_file_descriptor.size() != 2) {
     ERR(FTL) << "Found Joint measurement where the input file had no type: \""
              << s.GetS("input") << "\", expected \"INPUTTYPE:File.root;File2.root\"."
              << std::endl;
     throw;
   }
   std::string inpType = first_file_descriptor[0];
 
 
   for (std::vector<string>::iterator iter = entries.begin();
        iter != entries.end(); iter++) {
     if (GeneralUtils::ParseToStr(*iter, ":").size() != 2) {
       std::stringstream ss("");
       ss << inpType << ":" << (*iter);
       fSubInFiles.push_back(ss.str());
     } else {
       fSubInFiles.push_back(*iter);
     }
   }
 
   return s;
 }
 
 //********************************************************************
 void JointMeas1D::FinaliseSampleSettings() {
 //********************************************************************
 
   // Setup naming + renaming
   fName = fSettings.GetName();
   fSettings.SetS("originalname", fName);
   if (fSettings.Has("rename")) {
     fName = fSettings.GetS("rename");
     fSettings.SetS("name", fName);
   }
 
   // Setup all other options
   LOG(SAM) << "Finalising Sample Settings: " << fName << std::endl;
 
   if ((fSettings.GetS("originalname").find("Evt") != std::string::npos)) {
     fIsRawEvents = true;
     LOG(SAM) << "Found event rate measurement but using poisson likelihoods."
              << std::endl;
   }
 
   if (fSettings.GetS("originalname").find("XSec_1DEnu") != std::string::npos) {
     fIsEnu1D = true;
     LOG(SAM) << "::" << fName << "::" << std::endl;
     LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, "
              << "not flux averaged!" << std::endl;
   }
 
   if (fIsEnu1D && fIsRawEvents) {
     LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this "
              "really correct?!"
              << std::endl;
     LOG(SAM) << "Check experiment constructor for " << fName
              << " and correct this!" << std::endl;
     LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl;
     exit(-1);
   }
 
   // Parse Inputs
   fSubInFiles.clear();
 
   std::vector<std::string> entries = GeneralUtils::ParseToStr(fSettings.GetS("input"), ";");
 
   if (entries.size() < 2) {
     ERR(FTL) << "Joint measurement expected to recieve at least two semi-colon "
              "separated input files, but recieved: \""
              << fSettings.GetS("input") << "\"" << std::endl;
     throw;
   }
 
   std::vector<std::string> first_file_descriptor =
     GeneralUtils::ParseToStr(entries.front(), ":");
 
   if (first_file_descriptor.size() != 2) {
     ERR(FTL) << "Found Joint measurement where the input file had no type: \""
              << fSettings.GetS("input") << "\", expected \"INPUTTYPE:File.root;File2.root\"."
              << std::endl;
     throw;
   }
   std::string inpType = first_file_descriptor[0];
 
 
   for (std::vector<string>::iterator iter = entries.begin();
        iter != entries.end(); iter++) {
     if (GeneralUtils::ParseToStr(*iter, ":").size() != 2) {
       std::stringstream ss("");
       ss << inpType << ":" << (*iter);
       fSubInFiles.push_back(ss.str());
     } else {
       fSubInFiles.push_back(*iter);
     }
   }
 
 
   // Setup options
   SetFitOptions(fDefaultTypes); // defaults
   SetFitOptions(fSettings.GetS("type")); // user specified
 
   EnuMin = GeneralUtils::StrToDbl(fSettings.GetS("enu_min"));
   EnuMax = GeneralUtils::StrToDbl(fSettings.GetS("enu_max"));
 
   if (fAddNormPen) {
     if (fNormError <= 0.0) {
-      ERR(WRN) << "Norm error for class " << fName << " is 0.0!" << endl;
-      ERR(WRN) << "If you want to use it please add fNormError=VAL" << endl;
+      ERR(WRN) << "Norm error for class " << fName << " is 0.0!" << std::endl;
+      ERR(WRN) << "If you want to use it please add fNormError=VAL" << std::endl;
       throw;
     }
   }
 
   if (!fRW) fRW = FitBase::GetRW();
 
 
   LOG(SAM) << "Finalised Sample Settings" << std::endl;
 
 }
 
 //********************************************************************
 void JointMeas1D::SetDataFromTextFile(std::string datafile) {
 //********************************************************************
 
   LOG(SAM) << "Reading data from text file: " << datafile << std::endl;
   fDataHist = PlotUtils::GetTH1DFromFile(datafile,
                                          fSettings.GetName() + "_data",
                                          fSettings.GetFullTitles());
 
 }
 
 //********************************************************************
 void JointMeas1D::SetDataFromRootFile(std::string datafile,
                                         std::string histname) {
 //********************************************************************
 
   LOG(SAM) << "Reading data from root file: " << datafile << ";" << histname << std::endl;
   fDataHist = PlotUtils::GetTH1DFromRootFile(datafile, histname);
   fDataHist->SetNameTitle((fSettings.GetName() + "_data").c_str(),
                           (fSettings.GetFullTitles()).c_str());
 
   return;
 };
 
 //********************************************************************
 void JointMeas1D::SetPoissonErrors() {
 //********************************************************************
 
   if (!fDataHist) {
     ERR(FTL) << "Need a data hist to setup possion errors! " << std::endl;
     ERR(FTL) << "Setup Data First!" << std::endl;
     throw;
   }
 
   for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) {
     fDataHist->SetBinError(i + 1, sqrt(fDataHist->GetBinContent(i + 1)));
   }
 }
 
 //********************************************************************
 void JointMeas1D::SetCovarFromDiagonal(TH1D* data) {
 //********************************************************************
 
   if (!data and fDataHist) {
     data = fDataHist;
   }
 
   if (data) {
     LOG(SAM) << "Setting diagonal covariance for: " << data->GetName() << std::endl;
     fFullCovar = StatUtils::MakeDiagonalCovarMatrix(data);
     covar      = StatUtils::GetInvert(fFullCovar);
     fDecomp    = StatUtils::GetDecomp(fFullCovar);
   } else {
     ERR(FTL) << "No data input provided to set diagonal covar from!" << std::endl;
 
   }
 
   if (!fIsDiag) {
     ERR(FTL) << "SetCovarMatrixFromDiag called for measurement "
              << "that is not set as diagonal." << std::endl;
     throw;
   }
 
 }
 
 //********************************************************************
 void JointMeas1D::SetCovarFromTextFile(std::string covfile, int dim) {
 //********************************************************************
 
   LOG(SAM) << "Reading covariance from text file: " << covfile << std::endl;
   fFullCovar = StatUtils::GetCovarFromTextFile(covfile, dim);
   covar      = StatUtils::GetInvert(fFullCovar);
   fDecomp    = StatUtils::GetDecomp(fFullCovar);
 
 }
 
 //********************************************************************
 void JointMeas1D::SetCovarFromRootFile(std::string covfile, std::string histname) {
 //********************************************************************
 
   LOG(SAM) << "Reading covariance from text file: " << covfile << ";" << histname << std::endl;
   fFullCovar = StatUtils::GetCovarFromRootFile(covfile, histname);
   covar      = StatUtils::GetInvert(fFullCovar);
   fDecomp    = StatUtils::GetDecomp(fFullCovar);
 
 }
 
 //********************************************************************
 void JointMeas1D::SetCovarInvertFromTextFile(std::string covfile, int dim) {
 //********************************************************************
 
   LOG(SAM) << "Reading inverted covariance from text file: " << covfile << std::endl;
   covar       = StatUtils::GetCovarFromTextFile(covfile, dim);
   fFullCovar  = StatUtils::GetInvert(covar);
   fDecomp     = StatUtils::GetDecomp(fFullCovar);
 
 }
 
 //********************************************************************
 void JointMeas1D::SetCovarInvertFromRootFile(std::string covfile, std::string histname) {
 //********************************************************************
 
   LOG(SAM) << "Reading inverted covariance from text file: " << covfile << ";" << histname << std::endl;
   covar      = StatUtils::GetCovarFromRootFile(covfile, histname);
   fFullCovar = StatUtils::GetInvert(covar);
   fDecomp    = StatUtils::GetDecomp(fFullCovar);
 
 }
 
 //********************************************************************
 void JointMeas1D::SetCorrelationFromTextFile(std::string covfile, int dim) {
 //********************************************************************
 
   if (dim == -1) dim = fDataHist->GetNbinsX();
   LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << dim << std::endl;
   TMatrixDSym* correlation = StatUtils::GetCovarFromTextFile(covfile, dim);
 
   if (!fDataHist) {
     ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n"
              << "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl;
     throw;
   }
 
   // Fill covar from data errors and correlations
   fFullCovar = new TMatrixDSym(dim);
   for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
     for (int j = 0; j < fDataHist->GetNbinsX(); j++) {
       (*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76;
     }
   }
 
   // Fill other covars.
   covar   = StatUtils::GetInvert(fFullCovar);
   fDecomp = StatUtils::GetDecomp(fFullCovar);
 
   delete correlation;
 }
 
 //********************************************************************
 void JointMeas1D::SetCorrelationFromRootFile(std::string covfile, std::string histname) {
 //********************************************************************
 
   LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << histname << std::endl;
   TMatrixDSym* correlation = StatUtils::GetCovarFromRootFile(covfile, histname);
 
   if (!fDataHist) {
     ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n"
              << "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl;
     throw;
   }
 
   // Fill covar from data errors and correlations
   fFullCovar = new TMatrixDSym(fDataHist->GetNbinsX());
   for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
     for (int j = 0; j < fDataHist->GetNbinsX(); j++) {
       (*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76;
     }
   }
 
   // Fill other covars.
   covar   = StatUtils::GetInvert(fFullCovar);
   fDecomp = StatUtils::GetDecomp(fFullCovar);
 
   delete correlation;
 }
 
 
 //********************************************************************
 void JointMeas1D::SetCholDecompFromTextFile(std::string covfile, int dim) {
 //********************************************************************
 
   LOG(SAM) << "Reading cholesky from text file: " << covfile << std::endl;
   TMatrixD* temp = StatUtils::GetMatrixFromTextFile(covfile, dim, dim);
 
   TMatrixD* trans = (TMatrixD*)temp->Clone();
   trans->T();
   (*trans) *= (*temp);
 
   fFullCovar  = new TMatrixDSym(dim, trans->GetMatrixArray(), "");
   covar       = StatUtils::GetInvert(fFullCovar);
   fDecomp     = StatUtils::GetDecomp(fFullCovar);
 
   delete temp;
   delete trans;
 
 }
 
 //********************************************************************
 void JointMeas1D::SetCholDecompFromRootFile(std::string covfile, std::string histname) {
 //********************************************************************
 
   LOG(SAM) << "Reading cholesky decomp from root file: " << covfile << ";" << histname << std::endl;
   TMatrixD* temp = StatUtils::GetMatrixFromRootFile(covfile, histname);
 
   TMatrixD* trans = (TMatrixD*)temp->Clone();
   trans->T();
   (*trans) *= (*temp);
 
   fFullCovar  = new TMatrixDSym(temp->GetNrows(), trans->GetMatrixArray(), "");
   covar       = StatUtils::GetInvert(fFullCovar);
   fDecomp     = StatUtils::GetDecomp(fFullCovar);
 
   delete temp;
   delete trans;
 }
 
 
 //********************************************************************
 void JointMeas1D::ScaleData(double scale) {
 //********************************************************************
   fDataHist->Scale(scale);
 }
 
 //********************************************************************
 void JointMeas1D::ScaleCovar(double scale) {
 //********************************************************************
   (*fFullCovar) *= scale;
   (*covar) *= 1.0 / scale;
   (*fDecomp) *= sqrt(scale);
 }
 
 
 //********************************************************************
 void JointMeas1D::SetBinMask(std::string maskfile) {
 //********************************************************************
 
   if (!fIsMask) return;
   LOG(SAM) << "Reading bin mask from file: " << maskfile << std::endl;
 
   // Create a mask histogram with dim of data
   int nbins = fDataHist->GetNbinsX();
   fMaskHist =
     new TH1I((fSettings.GetName() + "_BINMASK").c_str(),
              (fSettings.GetName() + "_BINMASK; Bin; Mask?").c_str(), nbins, 0, nbins);
   std::string line;
   std::ifstream mask(maskfile.c_str(), ifstream::in);
 
   if (!mask.is_open()) {
     LOG(FTL) << " Cannot find mask file." << std::endl;
     throw;
   }
 
   while (std::getline(mask >> std::ws, line, '\n')) {
     std::vector<int> entries = GeneralUtils::ParseToInt(line, " ");
 
     // Skip lines with poorly formatted lines
     if (entries.size() < 2) {
       LOG(WRN) << "JointMeas1D::SetBinMask(), couldn't parse line: " << line
                << std::endl;
       continue;
     }
 
     // The first index should be the bin number, the second should be the mask
     // value.
     int val = 0;
     if (entries[1] > 0) val = 1;
     fMaskHist->SetBinContent(entries[0], val);
   }
 
   // Apply masking by setting masked data bins to zero
   PlotUtils::MaskBins(fDataHist, fMaskHist);
 
   return;
 }
 
 
 
 //********************************************************************
 void JointMeas1D::FinaliseMeasurement() {
 //********************************************************************
 
   LOG(SAM) << "Finalising Measurement: " << fName << std::endl;
 
   // Make sure data is setup
   if (!fDataHist) {
     ERR(FTL) << "No data has been setup inside " << fName << " constructor!" << std::endl;
     throw;
   }
 
   // Make sure covariances are setup
   if (!fFullCovar) {
     SetCovarFromDiagonal(fDataHist);
   }
 
   if (!covar) {
     covar = StatUtils::GetInvert(fFullCovar);
   }
 
   if (!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(),
                      fMCHist->GetBinLowEdge(1),
                      fMCHist->GetBinLowEdge(fDataHist->GetNbinsX() + 1));
   fMCFine->SetNameTitle((fSettings.GetName() + "_MC_FINE").c_str(),
                         (fSettings.GetFullTitles()).c_str());
   fMCFine->Reset();
 
   // Setup MC Stat
   fMCStat = (TH1D*)fMCHist->Clone();
   fMCStat->Reset();
 
   // Search drawopts for possible types to include by default
   std::string drawopts = FitPar::Config().GetParS("drawopts");
   if (drawopts.find("MODES") != std::string::npos) {
     fMCHist_Modes = new TrueModeStack( (fSettings.GetName() + "_MODES").c_str(),
                                        ("True Channels"), fMCHist);
     SetAutoProcessTH1(fMCHist_Modes);
   }
 
   // Setup bin masks using sample name
   if (fIsMask) {
 
     std::string curname  = fName;
     std::string origname = fSettings.GetS("originalname");
 
     // Check rename.mask
     std::string maskloc = FitPar::Config().GetParDIR(curname + ".mask");
 
     // Check origname.mask
     if (maskloc.empty()) maskloc = FitPar::Config().GetParDIR(origname + ".mask");
 
     // Check database
     if (maskloc.empty()) {
       maskloc = FitPar::GetDataBase() + "/masks/" + origname + ".mask";
     }
 
     // Setup Bin Mask
     SetBinMask(maskloc);
   }
 
   /*
   if (fScaleFactor < 0) {
     ERR(FTL) << "I found a negative fScaleFactor in " << __FILE__ << ":" << __LINE__ << std::endl;
     ERR(FTL) << "fScaleFactor = " << fScaleFactor << std::endl;
     ERR(FTL) << "EXITING" << std::endl;
     throw;
   }
   */
 
   // Create and fill Weighted Histogram
   if (!fMCWeighted) {
 
     fMCWeighted = (TH1D*)fMCHist->Clone();
     fMCWeighted->SetNameTitle((fName + "_MCWGHTS").c_str(),
                               (fName + "_MCWGHTS" + fPlotTitles).c_str());
     fMCWeighted->GetYaxis()->SetTitle("Weighted Events");
 
   }
 
 
 }
 
 //********************************************************************
 void JointMeas1D::SetFitOptions(std::string opt) {
 //********************************************************************
 
   // Do nothing if default given
   if (opt == "DEFAULT") return;
 
   // CHECK Conflicting Fit Options
   std::vector<std::string> fit_option_allow =
     GeneralUtils::ParseToStr(fAllowedTypes, "/");
 
   for (UInt_t i = 0; i < fit_option_allow.size(); i++) {
     std::vector<std::string> fit_option_section =
       GeneralUtils::ParseToStr(fit_option_allow.at(i), ",");
 
     bool found_option = false;
 
     for (UInt_t j = 0; j < fit_option_section.size(); j++) {
       std::string av_opt = fit_option_section.at(j);
 
       if (!found_option and opt.find(av_opt) != std::string::npos) {
         found_option = true;
 
       } else if (found_option and opt.find(av_opt) != std::string::npos) {
         ERR(FTL) << "ERROR: Conflicting fit options provided: "
                  << opt << std::endl
                  << "Conflicting group = " << fit_option_section.at(i) << std::endl
                  << "You should only supply one of these options in card file." << std::endl;
         throw;
       }
     }
   }
 
   // Check all options are allowed
   std::vector<std::string> fit_options_input =
     GeneralUtils::ParseToStr(opt, "/");
   for (UInt_t i = 0; i < fit_options_input.size(); i++) {
     if (fAllowedTypes.find(fit_options_input.at(i)) == std::string::npos) {
       ERR(FTL) << "ERROR: Fit Option '" << fit_options_input.at(i)
                << "' Provided is not allowed for this measurement."
                << std::endl;
       ERR(FTL) << "Fit Options should be provided as a '/' seperated list "
                "(e.g. FREE/DIAG/NORM)"
                << std::endl;
       ERR(FTL) << "Available options for " << fName << " are '" << fAllowedTypes
                << "'" << std::endl;
 
       throw;
     }
   }
 
   // Set TYPE
   fFitType = opt;
 
   // FIX,SHAPE,FREE
   if (opt.find("FIX") != std::string::npos) {
     fIsFree = fIsShape = false;
     fIsFix = true;
   } else if (opt.find("SHAPE") != std::string::npos) {
     fIsFree = fIsFix = false;
     fIsShape = true;
   } else if (opt.find("FREE") != std::string::npos) {
     fIsFix = fIsShape = false;
     fIsFree = true;
   }
 
   // DIAG,FULL (or default to full)
   if (opt.find("DIAG") != std::string::npos) {
     fIsDiag = true;
     fIsFull = false;
   } else if (opt.find("FULL") != std::string::npos) {
     fIsDiag = false;
     fIsFull = true;
   }
 
   // CHI2/LL (OTHERS?)
   if (opt.find("LOG") != std::string::npos) {
     fIsChi2 = false;
 
     ERR(FTL) << "No other LIKELIHOODS properly supported!" << std::endl;
     ERR(FTL) << "Try to use a chi2!" << std::endl;
     throw;
 
   } else {
     fIsChi2 = true;
   }
 
   // EXTRAS
   if (opt.find("RAW") != std::string::npos) fIsRawEvents = true;
   if (opt.find("DIF") != std::string::npos) fIsDifXSec = true;
   if (opt.find("ENU1D") != std::string::npos) fIsEnu1D = true;
   if (opt.find("NORM") != std::string::npos) fAddNormPen = true;
   if (opt.find("MASK") != std::string::npos) fIsMask = true;
 
   return;
 };
 
 
 //********************************************************************
 void JointMeas1D::SetSmearingMatrix(std::string smearfile, int truedim,
                                       int recodim) {
   //********************************************************************
 
   // The smearing matrix describes the migration from true bins (rows) to reco
   // bins (columns)
   // Counter over the true bins!
   int row = 0;
 
   std::string line;
   std::ifstream smear(smearfile.c_str(), ifstream::in);
 
   // Note that the smearing matrix may be rectangular.
   fSmearMatrix = new TMatrixD(truedim, recodim);
 
   if (smear.is_open())
     LOG(SAM) << "Reading smearing matrix from file: " << smearfile << std::endl;
   else
     ERR(FTL) << "Smearing matrix provided is incorrect: " << smearfile
              << std::endl;
 
   while (std::getline(smear >> std::ws, line, '\n')) {
     int column = 0;
 
     std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
     for (std::vector<double>::iterator iter = entries.begin();
          iter != entries.end(); iter++) {
       (*fSmearMatrix)(row, column) =
         (*iter) / 100.;  // Convert to fraction from
       // percentage (this may not be
       // general enough)
       column++;
     }
     row++;
   }
   return;
 }
 
 //********************************************************************
 void JointMeas1D::ApplySmearingMatrix() {
 //********************************************************************
 
   if (!fSmearMatrix) {
     ERR(WRN) << fName
              << ": attempted to apply smearing matrix, but none was set"
              << std::endl;
     return;
   }
 
   TH1D* unsmeared = (TH1D*)fMCHist->Clone();
   TH1D* smeared = (TH1D*)fMCHist->Clone();
   smeared->Reset();
 
   // Loop over reconstructed bins
   // true = row; reco = column
   for (int rbin = 0; rbin < fSmearMatrix->GetNcols(); ++rbin) {
     // Sum up the constributions from all true bins
     double rBinVal = 0;
 
     // Loop over true bins
     for (int tbin = 0; tbin < fSmearMatrix->GetNrows(); ++tbin) {
       rBinVal +=
         (*fSmearMatrix)(tbin, rbin) * unsmeared->GetBinContent(tbin + 1);
     }
     smeared->SetBinContent(rbin + 1, rBinVal);
   }
   fMCHist = (TH1D*)smeared->Clone();
 
   return;
 }
 
 /*
    Reconfigure LOOP
 */
 //********************************************************************
 void JointMeas1D::ResetAll() {
 //********************************************************************
 
   fMCHist->Reset();
   fMCFine->Reset();
   fMCStat->Reset();
 
   return;
 };
 
 //********************************************************************
 void JointMeas1D::FillHistograms() {
   //********************************************************************
 
   if (Signal) {
     fMCHist->Fill(fXVar, Weight);
     fMCFine->Fill(fXVar, Weight);
     fMCStat->Fill(fXVar, 1.0);
 
     if (fMCHist_Modes) fMCHist_Modes->Fill(Mode, fXVar, Weight);
   }
 
   return;
 };
 
 //********************************************************************
 void JointMeas1D::ScaleEvents() {
 //********************************************************************
 
   LOG(FIT) << "Scaling JointMeas1D" << std::endl;
 
   // Fill MCWeighted;
   for (int i = 0; i < fMCHist->GetNbinsX(); i++) {
     fMCWeighted->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1));
     fMCWeighted->SetBinError(i + 1,   fMCHist->GetBinError(i + 1));
   }
 
 
   // Setup Stat ratios for MC and MC Fine
   double* statratio     = new double[fMCHist->GetNbinsX()];
   for (int i = 0; i < fMCHist->GetNbinsX(); i++) {
     if (fMCHist->GetBinContent(i + 1) != 0) {
       statratio[i] = fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1);
     } else {
       statratio[i] = 0.0;
     }
   }
 
   double* statratiofine = new double[fMCFine->GetNbinsX()];
   for (int i = 0; i < fMCFine->GetNbinsX(); i++) {
     if (fMCFine->GetBinContent(i + 1) != 0) {
       statratiofine[i] = fMCFine->GetBinError(i + 1) / fMCFine->GetBinContent(i + 1);
     } else {
       statratiofine[i] = 0.0;
     }
   }
 
 
   // Scaling for raw event rates
   if (fIsRawEvents) {
     double datamcratio = fDataHist->Integral() / fMCHist->Integral();
 
     fMCHist->Scale(datamcratio);
     fMCFine->Scale(datamcratio);
 
     if (fMCHist_Modes) fMCHist_Modes->Scale(datamcratio);
 
     // Scaling for XSec as function of Enu
   } else if (fIsEnu1D) {
 
     PlotUtils::FluxUnfoldedScaling(fMCHist, GetFluxHistogram(),
                                    GetEventHistogram(), fScaleFactor,
                                    fNEvents);
     PlotUtils::FluxUnfoldedScaling(fMCFine, GetFluxHistogram(),
                                    GetEventHistogram(), fScaleFactor,
                                    fNEvents);
 
 
     // if (fMCHist_Modes) {
     // PlotUtils::FluxUnfoldedScaling(fMCHist_Modes, GetFluxHistogram(),
     // GetEventHistogram(), fScaleFactor,
     // fNEvents);
     // }
 
     // Any other differential scaling
   } else {
     fMCHist->Scale(fScaleFactor, "width");
     fMCFine->Scale(fScaleFactor, "width");
 
     if (fMCHist_Modes) fMCHist_Modes->Scale(fScaleFactor, "width");
   }
 
 
   // Proper error scaling - ROOT Freaks out with xsec weights sometimes
   for (int i = 0; i < fMCStat->GetNbinsX(); i++) {
     fMCHist->SetBinError(i + 1, fMCHist->GetBinContent(i + 1) * statratio[i]);
   }
 
   for (int i = 0; i < fMCFine->GetNbinsX(); i++) {
     fMCFine->SetBinError(i + 1, fMCFine->GetBinContent(i + 1) * statratiofine[i]);
   }
 
 
   // Clean up
   delete statratio;
   delete statratiofine;
 
   return;
 };
 
 //********************************************************************
 void JointMeas1D::ApplyNormScale(double norm) {
 //********************************************************************
 
   fCurrentNorm = norm;
 
   fMCHist->Scale(1.0 / norm);
   fMCFine->Scale(1.0 / norm);
 
   return;
 };
 
 
 
 /*
    Statistic Functions - Outsources to StatUtils
 */
 
 //********************************************************************
 int JointMeas1D::GetNDOF() {
   //********************************************************************
   return fDataHist->GetNbinsX() - fMaskHist->Integral();
 }
 
 //********************************************************************
 double JointMeas1D::GetLikelihood() {
 //********************************************************************
 
   // If this is for a ratio, there is no data histogram to compare to!
   if (fNoData || !fDataHist) return 0.;
 
   // Apply Masking to MC if Required.
   if (fIsMask and fMaskHist) {
     PlotUtils::MaskBins(fMCHist, fMaskHist);
   }
 
 
   // Sort Shape Scaling
   double scaleF = 0.0;
   if (fIsShape) {
     if (fMCHist->Integral(1, fMCHist->GetNbinsX(), "width")) {
       scaleF = fDataHist->Integral(1, fDataHist->GetNbinsX(), "width") /
                fMCHist->Integral(1, fMCHist->GetNbinsX(), "width");
       fMCHist->Scale(scaleF);
       fMCFine->Scale(scaleF);
     }
   }
 
 
   // Likelihood Calculation
   double stat = 0.;
   if (fIsChi2) {
 
     if (fIsRawEvents) {
       stat = StatUtils::GetChi2FromEventRate(fDataHist, fMCHist, fMaskHist);
     } else if (fIsDiag) {
       stat = StatUtils::GetChi2FromDiag(fDataHist, fMCHist, fMaskHist);
     } else if (!fIsDiag and !fIsRawEvents) {
       stat = StatUtils::GetChi2FromCov(fDataHist, fMCHist, covar, fMaskHist);
     }
 
   }
 
   // Sort Penalty Terms
   if (fAddNormPen) {
     double penalty =
       (1. - fCurrentNorm) * (1. - fCurrentNorm) / (fNormError * fNormError);
 
     stat += penalty;
   }
 
   // Return to normal scaling
   if (fIsShape and !FitPar::Config().GetParB("saveshapescaling")) {
     fMCHist->Scale(1. / scaleF);
     fMCFine->Scale(1. / scaleF);
   }
 
   return stat;
 }
 
 
 /*
   Fake Data Functions
 */
 //********************************************************************
 void JointMeas1D::SetFakeDataValues(std::string fakeOption) {
 //********************************************************************
 
   // Setup original/datatrue
   TH1D* tempdata = (TH1D*) fDataHist->Clone();
 
   if (!fIsFakeData) {
     fIsFakeData = true;
 
     // Make a copy of the original data histogram.
     if (!fDataOrig) fDataOrig = (TH1D*)fDataHist->Clone((fName + "_data_original").c_str());
 
   } else {
     ResetFakeData();
 
   }
 
   // Setup Inputs
   fFakeDataInput = fakeOption;
   LOG(SAM) << "Setting fake data from : " << fFakeDataInput << std::endl;
 
   // From MC
   if (fFakeDataInput.compare("MC") == 0) {
     fDataHist = (TH1D*)fMCHist->Clone((fName + "_MC").c_str());
 
     // Fake File
   } else {
     if (!fFakeDataFile) fFakeDataFile = new TFile(fFakeDataInput.c_str(), "READ");
     fDataHist = (TH1D*)fFakeDataFile->Get((fName + "_MC").c_str());
 
   }
 
   // Setup Data Hist
   fDataHist->SetNameTitle((fName + "_FAKE").c_str(),
                           (fName + fPlotTitles).c_str());
 
   // Replace Data True
   if (fDataTrue) delete fDataTrue;
   fDataTrue = (TH1D*)fDataHist->Clone();
   fDataTrue->SetNameTitle((fName + "_FAKE_TRUE").c_str(),
                           (fName + fPlotTitles).c_str());
 
 
   // Make a new covariance for fake data hist.
   int nbins = fDataHist->GetNbinsX();
   double alpha_i = 0.0;
   double alpha_j = 0.0;
 
   for (int i = 0; i < nbins; i++) {
     for (int j = 0; j < nbins; j++) {
       alpha_i = fDataHist->GetBinContent(i + 1) / tempdata->GetBinContent(i + 1);
       alpha_j = fDataHist->GetBinContent(j + 1) / tempdata->GetBinContent(j + 1);
 
       (*fFullCovar)(i, j) = alpha_i * alpha_j * (*fFullCovar)(i, j);
     }
   }
 
   // Setup Covariances
   if (covar) delete covar;
   covar   = StatUtils::GetInvert(fFullCovar);
 
   if (fDecomp) delete fDecomp;
   fDecomp = StatUtils::GetInvert(fFullCovar);
 
   delete tempdata;
 
   return;
 };
 
 //********************************************************************
 void JointMeas1D::ResetFakeData() {
 //********************************************************************
 
   if (fIsFakeData) {
     if (fDataHist) delete fDataHist;
     fDataHist = (TH1D*)fDataTrue->Clone((fSettings.GetName() + "_FKDAT").c_str());
   }
 
 }
 
 //********************************************************************
 void JointMeas1D::ResetData() {
 //********************************************************************
 
   if (fIsFakeData) {
     if (fDataHist) delete fDataHist;
     fDataHist = (TH1D*)fDataOrig->Clone((fSettings.GetName() + "_data").c_str());
   }
 
   fIsFakeData = false;
 }
 
 //********************************************************************
 void JointMeas1D::ThrowCovariance() {
 //********************************************************************
 
   // Take a fDecomposition and use it to throw the current dataset.
   // Requires fDataTrue also be set incase used repeatedly.
 
   if (fDataHist) delete fDataHist;
   fDataHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar);
 
   return;
 };
 
 /*
    Access Functions
 */
 
 //********************************************************************
 TH1D* JointMeas1D::GetMCHistogram() {
 //********************************************************************
 
   if (!fMCHist) return fMCHist;
 
   std::ostringstream chi2;
   chi2 << std::setprecision(5) << this->GetLikelihood();
 
   int linecolor = kRed;
   int linestyle = 1;
   int linewidth = 1;
 
   int fillcolor = 0;
   int fillstyle = 1001;
 
   if (fSettings.Has("linecolor")) linecolor = fSettings.GetI("linecolor");
   if (fSettings.Has("linestyle")) linestyle = fSettings.GetI("linestyle");
   if (fSettings.Has("linewidth")) linewidth = fSettings.GetI("linewidth");
 
   if (fSettings.Has("fillcolor")) fillcolor = fSettings.GetI("fillcolor");
   if (fSettings.Has("fillstyle")) fillstyle = fSettings.GetI("fillstyle");
 
   fMCHist->SetTitle(chi2.str().c_str());
 
   fMCHist->SetLineColor(linecolor);
   fMCHist->SetLineStyle(linestyle);
   fMCHist->SetLineWidth(linewidth);
 
   fMCHist->SetFillColor(fillcolor);
   fMCHist->SetFillStyle(fillstyle);
 
   return fMCHist;
 };
 
 //********************************************************************
 TH1D* JointMeas1D::GetDataHistogram() {
 //********************************************************************
 
   if (!fDataHist) return fDataHist;
 
   int datacolor = kBlack;
   int datastyle = 1;
   int datawidth = 1;
 
   if (fSettings.Has("datacolor")) datacolor = fSettings.GetI("datacolor");
   if (fSettings.Has("datastyle")) datastyle = fSettings.GetI("datastyle");
   if (fSettings.Has("datawidth")) datawidth = fSettings.GetI("datawidth");
 
   fDataHist->SetLineColor(datacolor);
   fDataHist->SetLineWidth(datawidth);
   fDataHist->SetMarkerStyle(datastyle);
 
   return fDataHist;
 };
 
 
 /*
    Write Functions
 */
 
 // Save all the histograms at once
 //********************************************************************
 void JointMeas1D::Write(std::string drawOpt) {
 //********************************************************************
 
   // Get Draw Options
   drawOpt = FitPar::Config().GetParS("drawopts");
 
   // Write 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 and Shape Plots
   if (drawOpt.find("RATIO") != std::string::npos) {
     WriteRatioPlot();
   }
 
   if (drawOpt.find("SHAPE") != std::string::npos) {
     WriteShapePlot();
     if (drawOpt.find("RATIO") != std::string::npos)
       WriteShapeRatioPlot();
   }
 
   // // RATIO
   // if (drawOpt.find("CANVMC") != std::string::npos) {
   //   TCanvas* c1 = WriteMCCanvas(fDataHist, fMCHist);
   //   c1->Write();
   //   delete c1;
   // }
 
   // // PDG
   // if (drawOpt.find("CANVPDG") != std::string::npos && fMCHist_Modes) {
   //   TCanvas* c2 = WritePDGCanvas(fDataHist, fMCHist, fMCHist_Modes);
   //   c2->Write();
   //   delete c2;
   // }
 
   // Write Extra Histograms
   AutoWriteExtraTH1();
   WriteExtraHistograms();
 
   if (fSaveSubMeas) {
     for (std::vector<MeasurementBase*>::const_iterator expIter =
            fSubChain.begin();
          expIter != fSubChain.end(); expIter++) {
       MeasurementBase* exp = *expIter;
       exp->Write(drawOpt);
     }
   }
 
   // Returning
   LOG(SAM) << "Written Histograms: " << fName << std::endl;
   return;
 }
 
 
 //********************************************************************
 void JointMeas1D::WriteRatioPlot() {
 //********************************************************************
 
   // Setup mc data ratios
   TH1D* dataRatio = (TH1D*)fDataHist->Clone((fName + "_data_RATIO").c_str());
   TH1D* mcRatio   = (TH1D*)fMCHist->Clone((fName + "_MC_RATIO").c_str());
 
   // Extra MC Data Ratios
   for (int i = 0; i < mcRatio->GetNbinsX(); i++) {
 
     dataRatio->SetBinContent(i + 1, fDataHist->GetBinContent(i + 1) / fMCHist->GetBinContent(i + 1));
     dataRatio->SetBinError(i + 1,   fDataHist->GetBinError(i + 1)   / fMCHist->GetBinContent(i + 1));
 
     mcRatio->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1) / fMCHist->GetBinContent(i + 1));
     mcRatio->SetBinError(i + 1,   fMCHist->GetBinError(i + 1)   / fMCHist->GetBinContent(i + 1));
 
   }
 
   // Write ratios
   mcRatio->Write();
   dataRatio->Write();
 
   delete mcRatio;
   delete dataRatio;
 }
 
 
 //********************************************************************
 void JointMeas1D::WriteShapePlot() {
 //********************************************************************
 
   TH1D* mcShape = (TH1D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str());
 
   double shapeScale = 1.0;
   if (fIsRawEvents) {
     shapeScale = fDataHist->Integral() / fMCHist->Integral();
   } else {
     shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width");
   }
 
   mcShape->Scale(shapeScale);
 
   std::stringstream ss;
   ss << shapeScale;
   mcShape->SetTitle(ss.str().c_str());
 
   mcShape->SetLineWidth(3);
   mcShape->SetLineStyle(7);
 
   mcShape->Write();
 
   delete mcShape;
 
 }
 
 //********************************************************************
 void JointMeas1D::WriteShapeRatioPlot() {
 //********************************************************************
 
   // Get a mcshape histogram
   TH1D* mcShape = (TH1D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str());
 
   double shapeScale = 1.0;
   if (fIsRawEvents) {
     shapeScale = fDataHist->Integral() / fMCHist->Integral();
   } else {
     shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width");
   }
 
   mcShape->Scale(shapeScale);
 
   // Create shape ratio histograms
   TH1D* mcShapeRatio   = (TH1D*)mcShape->Clone((fName + "_MC_SHAPE_RATIO").c_str());
   TH1D* dataShapeRatio = (TH1D*)fDataHist->Clone((fName + "_data_SHAPE_RATIO").c_str());
 
   // Divide the histograms
   mcShapeRatio->Divide(mcShape);
   dataShapeRatio->Divide(mcShape);
 
   // Colour the shape ratio plots
   mcShapeRatio->SetLineWidth(3);
   mcShapeRatio->SetLineStyle(7);
 
   mcShapeRatio->Write();
   dataShapeRatio->Write();
 
   delete mcShapeRatio;
   delete dataShapeRatio;
 
 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
 #include "JointMeas1D.h"
 
 /*
   Constructor/Deconstuctor
 */
 
 
 /*
   Setup Functions
 */
 //********************************************************************
 void JointMeas1D::SetupMeasurement(std::string input, std::string type,
                                    FitWeight* rw, std::string fkdt) {
   //********************************************************************
 
   // For joint samples, input files are given as a semi-colon seperated list.
   // Parse this list and save it for later, and set up the types etc.
 
   if (FitPar::Config().GetParB("EventManager")) {
     ERR(FTL) << "Event Manager does not yet work with JointMeas1D Samples" << std::endl;
     ERR(FTL) << "If you want good predictions for " << fName << " then run with it turned off! (-q EventManager=0)" << std::endl;
   }
 
   fSubInFiles.clear();
 
   std::vector<std::string> entries = GeneralUtils::ParseToStr(input, ";");
 
   if (entries.size() < 2) {
     ERR(FTL) << "Joint measurement expected to recieve at least two semi-colon "
              "separated input files, but recieved: \""
              << input << "\"" << std::endl;
     throw;
   }
 
   std::vector<std::string> first_file_descriptor =
     GeneralUtils::ParseToStr(entries.front(), ":");
 
   if (first_file_descriptor.size() != 2) {
     ERR(FTL) << "Found Joint measurement where the input file had no type: \""
              << input << "\", expected \"INPUTTYPE:File.root;File2.root\"."
              << std::endl;
     throw;
   }
   std::string inpType = first_file_descriptor[0];
 
 
   for (std::vector<string>::iterator iter = entries.begin();
        iter != entries.end(); iter++) {
     if (GeneralUtils::ParseToStr(*iter, ":").size() != 2) {
       std::stringstream ss("");
       ss << inpType << ":" << (*iter);
       fSubInFiles.push_back(ss.str());
     } else {
       fSubInFiles.push_back(*iter);
     }
   }
 
   // Set Engine and Fake Data
   fRW = rw;
   fFakeDataInput = fkdt;
 
   // Set Fit Options
   SetFitOptions(type);
 
   return;
 }
 
 /*
   XSec Functions
 */
 //********************************************************************
 double JointMeas1D::TotalIntegratedFlux(std::string intOpt, double low,
                                         double high) {
 //********************************************************************
 
   double totalflux = 0.0;
 
   // Destroy the job for sub samples
   for (std::vector<MeasurementBase*>::const_iterator expIter =
          fSubChain.begin();
        expIter != fSubChain.end(); expIter++) {
     MeasurementBase* exp = *expIter;
     double expflux = exp->TotalIntegratedFlux(intOpt, low, high);
 
     // Fill flux options
     if (fIsRatio) {
       totalflux = expflux;
       break;
     }
     if (fIsSummed) {
       totalflux += expflux;
     }
   }
 
   return totalflux;
 }
 
 /*
   Reconfigure Functions
 */
 
 //********************************************************************
 void JointMeas1D::Reconfigure() {
 //********************************************************************
 
   for (std::vector<MeasurementBase*>::const_iterator expIter =
          fSubChain.begin();
        expIter != fSubChain.end(); expIter++) {
     MeasurementBase* exp = *expIter;
     exp->Reconfigure();
   }
 
   ConvertEventRates();
   return;
 }
 
 //********************************************************************
 void JointMeas1D::ConvertEventRates() {
 //********************************************************************
 
   // Apply Event Scaling                                                                                                                                                                                                                   
   for (std::vector<MeasurementBase*>::const_iterator expIter =
          fSubChain.begin();
        expIter != fSubChain.end(); expIter++) {
     MeasurementBase* exp = static_cast<MeasurementBase*>(*expIter);
     exp->ScaleEvents();
   }
 
 
   // Joint function called by top level class
   MakePlots();
 
   // Do Final Normalisation
   ApplyNormScale(fRW->GetSampleNorm(this->fName));
 
 }
 
 //********************************************************************
 void JointMeas1D::MakePlots() {
 //********************************************************************
 
   // Reset the 1D histograms but not the subClasses
   ResetAll();
 
   // If Summed
   if (fIsSummed) {
     for (std::vector<MeasurementBase*>::const_iterator expIter =
            fSubChain.begin();
          expIter != fSubChain.end(); expIter++) {
       MeasurementBase* exp = static_cast<MeasurementBase*>(*expIter);
 
       this->fMCHist->Add(exp->GetMCList().at(0));
       this->fMCFine->Add(exp->GetFineList().at(0));
     }
 
     return;
   }
 
   // If Ratio
   if (fIsRatio) {
     int sample = 0;
     for (std::vector<MeasurementBase*>::const_iterator expIter =
            fSubChain.begin();
          expIter != fSubChain.end(); expIter++) {
       MeasurementBase* exp = *expIter;
 
       if (sample == 0) {
         this->fMCHist->Add(exp->GetMCList().at(0));
         this->fMCFine->Add(exp->GetFineList().at(0));
 
       } else if (sample == 1) {
         this->fMCHist->Divide(exp->GetMCList().at(0));
         this->fMCFine->Divide(exp->GetFineList().at(0));
 
       } else {
         break;
       }
 
       sample++;
     }
     return;
   }
 
   return;
 }
 
 /*
   Access Functions
 */
 
 //********************************************************************
 std::vector<TH1*> JointMeas1D::GetMCList() {
   //********************************************************************
 
   // Make Default Vector
   std::vector<TH1*> tempVect;
   tempVect.push_back(this->fMCHist);
 
   // Return vector from all sub samples
   for (std::vector<MeasurementBase*>::const_iterator expIter =
          fSubChain.begin();
        expIter != fSubChain.end(); expIter++) {
     MeasurementBase* exp = *expIter;
 
     std::vector<TH1*> subTempVect = exp->GetMCList();
 
     for (UInt_t i = 0; i < subTempVect.size(); i++) {
       tempVect.push_back(subTempVect.at(i));
     }
   }
 
   return tempVect;
 }
 
 //********************************************************************
 std::vector<TH1*> JointMeas1D::GetDataList() {
   //********************************************************************
 
   // Make Default Vector
   std::vector<TH1*> tempVect;
   tempVect.push_back(this->fDataHist);
 
   // Return vector from all sub samples
   for (std::vector<MeasurementBase*>::const_iterator expIter =
          fSubChain.begin();
        expIter != fSubChain.end(); expIter++) {
     MeasurementBase* exp = *expIter;
 
     std::vector<TH1*> subTempVect = exp->GetDataList();
 
     for (UInt_t i = 0; i < subTempVect.size(); i++) {
       tempVect.push_back(subTempVect.at(i));
     }
   }
 
   return tempVect;
 }
 
 //********************************************************************
 std::vector<TH1*> JointMeas1D::GetFineList() {
   //********************************************************************
 
   // Make Default Vector
   std::vector<TH1*> tempVect;
   tempVect.push_back(this->fMCFine);
 
   // Return vector from all sub samples
   for (std::vector<MeasurementBase*>::const_iterator expIter =
          fSubChain.begin();
        expIter != fSubChain.end(); expIter++) {
     MeasurementBase* exp = *expIter;
 
     std::vector<TH1*> subTempVect = exp->GetFineList();
 
     for (UInt_t i = 0; i < subTempVect.size(); i++) {
       tempVect.push_back(subTempVect.at(i));
     }
   }
 
   return tempVect;
 }
 
 //********************************************************************
 std::vector<TH1*> JointMeas1D::GetMaskList() {
   //********************************************************************
 
   // Make Default Vector
   std::vector<TH1*> tempVect;
   tempVect.push_back(this->fMaskHist);
 
   // Return vector from all sub samples
   for (std::vector<MeasurementBase*>::const_iterator expIter =
          fSubChain.begin();
        expIter != fSubChain.end(); expIter++) {
     MeasurementBase* exp = *expIter;
 
     std::vector<TH1*> subTempVect = exp->GetMaskList();
 
     for (UInt_t i = 0; i < subTempVect.size(); i++) {
       tempVect.push_back(subTempVect.at(i));
     }
   }
 
   return tempVect;
 }
 
 //********************************************************************
 std::vector<TH1*> JointMeas1D::GetFluxList() {
   //********************************************************************
 
   // Make Default Vector
   std::vector<TH1*> tempVect;
   tempVect.push_back(MeasurementBase::GetFluxHistogram());
 
   // Return vector from all sub samples
   for (std::vector<MeasurementBase*>::const_iterator expIter =
          fSubChain.begin();
        expIter != fSubChain.end(); expIter++) {
     MeasurementBase* exp = *expIter;
 
     std::vector<TH1*> subTempVect = exp->GetFluxList();
 
     for (UInt_t i = 0; i < subTempVect.size(); i++) {
       tempVect.push_back(subTempVect.at(i));
     }
   }
 
   return tempVect;
 }
 
 //********************************************************************
 std::vector<TH1*> JointMeas1D::GetEventRateList() {
   //********************************************************************
 
   // Make Default Vector
   std::vector<TH1*> tempVect;
   tempVect.push_back(MeasurementBase::GetEventHistogram());
 
   // Return vector from all sub samples
   for (std::vector<MeasurementBase*>::const_iterator expIter =
          fSubChain.begin();
        expIter != fSubChain.end(); expIter++) {
     MeasurementBase* exp = *expIter;
 
     std::vector<TH1*> subTempVect = exp->GetEventRateList();
 
     for (UInt_t i = 0; i < subTempVect.size(); i++) {
       tempVect.push_back(subTempVect.at(i));
     }
   }
 
   return tempVect;
 }
 
 //********************************************************************
 std::vector<TH1*> JointMeas1D::GetXSecList() {
   //********************************************************************
 
   // Make Default Vector
   std::vector<TH1*> tempVect;
   tempVect.push_back(MeasurementBase::GetXSecHistogram());
 
   // Return vector from all sub samples
   for (std::vector<MeasurementBase*>::const_iterator expIter =
          fSubChain.begin();
        expIter != fSubChain.end(); expIter++) {
     MeasurementBase* exp = *expIter;
 
     std::vector<TH1*> subTempVect = exp->GetXSecList();
 
     for (UInt_t i = 0; i < subTempVect.size(); i++) {
       tempVect.push_back(subTempVect.at(i));
     }
   }
 
   return tempVect;
 }
 
 //********************************************************************
 TH1D* JointMeas1D::GetCombinedFlux() {
   //********************************************************************
 
-  TH1D* newflux;
+  TH1D* newflux = NULL;
   int sample = 0;
 
   for (std::vector<MeasurementBase*>::const_iterator expIter =
          fSubChain.begin();
        expIter != fSubChain.end(); expIter++) {
     MeasurementBase* exp = *expIter;
 
     // Get flux from experiment
     std::vector<TH1*> fluxVect = exp->GetFluxList();
 
     // Setup newflux
     if (sample == 0) {
       newflux = (TH1D*)fluxVect.at(0);
       newflux->Reset();
     }
 
     // Add all fluxes
     for (UInt_t i = 0; i < fluxVect.size(); i++) {
       newflux->Add((TH1D*)fluxVect.at(i));
       sample++;
     }
   }
 
+  if (!newflux){
+    ERR(FTL) << "No combined flux setup in JointMeas1D" << std::endl;
+  }
+
   return newflux;
 }
 
 //********************************************************************
 TH1D* JointMeas1D::GetCombinedEventRate() {
   //********************************************************************
 
   TH1D* newflux;
   int sample = 0;
 
   for (std::vector<MeasurementBase*>::const_iterator expIter =
          fSubChain.begin();
        expIter != fSubChain.end(); expIter++) {
     MeasurementBase* exp = *expIter;
 
     // Get flux from experiment
     std::vector<TH1*> fluxVect = exp->GetFluxList();
 
     // Setup newflux
     if (sample == 0) {
       newflux = (TH1D*)fluxVect.at(0);
       newflux->Reset();
     }
 
     // Add all fluxes
     for (UInt_t i = 0; i < fluxVect.size(); i++) {
       newflux->Add(fluxVect.at(i));
       sample++;
     }
   }
 
+  if (!newflux){
+    ERR(FTL) << "No combined event rate setup in JointMeas1D" << std::endl;
+  }
+
   return newflux;
 }
 
 //********************************************************************
 std::vector<MeasurementBase*> JointMeas1D::GetSubSamples() {
 //********************************************************************
 
   std::vector<MeasurementBase*> exps;
   for (std::vector<MeasurementBase*>::const_iterator expIter =
          fSubChain.begin();
        expIter != fSubChain.end(); expIter++) {
     exps.push_back(*expIter);
   }
 
   return exps;
 }
 
 
 
 
 
 
 
 //// CRAP TO BE REMOVED
 
 
 
 //********************************************************************
 void JointMeas1D::SetDataValues(std::string dataFile) {
   //********************************************************************
 
   // Override this function if the input file isn't in a suitable format
   LOG(SAM) << "Reading data from: " << dataFile.c_str() << std::endl;
   fDataHist =
     PlotUtils::GetTH1DFromFile(dataFile, (fName + "_data"), fPlotTitles);
   fDataTrue = (TH1D*)fDataHist->Clone();
 
   // Number of data points is number of bins
   fNDataPointsX = fDataHist->GetXaxis()->GetNbins();
 
   return;
 };
 
 
 
 
 
 //********************************************************************
 void JointMeas1D::SetDataFromDatabase(std::string inhistfile,
                                         std::string histname) {
   //********************************************************************
 
   LOG(SAM) << "Filling histogram from " << inhistfile << "->" << histname
            << std::endl;
   fDataHist = PlotUtils::GetTH1DFromRootFile(
                 (GeneralUtils::GetTopLevelDir() + "/data/" + inhistfile), histname);
   fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_data").c_str());
 
   return;
 };
 
 //********************************************************************
 void JointMeas1D::SetDataFromFile(std::string inhistfile,
                                     std::string histname) {
   //********************************************************************
 
   LOG(SAM) << "Filling histogram from " << inhistfile << "->" << histname
            << std::endl;
   fDataHist = PlotUtils::GetTH1DFromRootFile((inhistfile), histname);
   fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_data").c_str());
 
   return;
 };
 
 //********************************************************************
 void JointMeas1D::SetCovarMatrix(std::string covarFile) {
   //********************************************************************
 
   // Covariance function, only really used when reading in the MB Covariances.
 
   TFile* tempFile = new TFile(covarFile.c_str(), "READ");
 
   TH2D* covarPlot = new TH2D();
   //  TH2D* decmpPlot = new TH2D();
   TH2D* covarInvPlot = new TH2D();
   TH2D* fFullCovarPlot = new TH2D();
   std::string covName = "";
   std::string covOption = FitPar::Config().GetParS("thrown_covariance");
 
   if (fIsShape || fIsFree) covName = "shp_";
   if (fIsDiag)
     covName += "diag";
   else
     covName += "full";
 
   covarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str());
   covarInvPlot = (TH2D*)tempFile->Get((covName + "covinv").c_str());
 
   if (!covOption.compare("SUB"))
     fFullCovarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str());
   else if (!covOption.compare("FULL"))
     fFullCovarPlot = (TH2D*)tempFile->Get("fullcov");
   else
     ERR(WRN) << "Incorrect thrown_covariance option in parameters."
              << std::endl;
 
   int dim = int(fDataHist->GetNbinsX());  //-this->masked->Integral());
   int covdim = int(fDataHist->GetNbinsX());
 
   this->covar = new TMatrixDSym(dim);
   fFullCovar = new TMatrixDSym(dim);
   fDecomp = new TMatrixDSym(dim);
 
   int row, column = 0;
   row = 0;
   column = 0;
   for (Int_t i = 0; i < covdim; i++) {
     // if (this->masked->GetBinContent(i+1) > 0) continue;
 
     for (Int_t j = 0; j < covdim; j++) {
       //   if (this->masked->GetBinContent(j+1) > 0) continue;
 
       (*this->covar)(row, column) = covarPlot->GetBinContent(i + 1, j + 1);
       (*fFullCovar)(row, column) = fFullCovarPlot->GetBinContent(i + 1, j + 1);
 
       column++;
     }
     column = 0;
     row++;
   }
 
   // Set bin errors on data
   if (!fIsDiag) {
     StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar);
   }
 
   // Get Deteriminant and inverse matrix
   // fCovDet = this->covar->Determinant();
 
   TDecompSVD LU = TDecompSVD(*this->covar);
   this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
 
   return;
 };
 
 //********************************************************************
 // Sets the covariance matrix from a provided file in a text format
 // scale is a multiplicative pre-factor to apply in the case where the
 // covariance is given in some unit (e.g. 1E-38)
 void JointMeas1D::SetCovarMatrixFromText(std::string covarFile, int dim,
     double scale) {
   //********************************************************************
 
   // Make a counter to track the line number
   int row = 0;
 
   std::string line;
   std::ifstream covarread(covarFile.c_str(), ifstream::in);
 
   this->covar = new TMatrixDSym(dim);
   fFullCovar = new TMatrixDSym(dim);
   if (covarread.is_open())
     LOG(SAM) << "Reading covariance matrix from file: " << covarFile
              << std::endl;
   else
     ERR(FTL) << "Covariance matrix provided is incorrect: " << covarFile
              << std::endl;
 
   // Loop over the lines in the file
   while (std::getline(covarread >> std::ws, line, '\n')) {
     int column = 0;
 
     // Loop over entries and insert them into matrix
     std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
 
     if (entries.size() <= 1) {
       ERR(WRN) << "SetCovarMatrixFromText -> Covariance matrix only has <= 1 "
                "entries on this line: "
                << row << std::endl;
     }
 
     for (std::vector<double>::iterator iter = entries.begin();
          iter != entries.end(); iter++) {
       (*covar)(row, column) = *iter;
       (*fFullCovar)(row, column) = *iter;
 
       column++;
     }
 
     row++;
   }
   covarread.close();
 
   // Scale the actualy covariance matrix by some multiplicative factor
   (*fFullCovar) *= scale;
 
   // Robust matrix inversion method
   TDecompSVD LU = TDecompSVD(*this->covar);
   // THIS IS ACTUALLY THE INVERSE COVARIANCE MATRIXA AAAAARGH
   delete this->covar;
   this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
 
   // Now need to multiply by the scaling factor
   // If the covariance
   (*this->covar) *= 1. / (scale);
 
   return;
 };
 
 //********************************************************************
 void JointMeas1D::SetCovarMatrixFromCorrText(std::string corrFile, int dim) {
   //********************************************************************
 
   // Make a counter to track the line number
   int row = 0;
 
   std::string line;
   std::ifstream corr(corrFile.c_str(), ifstream::in);
 
   this->covar = new TMatrixDSym(dim);
   this->fFullCovar = new TMatrixDSym(dim);
   if (corr.is_open())
     LOG(SAM) << "Reading and converting correlation matrix from file: "
              << corrFile << std::endl;
   else {
     ERR(FTL) << "Correlation matrix provided is incorrect: " << corrFile
              << std::endl;
     exit(-1);
   }
 
   while (std::getline(corr >> std::ws, line, '\n')) {
     int column = 0;
 
     // Loop over entries and insert them into matrix
     // Multiply by the errors to get the covariance, rather than the correlation
     // matrix
     std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
     for (std::vector<double>::iterator iter = entries.begin();
          iter != entries.end(); iter++) {
       double val = (*iter) * this->fDataHist->GetBinError(row + 1) * 1E38 *
                    this->fDataHist->GetBinError(column + 1) * 1E38;
       if (val == 0) {
         ERR(FTL) << "Found a zero value in the covariance matrix, assuming "
                  "this is an error!"
                  << std::endl;
         exit(-1);
       }
 
       (*this->covar)(row, column) = val;
       (*this->fFullCovar)(row, column) = val;
 
       column++;
     }
 
     row++;
   }
 
   // Robust matrix inversion method
   TDecompSVD LU = TDecompSVD(*this->covar);
   delete this->covar;
   this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
 
   return;
 };
 
 
 
 
 
 
 //********************************************************************
 // FullUnits refers to if we have "real" unscaled units in the covariance matrix, e.g. 1E-76.
 // If this is the case we need to scale it so that the chi2 contribution is correct
 // NUISANCE internally assumes the covariance matrix has units of 1E76
 void JointMeas1D::SetCovarFromDataFile(std::string covarFile,
     std::string covName, bool FullUnits) {
   //********************************************************************
 
   LOG(SAM) << "Getting covariance from " << covarFile << "->" << covName
            << std::endl;
 
   TFile* tempFile = new TFile(covarFile.c_str(), "READ");
   TH2D* covPlot = (TH2D*)tempFile->Get(covName.c_str());
   covPlot->SetDirectory(0);
   // Scale the covariance matrix if it comes in normal units
   if (FullUnits) {
     covPlot->Scale(1.E76);
   }
 
   int dim = covPlot->GetNbinsX();
   fFullCovar = new TMatrixDSym(dim);
 
   for (int i = 0; i < dim; i++) {
     for (int j = 0; j < dim; j++) {
       (*fFullCovar)(i, j) = covPlot->GetBinContent(i + 1, j + 1);
     }
   }
 
   this->covar = (TMatrixDSym*)fFullCovar->Clone();
   fDecomp = (TMatrixDSym*)fFullCovar->Clone();
 
   TDecompSVD LU = TDecompSVD(*this->covar);
   this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
 
   TDecompChol LUChol = TDecompChol(*fDecomp);
   LUChol.Decompose();
   fDecomp = new TMatrixDSym(dim, LU.GetU().GetMatrixArray(), "");
 
   return;
 };
 
 
+// std::vector<TH1*> JointMeas1D::GetMCList(void){
+//   std::vector<TH1*> temp;
+//   return temp;
+// }
+
+
+// std::vector<TH1*> JointMeas1D::GetDataList(void){
+//  std::vector<TH1*> temp;
+//   return temp;
+// }
 
 
 
+// std::vector<TH1*> JointMeas1D::GetMaskList(void){
+//  std::vector<TH1*> temp;
+//   return temp;
+// }
 
 
+// std::vector<TH1*> JointMeas1D::GetFineList(void){
+//  std::vector<TH1*> temp;
+//   return temp;
+// }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
diff --git a/src/FitBase/JointMeas1D.h b/src/FitBase/JointMeas1D.h
index 3eb8655..fab8689 100644
--- a/src/FitBase/JointMeas1D.h
+++ b/src/FitBase/JointMeas1D.h
@@ -1,664 +1,664 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
 #ifndef JOINTMEASUREMENT_1D_H_SEEN
 #define JOINTMEASUREMENT_1D_H_SEEN
 /*!
  *  \addtogroup FitBase
  *  @{
  */
 
 #include <math.h>
 #include <stdlib.h>
 #include <deque>
 #include <iomanip>
 #include <iostream>
 #include <list>
 #include <numeric>
 #include <sstream>
 #include <string>
 
 // ROOT includes
 #include <TArrayF.h>
 #include <TCanvas.h>
 #include <TCut.h>
 #include <TDecompChol.h>
 #include <TDecompSVD.h>
 #include <TGraph.h>
 #include <TGraphErrors.h>
 #include <TH1D.h>
 #include <TH2D.h>
 #include <TMatrixDSym.h>
 #include <TROOT.h>
 #include <TSystem.h>
 #include "Measurement1D.h"
 
 // External data fit includes
 #include "FitEvent.h"
 #include "FitParameters.h"
 #include "FitUtils.h"
 #include "MeasurementBase.h"
 #include "PlotUtils.h"
 #include "StatUtils.h"
 
 
 //********************************************************************
 /// 1D Measurement base class. Histogram handling is done in this base layer.
 class JointMeas1D : public MeasurementBase {
 //********************************************************************
 
 public:
   /*
     Constructor/Deconstuctor
   */
   JointMeas1D(void);
   virtual ~JointMeas1D(void);
 
   /*
     Setup Functions
   */
 
 
   SampleSettings LoadSampleSettings(nuiskey samplekey);
 
 
   /// \brief Setup all configs once initialised
   ///
   /// Should be called after all configs have been setup inside fSettings container.
   /// Handles the processing of inputs and setting up of types.
   /// Replaces the old 'SetupMeasurement' function.
   void FinaliseSampleSettings();
 
 
   /// \brief Read 1D data inputs from a text file.
   ///
   /// Inputfile should have the format: \n
   /// low_binedge_1    bin_content_1  bin_error_1 \n
   /// low_binedge_2    bin_content_2  bin_error_2 \n
   /// ....             ....           ....        \n
   /// high_bin_edge_N  0.0            0.0
   virtual void SetDataFromTextFile(std::string datafile);
 
   /// \brief Read 1D data inputs from a root file.
   ///
   /// inhistfile specifies the path to the root file
   /// histname specifies the name of the histogram.
   ///
   /// If no histogram name is given the inhistfile value
   /// is automatically parsed with ';' so that: \n
   /// 'myhistfile.root;myhistname' \n
   /// will also work.
   virtual void SetDataFromRootFile(std::string inhistfile, std::string histname = "");
 
 
   /// \brief Set data bin errors to sqrt(entries)
   ///
   /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST
   ///
   /// Sets the data errors as the sqrt of the bin contents
   /// Should be use for counting experiments
   virtual void SetPoissonErrors();
 
   /// \brief Make diagonal covariance from data
   ///
   /// \warning If no histogram passed, data must be setup first!
   /// Setup the covariance inputs by taking the data histogram
   /// errors and setting up a diagonal covariance matrix.
   ///
   /// If no data is supplied, fDataHist is used if already set.
   virtual void SetCovarFromDiagonal(TH1D* data = NULL);
 
   /// \brief Read the data covariance from a text file.
   ///
   /// Inputfile should have the format: \n
   /// covariance_11  covariance_12  covariance_13 ... \n
   /// covariance_21  covariance_22  covariance_23 ... \n
   /// ...            ...            ...           ... \n
   ///
   /// If no dimensions are given, it is assumed from the number
   /// entries in the first line of covfile.
   virtual void SetCovarFromTextFile(std::string covfile, int dim = -1);
 
   /// \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 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);
 
 
   /*
     Access Functions
   */
 
   /// \brief Returns nicely formatted MC Histogram
   ///
   /// Format options can also be given in the samplesettings:
   /// - linecolor
   /// - linestyle
   /// - linewidth
   /// - fillcolor
   /// - fillstyle
   ///
   /// So to have a sample line colored differently in the xml cardfile put: \n
   /// <sample name="MiniBooNE_CCQE_XSec_1DQ2_nu" input="NEUT:input.root"
   /// linecolor="2" linestyle="7"  linewidth="2" />
   virtual TH1D* GetMCHistogram(void);
 
   /// \brief Returns nicely formatted data Histogram
   ///
   /// Format options can also be given in the samplesettings:
   /// - datacolor
   /// - datastyle
   /// - datawidth
   ///
   /// So to have a sample data colored differently in the xml cardfile put: \n
   /// <sample name="MiniBooNE_CCQE_XSec_1DQ2_nu" input="NEUT:input.root"
   /// datacolor="2" datastyle="7"  datawidth="2" />
   virtual TH1D* GetDataHistogram(void);
 
   /// \brief Returns a list of all MC histograms.
   ///
   /// Override this if you have extra histograms that need to be
   /// accessed outside of the Measurement1D class.
-  inline virtual std::vector<TH1*> GetMCList(void);
+  virtual std::vector<TH1*> GetMCList(void);
 
 
   /// \brief Returns a list of all Data histograms.
   ///
   /// Override this if you have extra histograms that need to be
   /// accessed outside of the Measurement1D class.
-  inline virtual std::vector<TH1*> GetDataList(void);
+  virtual std::vector<TH1*> GetDataList(void);
 
 
   /// \brief Returns a list of all Mask histograms.
   ///
   /// Override this if you have extra histograms that need to be
   /// accessed outside of the Measurement1D class.
-  inline virtual std::vector<TH1*> GetMaskList(void);
+  virtual std::vector<TH1*> GetMaskList(void);
 
 
   /// \brief Returns a list of all Fine histograms.
   ///
   /// Override this if you have extra histograms that need to be
   /// accessed outside of the Measurement1D class.
-  inline virtual std::vector<TH1*> GetFineList(void);
+virtual std::vector<TH1*> GetFineList(void);
 
   /*
     Write Functions
   */
   /// \brief Save the current state to the current TFile directory \n
   ///
   /// Data/MC are both saved by default.
   /// A range of other histograms can be saved by setting the
   /// config option 'drawopts'.
   ///
   /// Possible options: \n
   /// - FINE    = Write Fine Histogram \n
   /// - WEIGHTS = Write Weighted MC Histogram (before scaling) \n
   /// - FLUX    = Write Flux Histogram from MC Input \n
   /// - EVT     = Write Event Histogram from MC Input \n
   /// - XSEC    = Write XSec Histogram from MC Input \n
   /// - MASK    = Write Mask Histogram \n
   /// - COV     = Write Covariance Histogram \n
   /// - INVCOV  = Write Inverted Covariance Histogram \n
   /// - DECMOP  = Write Decomp. Covariance Histogram \n
   /// - RESIDUAL= Write Resudial Histograms \n
   /// - RATIO   = Write Data/MC Ratio Histograms \n
   /// - SHAPE   = Write MC Shape Histograms norm. to Data \n
   /// - CANVMC  = Build MC Canvas Showing Data, MC, Shape \n
   /// - MODES   = Write PDG Stack \n
   /// - CANVPDG = Build MC Canvas Showing Data, PDGStack \n
   ///
   /// So to save a range of these in parameters/config.xml set: \n
   /// <config drawopts='FINE/COV/SHAPE/RATIO' />
   virtual void Write(std::string drawOpt);
 
 
 
   virtual void WriteRatioPlot();
 
 
 
 
   virtual void WriteShapePlot();
   virtual void WriteShapeRatioPlot();
 
 
   double TotalIntegratedFlux(std::string intOpt, double low,
                              double high);
 
   //*
   // OLD DEFUNCTIONS
   //
 
   /// OLD FUNCTION
   virtual void SetupMeasurement(std::string input, std::string type,
                                 FitWeight* rw, std::string fkdt);
 
   /// OLD FUNCTION
   virtual void SetupDefaultHist(void);
 
   /// OLD FUNCTION
   virtual void SetDataValues(std::string dataFile);
 
   /// OLD FUNCTION
   virtual void SetDataFromFile(std::string inhistfile, std::string histname);
   /// OLD FUNCTION
   virtual void SetDataFromDatabase(std::string inhistfile,
                                    std::string histname);
 
   /// OLD FUNCTION
   virtual void SetCovarMatrix(std::string covarFile);
   /// OLD FUNCTION
   virtual void SetCovarMatrixFromText(std::string covarFile, int dim,
                                       double scale = 1.0);
   /// OLD FUNCTION
   virtual void SetCovarMatrixFromCorrText(std::string covarFile, int dim);
 
 
   /// OLD FUNCTION
   virtual void SetCovarFromDataFile(std::string covarFile, std::string covName,
                                     bool FullUnits = false);
 
 
 
 
 
   ////// JOINT MEAS1D Functions //////
 
   /*
     Reconfigure Functions
   */
 
   /// Call reconfigure on every sub sample
   virtual void Reconfigure();
 
   /// Stitch the sub sample plots together to make a final fMCHist after
   /// reconfigure has been called
   virtual void MakePlots();
 
 
   virtual std::vector<MeasurementBase*> GetSubSamples();
   virtual void ConvertEventRates();
 
   /*
     Access Functions
   */
   virtual std::vector<TH1*> GetFluxList();
   virtual std::vector<TH1*> GetEventRateList();
   virtual std::vector<TH1*> GetXSecList();
 
   //! Return a flux integrated across all sub samples
   virtual TH1D* GetCombinedFlux();
 
   //! Return an event rate integrated across all sub samples
   virtual TH1D* GetCombinedEventRate();
 
   virtual TH1D* GetEventHistogram() { return GetCombinedEventRate(); };
   virtual TH1D* GetXSecHistogram() {
     ERR(WRN)
         << "XSec histogram not properly implemented for joint measurements.";
     return MeasurementBase::GetXSecHistogram();
   };
   virtual TH1D* GetFluxHistogram() { return GetCombinedFlux(); };
 
 
 protected:
 
   // Data
   TH1D* fDataHist;  ///< default data histogram
   TH1D* fDataOrig;  ///< histogram to store original data before throws.
   TH1D* fDataTrue;  ///< histogram to store true dataset
   std::string fPlotTitles;  ///< Plot title x and y for the histograms
 
 
   // MC
   TH1D* fMCHist;     ///< default MC Histogram used in the chi2 fits
   TH1D* fMCFine;     ///< finely binned MC histogram
   TH1D* fMCStat;     ///< histogram with unweighted events to properly calculate
   TH1D* fMCWeighted; ///< Weighted histogram before xsec scaling
 
   TH1I* fMaskHist;   ///< Mask histogram for neglecting specific bins
   TMatrixD* fSmearMatrix;   ///< Smearing matrix (note, this is not symmetric)
 
   TrueModeStack* fMCHist_Modes; ///< Optional True Mode Stack
 
 
   // Statistical
   TMatrixDSym* covar;       ///< Inverted Covariance
   TMatrixDSym* fFullCovar;  ///< Full Covariance
   TMatrixDSym* fDecomp;     ///< Decomposed Covariance
   TMatrixDSym* fCorrel;     ///< Correlation Matrix
 
   TMatrixDSym* fCovar;    ///< New FullCovar
   TMatrixDSym* fInvert;   ///< New covar
 
   double fNormError;        ///< Sample norm error
 
 
   // Fake Data
   bool fIsFakeData;            ///< Flag: is the current data fake from MC
   std::string fFakeDataInput;  ///< Input fake data file path
   TFile* fFakeDataFile;        ///< Input fake data file
 
 
   // Fit specific flags
   std::string fFitType;       ///< Current fit type
   std::string fAllowedTypes;  ///< Fit Types Possible
   std::string fDefaultTypes;  ///< Starting Default Fit Types
 
   bool fIsShape;      ///< Flag : Perform Shape-only fit
   bool fIsFree;       ///< Flag : Perform normalisation free fit
   bool fIsDiag;       ///< Flag : only include uncorrelated diagonal errors
   bool fIsMask;       ///< Flag : Apply bin masking
   bool fIsRawEvents;  ///< Flag : Are bin contents just event rates
   bool fIsEnu1D;      ///< Flag : Perform Flux Unfolded Scaling
   bool fIsChi2SVD;    ///< Flag : Use alternative Chi2 SVD Method (Do not use)
   bool fAddNormPen;   ///< Flag : Add a normalisation penalty term to the chi2.
   bool fIsFix;        ///< Flag : keeping norm fixed
   bool fIsFull;       ///< Flag : using full covariaince
   bool fIsDifXSec;    ///< Flag : creating a dif xsec
   bool fIsChi2;       ///< Flag : using Chi2 over LL methods
   bool fIsSmeared;    ///< Flag : Apply smearing?
 
 
 
 
   /// OLD STUFF TO REMOVE
   TH1D* fMCHist_PDG[61]; ///< REMOVE OLD MC PDG Plot
 
   // Arrays for data entries
   Double_t* fXBins;       ///< REMOVE xBin edges
   Double_t* fDataValues;  ///< REMOVE data bin contents
   Double_t* fDataErrors;  ///< REMOVE data bin errors
   Int_t fNDataPointsX;    ///< REMOVE number of data points
 
 
 
 
   //// JOINT MEAS1D OBJECTS ////
   std::vector<MeasurementBase*> fSubChain;  //!< Vector of experimental classes
   //! that are the sub measurements
   std::vector<std::string>
   fSubInFiles;  //!< vector of input files for each of the sub measurements.
 
   bool fIsRatio;      //!< Flag: is this sample a hist1/hist2 ratio sample
   bool fIsSummed;     //!< Flag: is this sample a combination hist1 + hist2
   bool fSaveSubMeas;  //!< Flag: Save each of the histograms from the sub
   //! samples as well as this joint samples plots
 
 };
 
 
 
 /*! @} */
 #endif
diff --git a/src/FitBase/Measurement1D.cxx b/src/FitBase/Measurement1D.cxx
index baff4b7..15ee6e0 100644
--- a/src/FitBase/Measurement1D.cxx
+++ b/src/FitBase/Measurement1D.cxx
@@ -1,1786 +1,1786 @@
 // Copyright 2016 L. Pickering, P caltowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This ile is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 #include "Measurement1D.h"
 
 
 //********************************************************************
 Measurement1D::Measurement1D(void) {
 //********************************************************************
 
   // XSec Scalings
   fScaleFactor = -1.0;
   fCurrentNorm = 1.0;
 
   // Histograms
   fDataHist = NULL;
   fDataTrue = NULL;
 
   fMCHist = NULL;
   fMCFine = NULL;
   fMCWeighted = NULL;
 
   fMaskHist = NULL;
 
   // Covar
   covar = NULL;
   fFullCovar = NULL;
 
   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;
 
 }
 
 //********************************************************************
 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 (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);
   }
 
   LOG(FIT) << "Sample isjoint = " << fIsJoint << std::endl;
 
   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!" << endl;
-      ERR(WRN) << "If you want to use it please add fNormError=VAL" << endl;
+      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::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::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::ScaleData(double scale) {
 //********************************************************************
   fDataHist->Scale(scale);
 }
 
 
 //********************************************************************
 void Measurement1D::ScaleDataErrors(double scale) {
 //********************************************************************
   for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
     fDataHist->SetBinError(i + 1, fDataHist->GetBinError(i + 1) * scale);
   }
 }
 
 
 
 //********************************************************************
 void Measurement1D::ScaleCovar(double scale) {
 //********************************************************************
   (*fFullCovar) *= scale;
   (*covar) *= 1.0 / scale;
   (*fDecomp) *= sqrt(scale);
 }
 
 
 //********************************************************************
 void Measurement1D::SetBinMask(std::string maskfile) {
 //********************************************************************
 
   if (!fIsMask) return;
   LOG(SAM) << "Reading bin mask from file: " << maskfile << std::endl;
 
   // Create a mask histogram with dim of data
   int nbins = fDataHist->GetNbinsX();
   fMaskHist =
     new TH1I((fSettings.GetName() + "_BINMASK").c_str(),
              (fSettings.GetName() + "_BINMASK; Bin; Mask?").c_str(), nbins, 0, nbins);
   std::string line;
   std::ifstream mask(maskfile.c_str(), ifstream::in);
 
   if (!mask.is_open()) {
     LOG(FTL) << " Cannot find mask file." << std::endl;
     throw;
   }
 
   while (std::getline(mask >> std::ws, line, '\n')) {
     std::vector<int> entries = GeneralUtils::ParseToInt(line, " ");
 
     // Skip lines with poorly formatted lines
     if (entries.size() < 2) {
       LOG(WRN) << "Measurement1D::SetBinMask(), couldn't parse line: " << line
                << std::endl;
       continue;
     }
 
     // The first index should be the bin number, the second should be the mask
     // value.
     int val = 0;
     if (entries[1] > 0) val = 1;
     fMaskHist->SetBinContent(entries[0], val);
   }
 
   // Apply masking by setting masked data bins to zero
   PlotUtils::MaskBins(fDataHist, fMaskHist);
 
   return;
 }
 
 
 
 //********************************************************************
 void Measurement1D::FinaliseMeasurement() {
 //********************************************************************
 
   LOG(SAM) << "Finalising Measurement: " << fName << std::endl;
 
   // 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) {
     SetCovarFromDiagonal(fDataHist);
   }
 
   if (!covar) {
     covar = StatUtils::GetInvert(fFullCovar);
   }
 
   if (!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(),
                      fMCHist->GetBinLowEdge(1),
                      fMCHist->GetBinLowEdge(fDataHist->GetNbinsX() + 1));
   fMCFine->SetNameTitle((fSettings.GetName() + "_MC_FINE").c_str(),
                         (fSettings.GetFullTitles()).c_str());
   fMCFine->Reset();
 
   // Setup MC Stat
   fMCStat = (TH1D*)fMCHist->Clone();
   fMCStat->Reset();
 
   // Search drawopts for possible types to include by default
   std::string drawopts = FitPar::Config().GetParS("drawopts");
   if (drawopts.find("MODES") != std::string::npos) {
     fMCHist_Modes = new TrueModeStack( (fSettings.GetName() + "_MODES").c_str(),
                                        ("True Channels"), fMCHist);
     SetAutoProcessTH1(fMCHist_Modes, kCMD_Reset, kCMD_Norm, kCMD_Write);
   }
 
   // Setup bin masks using sample name
   if (fIsMask) {
 
     std::string curname  = fName;
     std::string origname = fSettings.GetS("originalname");
 
     // Check rename.mask
     std::string maskloc = FitPar::Config().GetParDIR(curname + ".mask");
 
     // Check origname.mask
     if (maskloc.empty()) maskloc = FitPar::Config().GetParDIR(origname + ".mask");
 
     // Check database
     if (maskloc.empty()) {
       maskloc = FitPar::GetDataBase() + "/masks/" + origname + ".mask";
     }
 
     // Setup Bin Mask
     SetBinMask(maskloc);
   }
 
   if (fScaleFactor < 0) {
     ERR(FTL) << "I found a negative fScaleFactor in " << __FILE__ << ":" << __LINE__ << std::endl;
     ERR(FTL) << "fScaleFactor = " << fScaleFactor << std::endl;
     ERR(FTL) << "EXITING" << std::endl;
     throw;
   }
 
   // Create and fill Weighted Histogram
   if (!fMCWeighted) {
 
     fMCWeighted = (TH1D*)fMCHist->Clone();
     fMCWeighted->SetNameTitle((fName + "_MCWGHTS").c_str(),
                               (fName + "_MCWGHTS" + fPlotTitles).c_str());
     fMCWeighted->GetYaxis()->SetTitle("Weighted Events");
 
   }
 
 
 }
 
 //********************************************************************
 void Measurement1D::SetFitOptions(std::string opt) {
 //********************************************************************
 
   // Do nothing if default given
   if (opt == "DEFAULT") return;
 
   // CHECK Conflicting Fit Options
   std::vector<std::string> fit_option_allow =
     GeneralUtils::ParseToStr(fAllowedTypes, "/");
 
   for (UInt_t i = 0; i < fit_option_allow.size(); i++) {
     std::vector<std::string> fit_option_section =
       GeneralUtils::ParseToStr(fit_option_allow.at(i), ",");
 
     bool found_option = false;
 
     for (UInt_t j = 0; j < fit_option_section.size(); j++) {
       std::string av_opt = fit_option_section.at(j);
 
       if (!found_option and opt.find(av_opt) != std::string::npos) {
         found_option = true;
 
       } else if (found_option and opt.find(av_opt) != std::string::npos) {
         ERR(FTL) << "ERROR: Conflicting fit options provided: "
                  << opt << std::endl
                  << "Conflicting group = " << fit_option_section.at(i) << std::endl
                  << "You should only supply one of these options in card file." << std::endl;
         throw;
       }
     }
   }
 
   // Check all options are allowed
   std::vector<std::string> fit_options_input =
     GeneralUtils::ParseToStr(opt, "/");
   for (UInt_t i = 0; i < fit_options_input.size(); i++) {
     if (fAllowedTypes.find(fit_options_input.at(i)) == std::string::npos) {
       ERR(FTL) << "ERROR: Fit Option '" << fit_options_input.at(i)
                << "' Provided is not allowed for this measurement."
                << std::endl;
       ERR(FTL) << "Fit Options should be provided as a '/' seperated list "
                "(e.g. FREE/DIAG/NORM)"
                << std::endl;
       ERR(FTL) << "Available options for " << fName << " are '" << fAllowedTypes
                << "'" << std::endl;
 
       throw;
     }
   }
 
   // Set TYPE
   fFitType = opt;
 
   // FIX,SHAPE,FREE
   if (opt.find("FIX") != std::string::npos) {
     fIsFree = fIsShape = false;
     fIsFix = true;
   } else if (opt.find("SHAPE") != std::string::npos) {
     fIsFree = fIsFix = false;
     fIsShape = true;
   } else if (opt.find("FREE") != std::string::npos) {
     fIsFix = fIsShape = false;
     fIsFree = true;
   }
 
   // DIAG,FULL (or default to full)
   if (opt.find("DIAG") != std::string::npos) {
     fIsDiag = true;
     fIsFull = false;
   } else if (opt.find("FULL") != std::string::npos) {
     fIsDiag = false;
     fIsFull = true;
   }
 
   // CHI2/LL (OTHERS?)
   if (opt.find("LOG") != std::string::npos) {
     fIsChi2 = false;
 
     ERR(FTL) << "No other LIKELIHOODS properly supported!" << std::endl;
     ERR(FTL) << "Try to use a chi2!" << std::endl;
     throw;
 
   } else {
     fIsChi2 = true;
   }
 
   // EXTRAS
   if (opt.find("RAW") != std::string::npos) fIsRawEvents = true;
   if (opt.find("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;
 
 
 
   std::cout << fSettings.fKeyValues.fNode << std::endl;
 
   return;
 };
 
 
 //********************************************************************
 void Measurement1D::SetSmearingMatrix(std::string smearfile, int truedim,
                                       int recodim) {
   //********************************************************************
 
   // The smearing matrix describes the migration from true bins (rows) to reco
   // bins (columns)
   // Counter over the true bins!
   int row = 0;
 
   std::string line;
   std::ifstream smear(smearfile.c_str(), ifstream::in);
 
   // Note that the smearing matrix may be rectangular.
   fSmearMatrix = new TMatrixD(truedim, recodim);
 
   if (smear.is_open())
     LOG(SAM) << "Reading smearing matrix from file: " << smearfile << std::endl;
   else
     ERR(FTL) << "Smearing matrix provided is incorrect: " << smearfile
              << std::endl;
 
   while (std::getline(smear >> std::ws, line, '\n')) {
     int column = 0;
 
     std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
     for (std::vector<double>::iterator iter = entries.begin();
          iter != entries.end(); iter++) {
       (*fSmearMatrix)(row, column) =
         (*iter) / 100.;  // Convert to fraction from
       // percentage (this may not be
       // general enough)
       column++;
     }
     row++;
   }
   return;
 }
 
 //********************************************************************
 void Measurement1D::ApplySmearingMatrix() {
 //********************************************************************
 
   if (!fSmearMatrix) {
     ERR(WRN) << fName
              << ": attempted to apply smearing matrix, but none was set"
              << std::endl;
     return;
   }
 
   TH1D* unsmeared = (TH1D*)fMCHist->Clone();
   TH1D* smeared = (TH1D*)fMCHist->Clone();
   smeared->Reset();
 
   // Loop over reconstructed bins
   // true = row; reco = column
   for (int rbin = 0; rbin < fSmearMatrix->GetNcols(); ++rbin) {
     // Sum up the constributions from all true bins
     double rBinVal = 0;
 
     // Loop over true bins
     for (int tbin = 0; tbin < fSmearMatrix->GetNrows(); ++tbin) {
       rBinVal +=
         (*fSmearMatrix)(tbin, rbin) * unsmeared->GetBinContent(tbin + 1);
     }
     smeared->SetBinContent(rbin + 1, rBinVal);
   }
   fMCHist = (TH1D*)smeared->Clone();
 
   return;
 }
 
 /*
    Reconfigure LOOP
 */
 //********************************************************************
 void Measurement1D::ResetAll() {
 //********************************************************************
 
   fMCHist->Reset();
   fMCFine->Reset();
   fMCStat->Reset();
 
   return;
 };
 
 //********************************************************************
 void Measurement1D::FillHistograms() {
   //********************************************************************
 
   if (Signal) {
 
     fMCHist->Fill(fXVar, Weight);
     fMCFine->Fill(fXVar, Weight);
     fMCStat->Fill(fXVar, 1.0);
 
     if (fMCHist_Modes) fMCHist_Modes->Fill(Mode, fXVar, Weight);
   }
 
   return;
 };
 
 //********************************************************************
 void Measurement1D::ScaleEvents() {
 //********************************************************************
 
   // Fill MCWeighted;
   // for (int i = 0; i < fMCHist->GetNbinsX(); i++) {
   //   fMCWeighted->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1));
   //   fMCWeighted->SetBinError(i + 1,   fMCHist->GetBinError(i + 1));
   // }
 
 
   // Setup Stat ratios for MC and MC Fine
   double* statratio     = new double[fMCHist->GetNbinsX()];
   for (int i = 0; i < fMCHist->GetNbinsX(); i++) {
     if (fMCHist->GetBinContent(i + 1) != 0) {
       statratio[i] = fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1);
     } else {
       statratio[i] = 0.0;
     }
   }
 
   double* statratiofine = new double[fMCFine->GetNbinsX()];
   for (int i = 0; i < fMCFine->GetNbinsX(); i++) {
     if (fMCFine->GetBinContent(i + 1) != 0) {
       statratiofine[i] = fMCFine->GetBinError(i + 1) / fMCFine->GetBinContent(i + 1);
     } else {
       statratiofine[i] = 0.0;
     }
   }
 
 
   // Scaling for raw event rates
   if (fIsRawEvents) {
     double datamcratio = fDataHist->Integral() / fMCHist->Integral();
 
     fMCHist->Scale(datamcratio);
     fMCFine->Scale(datamcratio);
 
     if (fMCHist_Modes) fMCHist_Modes->Scale(datamcratio);
 
     // Scaling for XSec as function of Enu
   } else if (fIsEnu1D) {
 
     PlotUtils::FluxUnfoldedScaling(fMCHist, GetFluxHistogram(),
                                    GetEventHistogram(), fScaleFactor,
                                    fNEvents);
     PlotUtils::FluxUnfoldedScaling(fMCFine, GetFluxHistogram(),
                                    GetEventHistogram(), fScaleFactor,
                                    fNEvents);
 
 
     // if (fMCHist_Modes) {
     // PlotUtils::FluxUnfoldedScaling(fMCHist_Modes, GetFluxHistogram(),
     // GetEventHistogram(), fScaleFactor,
     // fNEvents);
     // }
 
     // 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) 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;
   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) {
       std::cout << "Getting likelihood from covariance " << std::endl;
       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);
   }
 
   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 (fDataHist) delete fDataHist;
   fDataHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar);
 
   return;
 };
 
 /*
    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 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 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());
 
   double shapeScale = 1.0;
   if (fIsRawEvents) {
     shapeScale = fDataHist->Integral() / fMCHist->Integral();
   } else {
     shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width");
   }
 
   mcShape->Scale(shapeScale);
 
   std::stringstream ss;
   ss << shapeScale;
   mcShape->SetTitle(ss.str().c_str());
 
   mcShape->SetLineWidth(3);
   mcShape->SetLineStyle(7);
 
   mcShape->Write();
 
   delete mcShape;
 
 }
 
 //********************************************************************
 void Measurement1D::WriteShapeRatioPlot() {
 //********************************************************************
 
   // Get a mcshape histogram
   TH1D* mcShape = (TH1D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str());
 
   double shapeScale = 1.0;
   if (fIsRawEvents) {
     shapeScale = fDataHist->Integral() / fMCHist->Integral();
   } else {
     shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width");
   }
 
   mcShape->Scale(shapeScale);
 
   // Create shape ratio histograms
   TH1D* mcShapeRatio   = (TH1D*)mcShape->Clone((fName + "_MC_SHAPE_RATIO").c_str());
   TH1D* dataShapeRatio = (TH1D*)fDataHist->Clone((fName + "_data_SHAPE_RATIO").c_str());
 
   // Divide the histograms
   mcShapeRatio->Divide(mcShape);
   dataShapeRatio->Divide(mcShape);
 
   // Colour the shape ratio plots
   mcShapeRatio->SetLineWidth(3);
   mcShapeRatio->SetLineStyle(7);
 
   mcShapeRatio->Write();
   dataShapeRatio->Write();
 
   delete mcShapeRatio;
   delete dataShapeRatio;
 
 }
 
 
 
 
 //// CRAP TO BE REMOVED
 
 
 //********************************************************************
 void Measurement1D::SetupMeasurement(std::string inputfile, std::string type,
                                      FitWeight * rw, std::string fkdt) {
   //********************************************************************
 
 
   //nuiskey samplekey = Config::CreateKey("sample");
 //  samplekey.AddS("name", fName);
 //  samplekey.AddS("type",type);
 //  samplekey.AddS("input",inputfile);
 //  fSettings = LoadSampleSettings(samplekey);
 
   // Reset everything to NULL
   // Init();
 
   // Check if name contains Evt, indicating that it is a raw number of events
   // measurements and should thus be treated as once
   fIsRawEvents = false;
   if ((fName.find("Evt") != std::string::npos) && fIsRawEvents == false) {
     fIsRawEvents = true;
     LOG(SAM) << "Found event rate measurement but fIsRawEvents == false!"
              << std::endl;
     LOG(SAM) << "Overriding this and setting fIsRawEvents == true!"
              << std::endl;
   }
 
   fIsEnu1D = false;
   if (fName.find("XSec_1DEnu") != std::string::npos) {
     fIsEnu1D = true;
     LOG(SAM) << "::" << fName << "::" << std::endl;
     LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, "
              "not flux averaged!"
              << std::endl;
   }
 
   if (fIsEnu1D && fIsRawEvents) {
     LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this "
              "really correct?!"
              << std::endl;
     LOG(SAM) << "Check experiment constructor for " << fName
              << " and correct this!" << std::endl;
     LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl;
     exit(-1);
   }
 
   fRW = rw;
 
   if (!fInput and !fIsJoint) SetupInputs(inputfile);
 
   // Set Default Options
   SetFitOptions(fDefaultTypes);
 
   // Set Passed Options
   SetFitOptions(type);
 
   // Still adding support for flat flux inputs
   //  // Set Enu Flux Scaling
   //  if (isFlatFluxFolding) this->Input()->ApplyFluxFolding(
   //  this->defaultFluxHist );
 
   // FinaliseMeasurement();
 }
 
 //********************************************************************
 void Measurement1D::SetupDefaultHist() {
   //********************************************************************
 
   // Setup fMCHist
   fMCHist = (TH1D*)fDataHist->Clone();
   fMCHist->SetNameTitle((fName + "_MC").c_str(),
                         (fName + "_MC" + fPlotTitles).c_str());
 
   // Setup fMCFine
   Int_t nBins = fMCHist->GetNbinsX();
   fMCFine = new TH1D(
     (fName + "_MC_FINE").c_str(), (fName + "_MC_FINE" + fPlotTitles).c_str(),
     nBins * 6, fMCHist->GetBinLowEdge(1), fMCHist->GetBinLowEdge(nBins + 1));
 
   fMCStat = (TH1D*)fMCHist->Clone();
   fMCStat->Reset();
 
   fMCHist->Reset();
   fMCFine->Reset();
 
   // Setup the NEUT Mode Array
   PlotUtils::CreateNeutModeArray((TH1D*)fMCHist, (TH1**)fMCHist_PDG);
   PlotUtils::ResetNeutModeArray((TH1**)fMCHist_PDG);
 
   // Setup bin masks using sample name
   if (fIsMask) {
     std::string maskloc = FitPar::Config().GetParDIR(fName + ".mask");
     if (maskloc.empty()) {
       maskloc = FitPar::GetDataBase() + "/masks/" + fName + ".mask";
     }
 
     SetBinMask(maskloc);
   }
 
   fMCHist_Modes = new TrueModeStack( (fName + "_MODES").c_str(), ("True Channels"), fMCHist);
   SetAutoProcessTH1(fMCHist_Modes, kCMD_Reset, kCMD_Norm, kCMD_Write);
 
   return;
 }
 
 
 
 
 
 //********************************************************************
 void Measurement1D::SetDataValues(std::string dataFile) {
   //********************************************************************
 
   // Override this function if the input file isn't in a suitable format
   LOG(SAM) << "Reading data from: " << dataFile.c_str() << std::endl;
   fDataHist =
     PlotUtils::GetTH1DFromFile(dataFile, (fName + "_data"), fPlotTitles);
   fDataTrue = (TH1D*)fDataHist->Clone();
 
   // Number of data points is number of bins
   fNDataPointsX = fDataHist->GetXaxis()->GetNbins();
 
   return;
 };
 
 
 
 
 
 //********************************************************************
 void Measurement1D::SetDataFromDatabase(std::string inhistfile,
                                         std::string histname) {
   //********************************************************************
 
   LOG(SAM) << "Filling histogram from " << inhistfile << "->" << histname
            << std::endl;
   fDataHist = PlotUtils::GetTH1DFromRootFile(
                 (GeneralUtils::GetTopLevelDir() + "/data/" + inhistfile), histname);
   fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_data").c_str());
 
   return;
 };
 
 //********************************************************************
 void Measurement1D::SetDataFromFile(std::string inhistfile,
                                     std::string histname) {
   //********************************************************************
 
   LOG(SAM) << "Filling histogram from " << inhistfile << "->" << histname
            << std::endl;
   fDataHist = PlotUtils::GetTH1DFromRootFile((inhistfile), histname);
   fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_data").c_str());
 
   return;
 };
 
 //********************************************************************
 void Measurement1D::SetCovarMatrix(std::string covarFile) {
   //********************************************************************
 
   // Covariance function, only really used when reading in the MB Covariances.
 
   TFile* tempFile = new TFile(covarFile.c_str(), "READ");
 
   TH2D* covarPlot = new TH2D();
   //  TH2D* decmpPlot = new TH2D();
   TH2D* covarInvPlot = new TH2D();
   TH2D* fFullCovarPlot = new TH2D();
   std::string covName = "";
   std::string covOption = FitPar::Config().GetParS("thrown_covariance");
 
   if (fIsShape || fIsFree) covName = "shp_";
   if (fIsDiag)
     covName += "diag";
   else
     covName += "full";
 
   covarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str());
   covarInvPlot = (TH2D*)tempFile->Get((covName + "covinv").c_str());
 
   if (!covOption.compare("SUB"))
     fFullCovarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str());
   else if (!covOption.compare("FULL"))
     fFullCovarPlot = (TH2D*)tempFile->Get("fullcov");
   else
     ERR(WRN) << "Incorrect thrown_covariance option in parameters."
              << std::endl;
 
   int dim = int(fDataHist->GetNbinsX());  //-this->masked->Integral());
   int covdim = int(fDataHist->GetNbinsX());
 
   this->covar = new TMatrixDSym(dim);
   fFullCovar = new TMatrixDSym(dim);
   fDecomp = new TMatrixDSym(dim);
 
   int row, column = 0;
   row = 0;
   column = 0;
   for (Int_t i = 0; i < covdim; i++) {
     // if (this->masked->GetBinContent(i+1) > 0) continue;
 
     for (Int_t j = 0; j < covdim; j++) {
       //   if (this->masked->GetBinContent(j+1) > 0) continue;
 
       (*this->covar)(row, column) = covarPlot->GetBinContent(i + 1, j + 1);
       (*fFullCovar)(row, column) = fFullCovarPlot->GetBinContent(i + 1, j + 1);
 
       column++;
     }
     column = 0;
     row++;
   }
 
   // Set bin errors on data
   if (!fIsDiag) {
     StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar);
   }
 
   // Get Deteriminant and inverse matrix
   // fCovDet = this->covar->Determinant();
 
   TDecompSVD LU = TDecompSVD(*this->covar);
   this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
 
   return;
 };
 
 //********************************************************************
 // Sets the covariance matrix from a provided file in a text format
 // scale is a multiplicative pre-factor to apply in the case where the
 // covariance is given in some unit (e.g. 1E-38)
 void Measurement1D::SetCovarMatrixFromText(std::string covarFile, int dim,
     double scale) {
   //********************************************************************
 
   // Make a counter to track the line number
   int row = 0;
 
   std::string line;
   std::ifstream covarread(covarFile.c_str(), ifstream::in);
 
   this->covar = new TMatrixDSym(dim);
   fFullCovar = new TMatrixDSym(dim);
   if (covarread.is_open())
     LOG(SAM) << "Reading covariance matrix from file: " << covarFile
              << std::endl;
   else
     ERR(FTL) << "Covariance matrix provided is incorrect: " << covarFile
              << std::endl;
 
   // Loop over the lines in the file
   while (std::getline(covarread >> std::ws, line, '\n')) {
     int column = 0;
 
     // Loop over entries and insert them into matrix
     std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
 
     if (entries.size() <= 1) {
       ERR(WRN) << "SetCovarMatrixFromText -> Covariance matrix only has <= 1 "
                "entries on this line: "
                << row << std::endl;
     }
 
     for (std::vector<double>::iterator iter = entries.begin();
          iter != entries.end(); iter++) {
       (*covar)(row, column) = *iter;
       (*fFullCovar)(row, column) = *iter;
 
       column++;
     }
 
     row++;
   }
   covarread.close();
 
   // Scale the actualy covariance matrix by some multiplicative factor
   (*fFullCovar) *= scale;
 
   // Robust matrix inversion method
   TDecompSVD LU = TDecompSVD(*this->covar);
   // THIS IS ACTUALLY THE INVERSE COVARIANCE MATRIXA AAAAARGH
   delete this->covar;
   this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
 
   // Now need to multiply by the scaling factor
   // If the covariance
   (*this->covar) *= 1. / (scale);
 
   return;
 };
 
 //********************************************************************
 void Measurement1D::SetCovarMatrixFromCorrText(std::string corrFile, int dim) {
   //********************************************************************
 
   // Make a counter to track the line number
   int row = 0;
 
   std::string line;
   std::ifstream corr(corrFile.c_str(), ifstream::in);
 
   this->covar = new TMatrixDSym(dim);
   this->fFullCovar = new TMatrixDSym(dim);
   if (corr.is_open())
     LOG(SAM) << "Reading and converting correlation matrix from file: "
              << corrFile << std::endl;
   else {
     ERR(FTL) << "Correlation matrix provided is incorrect: " << corrFile
              << std::endl;
     exit(-1);
   }
 
   while (std::getline(corr >> std::ws, line, '\n')) {
     int column = 0;
 
     // Loop over entries and insert them into matrix
     // Multiply by the errors to get the covariance, rather than the correlation
     // matrix
     std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
     for (std::vector<double>::iterator iter = entries.begin();
          iter != entries.end(); iter++) {
       double val = (*iter) * this->fDataHist->GetBinError(row + 1) * 1E38 *
                    this->fDataHist->GetBinError(column + 1) * 1E38;
       if (val == 0) {
         ERR(FTL) << "Found a zero value in the covariance matrix, assuming "
                  "this is an error!"
                  << std::endl;
         exit(-1);
       }
 
       (*this->covar)(row, column) = val;
       (*this->fFullCovar)(row, column) = val;
 
       column++;
     }
 
     row++;
   }
 
   // Robust matrix inversion method
   TDecompSVD LU = TDecompSVD(*this->covar);
   delete this->covar;
   this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
 
   return;
 };
 
 
 
 
 
 
 //********************************************************************
 // FullUnits refers to if we have "real" unscaled units in the covariance matrix, e.g. 1E-76.
 // If this is the case we need to scale it so that the chi2 contribution is correct
 // NUISANCE internally assumes the covariance matrix has units of 1E76
 void Measurement1D::SetCovarFromDataFile(std::string covarFile,
     std::string covName, bool FullUnits) {
   //********************************************************************
 
   LOG(SAM) << "Getting covariance from " << covarFile << "->" << covName
            << std::endl;
 
   TFile* tempFile = new TFile(covarFile.c_str(), "READ");
   TH2D* covPlot = (TH2D*)tempFile->Get(covName.c_str());
   covPlot->SetDirectory(0);
   // Scale the covariance matrix if it comes in normal units
   if (FullUnits) {
     covPlot->Scale(1.E76);
   }
 
   int dim = covPlot->GetNbinsX();
   fFullCovar = new TMatrixDSym(dim);
 
   for (int i = 0; i < dim; i++) {
     for (int j = 0; j < dim; j++) {
       (*fFullCovar)(i, j) = covPlot->GetBinContent(i + 1, j + 1);
     }
   }
 
   this->covar = (TMatrixDSym*)fFullCovar->Clone();
   fDecomp = (TMatrixDSym*)fFullCovar->Clone();
 
   TDecompSVD LU = TDecompSVD(*this->covar);
   this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
 
   TDecompChol LUChol = TDecompChol(*fDecomp);
   LUChol.Decompose();
   fDecomp = new TMatrixDSym(dim, LU.GetU().GetMatrixArray(), "");
 
   return;
 };
 
 // //********************************************************************
 // void Measurement1D::SetBinMask(std::string maskFile) {
 //   //********************************************************************
 
 //   // Create a mask histogram.
 //   int nbins = fDataHist->GetNbinsX();
 //   fMaskHist =
 //     new TH1I((fName + "_fMaskHist").c_str(),
 //              (fName + "_fMaskHist; Bin; Mask?").c_str(), nbins, 0, nbins);
 //   std::string line;
 //   std::ifstream mask(maskFile.c_str(), ifstream::in);
 
 //   if (mask.is_open())
 //     LOG(SAM) << "Reading bin mask from file: " << maskFile << std::endl;
 //   else
 //     LOG(FTL) << " Cannot find mask file." << std::endl;
 
 //   while (std::getline(mask >> std::ws, line, '\n')) {
 //     std::vector<int> entries = GeneralUtils::ParseToInt(line, " ");
 
 //     // Skip lines with poorly formatted lines
 //     if (entries.size() < 2) {
 //       LOG(WRN) << "Measurement1D::SetBinMask(), couldn't parse line: " << line
 //                << std::endl;
 //       continue;
 //     }
 
 //     // The first index should be the bin number, the second should be the mask
 //     // value.
 //     fMaskHist->SetBinContent(entries[0], entries[1]);
 //   }
 
 //   // Set masked data bins to zero
 //   PlotUtils::MaskBins(fDataHist, fMaskHist);
 
 //   return;
 // }
 
 // //********************************************************************
 // void Measurement1D::GetBinContents(std::vector<double>& cont,
 //                                    std::vector<double>& err) {
 //   //********************************************************************
 
 //   // Return a vector of the main bin contents
 //   for (int i = 0; i < fMCHist->GetNbinsX(); i++) {
 //     cont.push_back(fMCHist->GetBinContent(i + 1));
 //     err.push_back(fMCHist->GetBinError(i + 1));
 //   }
 
 //   return;
 // };
 
 
 /*
    XSec Functions
    */
 
 // //********************************************************************
 // void Measurement1D::SetFluxHistogram(std::string fluxFile, int minE, int
 // maxE,
 //     double fluxNorm) {
 //   //********************************************************************
 
 //   // Note this expects the flux bins to be given in terms of MeV
 //   LOG(SAM) << "Reading flux from file: " << fluxFile << std::endl;
 
 //   TGraph f(fluxFile.c_str(), "%lg %lg");
 
 //   fFluxHist =
 //     new TH1D((fName + "_flux").c_str(), (fName + "; E_{#nu} (GeV)").c_str(),
 //         f.GetN() - 1, minE, maxE);
 
 //   Double_t* yVal = f.GetY();
 
 //   for (int i = 0; i < fFluxHist->GetNbinsX(); ++i)
 //     fFluxHist->SetBinContent(i + 1, yVal[i] * fluxNorm);
 // };
 
 // //********************************************************************
 // double Measurement1D::TotalIntegratedFlux(std::string intOpt, double low,
 //     double high) {
 //   //********************************************************************
 
 //   if (fInput->GetType() == kGiBUU) {
 //     return 1.0;
 //   }
 
 //   // The default case of low = -9999.9 and high = -9999.9
 //   if (low == -9999.9) low = this->EnuMin;
 //   if (high == -9999.9) high = this->EnuMax;
 
 //   int minBin = fFluxHist->GetXaxis()->FindBin(low);
 //   int maxBin = fFluxHist->GetXaxis()->FindBin(high);
 
 //   // Get integral over custom range
 //   double integral = fFluxHist->Integral(minBin, maxBin + 1, intOpt.c_str());
 
 //   return integral;
 // };
 
diff --git a/src/FitBase/Measurement2D.cxx b/src/FitBase/Measurement2D.cxx
index d3e1ec7..b2640c5 100644
--- a/src/FitBase/Measurement2D.cxx
+++ b/src/FitBase/Measurement2D.cxx
@@ -1,1937 +1,1937 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
 #include "Measurement2D.h"
 #include "TDecompChol.h"
 
 
 //********************************************************************
 Measurement2D::Measurement2D(void) {
 //********************************************************************
 
   covar = NULL;
   fDecomp = NULL;
   fFullCovar = NULL;
 
   fMCHist = NULL;
   fMCFine = NULL;
   fDataHist = NULL;
 
   fMCHist_X = NULL;
   fMCHist_Y = NULL;
   fDataHist_X = NULL;
   fDataHist_Y = NULL;
 
   fMaskHist = NULL;
   fMapHist = NULL;
   fDataOrig = NULL;
   fDataTrue = NULL;
   fMCWeighted = NULL;
 
   fDefaultTypes = "FIX/FULL/CHI2";
   fAllowedTypes =
     "FIX,FREE,SHAPE/FULL,DIAG/CHI2/NORM/ENUCORR/Q2CORR/ENU1D/FITPROJX/"
     "FITPROJY";
 
   fIsFix = false;
   fIsShape = false;
   fIsFree = false;
 
   fIsDiag = false;
   fIsFull = false;
 
   fAddNormPen = false;
   fIsMask = false;
   fIsChi2SVD = false;
 
   fIsRawEvents = false;
   fIsDifXSec = false;
   fIsEnu = false;
 
 
   // XSec Scalings
   fScaleFactor = -1.0;
   fCurrentNorm = 1.0;
 
   // Histograms
   fDataHist = NULL;
   fDataTrue = NULL;
 
   fMCHist = NULL;
   fMCFine = NULL;
   fMCWeighted = NULL;
 
   fMaskHist = NULL;
 
   // Covar
   covar = NULL;
   fFullCovar = NULL;
 
   fCovar  = NULL;
   fInvert = NULL;
   fDecomp = NULL;
 
   // Fake Data
   fFakeDataInput = "";
   fFakeDataFile  = NULL;
 
   // Options
   fDefaultTypes = "FIX/FULL/CHI2";
   fAllowedTypes =
     "FIX,FREE,SHAPE/FULL,DIAG/CHI2/NORM/ENUCORR/Q2CORR/ENU1D/MASK";
 
   fIsFix = false;
   fIsShape = false;
   fIsFree = false;
   fIsDiag = false;
   fIsFull = false;
   fAddNormPen = false;
   fIsMask = false;
   fIsChi2SVD = false;
   fIsRawEvents = false;
   fIsDifXSec = false;
   fIsEnu1D = false;
 
   // Inputs
   fInput = NULL;
   fRW = NULL;
 
   // Extra Histograms
   fMCHist_Modes = NULL;
 
 }
 
 //********************************************************************
 Measurement2D::~Measurement2D(void) {
 //********************************************************************
 
   if (fDataHist)   delete fDataHist;
   if (fDataTrue)   delete fDataTrue;
   if (fMCHist)     delete fMCHist;
   if (fMCFine)     delete fMCFine;
   if (fMCWeighted) delete fMCWeighted;
   if (fMaskHist)   delete fMaskHist;
   if (covar)       delete covar;
   if (fFullCovar)  delete fFullCovar;
   if (fCovar)      delete fCovar;
   if (fInvert)     delete fInvert;
   if (fDecomp)     delete fDecomp;
 
 }
 
 //********************************************************************
 void Measurement2D::FinaliseSampleSettings() {
 //********************************************************************
 
   MeasurementBase::FinaliseSampleSettings();
 
   // Setup naming + renaming
   fName = fSettings.GetName();
   fSettings.SetS("originalname", fName);
   if (fSettings.Has("rename")) {
     fName = fSettings.GetS("rename");
     fSettings.SetS("name", fName);
   }
 
   // Setup all other options
   LOG(SAM) << "Finalising Sample Settings: " << fName << std::endl;
 
   if ((fSettings.GetS("originalname").find("Evt") != std::string::npos)) {
     fIsRawEvents = true;
     LOG(SAM) << "Found event rate measurement but using poisson likelihoods."
              << std::endl;
   }
 
   if (fSettings.GetS("originalname").find("XSec_1DEnu") != std::string::npos) {
     fIsEnu1D = true;
     LOG(SAM) << "::" << fName << "::" << std::endl;
     LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, "
              << "not flux averaged!" << std::endl;
   }
 
   if (fIsEnu1D && fIsRawEvents) {
     LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this "
              "really correct?!"
              << std::endl;
     LOG(SAM) << "Check experiment constructor for " << fName
              << " and correct this!" << std::endl;
     LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl;
     exit(-1);
   }
 
   if (!fRW) fRW = FitBase::GetRW();
   if (!fInput) SetupInputs(fSettings.GetS("input"));
 
   // Setup options
   SetFitOptions(fDefaultTypes); // defaults
   SetFitOptions(fSettings.GetS("type")); // user specified
 
   EnuMin = GeneralUtils::StrToDbl(fSettings.GetS("enu_min"));
   EnuMax = GeneralUtils::StrToDbl(fSettings.GetS("enu_max"));
 
   if (fAddNormPen) {
     if (fNormError <= 0.0) {
-      ERR(WRN) << "Norm error for class " << fName << " is 0.0!" << endl;
-      ERR(WRN) << "If you want to use it please add fNormError=VAL" << endl;
+      ERR(WRN) << "Norm error for class " << fName << " is 0.0!" << std::endl;
+      ERR(WRN) << "If you want to use it please add fNormError=VAL" << std::endl;
       throw;
     }
   }
 
 }
 
 void Measurement2D::CreateDataHistogram(int dimx, double* binx, int dimy, double* biny) {
   if (fDataHist) delete fDataHist;
 
   LOG(SAM) << "Creating Data Histogram dim : " << dimx << " " << dimy << std::endl;
 
   fDataHist = new TH2D( (fSettings.GetName() + "_data").c_str(), (fSettings.GetFullTitles()).c_str(),
                         dimx - 1, binx, dimy - 1, biny );
 
 }
 
 void Measurement2D::SetDataFromTextFile(std::string datfile) {
   // fDataHist = PlotUtils::GetTH2DFromTextFile(datfile,"");
 }
 
 void Measurement2D::SetDataFromRootFile(std::string datfile, std::string histname) {
   fDataHist = PlotUtils::GetTH2DFromRootFile(datfile, histname);
 }
 
 void Measurement2D::SetDataValuesFromTextFile(std::string datfile, TH2D* hist) {
 
   LOG(SAM) << "Setting data values from text file" << std::endl;
   if (!hist) hist = fDataHist;
 
   // Read TH2D From textfile
   TH2D* valhist = (TH2D*) hist->Clone();
   valhist->Reset();
   PlotUtils::Set2DHistFromText(datfile, valhist, 1.0, true);
 
  LOG(SAM) << " -> Filling values from read hist." << std::endl;
   for (int i = 0; i < valhist->GetNbinsX(); i++) {
     for (int j = 0; j < valhist->GetNbinsY(); j++) {
       hist->SetBinContent(i + 1, j + 1, valhist->GetBinContent(i + 1, j + 1));
     }
   }
   LOG(SAM) << " --> Done" << std::endl;
 }
 
 void Measurement2D::SetDataErrorsFromTextFile(std::string datfile, TH2D* hist) {
   LOG(SAM) << "Setting data errors from text file" << std::endl;
 
   if (!hist) hist = fDataHist;
 
   // Read TH2D From textfile
   TH2D* valhist = (TH2D*) hist->Clone();
   valhist->Reset();
   PlotUtils::Set2DHistFromText(datfile, valhist, 1.0);
 
   // Fill Errors
  LOG(SAM) << " -> Filling errors from read hist." << std::endl;
 
   for (int i = 0; i < valhist->GetNbinsX(); i++) {
     for (int j = 0; j < valhist->GetNbinsY(); j++) {
       hist->SetBinError(i + 1, j + 1, valhist->GetBinContent(i + 1, j + 1));
     }
   }
   LOG(SAM) << " --> Done" << std::endl;
 
 
 }
 
 void Measurement2D::SetMapValuesFromText(std::string dataFile) {
 
   TH2D* hist = fDataHist;
   std::vector<double> edgex;
   std::vector<double> edgey;
 
   for (int i = 0; i <= hist->GetNbinsX(); i++) edgex.push_back(hist->GetXaxis()->GetBinLowEdge(i+1));
   for (int i = 0; i <= hist->GetNbinsY(); i++) edgey.push_back(hist->GetYaxis()->GetBinLowEdge(i+1));
 
 
   fMapHist = new TH2I((fName + "_map").c_str(), (fName + fPlotTitles).c_str(),
                       edgex.size()-1, &edgex[0], edgey.size()-1, &edgey[0]);
 
   LOG(SAM) << "Reading map from: " << dataFile << std::endl;
   PlotUtils::Set2DHistFromText(dataFile, fMapHist, 1.0);
 
 }
 
 //********************************************************************
 void Measurement2D::SetPoissonErrors() {
 //********************************************************************
 
   if (!fDataHist) {
     ERR(FTL) << "Need a data hist to setup possion errors! " << std::endl;
     ERR(FTL) << "Setup Data First!" << std::endl;
     throw;
   }
 
   for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) {
     fDataHist->SetBinError(i + 1, sqrt(fDataHist->GetBinContent(i + 1)));
   }
 }
 
 //********************************************************************
 void Measurement2D::SetCovarFromDiagonal(TH2D* data) {
 //********************************************************************
 
   if (!data and fDataHist) {
     data = fDataHist;
   }
 
   if (data) {
     LOG(SAM) << "Setting diagonal covariance for: " << data->GetName() << std::endl;
     fFullCovar = StatUtils::MakeDiagonalCovarMatrix(data);
     covar      = StatUtils::GetInvert(fFullCovar);
     fDecomp    = StatUtils::GetDecomp(fFullCovar);
   } else {
     ERR(FTL) << "No data input provided to set diagonal covar from!" << std::endl;
 
   }
 
   // if (!fIsDiag) {
   //   ERR(FTL) << "SetCovarMatrixFromDiag called for measurement "
   //            << "that is not set as diagonal." << std::endl;
   //   throw;
   // }
 
 }
 
 //********************************************************************
 void Measurement2D::SetCovarFromTextFile(std::string covfile, int dim) {
 //********************************************************************
 
   if (dim == -1) {
     dim = this->GetNDOF(false);
   }
 
   LOG(SAM) << "Reading covariance from text file: " << covfile << std::endl;
   fFullCovar = StatUtils::GetCovarFromTextFile(covfile, dim);
   covar      = StatUtils::GetInvert(fFullCovar);
   fDecomp    = StatUtils::GetDecomp(fFullCovar);
 
 }
 
 //********************************************************************
 void Measurement2D::SetCovarFromRootFile(std::string covfile, std::string histname) {
 //********************************************************************
 
   LOG(SAM) << "Reading covariance from text file: " << covfile << ";" << histname << std::endl;
   fFullCovar = StatUtils::GetCovarFromRootFile(covfile, histname);
   covar      = StatUtils::GetInvert(fFullCovar);
   fDecomp    = StatUtils::GetDecomp(fFullCovar);
 
 }
 
 //********************************************************************
 void Measurement2D::SetCovarInvertFromTextFile(std::string covfile, int dim) {
 //********************************************************************
 
   if (dim == -1) {
     dim = this->GetNDOF(false);
   }
 
   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(false);
   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(false);
   }
 
   LOG(SAM) << "Reading cholesky from text file: " << covfile << " " << dim << std::endl;
   TMatrixD* temp = StatUtils::GetMatrixFromTextFile(covfile, dim, dim);
 
   TMatrixD* trans = (TMatrixD*)temp->Clone();
   trans->T();
   (*trans) *= (*temp);
 
   fFullCovar  = new TMatrixDSym(dim, trans->GetMatrixArray(), "");
   covar       = StatUtils::GetInvert(fFullCovar);
   fDecomp     = StatUtils::GetDecomp(fFullCovar);
 
   delete temp;
   delete trans;
 
 }
 
 //********************************************************************
 void Measurement2D::SetCholDecompFromRootFile(std::string covfile, std::string histname) {
 //********************************************************************
 
   LOG(SAM) << "Reading cholesky decomp from root file: " << covfile << ";" << histname << std::endl;
   TMatrixD* temp = StatUtils::GetMatrixFromRootFile(covfile, histname);
 
   TMatrixD* trans = (TMatrixD*)temp->Clone();
   trans->T();
   (*trans) *= (*temp);
 
   fFullCovar  = new TMatrixDSym(temp->GetNrows(), trans->GetMatrixArray(), "");
   covar       = StatUtils::GetInvert(fFullCovar);
   fDecomp     = StatUtils::GetDecomp(fFullCovar);
 
   delete temp;
   delete trans;
 }
 
 
 //********************************************************************
 void Measurement2D::ScaleData(double scale) {
 //********************************************************************
   fDataHist->Scale(scale);
 }
 
 
 //********************************************************************
 void Measurement2D::ScaleDataErrors(double scale) {
 //********************************************************************
   for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
     for (int j = 0; j < fDataHist->GetNbinsY(); j++) {
       fDataHist->SetBinError(i + 1, j + 1, fDataHist->GetBinError(i + 1, j + 1) * scale);
     }
   }
 }
 
 
 
 //********************************************************************
 void Measurement2D::ScaleCovar(double scale) {
 //********************************************************************
   (*fFullCovar) *= scale;
   (*covar) *= 1.0 / scale;
   (*fDecomp) *= sqrt(scale);
 }
 
 
 //********************************************************************
 void Measurement2D::SetBinMask(std::string maskfile) {
 //********************************************************************
 
   if (!fIsMask) return;
   LOG(SAM) << "Reading bin mask from file: " << maskfile << std::endl;
 
   // Create a mask histogram with dim of data
   int nbinsx = fDataHist->GetNbinsX();
   int nbinxy = fDataHist->GetNbinsY();
   fMaskHist =
     new TH2I((fSettings.GetName() + "_BINMASK").c_str(),
              (fSettings.GetName() + "_BINMASK; Bin; Mask?").c_str(), nbinsx, 0, nbinsx, nbinxy, 0, nbinxy);
   std::string line;
   std::ifstream mask(maskfile.c_str(), ifstream::in);
 
   if (!mask.is_open()) {
     LOG(FTL) << " Cannot find mask file." << std::endl;
     throw;
   }
 
   while (std::getline(mask >> std::ws, line, '\n')) {
     std::vector<int> entries = GeneralUtils::ParseToInt(line, " ");
 
     // Skip lines with poorly formatted lines
     if (entries.size() < 2) {
       LOG(WRN) << "Measurement2D::SetBinMask(), couldn't parse line: " << line
                << std::endl;
       continue;
     }
 
     // The first index should be the bin number, the second should be the mask
     // value.
     int val = 0;
     if (entries[2] > 0) val = 1;
     fMaskHist->SetBinContent(entries[0], entries[1], val);
   }
 
   // Apply masking by setting masked data bins to zero
   PlotUtils::MaskBins(fDataHist, fMaskHist);
 
 
   return;
 }
 
 
 
 //********************************************************************
 void Measurement2D::FinaliseMeasurement() {
 //********************************************************************
 
   LOG(SAM) << "Finalising Measurement: " << fName << std::endl;
 
   // 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) {
     SetCovarFromDiagonal(fDataHist);
   }
 
   if (!covar) {
     covar = StatUtils::GetInvert(fFullCovar);
   }
 
   if (!fDecomp) {
     fDecomp = StatUtils::GetDecomp(fFullCovar);
   }
 
   // Setup fMCHist from data
   fMCHist = (TH2D*)fDataHist->Clone();
   fMCHist->SetNameTitle((fSettings.GetName() + "_MC").c_str(),
                         (fSettings.GetFullTitles()).c_str());
   fMCHist->Reset();
 
   // Setup fMCFine
   fMCFine = new TH2D("mcfine", "mcfine", fDataHist->GetNbinsX() * 6,
                      fMCHist->GetXaxis()->GetBinLowEdge(1),
                      fMCHist->GetXaxis()->GetBinLowEdge(fDataHist->GetNbinsX() + 1),
                      fDataHist->GetNbinsY() * 6,
                      fMCHist->GetYaxis()->GetBinLowEdge(1),
                      fMCHist->GetYaxis()->GetBinLowEdge(fDataHist->GetNbinsY() + 1));
 
   fMCFine->SetNameTitle((fSettings.GetName() + "_MC_FINE").c_str(),
                         (fSettings.GetFullTitles()).c_str());
   fMCFine->Reset();
 
   // Setup MC Stat
   fMCStat = (TH2D*)fMCHist->Clone();
   fMCStat->Reset();
 
   // Search drawopts for possible types to include by default
   std::string drawopts = FitPar::Config().GetParS("drawopts");
   if (drawopts.find("MODES") != std::string::npos) {
     fMCHist_Modes = new TrueModeStack( (fSettings.GetName() + "_MODES").c_str(),
                                        ("True Channels"), fMCHist);
     SetAutoProcessTH1(fMCHist_Modes);
   }
 
   // Setup bin masks using sample name
   if (fIsMask) {
 
     std::string curname  = fName;
     std::string origname = fSettings.GetS("originalname");
 
     // Check rename.mask
     std::string maskloc = FitPar::Config().GetParDIR(curname + ".mask");
 
     // Check origname.mask
     if (maskloc.empty()) maskloc = FitPar::Config().GetParDIR(origname + ".mask");
 
     // Check database
     if (maskloc.empty()) {
       maskloc = FitPar::GetDataBase() + "/masks/" + origname + ".mask";
     }
 
     // Setup Bin Mask
     SetBinMask(maskloc);
   }
 
   if (fScaleFactor < 0) {
     ERR(FTL) << "I found a negative fScaleFactor in " << __FILE__ << ":" << __LINE__ << std::endl;
     ERR(FTL) << "fScaleFactor = " << fScaleFactor << std::endl;
     ERR(FTL) << "EXITING" << std::endl;
     throw;
   }
 
   // Create and fill Weighted Histogram
   if (!fMCWeighted) {
 
     fMCWeighted = (TH2D*)fMCHist->Clone();
     fMCWeighted->SetNameTitle((fName + "_MCWGHTS").c_str(),
                               (fName + "_MCWGHTS" + fPlotTitles).c_str());
     fMCWeighted->GetYaxis()->SetTitle("Weighted Events");
 
   }
 
 
 }
 
 //********************************************************************
 void Measurement2D::SetFitOptions(std::string opt) {
 //********************************************************************
 
   // Do nothing if default given
   if (opt == "DEFAULT") return;
 
   // CHECK Conflicting Fit Options
   std::vector<std::string> fit_option_allow =
     GeneralUtils::ParseToStr(fAllowedTypes, "/");
 
   for (UInt_t i = 0; i < fit_option_allow.size(); i++) {
     std::vector<std::string> fit_option_section =
       GeneralUtils::ParseToStr(fit_option_allow.at(i), ",");
 
     bool found_option = false;
 
     for (UInt_t j = 0; j < fit_option_section.size(); j++) {
       std::string av_opt = fit_option_section.at(j);
 
       if (!found_option and opt.find(av_opt) != std::string::npos) {
         found_option = true;
 
       } else if (found_option and opt.find(av_opt) != std::string::npos) {
         ERR(FTL) << "ERROR: Conflicting fit options provided: "
                  << opt << std::endl
                  << "Conflicting group = " << fit_option_section.at(i) << std::endl
                  << "You should only supply one of these options in card file." << std::endl;
         throw;
       }
     }
   }
 
   // Check all options are allowed
   std::vector<std::string> fit_options_input =
     GeneralUtils::ParseToStr(opt, "/");
   for (UInt_t i = 0; i < fit_options_input.size(); i++) {
     if (fAllowedTypes.find(fit_options_input.at(i)) == std::string::npos) {
       ERR(FTL) << "ERROR: Fit Option '" << fit_options_input.at(i)
                << "' Provided is not allowed for this measurement."
                << std::endl;
       ERR(FTL) << "Fit Options should be provided as a '/' seperated list "
                "(e.g. FREE/DIAG/NORM)"
                << std::endl;
       ERR(FTL) << "Available options for " << fName << " are '" << fAllowedTypes
                << "'" << std::endl;
 
       throw;
     }
   }
 
   // Set TYPE
   fFitType = opt;
 
   // FIX,SHAPE,FREE
   if (opt.find("FIX") != std::string::npos) {
     fIsFree = fIsShape = false;
     fIsFix = true;
   } else if (opt.find("SHAPE") != std::string::npos) {
     fIsFree = fIsFix = false;
     fIsShape = true;
   } else if (opt.find("FREE") != std::string::npos) {
     fIsFix = fIsShape = false;
     fIsFree = true;
   }
 
   // DIAG,FULL (or default to full)
   if (opt.find("DIAG") != std::string::npos) {
     fIsDiag = true;
     fIsFull = false;
   } else if (opt.find("FULL") != std::string::npos) {
     fIsDiag = false;
     fIsFull = true;
   }
 
   // CHI2/LL (OTHERS?)
   if (opt.find("LOG") != std::string::npos) {
     fIsChi2 = false;
 
     ERR(FTL) << "No other LIKELIHOODS properly supported!" << std::endl;
     ERR(FTL) << "Try to use a chi2!" << std::endl;
     throw;
 
   } else {
     fIsChi2 = true;
   }
 
   // EXTRAS
   if (opt.find("RAW") != std::string::npos) fIsRawEvents = true;
   if (opt.find("DIF") != std::string::npos) fIsDifXSec = true;
   if (opt.find("ENU1D") != std::string::npos) fIsEnu1D = true;
   if (opt.find("NORM") != std::string::npos) fAddNormPen = true;
   if (opt.find("MASK") != std::string::npos) fIsMask = true;
 
   // Set TYPE
   fFitType = opt;
 
   // FIX,SHAPE,FREE
   if (opt.find("FIX") != std::string::npos) {
     fIsFree = fIsShape = false;
     fIsFix = true;
   } else if (opt.find("SHAPE") != std::string::npos) {
     fIsFree = fIsFix = false;
     fIsShape = true;
   } else if (opt.find("FREE") != std::string::npos) {
     fIsFix = fIsShape = false;
     fIsFree = true;
   }
 
   // DIAG,FULL (or default to full)
   if (opt.find("DIAG") != std::string::npos) {
     fIsDiag = true;
     fIsFull = false;
   } else if (opt.find("FULL") != std::string::npos) {
     fIsDiag = false;
     fIsFull = true;
   }
 
   // CHI2/LL (OTHERS?)
   if (opt.find("LOG") != std::string::npos)
     fIsChi2 = false;
   else
     fIsChi2 = true;
 
   // EXTRAS
   if (opt.find("RAW") != std::string::npos) fIsRawEvents = true;
   if (opt.find("DIF") != std::string::npos) fIsDifXSec = true;
   if (opt.find("ENU1D") != std::string::npos) fIsEnu = true;
   if (opt.find("NORM") != std::string::npos) fAddNormPen = true;
   if (opt.find("MASK") != std::string::npos) fIsMask = true;
 
   fIsProjFitX = (opt.find("FITPROJX") != std::string::npos);
   fIsProjFitY = (opt.find("FITPROJY") != std::string::npos);
 
   return;
 };
 
 
 /*
    Reconfigure LOOP
 */
 //********************************************************************
 void Measurement2D::ResetAll() {
 //********************************************************************
 
   fMCHist->Reset();
   fMCFine->Reset();
   fMCStat->Reset();
 
   return;
 };
 
 //********************************************************************
 void Measurement2D::FillHistograms() {
   //********************************************************************
 
   if (Signal) {
     fMCHist->Fill(fXVar, fYVar, Weight);
     fMCFine->Fill(fXVar, fYVar, Weight);
     fMCStat->Fill(fXVar, fYVar, 1.0);
 
     if (fMCHist_Modes) fMCHist_Modes->Fill(Mode, fXVar, fYVar, Weight);
   }
 
   return;
 };
 
 //********************************************************************
 void Measurement2D::ScaleEvents() {
 //********************************************************************
 
   // Fill MCWeighted;
   // for (int i = 0; i < fMCHist->GetNbinsX(); i++) {
   // fMCWeighted->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1));
   // fMCWeighted->SetBinError(i + 1,   fMCHist->GetBinError(i + 1));
   // }
 
 
   // Setup Stat ratios for MC and MC Fine
   double* statratio     = new double[fMCHist->GetNbinsX()];
   for (int i = 0; i < fMCHist->GetNbinsX(); i++) {
     if (fMCHist->GetBinContent(i + 1) != 0) {
       statratio[i] = fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1);
     } else {
       statratio[i] = 0.0;
     }
   }
 
   double* statratiofine = new double[fMCFine->GetNbinsX()];
   for (int i = 0; i < fMCFine->GetNbinsX(); i++) {
     if (fMCFine->GetBinContent(i + 1) != 0) {
       statratiofine[i] = fMCFine->GetBinError(i + 1) / fMCFine->GetBinContent(i + 1);
     } else {
       statratiofine[i] = 0.0;
     }
   }
 
 
   // Scaling for raw event rates
   if (fIsRawEvents) {
     double datamcratio = fDataHist->Integral() / fMCHist->Integral();
 
     fMCHist->Scale(datamcratio);
     fMCFine->Scale(datamcratio);
 
     if (fMCHist_Modes) fMCHist_Modes->Scale(datamcratio);
 
     // Scaling for XSec as function of Enu
   } else if (fIsEnu1D) {
 
     PlotUtils::FluxUnfoldedScaling(fMCHist, GetFluxHistogram(),
                                    GetEventHistogram(), fScaleFactor);
 
     PlotUtils::FluxUnfoldedScaling(fMCFine, GetFluxHistogram(),
                                    GetEventHistogram(), fScaleFactor);
 
 
     // if (fMCHist_Modes) {
     // PlotUtils::FluxUnfoldedScaling(fMCHist_Modes, GetFluxHistogram(),
     // GetEventHistogram(), fScaleFactor,
     // fNEvents);
     // }
 
     // Any other differential scaling
   } else {
     fMCHist->Scale(fScaleFactor, "width");
     fMCFine->Scale(fScaleFactor, "width");
 
     // if (fMCHist_Modes) fMCHist_Modes->Scale(fScaleFactor, "width");
   }
 
 
   // Proper error scaling - ROOT Freaks out with xsec weights sometimes
   for (int i = 0; i < fMCStat->GetNbinsX(); i++) {
     fMCHist->SetBinError(i + 1, fMCHist->GetBinContent(i + 1) * statratio[i]);
   }
 
   for (int i = 0; i < fMCFine->GetNbinsX(); i++) {
     fMCFine->SetBinError(i + 1, fMCFine->GetBinContent(i + 1) * statratiofine[i]);
   }
 
 
   // Clean up
   delete statratio;
   delete statratiofine;
 
   return;
 };
 
 //********************************************************************
 void Measurement2D::ApplyNormScale(double norm) {
 //********************************************************************
 
   fCurrentNorm = norm;
 
   fMCHist->Scale(1.0 / norm);
   fMCFine->Scale(1.0 / norm);
 
   return;
 };
 
 
 
 /*
    Statistic Functions - Outsources to StatUtils
 */
 
 //********************************************************************
 int Measurement2D::GetNDOF(bool applymasking) {
   //********************************************************************
   // return fDataHist->GetNbinsX() - fMaskHist->Integral();
 
   // Just incase it has gone...
   if (!fDataHist) return 0;
 
   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->GetBinContent(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 (applymasking) {
     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;
+  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);
   }
 
   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;
 };
 
 /*
    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 Data/MC
   GetDataList().at(0)->Write();
   GetMCList().at(0)->Write();
 
   // Write Fine Histogram
   if (drawOpt.find("FINE") != std::string::npos)
     GetFineList().at(0)->Write();
 
   // Write Weighted Histogram
   if (drawOpt.find("WEIGHTS") != std::string::npos && fMCWeighted)
     fMCWeighted->Write();
 
 
   // Save Flux/Evt if no event manager
   if (!FitPar::Config().GetParB("EventManager")) {
 
     if (drawOpt.find("FLUX") != std::string::npos && GetFluxHistogram())
       GetFluxHistogram()->Write();
 
     if (drawOpt.find("EVT") != std::string::npos && GetEventHistogram())
       GetEventHistogram()->Write();
 
     if (drawOpt.find("XSEC") != std::string::npos && GetEventHistogram())
       GetEventHistogram()->Write();
 
   }
 
   // Write Mask
   if (fIsMask && (drawOpt.find("MASK") != std::string::npos)) {
     fMaskHist->Write();
   }
 
 
   // Write Covariances
   if (drawOpt.find("COV") != std::string::npos && fFullCovar) {
     PlotUtils::GetFullCovarPlot(fFullCovar, fSettings.GetName());
   }
 
   if (drawOpt.find("INVCOV") != std::string::npos && covar) {
     PlotUtils::GetInvCovarPlot(covar, fSettings.GetName());
   }
 
   if (drawOpt.find("DECOMP") != std::string::npos && fDecomp) {
     PlotUtils::GetDecompCovarPlot(fDecomp, fSettings.GetName());
   }
 
   // // Likelihood residual plots
   // if (drawOpt.find("RESIDUAL") != std::string::npos) {
   //   WriteResidualPlots();
   // }
 
 
   // // RATIO
   // if (drawOpt.find("CANVMC") != std::string::npos) {
   //   TCanvas* c1 = WriteMCCanvas(fDataHist, fMCHist);
   //   c1->Write();
   //   delete c1;
   // }
 
   // // PDG
   // if (drawOpt.find("CANVPDG") != std::string::npos && fMCHist_Modes) {
   //   TCanvas* c2 = WritePDGCanvas(fDataHist, fMCHist, fMCHist_Modes);
   //   c2->Write();
   //   delete c2;
   // }
 
   // Write Extra Histograms
   AutoWriteExtraTH1();
   WriteExtraHistograms();
 
   /// 2D VERSION
   // If null pointer return
   if (!fMCHist and !fDataHist) {
     LOG(SAM) << fName << "Incomplete histogram set!" << std::endl;
     return;
   }
 
   //  FitPar::Config().out->cd();
 
   // Get Draw Options
   drawOpt = FitPar::Config().GetParS("drawopts");
   bool drawData = (drawOpt.find("DATA") != std::string::npos);
   bool drawNormal = (drawOpt.find("MC") != std::string::npos);
   bool drawEvents = (drawOpt.find("EVT") != std::string::npos);
   bool drawXSec = (drawOpt.find("XSEC") != std::string::npos);
   bool drawFine = (drawOpt.find("FINE") != std::string::npos);
   bool drawRatio = (drawOpt.find("RATIO") != std::string::npos);
-  bool drawModes = (drawOpt.find("MODES") != std::string::npos);
+  // bool 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<double> entries = GeneralUtils::ParseToDbl(line, " ");
     for (std::vector<double>::iterator iter = entries.begin();
          iter != entries.end(); iter++) {
       fDataHist->SetBinContent(xBin + 1, yBin + 1, (*iter) * dataNorm);
       xBin++;
     }
     yBin++;
   }
 
   yBin = 0;
   std::ifstream error(errorFile.c_str(), ifstream::in);
 
   if (error.is_open())
     LOG(SAM) << "Reading errors from: " << errorFile.c_str() << std::endl;
 
   while (std::getline(error >> std::ws, line, '\n')) {
     int xBin = 0;
 
     // Loop over entries and insert them into the histogram
     std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
     for (std::vector<double>::iterator iter = entries.begin();
          iter != entries.end(); iter++) {
       fDataHist->SetBinError(xBin + 1, yBin + 1, (*iter) * errorNorm);
       xBin++;
     }
     yBin++;
   }
 
   return;
 };
 
 //********************************************************************
 void Measurement2D::SetDataValuesFromText(std::string dataFile,
     double dataNorm) {
   //********************************************************************
 
   fDataHist = new TH2D((fName + "_data").c_str(), (fName + fPlotTitles).c_str(),
                        fNDataPointsX - 1, fXBins, fNDataPointsY - 1, fYBins);
 
   LOG(SAM) << "Reading data from: " << dataFile << std::endl;
   PlotUtils::Set2DHistFromText(dataFile, fDataHist, dataNorm, true);
 
   return;
 };
 
 //********************************************************************
 void Measurement2D::SetCovarMatrix(std::string covarFile) {
   //********************************************************************
 
   // Used to read a covariance matrix from a root file
   TFile* tempFile = new TFile(covarFile.c_str(), "READ");
 
   // Make plots that we want
   TH2D* covarPlot = new TH2D();
   //  TH2D* decmpPlot = new TH2D();
   TH2D* covarInvPlot = new TH2D();
   TH2D* fFullCovarPlot = new TH2D();
 
   // Get covariance options for fake data studies
   std::string covName = "";
   std::string covOption = FitPar::Config().GetParS("throw_covariance");
 
   // Which matrix to get?
   if (fIsShape || fIsFree) covName = "shp_";
   if (fIsDiag)
     covName += "diag";
   else
     covName += "full";
 
   covarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str());
   covarInvPlot = (TH2D*)tempFile->Get((covName + "covinv").c_str());
 
   // Throw either the sub matrix or the full matrix
   if (!covOption.compare("SUB"))
     fFullCovarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str());
   else if (!covOption.compare("FULL"))
     fFullCovarPlot = (TH2D*)tempFile->Get("fullcov");
   else
     ERR(WRN) << " Incorrect thrown_covariance option in parameters."
              << std::endl;
 
   // Bin masking?
   int dim = int(fDataHist->GetNbinsX());  //-this->masked->Integral());
   int covdim = int(fDataHist->GetNbinsX());
 
   // Make new covars
   this->covar = new TMatrixDSym(dim);
   fFullCovar = new TMatrixDSym(dim);
   fDecomp = new TMatrixDSym(dim);
 
   // Full covariance values
   int row, column = 0;
   row = 0;
   column = 0;
   for (Int_t i = 0; i < covdim; i++) {
     // masking can be dodgy
     // if (this->masked->GetBinContent(i+1) > 0) continue;
     for (Int_t j = 0; j < covdim; j++) {
       //   if (this->masked->GetBinContent(j+1) > 0) continue;
       (*this->covar)(row, column) = covarPlot->GetBinContent(i + 1, j + 1);
       (*fFullCovar)(row, column) = fFullCovarPlot->GetBinContent(i + 1, j + 1);
 
       column++;
     }
     column = 0;
     row++;
   }
 
   // Set bin errors on data
   if (!fIsDiag) {
     for (Int_t i = 0; i < fDataHist->GetNbinsX(); i++) {
       fDataHist->SetBinError(
         i + 1, sqrt((covarPlot->GetBinContent(i + 1, i + 1))) * 1E-38);
     }
   }
 
   TDecompSVD LU = TDecompSVD(*this->covar);
   this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
 
   tempFile->Close();
   delete tempFile;
 
   return;
 };
 
 //********************************************************************
 void Measurement2D::SetCovarMatrixFromText(std::string covarFile, int dim) {
   //********************************************************************
 
   // Make a counter to track the line number
   int row = 0;
 
   std::string line;
   std::ifstream covar(covarFile.c_str(), ifstream::in);
 
   this->covar = new TMatrixDSym(dim);
   fFullCovar = new TMatrixDSym(dim);
   if (covar.is_open())
     LOG(SAM) << "Reading covariance matrix from file: " << covarFile
              << std::endl;
 
   while (std::getline(covar >> std::ws, line, '\n')) {
     int column = 0;
 
     // Loop over entries and insert them into matrix
     // Multiply by the errors to get the covariance, rather than the correlation
     // matrix
     std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
     for (std::vector<double>::iterator iter = entries.begin();
          iter != entries.end(); iter++) {
       double val = (*iter) * fDataHist->GetBinError(row + 1) * 1E38 *
                    fDataHist->GetBinError(column + 1) * 1E38;
       (*this->covar)(row, column) = val;
       (*fFullCovar)(row, column) = val;
 
       column++;
     }
 
     row++;
   }
 
   // Robust matrix inversion method
   TDecompSVD LU = TDecompSVD(*this->covar);
   this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
 
   return;
 };
 
 //********************************************************************
 void Measurement2D::SetCovarMatrixFromChol(std::string covarFile, int dim) {
   //********************************************************************
 
   // Make a counter to track the line number
   int row = 0;
 
   std::string line;
   std::ifstream covarread(covarFile.c_str(), ifstream::in);
 
   TMatrixD* newcov = new TMatrixD(dim, dim);
 
   if (covarread.is_open())
     LOG(SAM) << "Reading covariance matrix from file: " << covarFile
              << std::endl;
   while (std::getline(covarread >> std::ws, line, '\n')) {
     int column = 0;
 
     // Loop over entries and insert them into matrix
     // Multiply by the errors to get the covariance, rather than the correlation
     // matrix
     std::vector<double> entries = GeneralUtils::ParseToDbl(line, " ");
     for (std::vector<double>::iterator iter = entries.begin();
          iter != entries.end(); iter++) {
       (*newcov)(row, column) = *iter;
       column++;
     }
 
     row++;
   }
   covarread.close();
 
   // Form full covariance
   TMatrixD* trans = (TMatrixD*)(newcov)->Clone();
   trans->T();
   (*trans) *= (*newcov);
 
   fFullCovar = new TMatrixDSym(dim, trans->GetMatrixArray(), "");
 
   delete newcov;
   delete trans;
 
   // Robust matrix inversion method
   TDecompChol LU = TDecompChol(*this->fFullCovar);
   this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), "");
 
   return;
 };
 
 // //********************************************************************
 // void Measurement2D::SetMapValuesFromText(std::string dataFile) {
 // //********************************************************************
 
 //   fMapHist = new TH2I((fName + "_map").c_str(), (fName + fPlotTitles).c_str(),
 //                       fNDataPointsX - 1, fXBins, fNDataPointsY - 1, fYBins);
 
 //   LOG(SAM) << "Reading map from: " << dataFile << std::endl;
 //   PlotUtils::Set2DHistFromText(dataFile, fMapHist, 1.0);
 
 //   return;
 // };
 
 
diff --git a/src/FitBase/MeasurementBase.cxx b/src/FitBase/MeasurementBase.cxx
index 2e65539..6ff36fe 100644
--- a/src/FitBase/MeasurementBase.cxx
+++ b/src/FitBase/MeasurementBase.cxx
@@ -1,538 +1,538 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
 #include "MeasurementBase.h"
 
 /*
   Constructor/Destructors
 */
 
 //********************************************************************
 // 2nd Level Constructor (Inherits From MeasurementBase.h)
 MeasurementBase::MeasurementBase(void) {
   //********************************************************************
 
   fScaleFactor = 1.0;
   fMCFilled = false;
   fNoData = false;
   fInput = NULL;
 
   // Set the default values
   // After-wards this gets set in SetupMeasurement
   EnuMin = 0.;
   EnuMax = 1.E5;
 
   fMeasurementSpeciesType = kSingleSpeciesMeasurement;
   fEventVariables = NULL;
   fIsJoint = false;
 };
 
 void MeasurementBase::FinaliseMeasurement() {
 
   // Used to setup default data hists, covars, etc.
 
 
 
 }
 
 //********************************************************************
 // 2nd Level Destructor (Inherits From MeasurementBase.h)
 MeasurementBase::~MeasurementBase() {
   //********************************************************************
 
 };
 
 //********************************************************************
 double MeasurementBase::TotalIntegratedFlux(std::string intOpt, double low,
     double high) {
 //********************************************************************
 
   // Set Energy Limits
   if (low == -9999.9) low = this->EnuMin;
   if (high == -9999.9) high = this->EnuMax;
   return GetInput()->TotalIntegratedFlux(low, high, intOpt);
 };
 
 //********************************************************************
 double MeasurementBase::PredictedEventRate(std::string intOpt, double low,
     double high) {
   //********************************************************************
 
   // Set Energy Limits
   if (low == -9999.9) low = this->EnuMin;
   if (high == -9999.9) high = this->EnuMax;
 
   return GetInput()->PredictedEventRate(low, high, intOpt) * 1E-38;
 };
 
 //********************************************************************
 void MeasurementBase::SetupInputs(std::string inputfile) {
   //********************************************************************
 
 
   // Add this infile to the global manager
   if (FitPar::Config().GetParB("EventManager")) {
     fInput = FitBase::AddInput(fName, inputfile);
   } else {
     std::vector<std::string> file_descriptor =
       GeneralUtils::ParseToStr(inputfile, ":");
     if (file_descriptor.size() != 2) {
       ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfile
                << "\". expected \"FILETYPE:file.root\"" << std::endl;
       throw;
     }
     InputUtils::InputType inpType =
       InputUtils::ParseInputType(file_descriptor[0]);
 
     fInput = InputUtils::CreateInputHandler(fName, inpType, file_descriptor[1]);
   }
 
 
   fNEvents = fInput->GetNEvents();
 
   // Expect INPUTTYPE:FileLocation(s)
   std::vector<std::string> file_descriptor =
     GeneralUtils::ParseToStr(inputfile, ":");
   if (file_descriptor.size() != 2) {
     ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfile
              << "\". expected \"FILETYPE:file.root\"" << std::endl;
     throw;
   }
   fInputType = InputUtils::ParseInputType(file_descriptor[0]);
 
   fInputFileName = file_descriptor[1];
   if (EnuMin == 0 && EnuMax == 1.E5) {
     EnuMin = fInput->GetFluxHistogram()->GetBinLowEdge(1);
     EnuMax = fInput->GetFluxHistogram()->GetBinLowEdge(
                fInput->GetFluxHistogram()->GetNbinsX() + 1);
   }
 
   fFluxHist = fInput->GetFluxHistogram();
   fEventHist = fInput->GetEventHistogram();
 }
 
 //***********************************************
 int MeasurementBase::GetInputID() {
 //***********************************************
   return FitBase::GetInputID(fInputFileName);
 }
 
 //***********************************************
 SampleSettings MeasurementBase::LoadSampleSettings(nuiskey samplekey) {
 //***********************************************
   SampleSettings setting = SampleSettings(samplekey);
   fName = setting.GetS("name");
 
   // Used as an initial setup function incase we need to do anything here.
   LOG(SAM) << "Loading Sample : " << setting.GetName() << std::endl;
   if (!fIsJoint) SetupInputs( setting.GetS("input") );
 
   return setting;
 }
 
 //***********************************************
 SampleSettings MeasurementBase::LoadSampleSettings(std::string name, std::string input, std::string type) {
 //***********************************************
 
   nuiskey samplekey = Config::CreateKey("sample");
   samplekey.SetS("name",name);
   samplekey.SetS("input",input);
   samplekey.SetS("type",type);
 
   return LoadSampleSettings(samplekey);
 }
 
 void MeasurementBase::FinaliseSampleSettings() {
 
   EnuMin = fSettings.GetD("enu_min");
   EnuMax = fSettings.GetD("enu_max");
 
   std::cout << "SetEnuMin = " << EnuMin << " "<< EnuMax << std::endl;
 
 }
 
 
 //***********************************************
 void MeasurementBase::Reconfigure() {
 //***********************************************
   
   LOG(REC) << " Reconfiguring sample " << fName << std::endl;
 
   // Reset Histograms
   ResetExtraHistograms();
   AutoResetExtraTH1();
   this->ResetAll();
 
   // FitEvent* cust_event = fInput->GetEventPointer();
   int fNEvents = fInput->GetNEvents();
   int countwidth = (fNEvents / 5);
 
 
   // MAIN EVENT LOOP
   FitEvent* cust_event = fInput->FirstNuisanceEvent();
   int i = 0;
   int npassed = 0;
   while(cust_event){
 
     cust_event->RWWeight = fRW->CalcWeight(cust_event);
     cust_event->Weight = cust_event->RWWeight * cust_event->InputWeight;
 
     Weight = cust_event->Weight;
 
     // Initialize
     fXVar = -999.9;
     fYVar = -999.9;
     fZVar = -999.9;
     Signal = false;
     Mode = cust_event->Mode;
 
     // Extract Measurement Variables
     this->FillEventVariables(cust_event);
     Signal = this->isSignal(cust_event);
     if (Signal) npassed++;
 
     GetBox()->SetX(fXVar);
     GetBox()->SetY(fYVar);
     GetBox()->SetZ(fZVar);
     GetBox()->SetMode(Mode);
     // GetBox()->fSignal = Signal;
 
     // Fill Histogram Values
     GetBox()->FillBoxFromEvent(cust_event);
     // this->FillExtraHistograms(GetBox(), Weight);
     this->FillHistogramsFromBox(GetBox(), Weight);
 
     // Print Out
     if (LOG_LEVEL(REC) && countwidth > 0 && !(i % countwidth)) {
       std::stringstream ss("");
-      ss.unsetf(ios_base::fixed);
+      ss.unsetf(std::ios_base::fixed);
       ss << std::setw(7) << std::right << i << "/" << fNEvents << " events ("
          << std::setw(2) << double(i) / double(fNEvents) * 100. << std::left
          << std::setw(5) << "%) "
          << "[S,X,Y,Z,M,W] = [" << std::fixed << std::setprecision(2)
          << std::right << Signal << ", " << std::setw(5) << fXVar << ", "
          << std::setw(5) << fYVar << ", " << std::setw(5) << fYVar << ", "
          << std::setw(3) << (int)Mode << ", " << std::setw(5) << Weight << "] "
          << std::endl;
       LOG(SAM) << ss.str();
     }
 
     // iterate
     cust_event = fInput->NextNuisanceEvent();
     i++;
   }
 
   LOG(SAM) << npassed << "/" << fNEvents << " passed selection " << std::endl;
   if (npassed == 0) {
     LOG(SAM) << "WARNING: NO EVENTS PASSED SELECTION!" << std::endl;
   }
   LOG(REC) << std::setw(10) << std::right << NSignal << "/"
            << fNEvents << " events passed selection + binning after reweight"
            << std::endl;
 
   // Finalise Histograms
   fMCFilled = true;
   this->ConvertEventRates();
 }
 
 void MeasurementBase::FillHistogramsFromBox(MeasurementVariableBox* var, double weight) {
 
   fXVar  = var->GetX();
   fYVar  = var->GetY();
   fZVar  = var->GetZ();
   // Signal = var->fSignal;
   // Mode   = var->fMode;
   Weight = weight;
 
   FillHistograms();
   FillExtraHistograms(var, weight);
 
 }
 
 void MeasurementBase::FillHistograms(double weight){
   Weight = weight;
   FillHistograms();
   FillExtraHistograms(GetBox(), Weight);
 }
 
 
 MeasurementVariableBox* MeasurementBase::FillVariableBox(FitEvent* event) {
 
   GetBox()->Reset();
   Mode = event->Mode;
   
   this->FillEventVariables(event);
   Signal = this->isSignal(event);
 
   GetBox()->FillBoxFromEvent(event);
 
   GetBox()->SetX(fXVar);
   GetBox()->SetY(fYVar);
   GetBox()->SetZ(fZVar);
   GetBox()->SetMode(event->Mode);
   // GetBox()->fSignal = Signal;
 
   return GetBox();
 }
 
 MeasurementVariableBox* MeasurementBase::GetBox() {
   if (!fEventVariables) fEventVariables = CreateBox();
   return fEventVariables;
 }
 
 //***********************************************
 void MeasurementBase::ReconfigureFast() {
   //***********************************************
   this->Reconfigure();
 }
 
 //***********************************************
 void MeasurementBase::ConvertEventRates() {
   //***********************************************
 
   AutoScaleExtraTH1();
   ScaleExtraHistograms(GetBox());
   this->ScaleEvents();
 
   double normval = fRW->GetSampleNorm(this->fName);
   if (normval < 0.01 or normval > 10.0){
     ERR(WRN) << "Norm Value inside MeasurementBase::ConvertEventRates() looks off!" << std::endl;
     ERR(WRN) << "It could have become out of sync with the minimizer norm list." << std::endl;
     ERR(WRN) << "Setting it to 1.0" << std::endl;
     normval = 1.0;
   }
   AutoNormExtraTH1(normval);
   NormExtraHistograms(GetBox(), normval);
   this->ApplyNormScale(normval);
 
 }
 
 //***********************************************
 InputHandlerBase* MeasurementBase::GetInput() {
   //***********************************************
 
   if (!fInput) {
     ERR(FTL) << "MeasurementBase::fInput not set. Please submit your command "
              "line options and input cardfile with a bug report to: "
              "nuisance@projects.hepforge.org"
              << std::endl;
     throw;
   }
   return fInput;
 };
 
 //***********************************************
 void MeasurementBase::Renormalise() {
   //***********************************************
 
   // Called when the fitter has changed a measurements normalisation but not any
   // reweight dials
   // Means we don't have to call the time consuming reconfigure when this
   // happens.
   double norm = fRW->GetDialValue(this->fName + "_norm");
 
   if ((this->fCurrentNorm == 0.0 and norm != 0.0) or not fMCFilled) {
     this->ReconfigureFast();
     return;
   }
 
   if (this->fCurrentNorm == norm) return;
 
   this->ApplyNormScale(1.0 / this->fCurrentNorm);
   this->ApplyNormScale(norm);
 
   return;
 };
 
 //***********************************************
 void MeasurementBase::SetSignal(bool sig) {
   //***********************************************
   Signal = sig;
 }
 
 //***********************************************
 void MeasurementBase::SetSignal(FitEvent* evt) {
   //***********************************************
   Signal = this->isSignal(evt);
 }
 
 //***********************************************
 void MeasurementBase::SetWeight(double wght) {
   //***********************************************
   Weight = wght;
 }
 
 //***********************************************
 void MeasurementBase::SetMode(int md) {
   //***********************************************
   Mode = md;
 }
 
 //***********************************************
 std::vector<TH1*> MeasurementBase::GetFluxList() {
   //***********************************************
   return GetInput()->GetFluxList();
 }
 
 //***********************************************
 std::vector<TH1*> MeasurementBase::GetEventRateList() {
   //***********************************************
   return GetInput()->GetEventList();
 }
 
 //***********************************************
 std::vector<TH1*> MeasurementBase::GetXSecList() {
   //***********************************************
   return GetInput()->GetXSecList();
 }
 
 
 void MeasurementBase::ProcessExtraHistograms(int cmd,
     MeasurementVariableBox* vars,
     double weight) {
   // This should be overriden if we have extra histograms!!!
   // Add a flag to tell user this...
   return;
 }
 
 void MeasurementBase::FillExtraHistograms(MeasurementVariableBox* vars,
     double weight) {
   ProcessExtraHistograms(kCMD_Fill, vars, weight);
 }
 
 void MeasurementBase::ScaleExtraHistograms(MeasurementVariableBox* vars) {
   ProcessExtraHistograms(kCMD_Scale, vars, 1.0);
 }
 void MeasurementBase::ResetExtraHistograms() {
   ProcessExtraHistograms(kCMD_Reset, NULL, 1.0);
 }
 void MeasurementBase::NormExtraHistograms(MeasurementVariableBox* vars,
     double norm) {
   ProcessExtraHistograms(kCMD_Norm, vars, norm);
 }
 void MeasurementBase::WriteExtraHistograms() {
   ProcessExtraHistograms(kCMD_Write, NULL, 1.00);
 }
 
 void MeasurementBase::SetAutoProcessTH1(TH1* hist, int c1, int c2, int c3, int c4, int c5) {
   FakeStack* fake = new FakeStack(hist);
   SetAutoProcessTH1(fake, c1, c2, c3, c4, c5); // Need to add a destroy command!
 }
 
 void MeasurementBase::SetAutoProcessTH1(StackBase* hist,  int c1, int c2, int c3, int c4, int c5) {
 
   // Set Defaults
   // int ncommands = kCMD_extraplotflags;
   bool autoflags[5];
   autoflags[0] = false;
   autoflags[1] = false;
   autoflags[2] = false;
   autoflags[3] = false;
   autoflags[4] = false;
 
   int givenflags[5];
   givenflags[0] = c1;
   givenflags[1] = c2;
   givenflags[2] = c3;
   givenflags[3] = c4;
   givenflags[4] = c5;
   fExtraTH1s[hist] = std::vector<int>(5,0);
 
   // Setup a default one.
   if (c1 == -1 && c2 == -1 && c3 == -1 && c4 == -1 && c5 == -1){
     fExtraTH1s[hist][kCMD_Reset] = 1;
     fExtraTH1s[hist][kCMD_Scale] = 1;
     fExtraTH1s[hist][kCMD_Norm] = 1;
     fExtraTH1s[hist][kCMD_Write] = 1;
   }
 
   for (int i = 0; i < 5; i++) {
     switch (givenflags[i]) {
 
     // Skip over...
     case -1:
       break;
 
     case kCMD_Reset:
     case kCMD_Scale:
     case kCMD_Norm:
     case kCMD_Write:
       fExtraTH1s[hist][givenflags[i]] = 1;
       break;
 
     case kCMD_Fill:
       ERR(FTL) << "Can't auto fill yet!" << std::endl;
       autoflags[givenflags[i]] = 1;
       break;
 
     default:
       break;
     }
   }
 
   // LOG(SAM) << "AutoProcessing " << hist->GetName() << std::endl;
 };
 
 void MeasurementBase::AutoFillExtraTH1() {
   ERR(FTL) << "Can't auto fill yet! it's too inefficent!" << std::endl;
   return;
 }
 
 void MeasurementBase::AutoResetExtraTH1() {
 
   for (std::map<StackBase*, std::vector<int> >::iterator iter = fExtraTH1s.begin();
        iter != fExtraTH1s.end(); iter++) {
 
     if (!((*iter).second)[kCMD_Reset]) continue;
     (*iter).first->Reset();
   }
 };
 
 void MeasurementBase::AutoScaleExtraTH1() {
   for (std::map<StackBase*, std::vector<int> >::iterator iter = fExtraTH1s.begin();
        iter != fExtraTH1s.end(); iter++) {
 
     if (!((*iter).second)[kCMD_Scale]) continue;
     (*iter).first->Scale(fScaleFactor, "width");
   }
 };
 
 void MeasurementBase::AutoNormExtraTH1(double norm) {
   double sfactor = 0.0;
   if (norm != 0.0) sfactor = 1.0 / norm;
 
   for (std::map<StackBase*, std::vector<int> >::iterator iter = fExtraTH1s.begin();
        iter != fExtraTH1s.end(); iter++) {
 
     if (!((*iter).second)[kCMD_Norm]) continue;
     (*iter).first->Scale(sfactor);
   }
 };
 
 void MeasurementBase::AutoWriteExtraTH1() {
   for (std::map<StackBase*, std::vector<int> >::iterator iter = fExtraTH1s.begin();
        iter != fExtraTH1s.end(); iter++) {
 
     if (!(((*iter).second)[kCMD_Write])) continue;
     (*iter).first->Write();
   }
 };
 
 
 
diff --git a/src/FitBase/MeasurementBase.h b/src/FitBase/MeasurementBase.h
index f506f8a..ff86ab8 100644
--- a/src/FitBase/MeasurementBase.h
+++ b/src/FitBase/MeasurementBase.h
@@ -1,343 +1,343 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
 #ifndef INPUTHANDLER_H_SEEN
 #define INPUTHANDLER_H_SEEN
 
 /*!
  *  \addtogroup FitBase
  *  @{
  */
 
 // C Includes
 #include <math.h>
 #include <stdlib.h>
 #include <time.h>
 #include <deque>
 #include <iomanip>
 #include <iostream>
 #include <list>
 #include <numeric>
 #include <sstream>
 #include <string>
 
 // ROOT includes
 #include <TArrayF.h>
 #include <TDecompChol.h>
 #include <TDecompSVD.h>
 #include <TGraph.h>
 #include <TGraphErrors.h>
 #include <TH1D.h>
 #include <TH2D.h>
 #include <TMatrixDSym.h>
 #include <TROOT.h>
 #include <TSystem.h>
 
 // External data fit includes
 #include "FitEvent.h"
 #include "FitParameters.h"
 #include "FitUtils.h"
 #include "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 "InputHandler2.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 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<TH1*> GetDataList(void) = 0;
 
   ///! Virtual function to get MC histogram
   virtual std::vector<TH1*> GetMCList(void) = 0;
   virtual std::vector<TH1*> GetFineList(void) = 0;
   virtual std::vector<TH1*> GetMaskList(void) = 0;
 
   ///! Return flux histograms in a vector
   virtual std::vector<TH1*> GetFluxList(void);
   virtual std::vector<TH1*> GetEventRateList(void);
   virtual std::vector<TH1*> 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<MeasurementBase*> GetSubSamples() {
     return std::vector<MeasurementBase*>(1, this);
   }
 
 
   void SetAutoProcessTH1(TH1* 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)
 
   // 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<StackBase*, std::vector<int> > fExtraTH1s;
   int NSignal;
   // std::map<TH1*, bool[6] > fExtaStacks;
 
   bool fIsJoint;
 
 };
 
 
 
 
 // Class TypeDefs
 typedef std::list<MeasurementBase*>::const_iterator MeasListConstIter;
 typedef std::list<MeasurementBase*>::iterator MeasListIter;
 typedef std::vector<MeasurementBase*>::const_iterator MeasVectConstIter;
 typedef std::vector<MeasurementBase*>::iterator MeasVectIter;
 
 /*! @} */
 #endif
diff --git a/src/FitBase/MeasurementVariableBox.cxx b/src/FitBase/MeasurementVariableBox.cxx
index 38b3b61..a063d3d 100644
--- a/src/FitBase/MeasurementVariableBox.cxx
+++ b/src/FitBase/MeasurementVariableBox.cxx
@@ -1,31 +1,31 @@
 #include "MeasurementVariableBox.h"
 void MeasurementVariableBox::Reset() {
 }
 
 void MeasurementVariableBox::FillBoxFromEvent(FitEvent* evt) {
   return;
 }
 
 MeasurementVariableBox* MeasurementVariableBox::CloneSignalBox() {
   return NULL;
 };
 
 void MeasurementVariableBox::Print() {
   std::cout << "Printing Empty BOX! " << std::endl;
 }
 
 double MeasurementVariableBox::GetX(){
   return -999.9;
 }
 
 double MeasurementVariableBox::GetY(){
   return -999.9;
 }
 
 double MeasurementVariableBox::GetZ(){
   return -999.9;
 }
 
 int MeasurementVariableBox::GetMode(){
   return 0;
-}
\ No newline at end of file
+}
diff --git a/src/FitBase/MeasurementVariableBox.h b/src/FitBase/MeasurementVariableBox.h
index 21236ca..1d7217f 100644
--- a/src/FitBase/MeasurementVariableBox.h
+++ b/src/FitBase/MeasurementVariableBox.h
@@ -1,28 +1,28 @@
 #ifndef MEASUREMENTVARIABLEBOX_H
 #define MEASUREMENTVARIABLEBOX_H
 #include "FitEvent.h"
 
 class MeasurementVariableBox {
 public:
   
   MeasurementVariableBox() {};
   ~MeasurementVariableBox() {};
 
   virtual void Reset();
   virtual void FillBoxFromEvent(FitEvent* evt);
   virtual MeasurementVariableBox* CloneSignalBox();
   virtual void Print();
 
   virtual double GetX();
   virtual double GetY();
   virtual double GetZ();
   virtual int GetMode();
 
   virtual void SetX(double x){};
   virtual void SetY(double y){};
   virtual void SetZ(double z){};
   virtual void SetMode(int m){};
 
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/FitBase/MeasurementVariableBox1D.h b/src/FitBase/MeasurementVariableBox1D.h
index c95b879..3cc2422 100644
--- a/src/FitBase/MeasurementVariableBox1D.h
+++ b/src/FitBase/MeasurementVariableBox1D.h
@@ -1,30 +1,30 @@
 #ifndef MEASUREMENTVARIABLEBOX1D_H
 #define MEASUREMENTVARIABLEBOX1D_H
 #include "FitEvent.h"
 #include "MeasurementVariableBox.h"
 
 class MeasurementVariableBox1D : public MeasurementVariableBox {
 public:
   MeasurementVariableBox1D() {};
   ~MeasurementVariableBox1D() {};
 
   virtual void Reset();
   virtual void FillBoxFromEvent(FitEvent* evt);
   virtual MeasurementVariableBox* CloneSignalBox();
   virtual void Print();
 
   virtual double GetX();
   virtual double GetY();
   virtual double GetZ();
   virtual int GetMode();
 
   virtual void SetX(double x);
   virtual void SetY(double y){};
   virtual void SetZ(double z){};
   virtual void SetMode(int m){};
 
   double fX;
 
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/FitBase/MeasurementVariableBox2D.cxx b/src/FitBase/MeasurementVariableBox2D.cxx
index ec42e30..43e03c9 100644
--- a/src/FitBase/MeasurementVariableBox2D.cxx
+++ b/src/FitBase/MeasurementVariableBox2D.cxx
@@ -1,45 +1,45 @@
 #include "MeasurementVariableBox2D.h"
 
 void MeasurementVariableBox2D::Reset() {
   fX = -999.9;
   fY = -999.9;
 }
 
 void MeasurementVariableBox2D::FillBoxFromEvent(FitEvent* evt) {
   return;
 }
 
 MeasurementVariableBox* MeasurementVariableBox2D::CloneSignalBox() {
   MeasurementVariableBox2D* box = new MeasurementVariableBox2D();
   box->fX = this->fX;
   box->fY = this->fY;
   return box;
 };
 
 void MeasurementVariableBox2D::Print() {
   std::cout << "Printing Empty BOX! " << std::endl;
 }
 
 double MeasurementVariableBox2D::GetX(){
   return fX;
 }
 
 double MeasurementVariableBox2D::GetY(){
   return fY;
 }
 
 double MeasurementVariableBox2D::GetZ(){
   return -999.9;
 }
 
 int MeasurementVariableBox2D::GetMode(){
   return 0;
 }
 
 void MeasurementVariableBox2D::SetX(double x){
   fX = x;
 }
 
 void MeasurementVariableBox2D::SetY(double y){
   fY = y;
-}
\ No newline at end of file
+}
diff --git a/src/FitBase/MeasurementVariableBox2D.h b/src/FitBase/MeasurementVariableBox2D.h
index 5876516..cb63375 100644
--- a/src/FitBase/MeasurementVariableBox2D.h
+++ b/src/FitBase/MeasurementVariableBox2D.h
@@ -1,30 +1,30 @@
 #ifndef MEASUREMENTVARIABLEBOX2D_H
 #define MEASUREMENTVARIABLEBOX2D_H
 #include "FitEvent.h"
 #include "MeasurementVariableBox.h"
 
 class MeasurementVariableBox2D : public MeasurementVariableBox {
 public:
   MeasurementVariableBox2D() {};
   ~MeasurementVariableBox2D() {};
 
   virtual void Reset();
   virtual void FillBoxFromEvent(FitEvent* evt);
   virtual MeasurementVariableBox* CloneSignalBox();
   virtual void Print();
 
   virtual double GetX();
   virtual double GetY();
   virtual double GetZ();
   virtual int GetMode();
 
   virtual void SetX(double x);
   virtual void SetY(double y);
   virtual void SetZ(double z){};
   virtual void SetMode(int m){};
 
   double fX, fY;
 
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/FitBase/NEUTInputHandler.cxx b/src/FitBase/NEUTInputHandler.cxx
deleted file mode 100644
index c1f2b74..0000000
--- a/src/FitBase/NEUTInputHandler.cxx
+++ /dev/null
@@ -1,349 +0,0 @@
-#ifdef __NEUT_ENABLED__
-#include "NEUTInputHandler.h"
-
-void NEUTGeneratorInfo::AddBranchesToTree(TTree * tn) {
-	tn->Branch("NEUT_ParticleStatusCode",
-	           fNEUT_ParticleStatusCode, "NEUT_ParticleStatusCode[NParticles]/I");
-	tn->Branch("NEUT_ParticleAliveCode",
-	           fNEUT_ParticleStatusCode, "NEUT_ParticleAliveCode[NParticles]/I");
-}
-
-void NEUTGeneratorInfo::Reset() {
-	for (size_t i = 0; i < kMaxParticles; i++) {
-		fNEUT_ParticleStatusCode[i] = -1;
-		fNEUT_ParticleAliveCode[i]  = 9;
-	}
-}
-
-NEUTInputHandler::~NEUTInputHandler(){
-  fNEUTTreePerformance->Print();                                                                                                                                                                                            
-  fNEUTTreePerformance->Draw();
-  fNEUTTreePerformance->SaveAs("neutioperf.root");                                                                                                                                                                          
-};
-
-
-NEUTInputHandler::NEUTInputHandler(std::string const& handle, std::string const& rawinputs) {
-
-	LOG(SAM) << "Creating NEUTInputHandler : " << handle << std::endl;
-
-	// Run a joint input handling
-	fName = handle;
-	jointinput = false;
-	jointindexswitch = 0;
-
-	// Get initial flags
-	fMaxEvents = FitPar::Config().GetParI("MAXEVENTS");
-
-	// Form list of all inputs, remove brackets if required.
-	std::vector<std::string> inputs = GeneralUtils::ParseToStr(rawinputs, ",");
-	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);
-	}
-	for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) {
-		if (LOG_LEVEL(SAM)) {
-			std::cout << "\t\t|-> Input File " << inp_it
-			          << "      : " << inputs[inp_it] << std::endl;
-		}
-	}
-
-	// Setup the TChain
-	fNEUTTree = new TChain("neuttree");
-
-	// Need to keep a map of flux histograms for PDG. And allow measurements to redfine flux.
-
-	// Loop over all inputs and grab flux, eventhist, and nevents
-	// Also add it to the TChain
-	int evtcounter = 0;
-	if (inputs.size() > 1) jointinput = true;
-	for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) {
-
-		// Add to TChain
-		fNEUTTree->Add( inputs[inp_it].c_str() );
-
-		// Open File for histogram access
-		TFile* inp_file = new TFile(inputs[inp_it].c_str(), "READ");
-
-		// 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());
-
-		// Get N events
-		TTree* neuttree = (TTree*)inp_file->Get("neuttree");
-		int nevents = neuttree->GetEntries();
-
-		// Push into individual input vectors
-		jointfluxinputs.push_back( (TH1D*) fluxhist->Clone() );
-		jointeventinputs.push_back( (TH1D*) eventhist->Clone() );
-
-		jointindexlow.push_back(evtcounter);
-		jointindexhigh.push_back(evtcounter + nevents);
-		evtcounter += nevents;
-
-		// Add to the total flux/event hist
-		if (!fFluxHist) fFluxHist = (TH1D*) fluxhist->Clone();
-		else fFluxHist->Add(fluxhist);
-
-		if (!fEventHist) fEventHist = (TH1D*) eventhist->Clone();
-		else fEventHist->Add(eventhist);
-
-	}
-
-	// Setup NEvents and the FitEvent
-	//	gEnv->SetValue("TFile.AsyncPrefetching", 1);
-	fNEvents = fNEUTTree->GetEntries();
-	fEventType = kNEUT;
-	fNeutVect = NULL;
-	fNEUTTree->SetBranchAddress("vectorbranch", &fNeutVect);
-
-	fNUISANCEEvent = new FitEvent(fNeutVect);
-	fNUISANCEEvent->HardReset();
-	fBaseEvent = static_cast<BaseFitEvt*>(fNUISANCEEvent);
-
-
-	// Normalise event histograms for relative flux contributions.
-	for (size_t i = 0; i < jointeventinputs.size(); i++) {
-		TH1D* eventhist = (TH1D*) jointeventinputs.at(i)->Clone();
-
-		// Determine nallowed
-		int nallowed = jointindexhigh[i] - jointindexlow[i];
-		if (fMaxEvents != -1) {
-			nallowed = int( double(nallowed) *
-			                (double(fMaxEvents) / double(fNEvents)) );
-		}
-		jointindexallowed.push_back(nallowed);
-
-		// Set scale, undoing other scale factor.
-		double scale = double(fNEvents) / fEventHist->Integral("width");
-		scale *= eventhist->Integral("width");
-		scale /= double(jointindexallowed[i]);
-
-		jointindexscale .push_back(scale);
-	}
-
-	fEventHist->SetNameTitle((fName + "_EVT").c_str(), (fName + "_EVT").c_str());
-	fFluxHist->SetNameTitle((fName + "_FLUX").c_str(), (fName + "_FLUX").c_str());
-
-
-	// Setup extra flags
-	fSaveExtra = FitPar::Config().GetParB("save_extra_neut_info");
-	if (fSaveExtra) {
-		fNeutInfo = new NEUTGeneratorInfo();
-		fNUISANCEEvent->fGenInfo = fNeutInfo;
-	}
-
-	// 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
-		          << "\t\t|-> Save Extra Info  : " << fSaveExtra << std::endl;
-	}
-
-	// Setup Max Events
-	if (fMaxEvents > 1 && fMaxEvents < fNEvents) {
-		if (LOG_LEVEL(SAM)) {
-			std::cout << "\t\t|-> Read Max Entries : " << fMaxEvents << std::endl;
-		}
-		fNEvents = fMaxEvents;
-	}
-
-	fNEUTTree->SetCacheEntryRange(0,fNEvents);
-	fNEUTTree->AddBranchToCache("vectorbranch",1);
-	fNEUTTree->SetCacheSize(FitPar::Config().GetParI("CacheSize"));
-	fNEUTTreePerformance = new TTreePerfStats("ioperf",fNEUTTree);
-
-
-};
-
-
-FitEvent* NEUTInputHandler::GetNuisanceEvent(const UInt_t entry) {
-
-	// Catch too large entries
-  if (entry >= (UInt_t)fNEvents){
-    fNEUTTreePerformance->Print();
-    fNEUTTreePerformance->Draw();
-    fNEUTTreePerformance->SaveAs("neutioperf.root");
-
-    return NULL;
-  }
-
-	// Read Entry from TTree to fill NEUT Vect in BaseFitEvt;
-	fNEUTTree->GetEntry(entry);
-	// fNUISANCEEvent->eventid = entry;
-
-	// Setup Input scaling for joint inputs
-	if (jointinput) {
-		fNUISANCEEvent->InputWeight = GetInputWeight(entry);
-	} else {
-		fNUISANCEEvent->InputWeight = 1.0;
-	}
-
-	// Run NUISANCE Vector Filler
-	CalcNUISANCEKinematics();
-
-	// 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" << std::endl;
-		ERR(FTL) << "npart=" << npart << " kMax=" << kmax << std::endl;
-		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;
-
-		// 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;
-
-		// Extra
-		if (fSaveExtra) {
-			fNeutInfo->fNEUT_ParticleStatusCode[curpart] = part->fStatus;
-			fNeutInfo->fNEUT_ParticleAliveCode[curpart] = part->fIsAlive;
-		}
-
-		// Add up particle count
-		fNUISANCEEvent->fNParticles++;
-	}
-
-	// Run Initial, FSI, Final, Other ordering.
-	fNUISANCEEvent-> OrderStack();
-	return;
-}
-
-
-double NEUTInputHandler::GetInputWeight(const UInt_t entry) {
-
-	// Find Switch Scale
-	while ( entry < (UInt_t)jointindexlow[jointindexswitch] ||
-	        entry >= (UInt_t)jointindexhigh[jointindexswitch] ) {
-		jointindexswitch++;
-
-		// Loop Around
-		if (jointindexswitch == jointindexlow.size()) {
-			jointindexswitch = 0;
-		}
-	}
-	return jointindexscale[jointindexswitch];
-};
-
-
-BaseFitEvt* NEUTInputHandler::GetBaseEvent(const UInt_t entry) {
-
-	// Read entry from TTree to fill NEUT Vect in BaseFitEvt;
-	if (entry >= (UInt_t)fNEvents) return NULL;
-
-	fNEUTTree->GetEntry(entry);
-	// fBaseEvent->eventid = entry;
-
-	// Set joint scaling if required
-	if (jointinput) {
-		fBaseEvent->InputWeight = GetInputWeight(entry);
-	} else {
-		fBaseEvent->InputWeight = 1.0;
-	}
-
-	return fBaseEvent;
-}
-#endif
diff --git a/src/FitBase/NEUTInputHandler.h b/src/FitBase/NEUTInputHandler.h
deleted file mode 100644
index 3b273ce..0000000
--- a/src/FitBase/NEUTInputHandler.h
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef NEUTINPUTHANDLER_H
-#define NEUTINPUTHANDLER_H
-
-#ifdef __NEUT_ENABLED__
-#include "InputHandler2.h"
-#include "TargetUtils.h"
-#include "neutpart.h"
-#include "neutvect.h"
-#include "PlotUtils.h"
-#include "TTreePerfStats.h"
-
-
-/// NEUT Generator Container to save extra particle status codes.
-class NEUTGeneratorInfo : public GeneratorInfoBase {
-public:
-
-  NEUTGeneratorInfo(){};
-  ~NEUTGeneratorInfo(){};
-
-  /// Sets up tree branches for saving to NUISANCE format event trees.
-  void AddBranchesToTree(TTree* tn);
-
-  /// Resets particle stack. Called inside FitEvent::Reset();
-  void Reset();
-
-  /// Max Particle List.
-  const static UInt_t kMaxParticles = 400;
-
-  /// NEUT Particle Status Flags
-  int fNEUT_ParticleStatusCode[kMaxParticles];
-
-  /// NEUT Alive Code (0 dead, 1 final state)
-  int fNEUT_ParticleAliveCode[kMaxParticles];
-};
-
-/// NEUT Input Convertor to read in NeutVects and convert to FitEvents
-class NEUTInputHandler : public InputHandlerBase {
-public:
-
-	/// Main constructor. Can read in single or joint inputs.
-	NEUTInputHandler(std::string const& handle, std::string const& rawinputs);
-	~NEUTInputHandler();
-
-
-
-	/// Returns NUISANCE Format event from entry in fNEUTTree
-	FitEvent* GetNuisanceEvent(const UInt_t entry);
-
-	/// Returns BaseEvent (just NeutVect pointer) from entry in fNEUTTree
-	BaseFitEvt* GetBaseEvent(const UInt_t entry);
-
-	/// Convert NEUT particle status codes to NUISANCE format status
-	int GetNeutParticleStatus(NeutPart* part);
-
-	/// eads fNeutVect and fills into fNUISANCEEvent.
-	void CalcNUISANCEKinematics();
-
-	/// Calculates weight if using joint inputs
-	double GetInputWeight(const UInt_t entry);
-
-	bool fSaveExtra; ///< Save Extra NEUT information in to fNeutInfo
-	TChain* fNEUTTree; ///< TTree for reading neut vectors.
-	NeutVect* fNeutVect;  ///< Neut vector format event.
-	NEUTGeneratorInfo* fNeutInfo; ///< NEUT Generator Info container.
-	TTreePerfStats* fNEUTTreePerformance;
-};
-#endif
-#endif
diff --git a/src/FitBase/NUANCEInputHandler.cxx b/src/FitBase/NUANCEInputHandler.cxx
deleted file mode 100644
index 13041ec..0000000
--- a/src/FitBase/NUANCEInputHandler.cxx
+++ /dev/null
@@ -1,185 +0,0 @@
-#ifdef __NUANCE_ENABLED__
-#include "NUANCEInputHandler.h"
-
-NUANCEInputHandler::NUANCEInputHandler(std::string const& handle, std::string const& rawinputs) {
-
-	// Run a joint input handling
-	fName = handle;
-
-	// Read in Nuance output ROOT file (converted from hbook)
-	LOG(SAM) << " Reading NUANCE " << std::endl;
-	fEventType = kNUANCE;
-
-	std::vector<std::string> inputs = GeneralUtils::ParseToStr(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
-	fNEvents = fNUANCETree->GetEntries();
-	fNuanceEvent = new NuanceEvent();
-	fNuanceEvent->SetBranchAddresses(fNUANCETree);
-
-	double EnuMin = 0.0;     // tn->GetMinimum("p_neutrino[3]");
-	double EnuMax = 1000.0;  // tn->GetMaximum("p_neutrino[3]");
-
-	fFluxHist = new TH1D((fName + "_FLUX").c_str(), (fName + "_FLUX").c_str(),
-	                     100, EnuMin, EnuMax);
-	for (int i = 0; i < fFluxHist->GetNbinsX(); i++) {
-		fFluxHist->SetBinContent(i + 1, 1.0);
-	}
-	fFluxHist->Scale(1.0 / fFluxHist->Integral());
-
-	fEventHist = new TH1D((fName + "_EVT").c_str(), (fName + "_EVT").c_str(), 100,
-	                      EnuMin, EnuMax);
-	for (int i = 0; i < fFluxHist->GetNbinsX(); i++) {
-		fEventHist->SetBinContent(i + 1, 1.0);
-	}
-	fEventHist->Scale(1.0 / fEventHist->Integral());
-
-	fXSecHist = (TH1D*)fEventHist->Clone();
-	fXSecHist->Divide(fFluxHist);
-
-};
-
-
-FitEvent* NUANCEInputHandler::GetNuisanceEvent(const UInt_t entry) {
-
-	// Make sure events setup
-	if (!fNUISANCEEvent) fNUISANCEEvent = new FitEvent(fNuanceEvent);
-
-	// Read Entry from TTree to fill NEUT Vect in BaseFitEvt;
-	fNUANCETree->GetEntry(entry);
-
-	// Setup Input scaling for joint inputs
-	if (jointinput) {
-		fNUISANCEEvent->InputWeight = GetInputWeight(entry);
-	} else {
-		fNUISANCEEvent->InputWeight = 1.0;
-	}
-
-	// Run NUISANCE Vector Filler
-	CalcNUISANCEKinematics();
-
-	return fNUISANCEEvent;
-}
-
-
-void NUANCEInputHandler::CalcNUISANCEKinematics() {
-
-	// Reset all variables
-	fNUISANCEEvent->ResetEvent();
-
-	// Get shortened pointer
-	FitEvent* evt = fNUISANCEEvent;
-
-	// Fill Global
-	evt->fMode = GeneratorUtils::ConvertNuanceMode(fNuanceEvent);
-	evt->Mode = evt->fMode;
-	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++;
-	}
-
-	// Run Initial, FSI, Final, Other ordering.
-	fNUISANCEEvent-> OrderStack();
-	return;
-}
-
-
-double NUANCEInputHandler::GetInputWeight(int entry) {
-
-	// Find Switch Scale
-	while ( entry < jointindexlow[jointindexswitch] ||
-	        entry >= jointindexhigh[jointindexswitch] ) {
-		jointindexswitch++;
-
-		// Loop Around
-		if (jointindexswitch == jointindexlow.size()) {
-			jointindexswitch = 0;
-		}
-	}
-	return jointindexscale[jointindexswitch];
-};
-
-
-BaseFitEvt* NUANCEInputHandler::GetBaseEvent(const UInt_t entry) {
-
-	// Make sure events setup
-	// if (!fBaseEvent) fBaseEvent = new BaseFitEvt(fNeutVect);
-
-	// Read entry from TTree to fill NEUT Vect in BaseFitEvt;
-	fNUANCETree->GetEntry(entry);
-
-	// Set joint scaling if required
-	if (jointinput) {
-		fBaseEvent->InputWeight = GetInputWeight(entry);
-	} else {
-		fBaseEvent->InputWeight = 1.0;
-	}
-
-	return fBaseEvent;
-}
-
-void NUANCEInputHandler::Print() {}
-#endif
-
diff --git a/src/FitBase/NUANCEInputHandler.h b/src/FitBase/NUANCEInputHandler.h
deleted file mode 100644
index bcdd84f..0000000
--- a/src/FitBase/NUANCEInputHandler.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef NUANCEINPUTHANDLER_H
-#define NUANCEINPUTHANDLER_H
-#include "InputHandler2.h"
-#ifdef __NUANCE_ENABLED__
-
-#include "PlotUtils.h"
-
-class NUANCEInputHandler : public InputHandlerBase {
-public:
-
-	NUANCEInputHandler(std::string const& handle, std::string const& rawinputs);
-	~NUANCEInputHandler() {};
-
-	FitEvent* GetNuisanceEvent(const UInt_t entry);
-	void CalcNUISANCEKinematics();
-	double GetInputWeight(int entry);
-	BaseFitEvt* GetBaseEvent(const UInt_t entry);
-	void Print();
-
-	std::vector<TH1D*> jointfluxinputs;
-	std::vector<TH1D*> jointeventinputs;
-	std::vector<int> jointindexlow;
-	std::vector<int> jointindexhigh;
-	size_t jointindexswitch;
-	bool jointinput;
-	std::vector<double> jointindexscale;
-
-	NuanceEvent* fNuanceEvent;
-	TChain* fNUANCETree;
-};
-#endif
-#endif
\ No newline at end of file
diff --git a/src/FitBase/NuWroInputHandler.h b/src/FitBase/NuWroInputHandler.h
deleted file mode 100644
index 47eaf30..0000000
--- a/src/FitBase/NuWroInputHandler.h
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef NuWroINPUTHANDLER_H
-#define NuWroINPUTHANDLER_H
-#ifdef __NUWRO_ENABLED__
-#include "GeneratorUtils.h"
-#include "InputHandler2.h"
-#include "PlotUtils.h"
-
-/// NuWro Generator Container to save extra particle status codes.
-class NuWroGeneratorInfo : public GeneratorInfoBase {
-public:
-
-  NuWroGeneratorInfo(){};
-  ~NuWroGeneratorInfo(){};
-
-  /// Sets up tree branches for saving to NUISANCE format event trees.
-  void AddBranchesToTree(TTree* tn);
-
-  /// Resets particle stack. Called inside FitEvent::Reset();
-  void Reset();
-
-  /// Max Particle List.
-  const static UInt_t kMaxParticles = 400;
-
-};
-
-class NuWroInputHandler : public InputHandlerBase {
-public:
-
-	/// Constructor. Can handle single and joint inputs.
-	NuWroInputHandler(std::string const& handle, std::string const& rawinputs);
-	~NuWroInputHandler(){};
-
-	/// Returns filled NUISANCEEvent for given entry.
-	FitEvent* GetNuisanceEvent(const UInt_t entry);
-
-	/// Returns NUISANCE Base Event for given entry with pointer to fNuWroEvent
-	BaseFitEvt* GetBaseEvent(const UInt_t entry);
-
-	/// Fills fNUISANCEEvent from fNuWroEvent
-	void CalcNUISANCEKinematics();
-
-	/// Returns input weight for joint inputs.
-	double GetInputWeight(int entry);
-
-	/// (PLACEHOLDER) Automatically creates nuwro flux/event histograms that 
-	/// nuisance needs to normalise events.
-	void ProcessNuWroInputFlux(const std::string file);
-	
-	bool fSaveExtra; ///< Save Extra NuWro info into Nuisance Event
-	TChain* fNuWroTree; ///< TTree for reading NuWro event vectors
-	
-#ifdef __NUWRO_ENABLED__
-    event* fNuWroEvent;  ///< Pointer to NuWro Format Events 
-    /// Calculates a True Interaction code for NuWro events 
-	int ConvertNuwroMode (event * e); 
-
-	/// Adds a new particle to NUISANCE stack for given NuWro particle
-  	void AddNuWroParticle(FitEvent* evt, const particle& p, int state);
-#endif
-
-  	bool save_extra; ///< Save Extra NuWro info into Nuisance Event
-  	NuWroGeneratorInfo *fNuWroInfo; /// Extra Generator Info
-
-};
-#endif
-#endif
\ No newline at end of file
diff --git a/src/FitBase/SplineInputHandler.cxx b/src/FitBase/SplineInputHandler.cxx
deleted file mode 100644
index 0208e26..0000000
--- a/src/FitBase/SplineInputHandler.cxx
+++ /dev/null
@@ -1,195 +0,0 @@
-#include "SplineInputHandler.h"
-
-SplineInputHandler::SplineInputHandler(std::string const& handle, std::string const& rawinputs) {
-
-	LOG(SAM) << "Creating SplineInputHandler : " << handle << std::endl;
-
-	// Run a joint input handling
-	fName = handle;
-	jointinput = false;
-	jointindexswitch = 0;
-
-	// Setup the TChain
-	fFitEventTree = new TChain("nuisance_events");
-	fMaxEvents = FitPar::Config().GetParI("MAXEVENTS");
-
-	// Add to TChain
-	fFitEventTree->Add( rawinputs.c_str() );
-
-	// Open File for histogram access
-	int evtcounter = 0;
-	TFile* inp_file = new TFile(rawinputs.c_str(), "READ");
-
-	if (LOG_LEVEL(SAM)) {
-		std::cout << "\t\t|-> Input File 0"
-		          << "      : " << rawinputs << std::endl;
-	}
-
-	// Get Flux/Event hist
-	TH1D* fluxhist  = (TH1D*)inp_file->Get(
-	                      (PlotUtils::GetObjectWithName(inp_file, "nuisance_fluxhist")).c_str());
-	TH1D* eventhist = (TH1D*)inp_file->Get(
-	                      (PlotUtils::GetObjectWithName(inp_file, "nuisance_eventhist")).c_str());
-
-	// Get N events
-	TTree* neuttree = (TTree*)inp_file->Get("nuisance_events");
-	int nevents = neuttree->GetEntries();
-
-	// Push into individual input vectors
-	jointfluxinputs.push_back( (TH1D*) fluxhist->Clone() );
-	jointeventinputs.push_back( (TH1D*) eventhist->Clone() );
-
-	jointindexlow.push_back(evtcounter);
-	jointindexhigh.push_back(evtcounter + nevents);
-	evtcounter += nevents;
-
-	// Add to the total flux/event hist
-	if (!fFluxHist) fFluxHist = (TH1D*) fluxhist->Clone();
-	else fFluxHist->Add(fluxhist);
-
-	if (!fEventHist) fEventHist = (TH1D*) eventhist->Clone();
-	else fEventHist->Add(eventhist);
-
-
-	// Setup NEvents and the FitEvent
-	fNEvents = fFitEventTree->GetEntries();
-	fEventType = kNEWSPLINE;
-	fNUISANCEEvent = new FitEvent();
-	fNUISANCEEvent->SetBranchAddress(fFitEventTree);
-
-	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;
-	}
-
-	// Load into memory
-	for (int j = 0; j < fNEvents; j++) {
-		std::vector<float> tempval;
-
-		fFitEventTree->GetEntry(j);
-		//fSplTree->GetEntry(j);
-
-		//for (int i = 0; i < fNPar; i++){
-		//  tempval.push_back( fSplineCoeff[i] );
-		//}
-		//fAllSplineCoeff.push_back(tempval);
-		//	  if (j % (fNEvents/10) == 0 and j != 0) {
-		//  LOG(SAM) << "Pushed " << int(j*100/fNEvents)+1 << "% of spline sets into memory for " << fName
-		//	     << " (~" << int(sizeof(float)*tempval.size()*fAllSplineCoeff.size()/1.E6) <<"MB)" << std::endl;
-		//}
-
-		fStartingWeights.push_back(fNUISANCEEvent->SavedRWWeight * fNUISANCEEvent->InputWeight);
-	}
-
-	fEventType = kSPLINEPARAMETER;
-
-	// Normalise event histograms for relative flux contributions.
-	for (size_t i = 0; i < jointeventinputs.size(); i++) {
-		TH1D* eventhist = (TH1D*) jointeventinputs.at(i)->Clone();
-
-		double scale = double(fNEvents) / fEventHist->Integral("width");
-		scale *= eventhist->Integral("width");
-		scale /= double(jointindexhigh[i] - jointindexlow[i]);
-
-		jointindexscale .push_back(scale);
-	}
-
-	fEventHist->SetNameTitle((fName + "_EVT").c_str(), (fName + "_EVT").c_str());
-	fFluxHist->SetNameTitle((fName + "_FLUX").c_str(), (fName + "_FLUX").c_str());
-
-	// Setup Max Events
-	if (fMaxEvents > 1 && fMaxEvents < fNEvents) {
-		if (LOG_LEVEL(SAM)) {
-			std::cout << "\t\t|-> Read Max Entries : " << fMaxEvents << std::endl;
-		}
-		fNEvents = fMaxEvents;
-	}
-
-	// Setup Spline Reader
-	LOG(SAM) << "Loading Spline Reader." << std::endl;
-
-	fSplRead = new SplineReader();
-	fSplRead->Read( (TTree*)inp_file->Get("spline_reader") );
-	fNUISANCEEvent->fSplineRead = this->fSplRead;
-
-	fNPar = fSplRead->GetNPar();
-
-	// Setup Friend Spline TTree
-	fSplTree = (TTree*)inp_file->Get("spline_tree");
-	fSplTree->SetBranchAddress( "SplineCoeff", fSplineCoeff );
-	fNUISANCEEvent->fSplineCoeff = this->fSplineCoeff;
-
-	fBaseEvent = static_cast<BaseFitEvt*>(fNUISANCEEvent);
-
-};
-
-
-FitEvent* SplineInputHandler::GetNuisanceEvent(const UInt_t entry) {
-
-	// Make sure events setup
-	if (entry >= (UInt_t)fNEvents) return NULL;
-
-	// Reset all variables before tree read
-	fNUISANCEEvent->ResetEvent();
-
-	// Read NUISANCE Tree
-	fFitEventTree->GetEntry(entry);
-
-	fSplTree->GetEntry(entry);
-	fNUISANCEEvent->fSplineCoeff = fSplineCoeff;
-
-	// fNUISANCEEvent->eventid = entry;
-
-	// Run Initial, FSI, Final, Other ordering.
-	fNUISANCEEvent-> OrderStack();
-
-	// Setup Input scaling for joint inputs
-	if (jointinput) {
-		fNUISANCEEvent->InputWeight = fStartingWeights[entry] * GetInputWeight(entry);
-	} else {
-		fNUISANCEEvent->InputWeight = fStartingWeights[entry];
-	}
-
-	return fNUISANCEEvent;
-}
-
-
-double SplineInputHandler::GetInputWeight(int entry) {
-
-	// Find Switch Scale
-	while ( entry < jointindexlow[jointindexswitch] ||
-	        entry >= jointindexhigh[jointindexswitch] ) {
-		jointindexswitch++;
-
-		// Loop Around
-		if (jointindexswitch == jointindexlow.size()) {
-			jointindexswitch = 0;
-		}
-	}
-	return jointindexscale[jointindexswitch];
-};
-
-
-BaseFitEvt* SplineInputHandler::GetBaseEvent(const UInt_t entry) {
-
-	// Make sure events setup
-	if (entry >= (UInt_t)fNEvents) return NULL;
-
-	// fBaseEvent->eventid = entry;
-
-	// Set joint scaling if required
-	if (jointinput) {
-		fBaseEvent->InputWeight = fStartingWeights[entry] * GetInputWeight(entry);
-	} else {
-		fBaseEvent->InputWeight = fStartingWeights[entry];
-	}
-
-	return fBaseEvent;
-}
-
-void SplineInputHandler::Print() {}
-
-
diff --git a/src/FitBase/SplineInputHandler.h b/src/FitBase/SplineInputHandler.h
deleted file mode 100644
index afaf639..0000000
--- a/src/FitBase/SplineInputHandler.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef SPLINE_INPUTHANDLER_H
-#define SPLINE_INPUTHANDLER_H
-
-#include "InputHandler2.h"
-#include "FitEvent.h"
-#include "PlotUtils.h"
-
-class SplineInputHandler : public InputHandlerBase {
-public:
-
-	SplineInputHandler(std::string const& handle, std::string const& rawinputs);
-	~SplineInputHandler(){};
-
-	FitEvent* GetNuisanceEvent(const UInt_t entry);
-	double GetInputWeight(int entry);
-	BaseFitEvt* GetBaseEvent(const UInt_t entry);
-	void Print();
-
-	bool save_extra;
-	TChain* fFitEventTree;
-	SplineReader* fSplRead;
-	float fSplineCoeff[1000];
-	TTree* fSplTree;
-
-	std::vector<float> fStartingWeights;
-
-	std::vector< std::vector<float> > fAllSplineCoeff;
-	int fNPar;
-};
-#endif
diff --git a/src/FitBase/StatusMessage.h b/src/FitBase/StatusMessage.h
deleted file mode 100644
index 1310d5c..0000000
--- a/src/FitBase/StatusMessage.h
+++ /dev/null
@@ -1,336 +0,0 @@
-#ifndef STATUS_MESSAGE_H
-#define STATUS_MESSAGE_H
-
-#include <iostream>
-#include <sstream>
-
-inline std::string StatusMessage(bool happy = true) {
-    return "";
-    
-  std::stringstream ss("");
-  if (happy) {
-    ss << "   @@@                                                       "
-                 "         @@,  \n"
-                 "   @@@                                                       "
-                 "         @@.  \n"
-                 "  @ .@@  "
-                 "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ "
-                 ";@ @@@ \n"
-                 "@@@@@@@@@                                                    "
-                 "      @@@@@@@@\n"
-                 "@@:::::@@ "
-                 "........................................................ "
-                 "@;:::::@\n"
-                 "@@     @@ "
-                 "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@; @.  "
-                 "   @\n"
-                 "  @   @  "
-                 "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ "
-                 ";@  :@ \n"
-                 "   @@@ @@                                                    "
-                 "      @. @@,  \n"
-                 "   @@@ @@                                                    "
-                 "      @. @@,  \n"
-                 "   @: @                                                      "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@    @@@+                                          +@@@ "
-                 "       ;@ @,  \n"
-                 "  @ .@    +#@@@@+                                    +#@@@@+ "
-                 "       ;@ @,  \n"
-                 "  @ .@    ,'@@@@+.                                  .##@@@@, "
-                 "       ;@ @,  \n"
-                 "  @ .@     ;@@@@@+                                  +@@@@@@  "
-                 "       ;@ @,  \n"
-                 "  @ .@     :+@@#  @@+                            +@@  :@@++  "
-                 "       ;@ @,  \n"
-                 "  @ .@       @@#  `` +:                        `+ ``  :@@    "
-                 "       ;@ @,  \n"
-                 "  @ .@       @@#     @:                        `@     :@@    "
-                 "       ;@ @,  \n"
-                 "  @ .@       +@#      .@                      @'      :@+    "
-                 "       ;@ @,  \n"
-                 "  @ .@        @#        @`                   @        :@     "
-                 "       ;@ @,  \n"
-                 "  @ .@        #+;       .::;;;;;;;;;;;;;;;;::.       ;'+     "
-                 "       ;@ @,  \n"
-                 "  @ .@        ++@        ;+@@@@@@@@@@@@@@@@++        @++     "
-                 "       ;@ @,  \n"
-                 "  @ .@          +:         +              +         :+.      "
-                 "       ;@ @,  \n"
-                 "  @ .@           +:::                            :::+        "
-                 "       ;@ @,  \n"
-                 "  @ .@           ':::                            :::'        "
-                 "       ;@ @,  \n"
-                 "  @ .@            ++::.                        `::++         "
-                 "       ;@ @,  \n"
-                 "  @ .@              @+,                        `+@           "
-                 "  +    ;@ @,  \n"
-                 "  @ .@              @..                         .@           "
-                 ",:+    ;@ @,  \n"
-                 "  @ .@              @                            @           "
-                 "+@@    ;@ @,  \n"
-                 "  @ .@              +    +@@              @@@    +          "
-                 "@` @    ;@ @,  \n"
-                 "  @ .@            ++    @   @.           @   @    ++       @ "
-                 "  @    ;@ @,  \n"
-                 "  @ .@            ++    @`  @.           @   @    ++       @ "
-                 "  @    ;@ @,  \n"
-                 "  @ .@            @@    @`  @.           @   @    @@     @@  "
-                 "  @    ;@ @,  \n"
-                 "  @ .@            @@                              @@    @    "
-                 "  @    ;@ @,  \n"
-                 "  @ .@            #+ ::;,         ++.        ,;;, #+  ,+`    "
-                 "  @    ;@ @,  \n"
-                 "  @ .@            ++ :;+:         @@,        :+': ++  :@     "
-                 "  @    ;@ @,  \n"
-                 "  @ .@           +  :++++::                ,:++++:  +@,      "
-                 "  @    ;@ @,  \n"
-                 "  @ .@           @  +++++++  ;@   @@,  @@  ;++++++  @        "
-                 "  @    ;@ @,  \n"
-                 "  @ .@           @  '++++''  :'```'',``''  ;'++++'  @        "
-                 "  @    ;@ @,  \n"
-                 "  @ .@           @  :++++::    @+'  ,+@    ,:++++:  @        "
-                 "  @    ;@ @,  \n"
-                 "  @ .@           +   :;+:                    :+':   +        "
-                 "  @    ;@ @,  \n"
-                 "  @ .@            ++                              ++         "
-                 "  +    ;@ @,  \n"
-                 "  @ .@            ++                              ++         "
-                 "  +    ;@ @,  \n"
-                 "  @ .@              +                            +           "
-                 "+@     ;@ @,  \n"
-                 "  @ .@            @@         ,:::::::::::         ++       "
-                 "@+       ;@ @,  \n"
-                 "  @ .@            @@         ``::::::::``         ##    "
-                 ":,,,.       ;@ @,  \n"
-                 "  @ .@            @@           ::::::::           @@    @++  "
-                 "       ;@ @,  \n"
-                 "  @ .@            ++              ::`             ++ @++     "
-                 "       ;@ @,  \n"
-                 "  @ .@           +::     '+                '+     ::+   @    "
-                 "       ;@ @,  \n"
-                 "  @ .@           +::     ;+                ;+     ::+   @    "
-                 "       ;@ @,  \n"
-                 "  @ .@           @       +@                +@       @    @@  "
-                 "       ;@ @,  \n"
-                 "  @ .@           @         @              @`        @      + "
-                 "       ;@ @,  \n"
-                 "  @ .@           @         `;`           ;`         @    ##  "
-                 "       ;@ @,  \n"
-                 "  @ .@           @          +.           +          @    @@  "
-                 "       ;@ @,  \n"
-                 "  @ .@           @          @.           @          @   @    "
-                 "       ;@ @,  \n"
-                 "  @ .@           @   +:      ;@        @@      `+   @ :@     "
-                 "       ;@ @,  \n"
-                 "  '`,'`          '   :,      :'        ''      `:   ' ,'     "
-                 "       ;@ @,  \n"
-                 "   @: @                                                      "
-                 "       ;@ @,  \n"
-                 "   @@@ @@                                                    "
-                 "      @. @@,  \n"
-                 "  "
-                 ";.:@;..;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"
-                 ";;;;.:;.@'; \n"
-                 "  @ .@@  "
-                 "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ "
-                 ";@ @@@ \n"
-                 "@@@@@@@@@                                                    "
-                 "      @@@@@@@@\n"
-                 "@@     @@ "
-                 "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' @.  "
-                 "   @\n"
-                 ",,:   "
-                 ":,,:@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+:"
-                 ",,:  .:,\n"
-                 "  @   @  "
-                 "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ "
-                 ";@  :@ \n"
-                 "   @@@                                                       "
-                 "         @@,  \n"
-              << std::endl;
-  } else {
-    ss << "  @@@                                                        "
-                 "        @@,   \n"
-                 "   @@@                                                       "
-                 "         @@.  \n"
-                 "  @ .@@  "
-                 "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ "
-                 ";@ @@@ \n"
-                 "@@@@@@@@@                                                    "
-                 "      @@@@@@@@\n"
-                 "@@:::::@@ "
-                 "........................................................ "
-                 "@;:::::@\n"
-                 "@@     @@ "
-                 "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' @.  "
-                 "   @\n"
-                 "  @   @  "
-                 "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ "
-                 ";@  :@ \n"
-                 "   @@@ @@                                                    "
-                 "      @. @@,  \n"
-                 "   @@@ @@                                                    "
-                 "      @. @@,  \n"
-                 "   @: @                                                      "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@                                                       "
-                 "       ;@ @,  \n"
-                 "  @ .@    :;;;::                                         "
-                 "::;;::     ;@ @,  \n"
-                 "  @ .@    +#@@''                                         "
-                 "+'@@++     ;@ @,  \n"
-                 "  @ .@    @@@@@@@@@@@',                           "
-                 "+'@@@@@@@@@@@     ;@ @,  \n"
-                 "  @ .@     ;@@''     ++@@++                   ++@@'+     "
-                 "+'@@       ;@ @,  \n"
-                 "  @ .@     ;#@+'     ++##'+                   +'##'+     "
-                 "++@#`      ;@ @,  \n"
-                 "  @ .@       @@@+          +@@@@@@@@@@@@@@@@@+          +@@@ "
-                 "       ;@ @,  \n"
-                 "  @ .@        ++@:::        +.             ;+        :::@'+  "
-                 "       ;@ @,  \n"
-                 "  @ .@        ,.,'::..`     .              ..     ...:;',.,  "
-                 "       ;@ @,  \n"
-                 "  @ .@           @::::.                           ::::'@     "
-                 "       ;@ @,  \n"
-                 "  @ .@            @@::::                         ::::@,      "
-                 "       ;@ @,  \n"
-                 "  @ .@              +@#+                         +@@+        "
-                 "       ;@ @,  \n"
-                 "  @ .@              +@#+                         +@@+        "
-                 "       ;@ @,  \n"
-                 "  @ .@               @:                           @@         "
-                 "  +    ;@ @,  \n"
-                 "  @ .@               +,    @@.             +@@    ++         "
-                 "+@@    ;@ @,  \n"
-                 "  @ .@              ;    '#`@#+           +` @+;    ;       "
-                 "+``@    ;@ @,  \n"
-                 "  @ .@              '    +@ @@@           @  @@'    '       "
-                 "@` @    ;@ @,  \n"
-                 "  @ .@              @    +@@@@@           @@@@@'    @      @ "
-                 "  @    ;@ @,  \n"
-                 "  @ .@              @      @@`             +@@      @    @@  "
-                 "  @    ;@ @,  \n"
-                 "  @ .@              #  ````''`     ```     ;''````  #   `''  "
-                 "  @    ;@ @,  \n"
-                 "  @ .@              + `:+::        @@@        :;+:  +   @    "
-                 "  @    ;@ @,  \n"
-                 "  @ .@            ++ :;++++:                 :++++:: +#@     "
-                 "  @    ;@ @,  \n"
-                 "  @ .@            @@ +++++++       +++       +++++++ @.      "
-                 "  @    ;@ @,  \n"
-                 "  @ .@            @@ +++++++       +++       +++++++ @,      "
-                 "  @    ;@ @,  \n"
-                 "  @ .@            @@ :;++++:      +   +      :++++:: @,      "
-                 "  @    ;@ @,  \n"
-                 "  @ .@            ++  `:+::     @#     @@     :;+:   +.      "
-                 "  @    ;@ @,  \n"
-                 "  @ .@            ,.,  `.``     ,,     ,,     `..`  ,.`      "
-                 "  @    ;@ @,  \n"
-                 "  @ .@              +                               +        "
-                 "  @    ;@ @,  \n"
-                 "  @ .@               +,                           ++:        "
-                 "  +    ;@ @,  \n"
-                 "  @ .@              +          :::::::::::          +        "
-                 "#@     ;@ @,  \n"
-                 "  @ .@              '          :::::::::::          '        "
-                 "#@     ;@ @,  \n"
-                 "  @ .@              @           :::::::::           @:`    "
-                 "@+       ;@ @,  \n"
-                 "  @ .@              +              :::              +:` @'+  "
-                 "       ;@ @,  \n"
-                 "  @ .@            ';:                               :'';`    "
-                 "       ;@ @,  \n"
-                 "  @ .@            ++:                               :+++     "
-                 "       ;@ @,  \n"
-                 "  @ .@            @@       @                 @       @':@    "
-                 "       ;@ @,  \n"
-                 "  @ .@            @@       '                 '       @': @@  "
-                 "       ;@ @,  \n"
-                 "  '`,'`           ''       :                 :       ':, ''  "
-                 "       ;@ @,  \n"
-                 "   @: @                                                      "
-                 "       ;@ @,  \n"
-                 "   @@@ @@                                                    "
-                 "      @. @@,  \n"
-                 "  "
-                 ";.:@;..;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"
-                 ";;;;.:;.@'; \n"
-                 "  @ .@@  "
-                 "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ "
-                 ";@ @@@ \n"
-                 "@@@@@@@@@                                                    "
-                 "      @@@@@@@@\n"
-                 "@@     @@ "
-                 "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@' @.  "
-                 "   @\n"
-                 ",,:   "
-                 ":,,:@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+:"
-                 ",,:  .:,\n"
-                 "  @   @  "
-                 "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ "
-                 ";@  :@ \n"
-                 "   @@@                                                       "
-                 "         @@,  \n"
-              << std::endl;
-  }
-  return ss.str();
-}
-#endif
diff --git a/src/GGM/CMakeLists.txt b/src/GGM/CMakeLists.txt
index 4fdcda9..685ab67 100644
--- a/src/GGM/CMakeLists.txt
+++ b/src/GGM/CMakeLists.txt
@@ -1,54 +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 <http://www.gnu.org/licenses/>.
 ################################################################################
 set(IMPLFILES
 GGM_CC1ppip_Evt_1DQ2_nu.cxx
 GGM_CC1ppip_XSec_1DEnu_nu.cxx
 )
 
 set(HEADERFILES
 GGM_CC1ppip_Evt_1DQ2_nu.h
 GGM_CC1ppip_XSec_1DEnu_nu.h
 )
 
 set(LIBNAME expGGM)
 
 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(${RWENGINE_INCLUDE_DIRECTORIES})
 
 include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
+include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler)
+include_directories(${CMAKE_SOURCE_DIR}/src/Genie)
 include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
 include_directories(${CMAKE_SOURCE_DIR}/src/Reweight)
 include_directories(${CMAKE_SOURCE_DIR}/src/Splines)
 
 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/FitBase/BaseFitEvt.cxx b/src/InputHandler/BaseFitEvt.cxx
similarity index 99%
rename from src/FitBase/BaseFitEvt.cxx
rename to src/InputHandler/BaseFitEvt.cxx
index 08005f0..9814c63 100644
--- a/src/FitBase/BaseFitEvt.cxx
+++ b/src/InputHandler/BaseFitEvt.cxx
@@ -1,180 +1,180 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 #include "BaseFitEvt.h"
 
 BaseFitEvt::BaseFitEvt() {
 
   Mode = 0;
   E    = 0.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__
   fNuwroEvent = NULL;
 #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__
   if (fNuwroEvent) delete fNuwroEvent;
 #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) {
  
   this->Mode = obj->Mode;
   this->E    = obj->E;
 
   this->Weight        = obj->Weight;
   this->InputWeight   = obj->InputWeight;
   this->RWWeight      = obj->RWWeight;
   this->CustomWeight  = obj->CustomWeight;
   this->SavedRWWeight = obj->SavedRWWeight;
 
   this->fSplineCoeff = obj->fSplineCoeff;
   this->fSplineRead  = obj->fSplineRead;
 
   this->fGenInfo = obj->fGenInfo;
   this->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
 
 };
 
 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;
 }
 #endif
 
 #ifdef __NUWRO_ENABLED__
 void BaseFitEvt::SetNuwroEvent(event* e){
   fType = kNUWRO;
   fNuwroEvent = e;
 }
 #endif
 
 #ifdef __GENIE_ENABLED__
 void BaseFitEvt::SetGenieEvent(NtpMCEventRecord* ntpl){
   fType = kGENIE;
   genie_event = ntpl;
 }
 #endif
 
 #ifdef __NUANCE_ENABLED__
 void BaseFitEvt::SetNuanceEvent(NuanceEvent* e){
-  fType = kNUANCE:
+  fType = kNUANCE;
   nuance_event = e;
 }
 #endif
 
 #ifdef __GiBUU_ENABLED__
 void BaseFitEvt::SetGiBUUReader(GiBUUStdHepReader* g){
   fType = kGiBUU;
   GiRead = g;
 }
 #endif
 
 void BaseFitEvt::SetInputFitEvent(){
   fType = kINPUTFITEVENT;
 }
 
 void BaseFitEvt::SetInputFitSpline(){
   fType = kNEWSPLINE;
 }
 
 void BaseFitEvt::SetInputHepMC(){
   fType = kHEPMC;
 }
 
 
 
diff --git a/src/FitBase/BaseFitEvt.h b/src/InputHandler/BaseFitEvt.h
similarity index 83%
rename from src/FitBase/BaseFitEvt.h
rename to src/InputHandler/BaseFitEvt.h
index c9d64f7..ef102cc 100644
--- a/src/FitBase/BaseFitEvt.h
+++ b/src/InputHandler/BaseFitEvt.h
@@ -1,119 +1,132 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
-
 #ifndef FITEVENTBASE_H_SEEN
 #define FITEVENTBASE_H_SEEN
+/*!
+ *  \addtogroup InputHandler
+ *  @{
+ */
 
 #ifdef __NEUT_ENABLED__
 #include "neutpart.h"
 #include "neutvect.h"
 #endif
 
 #ifdef __NUWRO_ENABLED__
 #include "event1.h"
 #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"
 
-/*!
- *  \addtogroup FitBase
- *  @{
- */
-
 /// Base Event Class used to store just the generator event pointers 
 class BaseFitEvt {
  public:
 
-  // Base Constructors
+  /// Base Constructor
   BaseFitEvt(void);
   ~BaseFitEvt();
+
+  /// Copy base fit event pointers
   BaseFitEvt(const BaseFitEvt* obj);
 
   /// 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 E;  ///< True probe energy
   
   // 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 level pointers.
-  GeneratorInfoBase* fGenInfo;
-  UInt_t fType;
+  // 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
   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/FitBase/CMakeLists.txt b/src/InputHandler/CMakeLists.txt
similarity index 79%
copy from src/FitBase/CMakeLists.txt
copy to src/InputHandler/CMakeLists.txt
index 4631d6d..fbaccb6 100644
--- a/src/FitBase/CMakeLists.txt
+++ b/src/InputHandler/CMakeLists.txt
@@ -1,111 +1,95 @@
 # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 ################################################################################
 #    This file is part of NUISANCE.
 #
 #    NUISANCE is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
 #    (at your option) any later version.
 #
 #    NUISANCE is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #    GNU General Public License for more details.
 #
 #    You should have received a copy of the GNU General Public License
 #    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 ################################################################################
 set(IMPLFILES
-ParamPull.cxx
 BaseFitEvt.cxx
 FitParticle.cxx
-Measurement1D.cxx
-EventManager.cxx
-Measurement2D.cxx
 FitEvent.cxx
-JointMeas1D.cxx
-MeasurementBase.cxx
 GeneratorUtils.cxx
 StdHepEvt.cxx
-TemplateMeas1D.cxx
 InputUtils.cxx
 NEUTInputHandler.cxx
 GENIEInputHandler.cxx
 NuWroInputHandler.cxx
 GIBUUInputHandler.cxx
 NUANCEInputHandler.cxx
+InputHandler.cxx
 NuanceEvent.cxx
-SampleSettings.cxx
 FitEventInputHandler.cxx
 SplineInputHandler.cxx
-MeasurementVariableBox.cxx
-MeasurementVariableBox2D.cxx
-MeasurementVariableBox1D.cxx
-CustomVariableBoxes.h
 GeneratorInfoBase.h
 InputTypes.h
-GNUISANCEFlux.cxx
-GNUISANCEMCJDriver.cxx
 HepMCTextInputHandler.cxx
+InputFactory.cxx
 )
 
 set(HEADERFILES
-ParamPull.h
 NuanceEvent.h
-BaseFitEvt.h    FitEvent.h     JointMeas1D.h    Measurement2D.h
-EventManager.h  FitParticle.h      MeasurementBase.h   Measurement1D.h GeneratorUtils.h StdHepEvt.h TemplateMeas1D.h
+BaseFitEvt.h    
+FitEvent.h   
+FitParticle.h     
+GeneratorUtils.h 
+StdHepEvt.h 
 InputUtils.h
 NEUTInputHandler.h
 HepMCTextInputHandler.h
 GENIEInputHandler.h
 NuWroInputHandler.h
-InputHandler2.h
+InputHandler.h
 GIBUUInputHandler.h
 NUANCEInputHandler.h
-SampleSettings.h
 FitEventInputHandler.h
 SplineInputHandler.h
-MeasurementVariableBox.h
-MeasurementVariableBox2D.h
-MeasurementVariableBox1D.h
-CustomVariableBoxes.h
 GeneratorInfoBase.h
-GNUISANCEFlux.h
-GNUISANCEMCJDriver.h
+InputFactory.h
 )
 
-set(LIBNAME FitBase)
+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(${RWENGINE_INCLUDE_DIRECTORIES})
 
 if (USE_GENIE)
    include_directories(${GENIE_INCLUDES}/Apps)
    include_directories(${GENIE_INCLUDES}/FluxDrivers)
    include_directories(${GENIE_INCLUDES}/EVGDrivers)
 endif()
 
 include_directories(${CMAKE_SOURCE_DIR}/src/Reweight)
 include_directories(${CMAKE_SOURCE_DIR}/src/Splines)
 include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
 include_directories(${CMAKE_CURRENT_SOURCE_DIR})
 
 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/FitBase/FitEvent.cxx b/src/InputHandler/FitEvent.cxx
similarity index 90%
rename from src/FitBase/FitEvent.cxx
rename to src/InputHandler/FitEvent.cxx
index c89cd93..ddc376d 100644
--- a/src/FitBase/FitEvent.cxx
+++ b/src/InputHandler/FitEvent.cxx
@@ -1,414 +1,433 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is pddrt of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 #include "FitEvent.h"
 #include <iostream>
 #include "TObjArray.h"
 
-#ifdef __GENIE_ENABLED__
-#include "Conventions/Units.h"
-#endif
-
 FitEvent::FitEvent() {
 
   fGenInfo = NULL;
   kRemoveFSIParticles = true;
   kRemoveUndefParticles = true;
 
-  // AllocateParticleStack(400);
+  AllocateParticleStack(400);
 
 };
 
 
-void FitEvent::AllocateParticleStack(int stacksize) {
+void FitEvent::AddGeneratorInfo(GeneratorInfoBase* gen) {
+  fGenInfo = gen;
+  gen->AllocateParticleStack(kMaxParticles);
+}
 
+void FitEvent::AllocateParticleStack(int stacksize) {
+  LOG(DEB) << "Allocating particle stack of size: " << stacksize << std::endl;
   kMaxParticles = stacksize;
 
   fParticleList  = new FitParticle*[kMaxParticles];
 
   fParticleMom   = new double*[kMaxParticles];
   fParticleState = new UInt_t[kMaxParticles];
   fParticlePDG   = new int[kMaxParticles];
 
   fOrigParticleMom   = new double*[kMaxParticles];
   fOrigParticleState = new UInt_t[kMaxParticles];
   fOrigParticlePDG   = new int[kMaxParticles];
 
   for (size_t i = 0; i < kMaxParticles; i++) {
     fParticleList[i]    = NULL;
     fParticleMom[i]     = new double[4];
     fOrigParticleMom[i] = new double[4];
   }
 
-  // if (fGenInfo) fGenInfo->AllocateParticleStack(kMaxParticles);
+  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];
     fOrigParticleMom[i][0] = fParticleMom[i][0];
     fOrigParticleMom[i][1] = fParticleMom[i][1];
     fOrigParticleMom[i][2] = fParticleMom[i][2];
     fOrigParticleMom[i][3] = fParticleMom[i][3];
   }
 
   // Now run loops for each particle
   fNParticles = 0;
   int stateorder[6] = {kInitialState,   kFinalState,     kFSIState,
                        kNuclearInitial, kNuclearRemnant, kUndefinedState
                       };
 
   for (int s = 0; s < 6; s++) {
     for (int i = 0; i < npart; i++) {
       if ((UInt_t)fOrigParticleState[i] != (UInt_t)stateorder[s]) continue;
 
       fParticlePDG[fNParticles]    = fOrigParticlePDG[i];
       fParticleState[fNParticles]  = fOrigParticleState[i];
       fParticleMom[fNParticles][0] = fOrigParticleMom[i][0];
       fParticleMom[fNParticles][1] = fOrigParticleMom[i][1];
       fParticleMom[fNParticles][2] = fOrigParticleMom[i][2];
       fParticleMom[fNParticles][3] = fOrigParticleMom[i][3];
 
       fNParticles++;
     }
   }
 
   if (LOG_LEVEL(DEB)) {
     LOG(DEB) << "Ordered stack" << std::endl;
     for (int i = 0; i < fNParticles; i++) {
       LOG(DEB) << "Particle " << i << ". " << fParticlePDG[i] << " "
                << fParticleMom[i][0] << " " << fParticleMom[i][1] << " "
                << fParticleMom[i][2] << " " << fParticleMom[i][3] << " "
                << fParticleState[i] << std::endl;
     }
   }
 
   if (fNParticles != npart) {
     ERR(FTL) << "Dropped some particles when ordering the stack!" << std::endl;
   }
 
   return;
 }
 
 
 void FitEvent::Print() {
 
   if (LOG_LEVEL(EVT)) {
     LOG(EVT) << "EVTEvent print" << std::endl;
     LOG(EVT) << "Mode: " << fMode << std::endl;
     LOG(EVT) << "Particles: " << fNParticles << std::endl;
     LOG(EVT) << " -> Particle Stack " << std::endl;
     for (int i = 0; i < fNParticles; i++) {
       LOG(EVT) << " -> -> " << i << ". " << fParticlePDG[i] << " "
                << fParticleState[i] << " "
                << "  Mom(" << fParticleMom[i][0] << ", " << fParticleMom[i][1]
                << ", " << fParticleMom[i][2] << ", " << fParticleMom[i][3] << ")."
                << std::endl;
     }
   }
   return;
 }
 
 /* Read/Write own event class */
 void FitEvent::SetBranchAddress(TChain* tn) {
 
   tn->SetBranchAddress("Mode",    &fMode);
   tn->SetBranchAddress("Mode",    &Mode);
 
   tn->SetBranchAddress("EventNo", &fEventNo);
   tn->SetBranchAddress("TotCrs",  &fTotCrs);
   tn->SetBranchAddress("TargetA", &fTargetA);
   tn->SetBranchAddress("TargetH", &fTargetH);
   tn->SetBranchAddress("Bound",   &fBound);
 
   tn->SetBranchAddress("RWWeight",    &SavedRWWeight);
   tn->SetBranchAddress("InputWeight", &InputWeight);
 
   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("TargetA", &fTargetA, "TargetA/I");
   tn->Branch("TargetH", &fTargetH, "TargetH/I");
   tn->Branch("Bound",   &fBound,   "Bound/O");
 
   tn->Branch("RWWeight",    &RWWeight,    "RWWeight/D");
   tn->Branch("InputWeight", &InputWeight, "InputWeight/D");
 
   tn->Branch("NParticles",    &fNParticles,       "NParticles/I");
   tn->Branch("ParticleState", fOrigParticleState, "ParticleState[NParticles]/i");
   tn->Branch("ParticlePDG",   fOrigParticlePDG,   "ParticlePDG[NParticles]/I");
   tn->Branch("ParticleMom",   fOrigParticleMom,   "ParticleMom[NParticles][4]/D");
 
 }
 
 
 // ------- EVENT ACCESS FUNCTION --------- //
 TLorentzVector FitEvent::GetParticleP4 (int index) const {
   if (index == -1 or index >= fNParticles) return TLorentzVector();
   return TLorentzVector( fParticleMom[index][0],
                          fParticleMom[index][1],
                          fParticleMom[index][2],
                          fParticleMom[index][3] );
 }
 
 TVector3  FitEvent::GetParticleP3 (int index) const {
   if (index == -1 or index >= fNParticles) return TVector3();
   return TVector3( fParticleMom[index][0],
                    fParticleMom[index][1],
                    fParticleMom[index][2] );
 }
 
 double FitEvent::GetParticleMom (int index) const {
   if (index == -1 or index >= fNParticles) return 0.0;
   return sqrt(fParticleMom[index][0] * fParticleMom[index][0] +
               fParticleMom[index][1] * fParticleMom[index][1] +
               fParticleMom[index][2] * fParticleMom[index][2]);
 }
 
 double FitEvent::GetParticleMom2 (int index) const {
   if (index == -1 or index >= fNParticles) return 0.0;
   return fabs((fParticleMom[index][0] * fParticleMom[index][0] +
                fParticleMom[index][1] * fParticleMom[index][1] +
                fParticleMom[index][2] * fParticleMom[index][2]));
 }
 
 double FitEvent::GetParticleE (int index) const {
   if (index == -1 or index >= fNParticles) return 0.0;
   return fParticleMom[index][3];
 }
 
 int FitEvent::GetParticleState (int index) const {
   if (index == -1 or index >= fNParticles) return kUndefinedState;
   return (fParticleState[index]);
 }
 
 int FitEvent::GetParticlePDG (int index) const {
   if (index == -1 or index >= fNParticles) return 0;
   return (fParticlePDG[index]);
 }
 
-FitParticle* FitEvent::GetParticle (uint i) {
+FitParticle* FitEvent::GetParticle (int const i) {
+
+  // Check Valid Index
+  if (i == -1){
+    return NULL;
+  }
 
   // Check Valid
-  if (i > (UInt_t)fNParticles or i < 0) {
+  if (i > (UInt_t)fNParticles) {
     ERR(FTL) << "Requesting particle beyond stack!" << std::endl
              << "i = " << i << " N = " << fNParticles << std::endl
              << "Mode = " << fMode << std::endl;
     throw;
   }
 
   if (!fParticleList[i]) {
     fParticleList[i] = new FitParticle(fParticleMom[i][0], fParticleMom[i][1],
                                        fParticleMom[i][2], fParticleMom[i][3],
                                        fParticlePDG[i], fParticleState[i]);
   } else {
     fParticleList[i]->SetValues(fParticleMom[i][0], fParticleMom[i][1],
                                 fParticleMom[i][2], fParticleMom[i][3],
                                 fParticlePDG[i], fParticleState[i]);
 
   }
 
   return fParticleList[i];
 }
 
-bool FitEvent::HasParticle(int pdg, int state) const {
+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 pdg, int state) const {
+int FitEvent::NumParticle(int const pdg, int const state) const {
   int nfound = 0;
   for (int i = 0; i < fNParticles; i++) {
     if (state != -1 and fParticleState[i] != (uint)state) continue;
     if (pdg == 0 or fParticlePDG[i] == pdg) nfound += 1;
   }
   return nfound;
 }
 
-std::vector<int> FitEvent::GetAllParticleIndices (int pdg, int state) const {
+std::vector<int> FitEvent::GetAllParticleIndices (int const pdg, int const state) const {
   std::vector<int> indexlist;
   for (int i = 0; i < fNParticles; i++) {
     if (state != -1 and fParticleState[i] != (uint)state) continue;
     if (pdg == 0 or fParticlePDG[i] == pdg) {
       indexlist.push_back(i);
     }
   }
   return indexlist;
 }
 
-std::vector<FitParticle*> FitEvent::GetAllParticle(int pdg, int state) {
+std::vector<FitParticle*> FitEvent::GetAllParticle(int const pdg, int const state) {
   std::vector<int> indexlist = GetAllParticleIndices(pdg, state);
   std::vector<FitParticle*> plist;
   for (std::vector<int>::iterator iter = indexlist.begin();
        iter != indexlist.end(); iter++) {
     plist.push_back( GetParticle((*iter)) );
   }
   return plist;
 }
 
-int FitEvent::GetHMParticleIndex (int pdg, int 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 {
-  return GetHMISParticleIndex( PhysConst::pdg_neutrinos );
+  for (int i = 0; i < fNParticles; i++){
+    if (fParticleState[i] != kInitialState) continue;
+    int pdg = abs(fParticlePDG[i]);
+    if (pdg == 12 or pdg == 14 or pdg == 16){
+      return i;
+    }
+  }
+  return 0;
 }
 
+
 int FitEvent::GetBeamElectronIndex   (void) const {
   return GetHMISParticleIndex( 11 );
 }
 
 int FitEvent::GetBeamPionIndex   (void) const {
   return GetHMISParticleIndex( PhysConst::pdg_pions );
 }
 
 int FitEvent::NumFSMesons() {
   int nMesons = 0;
 
   for (int i = 0; i < fNParticles; i++) {
     if (fParticleState[i] != kFinalState) continue;
     if (abs(fParticlePDG[i]) >= 111 && abs(fParticlePDG[i]) <= 557)
       nMesons += 1;
   }
 
   return nMesons;
 }
 
 
diff --git a/src/FitBase/FitEvent.h b/src/InputHandler/FitEvent.h
similarity index 87%
rename from src/FitBase/FitEvent.h
rename to src/InputHandler/FitEvent.h
index 20756b4..7e7f14d 100644
--- a/src/FitBase/FitEvent.h
+++ b/src/InputHandler/FitEvent.h
@@ -1,569 +1,603 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
-
 #ifndef FITEVENT2_H_SEEN
 #define FITEVENT2_H_SEEN
-
 /*!
- *  \addtogroup FitBase
+ *  \addtogroup InputHandler
  *  @{
  */
 
 #include <algorithm>
 #include <iterator>
 #include <vector>
 #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"
 
 /// Common container for event particles
 class FitEvent : public BaseFitEvt {
 public:
 
   FitEvent();
   ~FitEvent() {};
 
   void FreeFitParticles();
   void ClearFitParticles();
   void ResetEvent(void);
   void ResetParticleList(void);
   void HardReset();
   void OrderStack();
   void SetBranchAddress(TChain* tn);
   void AddBranchesToTree(TTree* tn);
   void Print();
   void PrintChris();
   void DeallocateParticleStack();
   void AllocateParticleStack(int stacksize);
+  void ExpandParticleStack(int stacksize);
+  void AddGeneratorInfo(GeneratorInfoBase* gen);
+
 
   // ---- HELPER/ACCESS FUNCTIONS ---- //
+  /// Return True Interaction ID
   inline int GetMode    (void) const { return fMode;    };
+  /// Return Target Atomic Number
   inline int GetTargetA (void) const { return fTargetA; };
+  /// Return Target Nuclear Charge
   inline int GetTargetZ (void) const { return fTargetZ; };
+  /// Get Event Total Cross-section
   inline int GetTotCrs  (void) const { return fTotCrs;  };
 
-  // Access functions
+  /// Is Event Charged Current?
   inline bool IsCC() const { return (abs(fMode) <= 30); };
+  /// Is Event Neutral Current?
   inline bool IsNC() const { return (abs(fMode) > 30);  };
 
+  /// Return Particle 4-momentum for given index in particle stack
   TLorentzVector GetParticleP4    (int index) const;
+  /// Return Particle 3-momentum for given index in particle stack
   TVector3       GetParticleP3    (int index) const;
+  /// Return Particle absolute momentum for given index in particle stack
   double         GetParticleMom   (int index) const;
+  /// Return Particle absolute momentum-squared for given index in particle stack
   double         GetParticleMom2  (int index) const;
+  /// Return Particle energy for given index in particle stack
   double         GetParticleE     (int index) const;
+  /// Return Particle State for given index in particle stack
   int            GetParticleState (int index) const;
+  /// Return Particle PDG for given index in particle stack
   int            GetParticlePDG   (int index) const;
 
 
-  FitParticle* GetParticle(uint index);
+  /// 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; };
 
-  // PDG State specific functions
-  bool HasParticle (int pdg = 0, int state = -1) const ;
+  /// 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 <size_t N>
-  inline bool HasParticle(int const (&pdgs)[N], int state = -1) const {
+  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;
   }
 
-  int  NumParticle (int pdg = 0, int state = -1) const;
+  /// 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 <size_t N>
-  inline int NumParticle(int const (&pdgs)[N], int state = -1) const {
+  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 list of particles
-  std::vector<int> GetAllParticleIndices (int pdg = -1, int state = -1) const;
+  /// 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<int> GetAllParticleIndices (int const pdg = -1, int const state = -1) const;
 
   template <size_t N>
-  inline std::vector<int> GetAllParticleIndices(int const (&pdgs)[N], int state = -1) const {
+  inline std::vector<int> GetAllParticleIndices(int const (&pdgs)[N], const int state = -1) const {
     std::vector<int> plist;
     for (size_t i = 0; i < N; i++) {
       std::vector<int> plisttemp = GetAllParticleIndices(pdgs[i], state);
       plist.insert( plist.end(), plisttemp.begin(), plisttemp.end() );
     }
     return plist;
   }
 
-  std::vector<FitParticle*> GetAllParticle (int pdg = -1, int state = -1);
+  /// 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<FitParticle*> GetAllParticle (int const pdg = -1, int const state = -1);
 
   template <size_t N>
-  inline std::vector<FitParticle*> GetAllParticle(int const (&pdgs)[N], int state = -1) {
+  inline std::vector<FitParticle*> GetAllParticle(int const (&pdgs)[N], int const state = -1) {
     std::vector<FitParticle*> plist;
     for (size_t i = 0; i < N; i++) {
       std::vector<FitParticle*> plisttemp = GetAllParticle(pdgs[i], state);
       plist.insert( plist.end(), plisttemp.begin(), plisttemp.end() );
     }
     return plist;
   }
 
   inline std::vector<int> GetAllNuElectronIndices (void) { return GetAllParticleIndices(12);   };
   inline std::vector<int> GetAllNuMuonIndices     (void) { return GetAllParticleIndices(14);   };
   inline std::vector<int> GetAllNuTauIndices      (void) { return GetAllParticleIndices(16);   };
   inline std::vector<int> GetAllElectronIndices   (void) { return GetAllParticleIndices(11);   };
   inline std::vector<int> GetAllMuonIndices       (void) { return GetAllParticleIndices(13);   };
   inline std::vector<int> GetAllTauIndices        (void) { return GetAllParticleIndices(15);   };
   inline std::vector<int> GetAllProtonIndices     (void) { return GetAllParticleIndices(2212); };
   inline std::vector<int> GetAllNeutronIndices    (void) { return GetAllParticleIndices(2112); };
   inline std::vector<int> GetAllPiZeroIndices     (void) { return GetAllParticleIndices(111);  };
   inline std::vector<int> GetAllPiPlusIndices     (void) { return GetAllParticleIndices(211);  };
   inline std::vector<int> GetAllPiMinusIndices    (void) { return GetAllParticleIndices(-211); };
   inline std::vector<int> GetAllPhotonIndices     (void) { return GetAllParticleIndices(22);   };
 
   inline std::vector<FitParticle*> GetAllNuElectron (void) { return GetAllParticle(12);   };
   inline std::vector<FitParticle*> GetAllNuMuon     (void) { return GetAllParticle(14);   };
   inline std::vector<FitParticle*> GetAllNuTau      (void) { return GetAllParticle(16);   };
   inline std::vector<FitParticle*> GetAllElectron   (void) { return GetAllParticle(11);   };
   inline std::vector<FitParticle*> GetAllMuon       (void) { return GetAllParticle(13);   };
   inline std::vector<FitParticle*> GetAllTau        (void) { return GetAllParticle(15);   };
   inline std::vector<FitParticle*> GetAllProton     (void) { return GetAllParticle(2212); };
   inline std::vector<FitParticle*> GetAllNeutron    (void) { return GetAllParticle(2112); };
   inline std::vector<FitParticle*> GetAllPiZero     (void) { return GetAllParticle(111);  };
   inline std::vector<FitParticle*> GetAllPiPlus     (void) { return GetAllParticle(211);  };
   inline std::vector<FitParticle*> GetAllPiMinus    (void) { return GetAllParticle(-211); };
   inline std::vector<FitParticle*> GetAllPhoton     (void) { return GetAllParticle(22);   };
 
   // --- Highest Momentum Search Functions --- //
-  int  GetHMParticleIndex (int pdg = 0, int state = -1) const;
+  /// 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 <size_t N>
-  inline int GetHMParticleIndex (int const (&pdgs)[N], int state) const {
+  inline int GetHMParticleIndex (int const (&pdgs)[N], int const state = -1) const {
 
     double mom = 0.0;
-    size_t rtnindex = -1;
+    int rtnindex = -1;
 
     for (size_t i = 0; i < N; ++i) {
-
       // Use ParticleMom as doesn't require Particle Mem alloc
-      size_t pindex = GetHMParticleIndex(pdgs[i], state);
+      int pindex = GetHMParticleIndex(pdgs[i], state);
       double momnew = GetParticleMom2(pindex);
       if (momnew > 0.0 && (momnew > mom)) {
-        rtnindex = i;
+        rtnindex = pindex;
         mom = momnew;
       }
     }
-
     return rtnindex;
   };
 
-  inline FitParticle* GetHMParticle(int pdg = 0, int state = -1) {
+  /// 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 <size_t N>
-  inline FitParticle* GetHMParticle(int const (&pdgs)[N], int state) {
+  inline FitParticle* GetHMParticle(int const (&pdgs)[N], int const state) {
     return GetParticle(GetHMParticleIndex(pdgs, state));
   };
 
 
   // ---- Initial State Helpers --- //
-  inline bool HasISParticle(int pdg) const {
+  /// 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 <size_t N>
   inline bool HasISParticle(int const (&pdgs)[N]) const {
     return HasParticle(pdgs, kInitialState);
   };
 
-  inline int NumISParticle(int pdg = 0) const {
+  /// 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 <size_t N>
   inline int NumISParticle(int const (&pdgs)[N]) const {
     return NumParticle(pdgs, kInitialState);
   };
 
-  inline std::vector<int> GetAllISParticleIndices(int pdg = -1) const {
+  /// 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<int> GetAllISParticleIndices(int const pdg = -1) const {
     return GetAllParticleIndices(pdg, kInitialState);
   };
   template <size_t N>
   inline std::vector<int> GetAllISParticleIndices(int const (&pdgs)[N]) const {
     return GetAllParticleIndices(pdgs, kInitialState);
   };
 
-  inline std::vector<FitParticle*> GetAllISParticle(int pdg = -1) {
+  /// 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<FitParticle*> GetAllISParticle(int const pdg = -1) {
     return GetAllParticle(pdg, kInitialState);
   };
   template <size_t N>
   inline std::vector<FitParticle*> GetAllISParticle(int const (&pdgs)[N]) {
     return GetAllParticle(pdgs, kInitialState);
   };
 
-  inline FitParticle* GetHMISParticle(int pdg) {
+  /// Returns the highest momentum particle with a given pdg in the initial state.
+  inline FitParticle* GetHMISParticle(int const pdg) {
     return GetHMParticle(pdg, kInitialState);
   };
   template <size_t N>
   inline FitParticle* GetHMISParticle(int const (&pdgs)[N]) {
     return GetHMParticle(pdgs, kInitialState);
   };
 
-  inline int GetHMISParticleIndex(int pdg) const {
+  /// 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 <size_t N>
   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<int> GetAllISNuElectronIndices (void) const { return GetAllISParticleIndices(12);   };
   inline std::vector<int> GetAllISNuMuonIndices     (void) const { return GetAllISParticleIndices(14);   };
   inline std::vector<int> GetAllISNuTauIndices      (void) const { return GetAllISParticleIndices(16);   };
   inline std::vector<int> GetAllISElectronIndices   (void) const { return GetAllISParticleIndices(11);   };
   inline std::vector<int> GetAllISMuonIndices       (void) const { return GetAllISParticleIndices(13);   };
   inline std::vector<int> GetAllISTauIndices        (void) const { return GetAllISParticleIndices(15);   };
   inline std::vector<int> GetAllISProtonIndices     (void) const { return GetAllISParticleIndices(2212); };
   inline std::vector<int> GetAllISNeutronIndices    (void) const { return GetAllISParticleIndices(2112); };
   inline std::vector<int> GetAllISPiZeroIndices     (void) const { return GetAllISParticleIndices(111);  };
   inline std::vector<int> GetAllISPiPlusIndices     (void) const { return GetAllISParticleIndices(211);  };
   inline std::vector<int> GetAllISPiMinusIndices    (void) const { return GetAllISParticleIndices(-211); };
   inline std::vector<int> GetAllISPhotonIndices     (void) const { return GetAllISParticleIndices(22);   };
   inline std::vector<int> GetAllISLeptonsIndices    (void) const { return GetAllISParticleIndices(PhysConst::pdg_leptons);       };
   inline std::vector<int> GetAllISPionsIndices      (void) const { return GetAllISParticleIndices(PhysConst::pdg_pions);         };
   inline std::vector<int> GetAllISChargePionsIndices(void) const { return GetAllISParticleIndices(PhysConst::pdg_charged_pions); };
 
   inline std::vector<FitParticle*> GetAllISNuElectron (void) { return GetAllISParticle(12);   };
   inline std::vector<FitParticle*> GetAllISNuMuon     (void) { return GetAllISParticle(14);   };
   inline std::vector<FitParticle*> GetAllISNuTau      (void) { return GetAllISParticle(16);   };
   inline std::vector<FitParticle*> GetAllISElectron   (void) { return GetAllISParticle(11);   };
   inline std::vector<FitParticle*> GetAllISMuon       (void) { return GetAllISParticle(13);   };
   inline std::vector<FitParticle*> GetAllISTau        (void) { return GetAllISParticle(15);   };
   inline std::vector<FitParticle*> GetAllISProton     (void) { return GetAllISParticle(2212); };
   inline std::vector<FitParticle*> GetAllISNeutron    (void) { return GetAllISParticle(2112); };
   inline std::vector<FitParticle*> GetAllISPiZero     (void) { return GetAllISParticle(111);  };
   inline std::vector<FitParticle*> GetAllISPiPlus     (void) { return GetAllISParticle(211);  };
   inline std::vector<FitParticle*> GetAllISPiMinus    (void) { return GetAllISParticle(-211); };
   inline std::vector<FitParticle*> GetAllISPhoton     (void) { return GetAllISParticle(22);   };
   inline std::vector<FitParticle*> GetAllISLeptons    (void) { return GetAllISParticle(PhysConst::pdg_leptons);       };
   inline std::vector<FitParticle*> GetAllISPions      (void) { return GetAllISParticle(PhysConst::pdg_pions);         };
   inline std::vector<FitParticle*> 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* 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* GetHMISLeptons    (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 pdg) const {
+  inline bool HasFSParticle(int const pdg) const {
     return HasParticle(pdg, kFinalState);
   };
   template <size_t N>
   inline bool HasFSParticle(int const (&pdgs)[N]) const {
     return HasParticle(pdgs, kFinalState);
   };
 
-  inline int NumFSParticle(int pdg = 0) const {
+  inline int NumFSParticle(int const pdg = 0) const {
     return NumParticle(pdg, kFinalState);
   };
   template <size_t N>
   inline int NumFSParticle(int const (&pdgs)[N]) const {
     return NumParticle(pdgs, kFinalState);
   };
 
-  inline std::vector<int> GetAllFSParticleIndices(int pdg = -1) const {
+  inline std::vector<int> GetAllFSParticleIndices(int const pdg = -1) const {
     return GetAllParticleIndices(pdg, kFinalState);
   };
   template <size_t N>
   inline std::vector<int> GetAllFSParticleIndices(int const (&pdgs)[N]) const {
     return GetAllParticleIndices(pdgs, kFinalState);
   };
 
-  inline std::vector<FitParticle*> GetAllFSParticle(int pdg = -1) {
+  inline std::vector<FitParticle*> GetAllFSParticle(int const pdg = -1) {
     return GetAllParticle(pdg, kFinalState);
   };
   template <size_t N>
   inline std::vector<FitParticle*> GetAllFSParticle(int const (&pdgs)[N]) {
     return GetAllParticle(pdgs, kFinalState);
   };
 
-  inline FitParticle* GetHMFSParticle(int pdg) {
+  inline FitParticle* GetHMFSParticle(int const pdg) {
     return GetHMParticle(pdg, kFinalState);
   };
   template <size_t N>
   inline FitParticle* GetHMFSParticle(int const (&pdgs)[N]) {
     return GetHMParticle(pdgs, kFinalState);
   };
 
-  inline int GetHMFSParticleIndex(int pdg) const {
+  inline int GetHMFSParticleIndex(int const pdg) const {
     return GetHMParticleIndex(pdg, kFinalState);
   };
   template <size_t N>
   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);   };
   inline 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<int> GetAllFSNuElectronIndices (void) const { return GetAllFSParticleIndices(12);   };
   inline std::vector<int> GetAllFSNuMuonIndices     (void) const { return GetAllFSParticleIndices(14);   };
   inline std::vector<int> GetAllFSNuTauIndices      (void) const { return GetAllFSParticleIndices(16);   };
   inline std::vector<int> GetAllFSElectronIndices   (void) const { return GetAllFSParticleIndices(11);   };
   inline std::vector<int> GetAllFSMuonIndices       (void) const { return GetAllFSParticleIndices(13);   };
   inline std::vector<int> GetAllFSTauIndices        (void) const { return GetAllFSParticleIndices(15);   };
   inline std::vector<int> GetAllFSProtonIndices     (void) const { return GetAllFSParticleIndices(2212); };
   inline std::vector<int> GetAllFSNeutronIndices    (void) const { return GetAllFSParticleIndices(2112); };
   inline std::vector<int> GetAllFSPiZeroIndices     (void) const { return GetAllFSParticleIndices(111);  };
   inline std::vector<int> GetAllFSPiPlusIndices     (void) const { return GetAllFSParticleIndices(211);  };
   inline std::vector<int> GetAllFSPiMinusIndices    (void) const { return GetAllFSParticleIndices(-211); };
   inline std::vector<int> GetAllFSPhotonIndices     (void) const { return GetAllFSParticleIndices(22);   };
   inline std::vector<int> GetAllFSLeptonsIndices    (void) const { return GetAllFSParticleIndices(PhysConst::pdg_leptons);       };
   inline std::vector<int> GetAllFSPionsIndices      (void) const { return GetAllFSParticleIndices(PhysConst::pdg_pions);         };
   inline std::vector<int> GetAllFSChargePionsIndices(void) const { return GetAllFSParticleIndices(PhysConst::pdg_charged_pions); };
 
   inline std::vector<FitParticle*> GetAllFSNuElectron (void) { return GetAllFSParticle(12);   };
   inline std::vector<FitParticle*> GetAllFSNuMuon     (void) { return GetAllFSParticle(14);   };
   inline std::vector<FitParticle*> GetAllFSNuTau      (void) { return GetAllFSParticle(16);   };
   inline std::vector<FitParticle*> GetAllFSElectron   (void) { return GetAllFSParticle(11);   };
   inline std::vector<FitParticle*> GetAllFSMuon       (void) { return GetAllFSParticle(13);   };
   inline std::vector<FitParticle*> GetAllFSTau        (void) { return GetAllFSParticle(15);   };
   inline std::vector<FitParticle*> GetAllFSProton     (void) { return GetAllFSParticle(2212); };
   inline std::vector<FitParticle*> GetAllFSNeutron    (void) { return GetAllFSParticle(2112); };
   inline std::vector<FitParticle*> GetAllFSPiZero     (void) { return GetAllFSParticle(111);  };
   inline std::vector<FitParticle*> GetAllFSPiPlus     (void) { return GetAllFSParticle(211);  };
   inline std::vector<FitParticle*> GetAllFSPiMinus    (void) { return GetAllFSParticle(-211); };
   inline std::vector<FitParticle*> GetAllFSPhoton     (void) { return GetAllFSParticle(22);   };
   inline std::vector<FitParticle*> GetAllFSLeptons     (void) { return GetAllFSParticle(PhysConst::pdg_leptons);       };
   inline std::vector<FitParticle*> GetAllFSPions       (void) { return GetAllFSParticle(PhysConst::pdg_pions);         };
   inline std::vector<FitParticle*> 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* 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* 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 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
new file mode 100644
index 0000000..7de683a
--- /dev/null
+++ b/src/InputHandler/FitEventInputHandler.cxx
@@ -0,0 +1,100 @@
+#include "FitEventInputHandler.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<std::string> inputs = InputUtils::ParseInputFileList(rawinputs);
+    for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) {
+
+
+        // Open File for histogram access
+        TFile* inp_file = new TFile(inputs[inp_it].c_str(), "READ");
+        if (!inp_file or inp_file->IsZombie()) {
+            ERR(FTL) << "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() );
+    }
+
+    // Registor all our file inputs
+    SetupJointInputs();
+
+    // Assign to tree
+    fEventType = kINPUTFITEVENT;
+
+    // Create Fit Event
+    fNUISANCEEvent = new FitEvent();
+    fNUISANCEEvent->HardReset();
+    fNUISANCEEvent->SetBranchAddress(fFitEventTree);
+
+}
+
+FitEventInputHandler::~FitEventInputHandler(){
+    if (fFitEventTree) delete fFitEventTree;
+}
+
+void FitEventInputHandler::CreateCache() {
+    fFitEventTree->SetCacheEntryRange(0, fNEvents);
+    fFitEventTree->AddBranchToCache("*", 1);
+    fFitEventTree->SetCacheSize(fCacheSize);
+}
+
+void FitEventInputHandler::RemoveCache() {
+    fFitEventTree->SetCacheEntryRange(0, fNEvents);
+    fFitEventTree->AddBranchToCache("*", 0);
+    fFitEventTree->SetCacheSize(0);
+}
+
+FitEvent* FitEventInputHandler::GetNuisanceEvent(const UInt_t entry, const bool lightweight) {
+
+    // Return NULL if out of bounds
+    if (entry >= (UInt_t)fNEvents) return NULL;
+
+    // Reset all variables before tree read
+    fNUISANCEEvent->ResetEvent();
+
+    // Read NUISANCE Tree
+    fFitEventTree->GetEntry(entry);
+
+    // Setup Input scaling for joint inputs
+    fNUISANCEEvent->InputWeight = GetInputWeight(entry);
+
+    return fNUISANCEEvent;
+}
+
+
+double FitEventInputHandler::GetInputWeight(int entry) {
+    double w = InputHandlerBase::GetInputWeight(entry);
+    return w * fNUISANCEEvent->SavedRWWeight;
+}
+
+void FitEventInputHandler::Print() {
+}
+
+
diff --git a/src/InputHandler/FitEventInputHandler.h b/src/InputHandler/FitEventInputHandler.h
new file mode 100644
index 0000000..45eb979
--- /dev/null
+++ b/src/InputHandler/FitEventInputHandler.h
@@ -0,0 +1,37 @@
+#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.
+};
+/*! @} */
+#endif
diff --git a/src/FitBase/FitParticle.cxx b/src/InputHandler/FitParticle.cxx
similarity index 100%
rename from src/FitBase/FitParticle.cxx
rename to src/InputHandler/FitParticle.cxx
diff --git a/src/FitBase/FitParticle.h b/src/InputHandler/FitParticle.h
similarity index 95%
rename from src/FitBase/FitParticle.h
rename to src/InputHandler/FitParticle.h
index aecf7ad..ef3477c 100644
--- a/src/FitBase/FitParticle.h
+++ b/src/InputHandler/FitParticle.h
@@ -1,96 +1,98 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 #ifndef FITPARTICLE_H_SEEN
 #define FITPARTICLE_H_SEEN
-
-#include "TLorentzVector.h"
-
 /*!
- *  \addtogroup FitBase
+ *  \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(); }; 
 
   /// Get Kinetic Energy
   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;}; 
 
   /// Get 3 Momentum
   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
-};
 
+};
 /*! @} */
 #endif
diff --git a/src/FitBase/GENIEInputHandler.cxx b/src/InputHandler/GENIEInputHandler.cxx
similarity index 53%
rename from src/FitBase/GENIEInputHandler.cxx
rename to src/InputHandler/GENIEInputHandler.cxx
index 9fdbb65..8c84c26 100644
--- a/src/FitBase/GENIEInputHandler.cxx
+++ b/src/InputHandler/GENIEInputHandler.cxx
@@ -1,394 +1,373 @@
 #include "GENIEInputHandler.h"
-
-GENIEInputHandler::GENIEInputHandler(std::string const& handle, std::string const& rawinputs) {
 #ifdef __GENIE_ENABLED__
 
-  // Run a joint input handling
-  fName = handle;
-  jointinput = false;
-  jointindexswitch = 0;
+GENIEGeneratorInfo::~GENIEGeneratorInfo() {
+  DeallocateParticleStack();
+}
 
-  // Form list of all inputs, remove brackets if required.
-  std::vector<std::string> inputs = GeneralUtils::ParseToStr(rawinputs, ",");
-  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);
+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<GHepRecord*>(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<genie::GHepParticle*>((iter).Next())))) {
+    if (!p) continue;
+
+    // Get PDG
+    fGenieParticlePDGs[i] = p->Pdg();
+    i++;
   }
-  for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) {
-    LOG(SAM) << "\t -> Found input file: " << inputs[inp_it] << std::endl;
+}
+
+void GENIEGeneratorInfo::Reset() {
+  for (int i = 0; i < kMaxParticles; i++) {
+    fGenieParticlePDGs[i] = 0;
   }
+}
 
-  fMaxEvents = FitPar::Config().GetParI("MAXEVENTS");
+
+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");
 
   // Loop over all inputs and grab flux, eventhist, and nevents
-  // Also add it to the TChain
-  int evtcounter = 0;
-  if (inputs.size() > 1) jointinput = true;
+  std::vector<std::string> inputs = InputUtils::ParseInputFileList(rawinputs);
   for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) {
 
-    // Add To TChain
-    fGENIETree->AddFile( inputs[inp_it].c_str() );
-
     // 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) << "GENIE File IsZombie() at " << inputs[inp_it] << std::endl;
+      throw;
+    }
 
     // Get Flux/Event hist
-    TH1D* fluxhist  = (TH1D*)inp_file->Get(
-                        (PlotUtils::GetObjectWithName(inp_file, "nuisance_flux")).c_str());
-    TH1D* eventhist = (TH1D*)inp_file->Get(
-                        (PlotUtils::GetObjectWithName(inp_file, "nuisance_events")).c_str());
-
-    // Error Check
-    if (!fluxhist) {
+    TH1D* fluxhist  = (TH1D*)inp_file->Get("nuisance_flux");
+    TH1D* eventhist = (TH1D*)inp_file->Get("nuisance_events");
+    if (!fluxhist or !eventhist) {
       ERR(FTL) << "GENIE FILE doesn't contain flux/xsec info" << std::endl;
       ERR(FTL) << "Run app/PrepareGENIE first on :" << inputs[inp_it] << std::endl;
       throw;
     }
 
     // Get N Events
     TTree* genietree = (TTree*)inp_file->Get("gtree");
+    if (!genietree) {
+      ERR(FTL) << "gtree not located in GENIE file! " << inputs[inp_it] << std::endl;
+      throw;
+    }
     int nevents = genietree->GetEntries();
 
-    // Push into individual input vectors
-    jointfluxinputs.push_back( (TH1D*) fluxhist->Clone() );
-    jointeventinputs.push_back( (TH1D*) eventhist->Clone() );
-
-    jointindexlow.push_back(evtcounter);
-    jointindexhigh.push_back(evtcounter + nevents);
-    evtcounter += nevents;
-
-    // Add to the total flux/event hist
-    if (!fFluxHist) fFluxHist = (TH1D*) fluxhist->Clone();
-    else fFluxHist->Add(fluxhist);
-
-    if (!fEventHist) fEventHist = (TH1D*) eventhist->Clone();
-    else fEventHist->Add(eventhist);
+    // 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() );
   }
 
-  // Setup NEvents and the FitEvent
-  fNEvents = fGENIETree->GetEntries();
+  // Registor all our file inputs
+  SetupJointInputs();
+
+  // Assign to tree
   fEventType = kGENIE;
-  fGenieGHep = NULL;
   fGenieNtpl = NULL;
   fGENIETree->SetBranchAddress("gmcrec", &fGenieNtpl);
 
-  fNUISANCEEvent = new FitEvent(fGenieNtpl);
-  fNUISANCEEvent->HardReset();
-  fBaseEvent = static_cast<BaseFitEvt*>(fNUISANCEEvent);
-
-  // Normalise event histograms for relative flux contributions.
-  for (size_t i = 0; i < jointeventinputs.size(); i++) {
-    TH1D* eventhist = (TH1D*) jointeventinputs.at(i)->Clone();
+  // Create Fit Event
+  fNUISANCEEvent = new FitEvent();
+  fNUISANCEEvent->SetGenieEvent(fGenieNtpl);
 
-    double scale = double(fNEvents) / fEventHist->Integral("width");
-    scale *= eventhist->Integral("width");
-    scale /= double(jointindexhigh[i] - jointindexlow[i]);
-
-    jointindexscale .push_back(scale);
+  if (fSaveExtra) {
+    fGenieInfo     = new GENIEGeneratorInfo();
+    fNUISANCEEvent->AddGeneratorInfo(fGenieInfo);
   }
 
-  fEventHist->SetNameTitle((fName + "_EVT").c_str(), (fName + "_EVT").c_str());
-  fFluxHist->SetNameTitle((fName + "_FLUX").c_str(), (fName + "_FLUX").c_str());
+  fNUISANCEEvent->HardReset();
 
-  // Setup Max Events
-  if (fMaxEvents > 1 && fMaxEvents < fNEvents) {
-    if (LOG_LEVEL(SAM)) {
-      std::cout << "\t\t|-> Read Max Entries : " << fMaxEvents << std::endl;
-    }
-    fNEvents = fMaxEvents;
-  }
-#endif
 };
 
+GENIEInputHandler::~GENIEInputHandler() {
+  if (fGenieGHep) delete fGenieGHep;
+  if (fGenieNtpl) delete fGenieNtpl;
+  if (fGENIETree) delete fGENIETree;
+  if (fGenieInfo) delete fGenieInfo;
+}
 
-FitEvent* GENIEInputHandler::GetNuisanceEvent(const UInt_t entry) {
-#ifdef __GENIE_ENABLED__
+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) {
   if (entry >= (UInt_t)fNEvents) return NULL;
 
   // Read Entry from TTree to fill NEUT Vect in BaseFitEvt;
   fGENIETree->GetEntry(entry);
 
   // Setup Input scaling for joint inputs
-  if (jointinput) {
-    fNUISANCEEvent->InputWeight = GetInputWeight(entry);
-  } else {
-    fNUISANCEEvent->InputWeight = 1.0;
-  }
+  fNUISANCEEvent->InputWeight = GetInputWeight(entry);
 
   // Run NUISANCE Vector Filler
-  CalcNUISANCEKinematics();
+  if (!lightweight) {
+    CalcNUISANCEKinematics();
+  }
 
   return fNUISANCEEvent;
-#endif
-  return NULL;
 }
 
 
-#ifdef __GENIE_ENABLED__
 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)
       state = kInitialState;
     else
       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;
   }
 
   // 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()->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;
       else {
-	ERR(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() << std::endl;
-	return 0;
+        ERR(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() << std::endl;
+        return 0;
       }
     }
 
     // Weak CC
-  } else if (gheprec->Summary()->ProcInfo().IsWeakCC()){
+  } 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;
+      else if (pdg::IsAntiNeutrino(gheprec->Summary()->InitState().ProbePdg())) return -2;
 
-    // CC OTHER
+      // CC OTHER
     } else {
       return utils::ghep::NeutReactionCode(gheprec);
     }
-   
+
     // Weak NC
-  } else if (gheprec->Summary()->ProcInfo().IsWeakNC()){
-    // NC MEC                                                                                                                                                                                                                              
+  } 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;
 
-      // NC OTHER                                                                                                                                                                                                                          
+      // NC OTHER
     } else {
       return utils::ghep::NeutReactionCode(gheprec);
     }
   }
 
   return 0;
 }
-#endif
 
 void GENIEInputHandler::CalcNUISANCEKinematics() {
-#ifdef __GENIE_ENABLED__
 
   // Reset all variables
   fNUISANCEEvent->ResetEvent();
 
   // Check for GENIE Event
   if (!fGenieNtpl) return;
   if (!fGenieNtpl->event) return;
 
   // Cast Event Record
   fGenieGHep = static_cast<GHepRecord*>(fGenieNtpl->event);
   if (!fGenieGHep) return;
 
   // Convert GENIE Reaction Code
   fNUISANCEEvent->fMode = 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->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(FTL) << "GENIE has too many particles" << std::endl;
-    ERR(FTL) << "npart=" << npart << " kMax=" << kmax << std::endl;
-    throw;
-  }
-
-  // Initialise Extra NEUT Information in NUISANCE Event
-  bool save_extra = false;//FitPar::Config().GetParB("save_extra_genie_info");
-  if (save_extra) {
-    // Add one of these for each exta piece of information you
-    // add to FitEvent for specific generators.
-    // Example below is the NEUT One
-    // if (!fNUISANCEEvent->fNEUT_ParticleStatusCode)
-    // fNUISANCEEvent->fNEUT_ParticleStatusCode = new double[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<genie::GHepParticle*>((iter).Next())))) {
     if (!p) continue;
 
     // Get Status
-    int state = GetGENIEParticleStatus(p);
+    int state = GetGENIEParticleStatus(p, fNUISANCEEvent->fMode);
 
     // 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;
 
     // 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();
 
-    // Fill extra information, NEUT Example Given
-    // if (save_extra){
-    // }
-
     // 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;
       break;
     }
   }
 
+  // Fill Extra Stack
+  if (fSaveExtra) fGenieInfo->FillGeneratorInfo(fGenieNtpl);
+
   // Run Initial, FSI, Final, Other ordering.
   fNUISANCEEvent-> OrderStack();
 
   return;
-#endif
 }
 
-double GENIEInputHandler::GetInputWeight(int entry) {
-#ifdef __GENIE_ENABLED__
-
-  // Find Switch Scale
-  while ( entry < jointindexlow[jointindexswitch] ||
-          entry >= jointindexhigh[jointindexswitch] ) {
-    jointindexswitch++;
-
-    // Loop Around
-    if (jointindexswitch == jointindexlow.size()) {
-      jointindexswitch = 0;
-    }
-  }
-
-  return jointindexscale[jointindexswitch];
-#endif
-  return 0.0;
-};
-
-
-BaseFitEvt* GENIEInputHandler::GetBaseEvent(const UInt_t entry) {
-#ifdef __GENIE_ENABLED__
-
-  if (entry >= (UInt_t)fNEvents) return NULL;
-
-  // Read entry from TTree to fill GENIE Vect in BaseFitEvt;
-  fGENIETree->GetEntry(entry);
-
-  // Set joint scaling if required
-  if (jointinput) {
-    fBaseEvent->InputWeight = GetInputWeight(entry);
-  } else {
-    fBaseEvent->InputWeight = 1.0;
-  }
-
-  return fBaseEvent;
-#endif
-  return NULL;
+void GENIEInputHandler::Print() {
 }
 
-void GENIEInputHandler::Print() {}
+#endif
 
 
diff --git a/src/InputHandler/GENIEInputHandler.h b/src/InputHandler/GENIEInputHandler.h
new file mode 100644
index 0000000..1cc6b69
--- /dev/null
+++ b/src/InputHandler/GENIEInputHandler.h
@@ -0,0 +1,108 @@
+// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
+
+/*******************************************************************************
+*    This file is part of NUISANCE.
+*
+*    NUISANCE is free software: you can redistribute it and/or modify
+*    it under the terms of the GNU General Public License as published by
+*    the Free Software Foundation, either version 3 of the License, or
+*    (at your option) any later version.
+*
+*    NUISANCE is distributed in the hope that it will be useful,
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*    GNU General Public License for more details.
+*
+*    You should have received a copy of the GNU General Public License
+*    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
+*******************************************************************************/
+#ifndef GENIEINPUTHANDLER_H
+#define GENIEINPUTHANDLER_H
+/*!
+ *  \addtogroup InputHandler
+ *  @{
+ */
+#ifdef __GENIE_ENABLED__
+#include "InputHandler.h"
+#include "InputUtils.h"
+#include "PlotUtils.h"
+
+#include "GHEP/GHepParticle.h"
+#include "PDG/PDGUtils.h"
+#include "GHEP/GHepUtils.h"
+#include "Conventions/Units.h"
+#include "EVGCore/EventRecord.h"
+#include "GHEP/GHepRecord.h"
+#include "Ntuple/NtpMCEventRecord.h"
+using namespace genie;
+
+/// GENIE Generator Container to save extra particle status codes.
+class GENIEGeneratorInfo : public GeneratorInfoBase {
+public:
+	GENIEGeneratorInfo() {};
+	virtual ~GENIEGeneratorInfo();
+
+	/// 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 genie information from the event
+	void FillGeneratorInfo(NtpMCEventRecord* ntpl);
+
+	/// Reset extra information to default/empty values
+	void Reset();
+
+	int  kMaxParticles; ///< Number of particles in stack
+	int* fGenieParticlePDGs; ///< GENIE Particle PDGs (example)
+};
+
+/// Main GENIE InputHandler
+class GENIEInputHandler : public InputHandlerBase {
+public:
+
+	/// Standard constructor given a name and input files
+	GENIEInputHandler(std::string const& handle, std::string const& rawinputs);
+	virtual ~GENIEInputHandler();
+
+	/// Create a TTree Cache to speed up file read
+	void CreateCache();
+
+	/// Remove TTree Cache to save memory
+	void RemoveCache();
+	
+	/// Returns a NUISANCE format event from the GENIE TTree. If !lightweight
+	/// then CalcNUISANCEKinematics() is called to convert the GENIE event into
+	/// a standard NUISANCE format.
+	FitEvent* GetNuisanceEvent(const UInt_t entry, const bool lightweight = false);
+
+	/// Converts GENIE event into standard NUISANCE FitEvent by looping over all
+	/// particles in the event and adding them to stack in fNUISANCEEvent.
+	void CalcNUISANCEKinematics();
+
+	/// Placeholder for GENIE related event printing.
+	void Print();
+
+	/// Converts GENIE particle status codes into NUISANCE status codes.
+	int GetGENIEParticleStatus(genie::GHepParticle* part, int mode = 0);
+
+	/// Converts GENIE event reaction codes into NUISANCE reaction codes.
+	int ConvertGENIEReactionCode(GHepRecord* gheprec);
+
+	GHepRecord* fGenieGHep;         ///< Pointer to actual event record
+	NtpMCEventRecord* fGenieNtpl;   ///< Ntpl Wrapper Class
+
+	TChain* fGENIETree;             ///< Main GENIE Event TTree
+	bool fSaveExtra;    ///< Flag to save Extra GENIE info into Nuisance Event
+	GENIEGeneratorInfo* fGenieInfo; ///< Extra GENIE Generator Info Writer
+};
+/*! @} */
+#endif
+#endif
\ No newline at end of file
diff --git a/src/FitBase/GIBUUInputHandler.cxx b/src/InputHandler/GIBUUInputHandler.cxx
similarity index 82%
rename from src/FitBase/GIBUUInputHandler.cxx
rename to src/InputHandler/GIBUUInputHandler.cxx
index 9963a7b..a6fd45f 100644
--- a/src/FitBase/GIBUUInputHandler.cxx
+++ b/src/InputHandler/GIBUUInputHandler.cxx
@@ -1,458 +1,482 @@
 #ifdef __GiBUU_ENABLED__
 #include "GIBUUInputHandler.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<TH1D*>(rootFile->Get("numu_flux"));
 	TH1D* numubFlux = dynamic_cast<TH1D*>(rootFile->Get("numub_flux"));
 	TH1D* nueFlux = dynamic_cast<TH1D*>(rootFile->Get("nue_flux"));
 	TH1D* nuebFlux = dynamic_cast<TH1D*>(rootFile->Get("nueb_flux"));
+	std::vector<TH1D*> fFluxList;
 
 	// Replace local pointers with NULL dir'd clones.
 	if (numuFlux) {
 		numuFlux = static_cast<TH1D*>(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<TH1D*>(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<TH1D*>(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<TH1D*>(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);
 	}
 	rootFile->Close();
 
 	fGIBUUTree = new TChain("giRooTracker");
 	fGIBUUTree->AddFile(rawinputs.c_str());
 
 	fGiReader = new GiBUUStdHepReader();
 	fGiReader->SetBranchAddresses(fGIBUUTree);
 
 	bool IsNuBarDominant = false;
 	size_t Found_nu = 0;
 	size_t Found_nuMask = ((numuFlux ? 1 : 0) + (numubFlux ? 2 : 0) +
 	                       (nueFlux ? 4 : 0) + (nuebFlux ? 8 : 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 += ", ";
 			}
 		}
 	}
 
 	LOG(SAM) << "Looking for dominant vector species in GiBUU file ("
 	         << rawinputs << ") expecting to find: " << expectStr << std::endl;
 
 	size_t maskHW = GeneralUtils::GetHammingWeight(Found_nuMask);
 	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;
 	}
 
 	double SpeciesWeights[] = {0, 0, 0, 0};
 	Long64_t nevt = 0;
 	fNEvents = fGIBUUTree->GetEntries();
-	fFluxHist = NULL;
 	fNUISANCEEvent = new FitEvent();
+	TH1D* flux = NULL;
 
 	while ((Found_nu != Found_nuMask) && (nevt < fNEvents)) {
-		if ((maskHW == 2) && fFluxHist) {  // If we have found the dominant one can
+		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;
 			}
-			fFluxHist = nueFlux;
+			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;
-			fFluxHist = nuebFlux;
+			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;
 			}
-			fFluxHist = numuFlux;
+			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;
-			fFluxHist = numubFlux;
+			flux = numubFlux;
 			LOG(SAM) << "\tInput file: " << rawinputs
 			         << " determined to be numubar dominated vector." << std::endl;
 			break;
 		}
 		default: {}
 		}
 	}
 
 	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;
 		throw;
 	}
 
-	if (!fFluxHist) {
+	if (!flux) {
 		ERR(FTL) << "Couldn't find: "
 		         << (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<TH1D*>(numuFlux->Clone((fName + "_numu_EVT").c_str()));
 		numuEvt->Reset();
 		numuEvt->SetBinContent(1, SpeciesWeights[0] * double(fNEvents) /
 		                       numuEvt->GetXaxis()->GetBinWidth(1));
 
 		TH1D* numuXSec =
 		    static_cast<TH1D*>(numuEvt->Clone((fName + "_numu_XSEC").c_str()));
-		numuXSec->Divide(fFluxHist);
+		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<TH1D*>(numubFlux->Clone((fName + "_numub_EVT").c_str()));
 		numubEvt->Reset();
 		numubEvt->SetBinContent(1, SpeciesWeights[1] * double(fNEvents) /
 		                        numubEvt->GetXaxis()->GetBinWidth(1));
 
 		TH1D* numubXSec =
 		    static_cast<TH1D*>(numubEvt->Clone((fName + "_numub_XSEC").c_str()));
-		numubXSec->Divide(fFluxHist);
+		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<TH1D*>(nueFlux->Clone((fName + "_nue_EVT").c_str()));
 		nueEvt->Reset();
 		nueEvt->SetBinContent(1, SpeciesWeights[2] * double(fNEvents) /
 		                      nueEvt->GetXaxis()->GetBinWidth(1));
 
 		TH1D* nueXSec =
 		    static_cast<TH1D*>(nueEvt->Clone((fName + "_nue_XSEC").c_str()));
-		nueXSec->Divide(fFluxHist);
+		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]);
 		}
 		TH1D* nuebEvt =
 		    static_cast<TH1D*>(nuebFlux->Clone((fName + "_nueb_EVT").c_str()));
 		nuebEvt->Reset();
 		nuebEvt->SetBinContent(1, SpeciesWeights[3] * double(fNEvents) /
 		                       nuebEvt->GetXaxis()->GetBinWidth(1));
 
 		TH1D* nuebXSec =
 		    static_cast<TH1D*>(nuebEvt->Clone((fName + "_nueb_XSEC").c_str()));
-		nuebXSec->Divide(fFluxHist);
+		nuebXSec->Divide(flux);
 
 		nuebXSec->SetTitle((fName + "; E_{#nu} (GeV);XSec").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;
 
-	fFluxHist->SetNameTitle(
+	flux->SetNameTitle(
 	    (fName + "_FLUX").c_str(),
 	    (fName + "; E_{#nu} (GeV);" +
 	     (IsNuBarDominant ? "#Phi_{#bar{#nu}} (A.U.)" : "#Phi_{#nu} (A.U.)"))
 	    .c_str());
 
-	fEventHist = static_cast<TH1D*>(fFluxHist->Clone((fName + "_EVT").c_str()));
-	fEventHist->Reset();
-	fEventHist->SetBinContent(1, double(fNEvents) *
-	                          TotalIntegratedFlux(0, 1.E5, "width") /
-	                          fEventHist->GetXaxis()->GetBinWidth(1));
+	TH1D* eventhist = static_cast<TH1D*>(flux->Clone((fName + "_EVT").c_str()));
+	eventhist->Reset();
+	eventhist->SetBinContent(1, double(fNEvents) *
+	                         TotalIntegratedFlux(0, 1.E5, "width") /
+	                         fEventHist->GetXaxis()->GetBinWidth(1));
+
+	TH1D* xsechist = static_cast<TH1D*>(eventhist->Clone((fName + "_XSEC").c_str()));
+	xsechist->Divide(flux);
 
-	fXSecHist = static_cast<TH1D*>(fEventHist->Clone((fName + "_XSEC").c_str()));
-	fXSecHist->Divide(fFluxHist);
+	xsechist->SetTitle((fName + "; E_{#nu} (GeV);XSec").c_str());
 
-	fXSecHist->SetTitle((fName + "; E_{#nu} (GeV);XSec").c_str());
+	RegisterJointInput(rawinputs, fNEvents, flux, eventhist);
+	SetupJointInputs();
 
 
 };
 
 
-FitEvent* GIBUUInputHandler::GetNuisanceEvent(const UInt_t entry) {
+FitEvent* GIBUUInputHandler::GetNuisanceEvent(const UInt_t entry, const bool lightweight) {
 
-	// Make sure events setup
-	// if (!fNUISANCEEvent) fNUISANCEEvent = new FitEvent(fGiReader);
+	// Check out of bounds
+	if (entry >= (UInt_t)fNEvents) return NULL;
 
 	// Read Entry from TTree to fill NEUT Vect in BaseFitEvt;
 	fGIBUUTree->GetEntry(entry);
 
-	// GiBUU reads input weight from tree
-	// fNUISANCEEvent->InputWeight = GetInputWeight(entry);
-
 	// Run NUISANCE Vector Filler
-	CalcNUISANCEKinematics();
+	if (!lightweight) {
+		CalcNUISANCEKinematics();
+	}
 
 	return fNUISANCEEvent;
 }
 
 int GIBUUInputHandler::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;
-	// Split Kinematics
-	// LOG(DEB) << "Reading GiBUU Event: " << std::endl;
-	// LOG(DEB) << WriteGiBUUEvent(*GiRead) << std::endl;
-
 	evt->fMode = fGiReader->GiBUU2NeutCode;
 	evt->Mode = evt->fMode;
 	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" << std::endl;
-		ERR(FTL) << "npart=" << npart << " kMax=" << kmax << std::endl;
-		throw;
+		ERR(FTL) << "GiBUU has too many particles. Expanding Stack." << std::endl;
+		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();
 	return;
 }
 
-
-double GIBUUInputHandler::GetInputWeight(int entry) {
-	return fNUISANCEEvent->InputWeight;
-};
-
-
-BaseFitEvt* GIBUUInputHandler::GetBaseEvent(const UInt_t entry) {
-
-	// Make sure events setup
-	// if (!fBaseEvent) fBaseEvent = new BaseFitEvt(fGiReader);
-
-	// Read entry from TTree to fill NEUT Vect in BaseFitEvt;
-	fGIBUUTree->GetEntry(entry);
-
-	// GiBUU don't need no input weight...
-	// fBaseEvent->InputWeight = GetInputWeight(entry);
-
-	return fBaseEvent;
-}
-
 void GIBUUInputHandler::Print() {}
 #endif
 
diff --git a/src/InputHandler/GIBUUInputHandler.h b/src/InputHandler/GIBUUInputHandler.h
new file mode 100644
index 0000000..7d5fcbe
--- /dev/null
+++ b/src/InputHandler/GIBUUInputHandler.h
@@ -0,0 +1,68 @@
+#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; ///<GIBUU Particle Status Flags
+	// int* fNEUTParticleAliveCode; ///< GIBUU Alive Code (0 dead, 1 final state)
+	// int fNEUTParticleN; ///< Number of particles
+};
+
+
+/// GiBUU Handler to read in Luke's formatted GiBUU events
+class GIBUUInputHandler : public InputHandlerBase {
+public:
+
+	/// Standard constructor given name and inputs
+	GIBUUInputHandler(std::string const& handle, std::string const& rawinputs);
+	~GIBUUInputHandler() {};
+
+	/// Returns NUISANCE Format Event from GiReader
+	FitEvent* GetNuisanceEvent(const UInt_t entry, const bool lightweight = false);
+
+	/// Convert GiBUU Code to NUISANCE Event Code
+	int GetGIBUUParticleStatus(int status, int pdg);
+
+	/// Fill NUISANCE Particle Stack
+	void CalcNUISANCEKinematics();
+
+	/// Print event information
+	void Print();
+
+private:
+	GiBUUStdHepReader* fGiReader; ///< GiBUU Event Reader
+	TChain* fGIBUUTree;           ///< GiBUU Event Tree
+};
+#endif
+#endif
diff --git a/src/FitBase/GeneratorInfoBase.h b/src/InputHandler/GeneratorInfoBase.h
similarity index 77%
copy from src/FitBase/GeneratorInfoBase.h
copy to src/InputHandler/GeneratorInfoBase.h
index f49b77d..4623916 100644
--- a/src/FitBase/GeneratorInfoBase.h
+++ b/src/InputHandler/GeneratorInfoBase.h
@@ -1,27 +1,39 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
+#ifndef GENERATOR_INFO_BASE_SEEN_H
+#define GENERATOR_INFO_BASE_SEEN_H
+/*!
+ *  \addtogroup InputHandler
+ *  @{
+ */
+
 /// Base Box object that allows user to save extra generator level info
-/// by overriding.
+/// by overriding functions. For an example see GENIEGeneratorInfo
 class GeneratorInfoBase {
 public:
   inline GeneratorInfoBase(){};
   inline virtual ~GeneratorInfoBase(){};
   inline virtual void AddBranchesToTree(TTree* tn){};
   inline virtual void SetBranchesFromTree(TTree* tn){};
-};
\ No newline at end of file
+  inline virtual void AllocateParticleStack(int stacksize){};
+  inline virtual void DeallocateParticleStack(){};
+  inline virtual void Reset(){};
+};
+/*! @} */
+#endif
diff --git a/src/InputHandler/GeneratorUtils.cxx b/src/InputHandler/GeneratorUtils.cxx
new file mode 100644
index 0000000..0a17f3e
--- /dev/null
+++ b/src/InputHandler/GeneratorUtils.cxx
@@ -0,0 +1,58 @@
+// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
+
+/*******************************************************************************
+*    This file is part of NUISANCE.
+*
+*    NUISANCE is free software: you can redistribute it and/or modify
+*    it under the terms of the GNU General Public License as published by
+*    the Free Software Foundation, either version 3 of the License, or
+*    (at your option) any later version.
+*
+*    NUISANCE is distributed in the hope that it will be useful,
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*    GNU General Public License for more details.
+*
+*    You should have received a copy of the GNU General Public License
+*    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
+*******************************************************************************/
+
+#include <iostream>
+
+#include "GeneratorUtils.h"
+#include "FitLogger.h"
+
+#ifdef __NIWG_ENABLED__
+niwg::rew::NIWGEvent * GeneratorUtils::GetNIWGEvent(NeutVect* nvect)
+{
+  niwg::rew::NIWGEvent * fDummyNIWGEvent = NULL;
+
+  fDummyNIWGEvent = new niwg::rew::NIWGEvent();
+  fDummyNIWGEvent->detid = 1;   // MiniBooNE (apply CCQE LowE variations)
+  fDummyNIWGEvent->neutmode = nvect->Mode;
+  fDummyNIWGEvent->targetA = nvect->TargetA;
+  fDummyNIWGEvent->recenu_ccqe_sk = -1;
+  if (nvect->Ibound==0) fDummyNIWGEvent->targetA = 1;//RT: identifies as H, rather than O16
+
+  // Fill initial particle stack
+  for (int ip=0; ip<nvect->Npart(); ++ip) {
+
+    niwg::rew::NIWGPartStack fDummyPartStack;
+
+    fDummyPartStack.p = (nvect->PartInfo(ip)->fP)*0.001;  // Convert to GeV
+
+    fDummyPartStack.pdg = nvect->PartInfo(ip)->fPID;
+    fDummyPartStack.chase = nvect->PartInfo(ip)->fIsAlive;
+    fDummyPartStack.parent = nvect->ParentIdx(ip)-1;       // WARNING: this needs to be tested with a NeutRoot file
+
+    fDummyNIWGEvent->part_stack.push_back(fDummyPartStack);
+  }
+  fDummyNIWGEvent->CalcKinematics();
+
+  return fDummyNIWGEvent;
+}
+#endif // neut enabled
+
+// #endif
+
+
diff --git a/src/FitBase/NuanceEvent.h b/src/InputHandler/GeneratorUtils.h
similarity index 59%
copy from src/FitBase/NuanceEvent.h
copy to src/InputHandler/GeneratorUtils.h
index d693e01..ea5fa12 100644
--- a/src/FitBase/NuanceEvent.h
+++ b/src/InputHandler/GeneratorUtils.h
@@ -1,70 +1,38 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
-
-#ifndef NUANCE_H_SEEN
-#define NUANCE_H_SEEN
-
-#ifdef __NUANCE_ENABLED__
+#ifndef GENERATOR_UTILS_H
+#define GENERATOR_UTILS_H
 /*!
- *  \addtogroup FitBase
+ *  \addtogroup InputHandler
  *  @{
  */
-#include "TTree.h"
-
-class NuanceEvent {
- public:
-
-  NuanceEvent(){};
-  void SetBranchAddresses(TTree* tn);
 
+#ifdef __NIWG_ENABLED__
+#include "NIWGEvent.h"
+#include "NIWGSyst.h"
+#endif
 
-  bool cc;
-  bool bound;
-  int neutrino;
-  int target;
-  float iniQ;
-  float finQ;
-  int lepton0;
-  float polar;
-  int channel;
-  float qsq;
-  float w;
-  float x;
-  float y;
-
-  float p_neutrino[4];
-  float p_targ[5];
-  float vertex[4];
-  float start[4];
-  float depth;
-  float flux;
+namespace GeneratorUtils {
+#ifdef __NIWG_ENABLED__
+  niwg::rew::NIWGEvent* GetNIWGEvent(NeutVect* nvect);
+#endif
 
-  int n_leptons;
-  
-  float p_ltot[5];
-  int lepton[200];
-  float p_lepton[5][200];
-  
-  int n_hadrons;
-  float p_htot[5];
-  int hadron[200];
-  float p_hadron[5][200];
 };
-#endif
+/*! @} */
 #endif
diff --git a/src/FitBase/HepMCTextInputHandler.cxx b/src/InputHandler/HepMCTextInputHandler.cxx
similarity index 100%
rename from src/FitBase/HepMCTextInputHandler.cxx
rename to src/InputHandler/HepMCTextInputHandler.cxx
diff --git a/src/FitBase/HepMCTextInputHandler.h b/src/InputHandler/HepMCTextInputHandler.h
similarity index 97%
rename from src/FitBase/HepMCTextInputHandler.h
rename to src/InputHandler/HepMCTextInputHandler.h
index 995a297..7e8dfde 100644
--- a/src/FitBase/HepMCTextInputHandler.h
+++ b/src/InputHandler/HepMCTextInputHandler.h
@@ -1,40 +1,40 @@
 #ifndef HEPMCINPUTHANDLER_H
 #define HEPMCINPUTHANDLER_H
 
 #ifdef __HEPMC_ENABLED__
 #include "SimpleVector.h"
 #include "Flow.h"
 #include "GenParticle.h"
 #include "GenEvent.h"
-#include "InputHandler2.h"
+#include "InputHandler.h"
 #include "TargetUtils.h"
 #include "PlotUtils.h"
 
 /// NEUT Input Convertor to read in NeutVects and convert to FitEvents
 class HepMCTextInputHandler : public InputHandlerBase {
 public:
 
 	/// Main constructor. Can read in single or joint inputs.
 	HepMCTextInputHandler(std::string const& handle, std::string const& rawinputs);
 	~HepMCTextInputHandler();
 
 	/// Returns NUISANCE Format event from entry in fNEUTTree
 	FitEvent* GetNuisanceEvent(const UInt_t entry);
 
 	/// Returns BaseEvent (just NeutVect pointer) from entry in fNEUTTree
 	BaseFitEvt* GetBaseEvent(const UInt_t entry);
 
 	/// eads fNeutVect and fills into fNUISANCEEvent.
 	void CalcNUISANCEKinematics();
 
 	/// Convert status codes to our format
 	int ConvertHepMCStatus();
 
 	/// Calculates weight if using joint inputs
 	double GetInputWeight(const UInt_t entry);
 
 	HepMC::GenEvent fHepMCEvent;
 	std::ifstream fASCIIStream;
 };
 #endif
 #endif
diff --git a/src/InputHandler/InputFactory.cxx b/src/InputHandler/InputFactory.cxx
new file mode 100644
index 0000000..dff1469
--- /dev/null
+++ b/src/InputHandler/InputFactory.cxx
@@ -0,0 +1,82 @@
+// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
+
+/*******************************************************************************
+*    This file is part of NUISANCE.
+*
+*    NUISANCE is free software: you can redistribute it and/or modify
+*    it under the terms of the GNU General Public License as published by
+*    the Free Software Foundation, either version 3 of the License, or
+*    (at your option) any later version.
+*
+*    NUISANCE is distributed in the hope that it will be useful,
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*    GNU General Public License for more details.
+*
+*    You should have received a copy of the GNU General Public License
+*    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
+*******************************************************************************/
+
+#include "InputFactory.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):
+#ifdef __NEUT_ENABLED__
+    input = new NEUTInputHandler(handle, newinputs);
+#endif
+    break;
+
+  case (kGENIE_Input):
+#ifdef __GENIE_ENABLED__
+    input = new GENIEInputHandler(handle, newinputs);
+#endif
+    break;
+
+
+  case (kNUWRO_Input):
+#ifdef __NUWRO_ENABLED__
+    input = new NuWroInputHandler(handle, newinputs);
+#endif
+    break;
+
+
+  case (kGiBUU_Input):
+#ifdef __GiBUU_ENABLED__
+    input = new GIBUUInputHandler(handle, newinputs);
+#endif
+    break;
+
+  case (kFEVENT_Input):
+    input = new FitEventInputHandler(handle, newinputs);
+    break;
+
+  case (kEVSPLN_Input):
+    input = new SplineInputHandler(handle, newinputs);
+    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/FitBase/GeneratorInfoBase.h b/src/InputHandler/InputFactory.h
similarity index 60%
rename from src/FitBase/GeneratorInfoBase.h
rename to src/InputHandler/InputFactory.h
index f49b77d..ed5ab42 100644
--- a/src/FitBase/GeneratorInfoBase.h
+++ b/src/InputHandler/InputFactory.h
@@ -1,27 +1,45 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
-/// Base Box object that allows user to save extra generator level info
-/// by overriding.
-class GeneratorInfoBase {
-public:
-  inline GeneratorInfoBase(){};
-  inline virtual ~GeneratorInfoBase(){};
-  inline virtual void AddBranchesToTree(TTree* tn){};
-  inline virtual void SetBranchesFromTree(TTree* tn){};
-};
\ No newline at end of file
+
+#ifndef INPUT_FACTORY_H
+#define INPUT_FACTORY_H
+
+#include <string>
+#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"
+
+namespace InputUtils {
+
+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
new file mode 100644
index 0000000..dc8fc29
--- /dev/null
+++ b/src/InputHandler/InputHandler.cxx
@@ -0,0 +1,293 @@
+// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
+
+/*******************************************************************************
+*    This file is part of NUISANCE.
+*
+*    NUISANCE is free software: you can redistribute it and/or modify
+*    it under the terms of the GNU General Public License as published by
+*    the Free Software Foundation, either version 3 of the License, or
+*    (at your option) any later version.
+*
+*    NUISANCE is distributed in the hope that it will be useful,
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*    GNU General Public License for more details.
+*
+*    You should have received a copy of the GNU General Public License
+*    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
+*******************************************************************************/
+#include "InputHandler.h"
+
+std::vector<std::string> InputUtils::ParseInputFileList(std::string const& inpFile) {
+
+  std::vector<std::string> 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;
+
+}
+
+InputHandlerBase::InputHandlerBase() {
+  fName = "";
+  fFluxHist = NULL;
+  fEventHist = NULL;
+  fNEvents = 0;
+  fNUISANCEEvent = NULL;
+  fBaseEvent = NULL;
+  kRemoveUndefParticles = FitPar::Config().GetParB("RemoveUndefParticles");
+  kRemoveFSIParticles = FitPar::Config().GetParB("RemoveFSIParticles");
+  kRemoveNuclearParticles = FitPar::Config().GetParB("RemoveNuclearParticles");
+  fMaxEvents = FitPar::Config().GetParI("MAXEVENTS");
+  fTTreePerformance= NULL;
+
+};
+
+InputHandlerBase::~InputHandlerBase() {
+
+    if (fFluxHist) delete fFluxHist;
+    if (fEventHist) delete fEventHist;
+    if (fXSecHist) delete fXSecHist;
+    if (fNUISANCEEvent) delete fNUISANCEEvent;
+    jointfluxinputs.clear();
+    jointeventinputs.clear();
+    jointindexlow.clear();
+    jointindexhigh.clear();
+    jointindexallowed.clear();
+    jointindexscale.clear();
+    
+    if (fTTreePerformance){
+      fTTreePerformance->SaveAs(("ttreeperfstats_" + fName + ".root").c_str());
+    }
+  }
+
+void InputHandlerBase::Print() {
+};
+
+TH1D* InputHandlerBase::GetXSecHistogram(void) {
+  fXSecHist = (TH1D*)fFluxHist->Clone();
+  fXSecHist->Divide(fEventHist);
+  return fXSecHist;
+};
+
+double InputHandlerBase::PredictedEventRate(double low, double high,
+    std::string intOpt) {
+
+  int minBin = fFluxHist->GetXaxis()->FindBin(low);
+  int maxBin = fFluxHist->GetXaxis()->FindBin(high);
+
+  return fEventHist->Integral(minBin, maxBin + 1, intOpt.c_str());
+};
+
+double InputHandlerBase::TotalIntegratedFlux(double low, double high,
+    std::string intOpt) {
+
+  std::cout << "Getting Total Integrated Flux Between : " << low << " - " << high << std::endl;
+
+  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;
+  }
+
+  std::cout << "Getting Between Bins " << minBin << " " << maxBin << std::endl;
+  // If we are within a single bin
+  if (minBin == maxBin) {
+    std::cout << "Getting minBin == maxBin " << std::endl;
+    // Get the contained fraction of the single bin's width
+    return ((high - low) / fFluxHist->GetXaxis()->GetBinWidth(minBin)) *
+           fFluxHist->Integral(minBin, minBin, intOpt.c_str());
+  }
+
+  double lowBinUpEdge = fFluxHist->GetXaxis()->GetBinUpEdge(minBin);
+  double highBinLowEdge = fFluxHist->GetXaxis()->GetBinLowEdge(maxBin);
+
+  double lowBinfracIntegral =
+    ((lowBinUpEdge - low) / fFluxHist->GetXaxis()->GetBinWidth(minBin)) *
+    fFluxHist->Integral(minBin, minBin, intOpt.c_str());
+  double highBinfracIntegral =
+    ((high - highBinLowEdge) / fFluxHist->GetXaxis()->GetBinWidth(maxBin)) *
+    fFluxHist->Integral(maxBin, maxBin, intOpt.c_str());
+
+  // If they are neighbouring bins
+  if ((minBin + 1) == maxBin) {
+    std::cout << "Get lowfrac + highfrac" << std::endl;
+    // Get the contained fraction of the two bin's width
+    return lowBinfracIntegral + highBinfracIntegral;
+  }
+
+  std::cout << "Returning highBinFracIntegral and LowBinFracIntegral " << std::endl;
+  // If there are filled bins between them
+  return lowBinfracIntegral + highBinfracIntegral +
+         fFluxHist->Integral(minBin + 1, maxBin - 1, intOpt.c_str());
+  // return fFluxHist->Integral(minBin + 1, maxBin - 1, intOpt.c_str());
+}
+
+
+std::vector<TH1*> InputHandlerBase::GetFluxList(void) {
+  return std::vector<TH1*>(1, fFluxHist);
+};
+
+std::vector<TH1*> InputHandlerBase::GetEventList(void) {
+  return std::vector<TH1*>(1, fEventHist);
+};
+
+std::vector<TH1*> InputHandlerBase::GetXSecList(void) {
+  return std::vector<TH1*>(1, GetXSecHistogram());
+};
+
+FitEvent* InputHandlerBase::FirstNuisanceEvent() {
+  fCurrentIndex = 0;
+  return GetNuisanceEvent(fCurrentIndex);
+};
+
+
+
+FitEvent* InputHandlerBase::NextNuisanceEvent() {
+  fCurrentIndex++;
+
+  if (jointinput and fMaxEvents != -1) {
+    while ( fCurrentIndex < jointindexlow[jointindexswitch] ||
+            fCurrentIndex >= jointindexhigh[jointindexswitch] ) {
+      jointindexswitch++;
+
+      // Loop Around
+      if (jointindexswitch == jointindexlow.size()) {
+        jointindexswitch = 0;
+      }
+    }
+
+
+    if (fCurrentIndex > jointindexlow[jointindexswitch] + jointindexallowed[jointindexswitch]) {
+      fCurrentIndex = jointindexlow[jointindexswitch];
+    }
+  }
+
+  return GetNuisanceEvent(fCurrentIndex);
+};
+
+
+BaseFitEvt* InputHandlerBase::FirstBaseEvent() {
+  fCurrentIndex = 0;
+  return GetBaseEvent(fCurrentIndex);
+};
+
+BaseFitEvt* InputHandlerBase::NextBaseEvent() {
+  fCurrentIndex++;
+
+  if (jointinput and fMaxEvents != -1) {
+    while ( fCurrentIndex < jointindexlow[jointindexswitch] ||
+            fCurrentIndex >= jointindexhigh[jointindexswitch] ) {
+      jointindexswitch++;
+
+      // Loop Around
+      if (jointindexswitch == jointindexlow.size()) {
+        jointindexswitch = 0;
+      }
+    }
+
+
+    if (fCurrentIndex > jointindexlow[jointindexswitch] + jointindexallowed[jointindexswitch]) {
+      fCurrentIndex = jointindexlow[jointindexswitch];
+    }
+  }
+
+  return GetBaseEvent(fCurrentIndex);
+};
+
+
+void InputHandlerBase::RegisterJointInput(std::string input, int n, TH1D* f, TH1D* e) {
+
+  if (jointfluxinputs.size() == 0){
+    jointindexswitch = 0;
+  }
+
+  // Push into individual input vectors
+  jointfluxinputs.push_back(  (TH1D*) f->Clone() );
+  jointeventinputs.push_back( (TH1D*) e->Clone() );
+
+  jointindexlow.push_back(fNEvents);
+  jointindexhigh.push_back(fNEvents + n);
+  fNEvents += n;
+
+  // Add to the total flux/event hist
+  if (!fFluxHist) fFluxHist = (TH1D*) f->Clone();
+  else fFluxHist->Add(f);
+
+  if (!fEventHist) fEventHist = (TH1D*) e->Clone();
+  else fEventHist->Add(e);
+
+}
+
+
+void InputHandlerBase::SetupJointInputs() {
+
+    if (jointeventinputs.size() == 1){
+      jointinput = false;
+    } else {
+      jointinput= true;
+    }
+  fMaxEvents = FitPar::Config().GetParI("MAXEVENTS");
+
+  for (size_t i = 0; i < jointeventinputs.size(); i++) {
+    TH1D* eventhist = (TH1D*) jointeventinputs.at(i)->Clone();
+
+    double scale = double(fNEvents) / fEventHist->Integral("width");
+    scale *= eventhist->Integral("width");
+    scale /= double(jointindexhigh[i] - jointindexlow[i]);
+
+    jointindexscale .push_back(scale);
+  }
+
+  fEventHist->SetNameTitle((fName + "_EVT").c_str(), (fName + "_EVT").c_str());
+  fFluxHist->SetNameTitle((fName + "_FLUX").c_str(), (fName + "_FLUX").c_str());
+
+  // Setup Max Events
+  if (fMaxEvents > 1 && fMaxEvents < fNEvents) {
+    if (LOG_LEVEL(SAM)) {
+      std::cout << "\t\t|-> Read Max Entries : " << fMaxEvents << std::endl;
+    }
+    fNEvents = fMaxEvents;
+  }
+
+  // Print out Status
+  if (LOG_LEVEL(SAM)) {
+    std::cout << "\t\t|-> Total Entries    : " << fNEvents << std::endl
+              << "\t\t|-> Event Integral   : " << fEventHist->Integral("width") * 1.E-38 << " events/nucleon" << std::endl
+              << "\t\t|-> Flux Integral    : " << fFluxHist->Integral("width") << " /cm2" << std::endl
+              << "\t\t|-> Event/Flux       : "
+              << fEventHist->Integral("width") * 1.E-38 / fFluxHist->Integral("width") << " cm2/nucleon" <<  std::endl;
+  }
+
+}
+
+BaseFitEvt* InputHandlerBase::GetBaseEvent(const UInt_t entry) {
+  return static_cast<BaseFitEvt*>(GetNuisanceEvent(entry, true));
+}
+
+double InputHandlerBase::GetInputWeight(int entry) {
+
+  if (!jointinput) return 1.0;
+
+  // Find Switch Scale
+  while ( entry < jointindexlow[jointindexswitch] ||
+          entry >= jointindexhigh[jointindexswitch] ) {
+    jointindexswitch++;
+
+    // Loop Around
+    if (jointindexswitch == jointindexlow.size()) {
+      jointindexswitch = 0;
+    }
+  }
+
+  return jointindexscale[jointindexswitch];
+};
+
diff --git a/src/InputHandler/InputHandler.h b/src/InputHandler/InputHandler.h
new file mode 100644
index 0000000..5998c56
--- /dev/null
+++ b/src/InputHandler/InputHandler.h
@@ -0,0 +1,151 @@
+// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
+
+/*******************************************************************************
+*    This file is part of NUISANCE.
+*
+*    NUISANCE is free software: you can redistribute it and/or modify
+*    it under the terms of the GNU General Public License as published by
+*    the Free Software Foundation, either version 3 of the License, or
+*    (at your option) any later version.
+*
+*    NUISANCE is distributed in the hope that it will be useful,
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*    GNU General Public License for more details.
+*
+*    You should have received a copy of the GNU General Public License
+*    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
+*******************************************************************************/
+#ifndef INPUTHANDLER2_H
+#define INPUTHANDLER2_H
+/*!
+ *  \addtogroup InputHandler
+ *  @{
+ */
+#include "TH1D.h"
+#include "FitEvent.h"
+#include "BaseFitEvt.h"
+#include "TTreePerfStats.h"
+
+/// Utils namespace for everything that supports InputHandler creation
+namespace InputUtils {
+  /// Parses a file list by commas and removes brackets
+  std::vector<std::string> ParseInputFileList(std::string const& inpFile);
+}
+
+/// Base InputHandler class defining how events are requested and setup.
+class InputHandlerBase {
+public:
+
+  /// Base constructor resets everything to default
+  InputHandlerBase();
+
+  /// Removes flux/event rate histograms
+  virtual ~InputHandlerBase();
+
+  /// Return NUISANCE FitEvent Class from given event entry. 
+  /// Must be overriden by GeneratorInputHandler. Lightweight allows a faster option
+  /// to be given where only RW information is needed.
+  virtual FitEvent* GetNuisanceEvent(const UInt_t entry, const bool lightweight=false) = 0;
+  /// Calls GetNuisanceEvent(entry, TRUE);
+  virtual BaseFitEvt* GetBaseEvent(const UInt_t entry);
+
+
+  /// Print current event information
+  virtual void Print();
+
+
+  /// Return handler ID
+  inline std::string GetName (void) {return fName;     };
+  /// Return Handler Event Type Index
+  inline int         GetType (void) {return fEventType;};
+
+
+  /// Get Total Number of Events being Handled
+  inline virtual int   GetNEvents        (void) {return fNEvents;  };
+  /// Get the Total Flux Histogram these events were generated with
+  inline virtual TH1D* GetFluxHistogram  (void) {return fFluxHist; };
+  /// Get the Total Event Histogram these events were generated with
+  inline virtual TH1D* GetEventHistogram (void) {return fEventHist;};
+  /// Get the Total Cross-section Histogram (EventHist/FluxHist)
+  virtual TH1D* GetXSecHistogram(void);
+
+
+  /// Return all Flux Histograms for all InputFiles.
+  virtual std::vector<TH1*> GetFluxList(void);
+  /// Return all Event Histograms for all InputFiles
+  virtual std::vector<TH1*> GetEventList(void);
+  /// Return all Xsec Histograms for all InputFiles
+  virtual std::vector<TH1*> GetXSecList(void);
+
+
+  /// Placeholder to create a cache to speed up reads in GeneratorInputHandler
+  inline virtual void CreateCache(){};
+  /// Placeholder to remove optional cache to free up memory
+  inline virtual void RemoveCache(){};
+
+
+  /// Return starting NUISANCE event pointer (entry=0)
+  FitEvent* FirstNuisanceEvent();
+  /// Iterate to next NUISANCE event. Returns NULL when entry > fNEvents.
+  FitEvent* NextNuisanceEvent();
+  /// Returns starting Base Event Pointer (entry=0)
+  BaseFitEvt* FirstBaseEvent();
+  /// Iterate to next NUISANCE Base Event. Returns NULL when entry > fNEvents.
+  BaseFitEvt* NextBaseEvent();
+
+
+  /// Register an input file and update event/flux information
+  virtual void RegisterJointInput(std::string input, int n, TH1D* f, TH1D* e);
+  /// Finalise setup of Input event/flux information and calculate
+  /// joint input weights if joint input is provided.
+  virtual void SetupJointInputs();
+  /// Calculate a weight for the event given the joint input information.
+  /// Used to scale the relative proportion of multiple inputs correctly
+  /// with respect to one another.
+  virtual double GetInputWeight(int entry);
+
+
+  /// Returns the total predicted event rate for this input given the
+  /// low and high energy ranges. intOpt specifies the option the ROOT
+  /// TH1D integral should use. e.g. "" or "width"
+  double PredictedEventRate(double low, double high,
+                            std::string intOpt);
+
+  /// Returns the total generated flux for this input given the
+  /// low and high energy ranges. intOpt specifies the option the ROOT
+  /// TH1D integral should use. e.g. "" or "width"
+  double TotalIntegratedFlux(double low = -9999.9, double high = -9999.9,
+                             std::string intOpt = "");
+
+
+  /// Actual data members.
+  std::vector<TH1D*> jointfluxinputs;
+  std::vector<TH1D*> jointeventinputs;
+  std::vector<int> jointindexlow;
+  std::vector<int> jointindexhigh;
+  std::vector<int> jointindexallowed;
+  size_t jointindexswitch;
+  bool jointinput;
+  std::vector<double> jointindexscale;
+
+  std::string fName;
+  TH1D* fFluxHist;
+  TH1D* fEventHist;
+  TH1D* fXSecHist;
+  int fNEvents;
+  int fMaxEvents;
+  FitEvent* fNUISANCEEvent;
+  BaseFitEvt* fBaseEvent;
+  int fEventType;
+  int fCurrentIndex;
+  int fCacheSize;
+  bool kRemoveUndefParticles;
+  bool kRemoveFSIParticles;
+  bool kRemoveNuclearParticles;
+  TTreePerfStats* fTTreePerformance;
+
+
+};
+/*! @} */
+#endif
diff --git a/src/InputHandler/InputTypes.h b/src/InputHandler/InputTypes.h
new file mode 100644
index 0000000..a3863de
--- /dev/null
+++ b/src/InputHandler/InputTypes.h
@@ -0,0 +1,90 @@
+// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
+
+/*******************************************************************************
+*    This file is part of NUISANCE.
+*
+*    NUISANCE is free software: you can redistribute it and/or modify
+*    it under the terms of the GNU General Public License as published by
+*    the Free Software Foundation, either version 3 of the License, or
+*    (at your option) any later version.
+*
+*    NUISANCE is distributed in the hope that it will be useful,
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*    GNU General Public License for more details.
+*
+*    You should have received a copy of the GNU General Public License
+*    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
+*******************************************************************************/
+#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,
+};
+
+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";
+  }
+  default: { return os << "kUNKNOWN"; }
+  }
+}
+#endif
diff --git a/src/FitBase/InputUtils.cxx b/src/InputHandler/InputUtils.cxx
similarity index 74%
rename from src/FitBase/InputUtils.cxx
rename to src/InputHandler/InputUtils.cxx
index ccbe8fc..c123e26 100644
--- a/src/FitBase/InputUtils.cxx
+++ b/src/InputHandler/InputUtils.cxx
@@ -1,214 +1,170 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
 #include "FitParameters.h"
 #include "GeneralUtils.h"
 #include "GeneratorUtils.h"
 
 #include "InputUtils.h"
-#include "InputHandler2.h"
+#include "InputHandler.h"
 
 namespace InputUtils {
-//********************************************************************
+
 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"
                                          };
 
   size_t nInputTypes = GeneralUtils::GetArraySize(filetypes);
 
   for (size_t i = 0; i < nInputTypes; i++) {
     if (inp == filetypes[i]) {
       std::cout << "INPUT TYPE = " << inp << " " << i << std::endl;
       return InputType(i);
     }
   }
 
   return kInvalid_Input;
 }
-//********************************************************************
+
 bool IsJointInput(std::string const &inputs) {
-  //********************************************************************
 
   bool isJoint = (inputs[0] == '(');
   if (isJoint && (inputs[inputs.length() - 1] != ')')) {
     ERR(FTL) << "Inputs specifier: \"" << inputs
              << "\" looks like a composite input specifier -- "
              "(filea.root,fileb.root), however, it did not end in a \')\', "
              "it ended in a \'"
              << inputs[inputs.length() - 1] << "\'" << std::endl;
     throw;
   }
   return isJoint;
 }
 
-//********************************************************************
 std::string ExpandInputDirectories(std::string const &inputs) {
-  //********************************************************************
 
   // Parse the "environement" flags in the fitter config
   // Can specify NEUT_DIR = "" and others in parameters/fitter.config.dat
   const static std::string filedir[] = {"NEUT_DIR",   "NUWRO_DIR",
                                         "GENIE_DIR",  "NUANCE_DIR",
                                         "EVSPLN_DIR", "GIBUU_DIR"
                                        };
   size_t nfiledir = GeneralUtils::GetArraySize(filedir);
   std::string expandedInputs = inputs;
 
   for (size_t i = 0; i < nfiledir; i++) {
     std::string tempdir = "@" + filedir[i];
     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);
       break;
     }
   }
 
   return expandedInputs;
 }
 
 InputType GuessInputTypeFromFile(TFile *inpF) {
+  /*
+    const std::string NEUT_TreeName = "neuttree";
+  const std::string NuWro_TreeName = "treeout";
+  const std::string GENIE_TreeName = "gtree";
+  const std::string GiBUU_TreeName = "giRooTracker";
   if (!inpF) {
     return kInvalid_Input;
   }
   TTree *NEUT_Input =
     dynamic_cast<TTree *>(inpF->Get(GeneratorUtils::NEUT_TreeName.c_str()));
   if (NEUT_Input) {
     return kNEUT_Input;
   }
   TTree *NUWRO_Input =
     dynamic_cast<TTree *>(inpF->Get(GeneratorUtils::NuWro_TreeName.c_str()));
   if (NUWRO_Input) {
     return kNUWRO_Input;
   }
   TTree *GENIE_Input =
     dynamic_cast<TTree *>(inpF->Get(GeneratorUtils::GENIE_TreeName.c_str()));
   if (GENIE_Input) {
     return kGENIE_Input;
   }
   TTree *GiBUU_Input =
     dynamic_cast<TTree *>(inpF->Get(GeneratorUtils::GiBUU_TreeName.c_str()));
   if (GiBUU_Input) {
     return kGiBUU_Input;
   }
-
+*/
   return kInvalid_Input;
 }
 
 std::string PrependGuessedInputTypeToName(std::string const &inpFName) {
   TFile *inpF = TFile::Open(inpFName.c_str(), "READ");
   if (!inpF || !inpF->IsOpen()) {
     ERR(FTL) << "Couldn't open \"" << inpFName << "\" for reading."
              << std::endl;
     throw;
   }
   InputType iType = GuessInputTypeFromFile(inpF);
   if (iType == kInvalid_Input) {
     ERR(FTL) << "Couldn't determine input type from file: " << inpFName
              << "." << std::endl;
     throw;
   }
   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;
   }
   }
 }
 
-InputHandlerBase* CreateInputHandler(std::string const& handle,
-                                     InputUtils::InputType inpType,
-                                     std::string const& inputs) {
-
-  InputHandlerBase* input = NULL;
-
-  std::string newinputs = ExpandInputDirectories(inputs);
-
-  switch (inpType) {
-
-
-  case (kNEUT_Input):
-#ifdef __NEUT_ENABLED__
-    input = new NEUTInputHandler(handle, newinputs);
-    break;
-#endif
-
-
-  case (kGENIE_Input):
-#ifdef __GENIE_ENABLED__
-    input = new GENIEInputHandler(handle, newinputs);
-#endif
-    break;
+// std::vector<std::string> ParseInputFileList(std::string const& inpFile) {
 
+//   std::vector<std::string> 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;
 
-  case (kNUWRO_Input):
-#ifdef __NUWRO_ENABLED__
-    input = new NuWroInputHandler(handle, newinputs);
-#endif
-    break;
-
-
-  case (kGiBUU_Input):
-#ifdef __GiBUU_ENABLED__
-    input = new GIBUUInputHandler(handle, newinputs);
-#endif
-    break;
-
-  case (kFEVENT_Input):
-    input = new FitEventInputHandler(handle, newinputs);
-    break;
-
-  case (kEVSPLN_Input):
-    input = new SplineInputHandler(handle, newinputs);
-    break;
-
-  default:
-    break;
-  }
-
-  /// Input failed
-  if (!input) {
-    ERR(FTL) << "Input handler creation failed!" << std::endl;
-  }
-
+// }
 
-  return input;
-};
 }
diff --git a/src/FitBase/InputUtils.h b/src/InputHandler/InputUtils.h
similarity index 85%
rename from src/FitBase/InputUtils.h
rename to src/InputHandler/InputUtils.h
index fa3edb6..18d9ce6 100644
--- a/src/FitBase/InputUtils.h
+++ b/src/InputHandler/InputUtils.h
@@ -1,102 +1,94 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
 #ifndef INPUT_UTILS_H
 #define INPUT_UTILS_H
 
 #include <string>
 #include "TFile.h"
-#include "InputHandler2.h"
-#include "NEUTInputHandler.h"
-#include "GENIEInputHandler.h"
-#include "NuWroInputHandler.h"
-#include "GIBUUInputHandler.h"
-#include "NUANCEInputHandler.h"
-#include "FitEventInputHandler.h"
-#include "SplineInputHandler.h"
+
 
 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, // Kept for backwards compatibility
   kInvalid_Input,
   kHIST_Input,   // Not sure if this are currently used.
   kBNSPLN_Input  // Not sure if this are currently used.
 };
 
 InputType ParseInputType(std::string const &inp);
 bool IsJointInput(std::string const &inputs);
 std::string ExpandInputDirectories(std::string const &inputs);
 
 InputType GuessInputTypeFromFile(TFile *inpF);
 std::string PrependGuessedInputTypeToName(std::string const &inpFName);
 
-InputHandlerBase* CreateInputHandler(std::string const& handle, 
-                                     InputUtils::InputType inpType,
-                                     std::string const& inputs);
+// std::vector<std::string> ParseInputFileList(std::string const& inpFile);
+
 
 }
 
 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::kInvalid_Input:
     case InputUtils::kHIST_Input:
     case InputUtils::kBNSPLN_Input:
     default: { return os << "kInvalid_Input"; }
   }
 }
 
 
 
 #endif
diff --git a/src/InputHandler/NEUTInputHandler.cxx b/src/InputHandler/NEUTInputHandler.cxx
new file mode 100644
index 0000000..f84c4c7
--- /dev/null
+++ b/src/InputHandler/NEUTInputHandler.cxx
@@ -0,0 +1,429 @@
+#ifdef __NEUT_ENABLED__
+#include "NEUTInputHandler.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<std::string> inputs = InputUtils::ParseInputFileList(rawinputs);
+	for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) {
+
+		// Open File for histogram access
+		TFile* inp_file = new TFile(inputs[inp_it].c_str(), "READ");
+		if (!inp_file or inp_file->IsZombie()) {
+			ERR(FTL) << "NEUT File IsZombie() at " << inputs[inp_it] << std::endl;
+			throw;
+		}
+
+		// 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) {
+			ERR(FTL) << "NEUT FILE doesn't contain flux/xsec info" << std::endl;
+			throw;
+		}
+
+		// Get N Events
+		TTree* neuttree = (TTree*)inp_file->Get("neuttree");
+		if (!neuttree) {
+			ERR(FTL) << "neuttree not located in NEUT file! " << inputs[inp_it] << std::endl;
+			throw;
+		}
+		int nevents = neuttree->GetEntries();
+
+		// 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);
+
+	// 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);
+
+	// Setup Input scaling for joint inputs
+	fNUISANCEEvent->InputWeight = GetInputWeight(entry);
+
+	// Run NUISANCE Vector Filler
+	if (!lightweight) {
+		CalcNUISANCEKinematics();
+	}
+
+	// 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();
+	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/NEUTInputHandler.h b/src/InputHandler/NEUTInputHandler.h
new file mode 100644
index 0000000..4ff2144
--- /dev/null
+++ b/src/InputHandler/NEUTInputHandler.h
@@ -0,0 +1,99 @@
+#ifndef NEUTINPUTHANDLER_H
+#define NEUTINPUTHANDLER_H
+
+#ifdef __NEUT_ENABLED__
+#include "InputHandler.h"
+#include "TargetUtils.h"
+#include "neutpart.h"
+#include "neutvect.h"
+#include "PlotUtils.h"
+#include "TTreePerfStats.h"
+#include "nefillverC.h"
+#include "necardC.h"
+#include "neutmodelC.h"
+#include "neutparamsC.h"
+#include "neworkC.h"
+#include "fsihistC.h"
+#include "neutcrsC.h"
+#include "neutvect.h"
+#include "neutpart.h"
+#include "neutfsipart.h"
+#include "neutfsivert.h"
+#include "neutrootTreeSingleton.h"
+#include "NModeDefn.h"
+#include "NSyst.h"
+#include "NFortFns.h" // Contains all the NEUT common blocks
+
+#ifdef __NEUT_NUCFSI_ENABLED__
+#include "nucleonfsihistC.h"
+#include "neutnucfsivert.h"
+#include "neutnucfsistep.h"
+#endif
+
+/// NEUT Generator Container to save extra particle status codes.
+class NEUTGeneratorInfo : public GeneratorInfoBase {
+public:
+	NEUTGeneratorInfo() {};
+	virtual ~NEUTGeneratorInfo();
+
+	/// 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 NEUT information from the event
+	void FillGeneratorInfo(NeutVect* nevent);
+
+	/// Reset extra information to default/empty values
+	void Reset();
+
+	int  kMaxParticles; ///< Number of particles in stack
+	int* fNEUTParticleStatusCode; ///<NEUT Particle Status Flags
+	int* fNEUTParticleAliveCode; ///< NEUT Alive Code (0 dead, 1 final state)
+	int fNEUTParticleN; ///< Number of particles
+};
+
+/// NEUT Input Convertor to read in NeutVects and convert to FitEvents
+class NEUTInputHandler : public InputHandlerBase {
+public:
+
+	/// Main constructor. Can read in single or joint inputs.
+	NEUTInputHandler(std::string const& handle, std::string const& rawinputs);
+	~NEUTInputHandler();
+
+	/// Returns NUISANCE Format event from entry in fNEUTTree
+	FitEvent* GetNuisanceEvent(const UInt_t entry, const bool lightweight);
+
+	/// Create a TTree Cache to speed up file read
+	void CreateCache();
+
+	/// Remove TTree Cache to save memory
+	void RemoveCache();
+
+	/// Convert NEUT particle status codes to NUISANCE format status
+	int GetNeutParticleStatus(NeutPart* part);
+
+	/// eads fNeutVect and fills into fNUISANCEEvent.
+	void CalcNUISANCEKinematics();
+
+	bool fSaveExtra; ///< Save Extra NEUT information in to fNeutInfo
+	TChain* fNEUTTree; ///< TTree for reading neut vectors.
+	NeutVect* fNeutVect;  ///< Neut vector format event.
+	NEUTGeneratorInfo* fNeutInfo; ///< NEUT Generator Info container.
+};
+
+namespace NEUTUtils {
+#ifdef __NEUT_ENABLED__
+void FillNeutCommons(NeutVect* nvect);
+#endif
+}
+
+#endif
+#endif
diff --git a/src/InputHandler/NUANCEInputHandler.cxx b/src/InputHandler/NUANCEInputHandler.cxx
new file mode 100644
index 0000000..cf7e4f4
--- /dev/null
+++ b/src/InputHandler/NUANCEInputHandler.cxx
@@ -0,0 +1,834 @@
+#ifdef __NUANCE_ENABLED__
+#include "NUANCEInputHandler.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<std::string> 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);
+
+	// 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->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/NUANCEInputHandler.h b/src/InputHandler/NUANCEInputHandler.h
new file mode 100644
index 0000000..a6c1b4c
--- /dev/null
+++ b/src/InputHandler/NUANCEInputHandler.h
@@ -0,0 +1,92 @@
+// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
+
+/*******************************************************************************
+*    This file is part of NUISANCE.
+*
+*    NUISANCE is free software: you can redistribute it and/or modify
+*    it under the terms of the GNU General Public License as published by
+*    the Free Software Foundation, either version 3 of the License, or
+*    (at your option) any later version.
+*
+*    NUISANCE is distributed in the hope that it will be useful,
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*    GNU General Public License for more details.
+*
+*    You should have received a copy of the GNU General Public License
+*    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
+*******************************************************************************/
+#ifndef NUANCEINPUTHANDLER_H
+#define NUANCEINPUTHANDLER_H
+#ifdef __NUANCE_ENABLED__
+/*!
+ *  \addtogroup InputHandler
+ *  @{
+ */
+#include "InputHandler.h"
+#include "PlotUtils.h"
+
+/// NUANCE Generator Container to save extra particle status codes.
+class NUANCEGeneratorInfo : public GeneratorInfoBase {
+public:
+	NUANCEGeneratorInfo() {};
+	virtual ~NUANCEGeneratorInfo();
+
+	/// 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 NUANCE information from the event
+	void FillGeneratorInfo(NuanceEvent* nevent);
+
+	/// Reset extra information to default/empty values
+	void Reset();
+
+	// int  kMaxParticles; ///< Number of particles in stack
+	// int* fNEUTParticleStatusCode; ///<NEUT Particle Status Flags
+	// int* fNEUTParticleAliveCode; ///< NEUT Alive Code (0 dead, 1 final state)
+	// int fNEUTParticleN; ///< Number of particles
+};
+
+/// Handler to read NUANCE TTrees directly into NUISANCE Format
+class NUANCEInputHandler : public InputHandlerBase {
+public:
+
+	/// Standard  constructor given name and input file list
+	NUANCEInputHandler(std::string const& handle, std::string const& rawinputs);
+	~NUANCEInputHandler();
+
+	/// Returns NUISANCE format event by reading fNUANCETree
+	FitEvent* GetNuisanceEvent(const UInt_t entry, const bool lightweight = false);
+
+	/// Converts events from the current TTree entry into NUISANCE event.
+	void CalcNUISANCEKinematics();
+
+	/// Create a TTree Cache to speed up file read
+	void CreateCache();
+
+	/// Remove TTree Cache to save memory
+	void RemoveCache();
+
+	/// Print event information
+	void Print();
+
+	/// Converts Nuance Interaction Mode to NUISANCE codes
+	int ConvertNuanceMode(NuanceEvent * evt);
+
+	bool fSaveExtra; ///< Save Extra NUANCE information in to fNuanceInfo
+	NUANCEGeneratorInfo fNuanceInfo; ///< Generator Info Saver
+	NuanceEvent* fNuanceEvent; ///< NUANCE Reader
+	TChain* fNUANCETree;       ///< Pointer to TTree in file
+};
+#endif
+/*! @} */
+#endif
diff --git a/src/FitBase/NuWroInputHandler.cxx b/src/InputHandler/NuWroInputHandler.cxx
similarity index 61%
rename from src/FitBase/NuWroInputHandler.cxx
rename to src/InputHandler/NuWroInputHandler.cxx
index ac081b9..e0625e8 100644
--- a/src/FitBase/NuWroInputHandler.cxx
+++ b/src/InputHandler/NuWroInputHandler.cxx
@@ -1,552 +1,465 @@
 #ifdef __NUWRO_ENABLED__
 #include "NuWroInputHandler.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);
+}
 
-// Generator Info Box Definitions
-void NuWroGeneratorInfo::AddBranchesToTree(TTree * tn) {
+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;
+	}
 }
 
-// Input Handler Definition
 NuWroInputHandler::NuWroInputHandler(std::string const& handle, std::string const& rawinputs) {
-
 	LOG(SAM) << "Creating NuWroInputHandler : " << handle << std::endl;
 
 	// Run a joint input handling
 	fName = handle;
-	jointinput = false;
-	jointindexswitch = 0;
 	fMaxEvents = FitPar::Config().GetParI("MAXEVENTS");
-
-	// Form list of all inputs, remove brackets if required.
-	std::vector<std::string> inputs = GeneralUtils::ParseToStr(rawinputs, ",");
-	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);
-	}
-	for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) {
-		if (LOG_LEVEL(SAM)) {
-			std::cout << "\t\t|-> Input File " << inp_it
-			          << "      : " << inputs[inp_it] << std::endl;
-		}
-	}
-
+	fSaveExtra =  false; //FitPar::Config().GetParB("NuWroSaveExtra");
 	// Setup the TChain
 	fNuWroTree = new TChain("treeout");
 
 	// Loop over all inputs and grab flux, eventhist, and nevents
-	// Also add it to the TChain
-	int evtcounter = 0;
-	if (inputs.size() > 1) jointinput = true;
+	std::vector<std::string> inputs = InputUtils::ParseInputFileList(rawinputs);
 	for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) {
 
-		// Add to TChain
-		fNuWroTree->Add( inputs[inp_it].c_str() );
-
 		// 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 no flux hist throw
 		if (!fluxhist or !eventhist) {
-			ERR(FTL) << "NuWro Inputs do not have input histograms!" << std::endl;
-
+			ERR(FTL) << "nuwro FILE doesn't contain flux/xsec info" << std::endl;
 			if (FitPar::Config().GetParB("regennuwro")) {
-				ProcessNuWroInputFlux(inputs[inp_it]);
+				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
+		// 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();
 
-		// Push into individual input vectors
-		jointfluxinputs.push_back( (TH1D*) fluxhist->Clone() );
-		jointeventinputs.push_back( (TH1D*) eventhist->Clone() );
-
-		jointindexlow.push_back(evtcounter);
-		jointindexhigh.push_back(evtcounter + nevents);
-		evtcounter += nevents;
-
-		// Add to the total flux/event hist
-		if (!fFluxHist) fFluxHist = (TH1D*) fluxhist->Clone();
-		else fFluxHist->Add(fluxhist);
+		// Register input to form flux/event rate hists
+		RegisterJointInput(inputs[inp_it], nevents, fluxhist, eventhist);
 
-		if (!fEventHist) fEventHist = (TH1D*) eventhist->Clone();
-		else fEventHist->Add(eventhist);
+		// Add to TChain
+		fNuWroTree->Add( inputs[inp_it].c_str() );
 	}
 
-	// Setup NEvents and the FitEvent
-	fNEvents = fNuWroTree->GetEntries();
-	fEventType = kNUWRO;
+	// Registor all our file inputs
+	SetupJointInputs();
+
+	// Setup Events
 	fNuWroEvent = NULL;
 	fNuWroTree->SetBranchAddress("e", &fNuWroEvent);
 
 	fNUISANCEEvent = new FitEvent();
 	fNUISANCEEvent->SetNuwroEvent(fNuWroEvent);
 	fNUISANCEEvent->HardReset();
 
-	fBaseEvent = static_cast<BaseFitEvt*>(fNUISANCEEvent);
-
-	// Normalise event histograms for relative flux contributions.
-	for (size_t i = 0; i < jointeventinputs.size(); i++) {
-		TH1D* eventhist = (TH1D*) jointeventinputs.at(i)->Clone();
-
-		// Determine nallowed
-		int nallowed = jointindexhigh[i] - jointindexlow[i];
-		if (fMaxEvents != -1) {
-			nallowed = int( double(nallowed) *
-			                (double(fMaxEvents) / double(fNEvents)) );
-		}
-		jointindexallowed.push_back(nallowed);
-
-		// Set scale, undoing other scale factor.
-		double scale = double(fNEvents) / fEventHist->Integral("width");
-		scale *= eventhist->Integral("width");
-		scale /= double(jointindexallowed[i]);
-
-		jointindexscale .push_back(scale);
-	}
-
-
-	fEventHist->SetNameTitle((fName + "_EVT").c_str(), (fName + "_EVT").c_str());
-	fFluxHist->SetNameTitle((fName + "_FLUX").c_str(), (fName + "_FLUX").c_str());
-
-	// Setup extra flags
-	save_extra = FitPar::Config().GetParB("save_extra_nuwro_info");
-	if (save_extra) {
+	if (fSaveExtra) {
 		fNuWroInfo = new NuWroGeneratorInfo();
-		fNUISANCEEvent->fGenInfo = fNuWroInfo;
-	}
-
-	// 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
-		          << "\t\t|-> Save Extra Info  : " << save_extra << std::endl;
-	}
-
-	// Setup Max Events
-	if (fMaxEvents > 1 && fMaxEvents < fNEvents) {
-		if (LOG_LEVEL(SAM)) {
-			std::cout << "\t\t|-> Read Max Entries : " << fMaxEvents << std::endl;
-		}
-		fNEvents = fMaxEvents;
+		fNUISANCEEvent->AddGeneratorInfo(fNuWroInfo);
 	}
 
 };
 
-void NuWroInputHandler::ProcessNuWroInputFlux(const std::string file) {
+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) {
+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);
 
-	// Get latest TTree and get entry, loop round in parrallel and grab entries from other TTrees.
-	// Get event corresponding to this TTree and replace pointer in fNuWroEvent with it.
-
 	// Setup Input scaling for joint inputs
-	if (jointinput) {
-		fNUISANCEEvent->InputWeight = GetInputWeight(entry);
-	} else {
-		fNUISANCEEvent->InputWeight = 1.0;
-	}
+	fNUISANCEEvent->InputWeight = GetInputWeight(entry);
 
 	// Run NUISANCE Vector Filler
-	CalcNUISANCEKinematics();
-
+	if (!lightweight) {
+		CalcNUISANCEKinematics();
+	}
+	
 	return fNUISANCEEvent;
 }
 
-#ifdef __NUWRO_ENABLED__
 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 (e->nof (proton_pdg))
 					return -51;
 				else if (e->nof (neutron_pdg))
 					return -52;	// sprawdzam dodatkowo ?
 			}
 		}
 		else			// oddziaływanie z neutrinem
 		{
 			if (e->flag.cc)
 				return 1;
 			else
 			{
 				if (e->nof (proton_pdg))
 					return 51;
 				else if (e->nof (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 =
 		    e->nof (pion_pdg) + e->nof (pion_plus_pdg) + e->nof (pion_minus_pdg);
 		liczba_kaonow = e->nof (kaon_pdg) + e->nof (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 (e->nof (neutron_pdg) && e->nof (pion_minus_pdg))
 						return -11;
 					if (e->nof (neutron_pdg) && e->nof (pion_pdg))
 						return -12;
 					if (e->nof (proton_pdg) && e->nof (pion_minus_pdg))
 						return -13;
 				}
 				else
 				{
 					if (e->nof (proton_pdg))
 					{
 						if (e->nof (pion_minus_pdg))
 							return -33;
 						else if (e->nof (pion_pdg))
 							return -32;
 					}
 					else if (e->nof (neutron_pdg))
 					{
 						if (e->nof (pion_plus_pdg))
 							return -34;
 						else if (e->nof (pion_pdg))
 							return -31;
 					}
 				}
 			}
 			else			// oddziaływanie z neutrinem
 			{
 				if (e->flag.cc)
 				{
 					if (e->nof (proton_pdg) && e->nof (pion_plus_pdg))
 						return 11;
 					if (e->nof (proton_pdg) && e->nof (pion_pdg))
 						return 12;
 					if (e->nof (neutron_pdg) && e->nof (pion_plus_pdg))
 						return 13;
 				}
 				else
 				{
 					if (e->nof (proton_pdg))
 					{
 						if (e->nof (pion_minus_pdg))
 							return 33;
 						else if (e->nof (pion_pdg))
 							return 32;
 					}
 					else if (e->nof (neutron_pdg))
 					{
 						if (e->nof (pion_plus_pdg))
 							return 34;
 						else if (e->nof (pion_pdg))
 							return 31;
 					}
 				}
 			}
 		}
 
 		if (e->nof (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 (e->nof (neutron_pdg))
 						return -42;
 					else if (e->nof (proton_pdg))
 						return -43;	// sprawdzam dodatkowo ?
 				}
 			}
 			else			// oddziaływanie z neutrinem
 			{
 				if (e->flag.cc)
 					return 22;
 				else
 				{
 					if (e->nof (neutron_pdg))
 						return 42;
 					else if (e->nof (proton_pdg))
 						return 43;
 				}
 			}
 		}
 
 		if (e->nof (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 && e->nof (kaon_pdg))
 					return -23;
 				else
 				{
 					if (e->nof (kaon_pdg))
 						return -44;
 					else if (e->nof (kaon_plus_pdg))
 						return -45;
 				}
 			}
 			else			// oddziaływanie z neutrinem
 			{
 				if (e->flag.cc && e->nof (kaon_plus_pdg))
 					return 23;
 				else
 				{
 					if (e->nof (kaon_pdg))
 						return 44;
 					else if (e->nof (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 && e->nof (pion_minus_pdg))
 					return -16;
 				else if (e->nof (pion_pdg))
 					return -36;
 			}
 			else			// oddziaływanie z neutrinem
 			{
 				if (e->flag.cc && e->nof (pion_plus_pdg))
 					return 16;
 				else if (e->nof (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;
 }
-#endif
 
 void NuWroInputHandler::CalcNUISANCEKinematics() {
 	// std::cout << "NuWro Event Address " << fNuWroEvent << std::endl;
 	// Reset all variables
 	fNUISANCEEvent->ResetEvent();
 	FitEvent* evt = fNUISANCEEvent;
 
 	// Sort Event Info
-	evt->fMode = GeneratorUtils::ConvertNuwroMode(fNuWroEvent);
+	evt->fMode = ConvertNuwroMode(fNuWroEvent);
 	if (abs(evt->fMode) > 60) evt->fMode = 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(FTL) << "NUWRO has too many particles" << std::endl;
-		ERR(FTL) << "npart=" << npart << " kMax=" << kmax
-		         << " in,out,post = " << npart_in << "," << npart_out << ","
-		         << npart_post << std::endl;
-		throw;
+		ERR(WRN) << "NUWRO has too many particles. Expanding stack." << std::endl;
+	    fNUISANCEEvent->ExpandParticleStack(npart);
 	}
 
-	// Setup Infomation for extra stuff
-	// if (fSaveExtraInfo){
-	// }
-
 	// Sort Particles
 	evt->fNParticles = 0;
 	std::vector<particle>::iterator p_iter;
 
 	// Initial State
 	for (p_iter = fNuWroEvent->in.begin(); p_iter != fNuWroEvent->in.end(); p_iter++) {
 		AddNuWroParticle(fNUISANCEEvent, (*p_iter), kInitialState);
 	}
 
+	// FSI State
+	for (size_t i = 0; i < npart_in; i++ ) {
+		AddNuWroParticle(fNUISANCEEvent, (*p_iter), kFSIState);
+	}
+
+	// Final State
 	for (p_iter = fNuWroEvent->post.begin(); p_iter != fNuWroEvent->post.end(); p_iter++) {
 		AddNuWroParticle(fNUISANCEEvent, (*p_iter), kFinalState);
 	}
 
-	// // FSI State
-	// for (size_t i = 0; i < npart_in; i++ ) {
-	// 	AddNuWroParticle(fNUISANCEEvent, &fNuWroEvent->out[i], kFSIState);
-	// }
-
-	// // Final Particles
-	// for (size_t i = 0; i < npart_in; i++ ) {
-	// 	AddNuWroParticle(fNUISANCEEvent, &fNuWroEvent->post[i], kFinalState);
-	// }
-
+	// Fill Generator Info
+	if (fSaveExtra) fNuWroInfo->FillGeneratorInfo(fNuWroEvent);
 
 	// Run Initial, FSI, Final, Other ordering.
 	fNUISANCEEvent->OrderStack();
 	return;
 }
 
-void NuWroInputHandler::AddNuWroParticle(FitEvent* evt, const particle& p, int state) {
+void NuWroInputHandler::AddNuWroParticle(FitEvent * evt, const particle & p, int state) {
 
 	// Add Mom
 	evt->fParticleMom[evt->fNParticles][0] = p.p4().x;
 	evt->fParticleMom[evt->fNParticles][1] = p.p4().y;
 	evt->fParticleMom[evt->fNParticles][2] = p.p4().z;
 	evt->fParticleMom[evt->fNParticles][3] = p.p4().t;
 
 	// Status/PDG
 	evt->fParticleState[evt->fNParticles] = state;
 	evt->fParticlePDG[evt->fNParticles] = p.pdg;
 
-	// Flag setup for saving extra information.
-	// if (fSaveExtraInfo){
-	// }
-
 	// Add to particle count
 	evt->fNParticles++;
 }
 
-
-double NuWroInputHandler::GetInputWeight(int entry) {
-
-	// Find Switch Scale
-	while ( entry < jointindexlow[jointindexswitch] ||
-	        entry >= jointindexhigh[jointindexswitch] ) {
-		jointindexswitch++;
-
-		// Loop Around
-		if (jointindexswitch == jointindexlow.size()) {
-			jointindexswitch = 0;
-		}
-	}
-	return jointindexscale[jointindexswitch];
-};
-
-
-BaseFitEvt* NuWroInputHandler::GetBaseEvent(const UInt_t entry) {
-
-	// Catch too large entries
-	if (entry >= (UInt_t)fNEvents) return NULL;
-
-	// Read entry from TTree to fill NEUT Vect in BaseFitEvt;
-	fNuWroTree->GetEntry(entry);
-
-	// Set joint scaling if required
-	if (jointinput) {
-		fBaseEvent->InputWeight = GetInputWeight(entry);
-	} else {
-		fBaseEvent->InputWeight = 1.0;
-	}
-
-	return fBaseEvent;
+void NuWroInputHandler::Print(){
 }
 
 #endif
 
diff --git a/src/InputHandler/NuWroInputHandler.h b/src/InputHandler/NuWroInputHandler.h
new file mode 100644
index 0000000..4b498ed
--- /dev/null
+++ b/src/InputHandler/NuWroInputHandler.h
@@ -0,0 +1,78 @@
+#ifndef NuWroINPUTHANDLER_H
+#define NuWroINPUTHANDLER_H
+#ifdef __NUWRO_ENABLED__
+#include "GeneratorUtils.h"
+#include "InputHandler.h"
+#include "PlotUtils.h"
+
+/// NuWro Generator Container to save extra particle status codes.
+class NuWroGeneratorInfo : public GeneratorInfoBase {
+public:
+	NuWroGeneratorInfo() {};
+	virtual ~NuWroGeneratorInfo();
+
+	/// 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 genie information from the event
+	void FillGeneratorInfo(event* e);
+
+	/// Reset extra information to default/empty values
+	void Reset();
+
+	int  kMaxParticles; ///< Number of particles in stack
+	int* fNuWroParticlePDGs; ///< NuWro Particle PDGs (example)
+};
+
+/// Main NuWro Input Reader. Requires events have flux and xsec TH1Ds saved into them.
+class NuWroInputHandler : public InputHandlerBase {
+public:
+
+	/// Constructor. Can handle single and joint inputs.
+	NuWroInputHandler(std::string const& handle, std::string const& rawinputs);
+	~NuWroInputHandler();
+
+	/// Create a TTree Cache to speed up file read
+	void CreateCache();
+
+	/// Remove TTree Cache to save memory
+	void RemoveCache();
+
+	/// Returns filled NUISANCEEvent for given entry.
+	FitEvent* GetNuisanceEvent(const UInt_t entry, const bool lightweight = false);
+
+	/// Fills fNUISANCEEvent from fNuWroEvent
+	void CalcNUISANCEKinematics();
+
+	/// (LEGACY) Automatically creates nuwro flux/event histograms that
+	/// nuisance needs to normalise events.
+	void ProcessNuWroInputFlux(const std::string file);
+
+	/// Calculates a True Interaction code for NuWro events
+	int ConvertNuwroMode (event * e);
+
+	/// Adds a new particle to NUISANCE stack for given NuWro particle
+	void AddNuWroParticle(FitEvent* evt, const particle& p, int state);
+
+	event* fNuWroEvent;  ///< Pointer to NuWro Format Events
+
+	/// Print Event Information
+	void Print();
+
+	TChain* fNuWroTree; ///< TTree for reading NuWro event vectors
+	bool fSaveExtra;    ///< Save Extra NuWro info into Nuisance Event
+	NuWroGeneratorInfo *fNuWroInfo; ///< Extra NuWro Generator Info
+
+};
+/*! @} */
+#endif
+#endif
diff --git a/src/FitBase/NuanceEvent.cxx b/src/InputHandler/NuanceEvent.cxx
similarity index 53%
rename from src/FitBase/NuanceEvent.cxx
rename to src/InputHandler/NuanceEvent.cxx
index 83ea3dd..dd9118c 100644
--- a/src/FitBase/NuanceEvent.cxx
+++ b/src/InputHandler/NuanceEvent.cxx
@@ -1,37 +1,59 @@
+// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
+
+/*******************************************************************************
+*    This file is part of NUISANCE.
+*
+*    NUISANCE is free software: you can redistribute it and/or modify
+*    it under the terms of the GNU General Public License as published by
+*    the Free Software Foundation, either version 3 of the License, or
+*    (at your option) any later version.
+*
+*    NUISANCE is distributed in the hope that it will be useful,
+*    but WITHOUT ANY WARRANTY; without even the implied warranty of
+*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*    GNU General Public License for more details.
+*
+*    You should have received a copy of the GNU General Public License
+*    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
+*******************************************************************************/
+/*!
+ *  \addtogroup FitBase
+ *  @{
+ */
 #ifdef __NUANCE_ENABLED__
 #include "NuanceEvent.h"
 
 void NuanceEvent::SetBranchAddresses(TTree* tn) {
 
 	tn->SetBranchAddress("neutrino", &neutrino);
 	tn->SetBranchAddress("target", &target);
 	tn->SetBranchAddress("channel", &channel);
 	tn->SetBranchAddress("iniQ", &iniQ);
 	tn->SetBranchAddress("finQ", &finQ);
 	tn->SetBranchAddress("lepton0", &lepton0);
 	tn->SetBranchAddress("polar", &polar);
 	tn->SetBranchAddress("qsq", &qsq);
 
 	tn->SetBranchAddress("w", &w);
 	tn->SetBranchAddress("x", &x);
 	tn->SetBranchAddress("y", &y);
 
 	tn->SetBranchAddress("p_neutrino", p_neutrino);
 	tn->SetBranchAddress("p_targ", p_targ);
 	tn->SetBranchAddress("vertex", vertex);
 	tn->SetBranchAddress("start", start);
 	tn->SetBranchAddress("depth", &depth);
 	tn->SetBranchAddress("flux", &flux);
 
 	tn->SetBranchAddress("n_leptons", &n_leptons);
 	tn->SetBranchAddress("p_ltot", p_ltot);
 	tn->SetBranchAddress("lepton", lepton);
 	tn->SetBranchAddress("p_lepton", p_lepton);
 
 	tn->SetBranchAddress("n_hadrons", &n_hadrons);
 	tn->SetBranchAddress("p_htot", p_htot);
 	tn->SetBranchAddress("hadron", hadron);
 	tn->SetBranchAddress("p_hadron", p_hadron);
 
 }
-#endif
\ No newline at end of file
+#endif
diff --git a/src/FitBase/NuanceEvent.h b/src/InputHandler/NuanceEvent.h
similarity index 57%
rename from src/FitBase/NuanceEvent.h
rename to src/InputHandler/NuanceEvent.h
index d693e01..09c620e 100644
--- a/src/FitBase/NuanceEvent.h
+++ b/src/InputHandler/NuanceEvent.h
@@ -1,70 +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 <http://www.gnu.org/licenses/>.
 *******************************************************************************/
-
 #ifndef NUANCE_H_SEEN
 #define NUANCE_H_SEEN
-
-#ifdef __NUANCE_ENABLED__
 /*!
  *  \addtogroup FitBase
  *  @{
  */
+
+#ifdef __NUANCE_ENABLED__
 #include "TTree.h"
 
+/// TTree Reader for Nuance TTree Events
 class NuanceEvent {
  public:
 
+  /// Empty constructor
   NuanceEvent(){};
-  void SetBranchAddresses(TTree* tn);
 
+  /// Reads values from the tTree
+  void SetBranchAddresses(TTree* tn);
 
-  bool cc;
-  bool bound;
-  int neutrino;
-  int target;
+  bool cc;       ///< Is Charged Current
+  bool bound;    ///< On Bound Target
+  int neutrino;  ///< Neutrino PDG
+  int target;    ///< Target PDG
   float iniQ;
   float finQ;
-  int lepton0;
+  int lepton0;  
   float polar;
   int channel;
   float qsq;
   float w;
-  float x;
-  float y;
+  float x;       ///< Event Bjorken x
+  float y;       ///< Event Bjorken y
 
-  float p_neutrino[4];
-  float p_targ[5];
-  float vertex[4];
-  float start[4];
+  float p_neutrino[4]; ///< Neutrino 4-Mom
+  float p_targ[5];     ///< Target 5-mom
+  float vertex[4];     ///< Vertex Position
+  float start[4];      ///< Start Position 
   float depth;
   float flux;
 
-  int n_leptons;
-  
-  float p_ltot[5];
-  int lepton[200];
-  float p_lepton[5][200];
+  int n_leptons;       ///< Number of final state leptons
+  float p_ltot[5];     ///< Total 5-momentum of leptonic side
+  int lepton[200];     ///< Lepton PDGs
+  float p_lepton[5][200]; ///< Lepton 5-momentum
   
-  int n_hadrons;
-  float p_htot[5];
-  int hadron[200];
-  float p_hadron[5][200];
+  int n_hadrons;       ///< Number of final state hadrons
+  float p_htot[5];     ///< Total 5-momentum of hadronic side
+  int hadron[200];     ///< Hadron PDGs
+  float p_hadron[5][200]; ///< Hadron 5-momentum
 };
 #endif
+/*! @} */
 #endif
+
+
diff --git a/src/InputHandler/SplineInputHandler.cxx b/src/InputHandler/SplineInputHandler.cxx
new file mode 100644
index 0000000..9209f19
--- /dev/null
+++ b/src/InputHandler/SplineInputHandler.cxx
@@ -0,0 +1,133 @@
+#include "SplineInputHandler.h"
+
+SplineInputHandler::SplineInputHandler(std::string const& handle, std::string const& rawinputs) {
+	LOG(SAM) << "Creating SplineInputHandler : " << handle << std::endl;
+
+	// Run a joint input handling
+	fName = handle;
+	fCacheSize = FitPar::Config().GetParI("CacheSize");
+	fMaxEvents = FitPar::Config().GetParI("MAXEVENTS");
+
+	// Setup the TChain
+	fFitEventTree = new TChain("nuisance_events");
+
+	// Open File for histogram access
+	TFile* inp_file = new TFile(rawinputs.c_str(), "READ");
+	if (!inp_file or inp_file->IsZombie()) {
+		ERR(FTL) << "FitEvent File IsZombie() at " << rawinputs << 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 FitSpline file! " << rawinputs << std::endl;
+		throw;
+	}
+	int nevents = eventtree->GetEntries();
+
+	// Register input to form flux/event rate hists
+	RegisterJointInput(rawinputs, nevents, fluxhist, eventhist);
+	SetupJointInputs();
+
+	// Add to TChain
+	fFitEventTree->Add( rawinputs.c_str() );
+
+	// Setup NEvents and the FitEvent
+	fNEvents = fFitEventTree->GetEntries();
+	fEventType = kSPLINEPARAMETER;
+	fNUISANCEEvent = new FitEvent();
+	fNUISANCEEvent->SetBranchAddress(fFitEventTree);
+
+	// Setup Spline Reader
+	LOG(SAM) << "Loading Spline Reader." << std::endl;
+
+	fSplRead = new SplineReader();
+	fSplRead->Read( (TTree*)inp_file->Get("spline_reader") );
+	fNUISANCEEvent->fSplineRead = this->fSplRead;
+
+	// Setup Matching Spline TTree
+	fSplTree = (TTree*)inp_file->Get("spline_tree");
+	fSplTree->SetBranchAddress( "SplineCoeff", fSplineCoeff );
+	fNUISANCEEvent->fSplineCoeff = this->fSplineCoeff;
+
+	// Load into memory
+	for (int j = 0; j < fNEvents; j++) {
+		std::vector<float> tempval;
+		fFitEventTree->GetEntry(j);
+		fStartingWeights.push_back( GetInputWeight(j) );
+	}
+
+};
+
+SplineInputHandler::~SplineInputHandler() {
+	if (fFitEventTree) delete fFitEventTree;
+	if (fSplTree) delete fSplTree;
+	if (fSplRead) delete fSplRead;
+	fStartingWeights.clear();
+}
+
+void SplineInputHandler::CreateCache() {
+	if (fCacheSize > 0) {
+		fFitEventTree->SetCacheEntryRange(0, fNEvents);
+		fFitEventTree->AddBranchToCache("*", 1);
+		fFitEventTree->SetCacheSize(fCacheSize);
+
+		fSplTree->SetCacheEntryRange(0, fNEvents);
+		fSplTree->AddBranchToCache("*", 1);
+		fSplTree->SetCacheSize(fCacheSize);
+	}
+}
+
+void SplineInputHandler::RemoveCache() {
+	fFitEventTree->SetCacheEntryRange(0, fNEvents);
+	fFitEventTree->AddBranchToCache("*", 0);
+	fFitEventTree->SetCacheSize(0);
+
+	fSplTree->SetCacheEntryRange(0, fNEvents);
+	fSplTree->AddBranchToCache("*", 0);
+	fSplTree->SetCacheSize(0);
+}
+
+
+FitEvent* SplineInputHandler::GetNuisanceEvent(const UInt_t entry, const bool lightweight) {
+
+	// Make sure events setup
+	if (entry >= (UInt_t)fNEvents) return NULL;
+
+	// Reset all variables before tree read
+	fNUISANCEEvent->ResetEvent();
+
+	// Read NUISANCE Tree
+	if (!lightweight)
+		fFitEventTree->GetEntry(entry);
+
+	// Get Spline Coefficients
+	fSplTree->GetEntry(entry);
+	fNUISANCEEvent->fSplineCoeff = fSplineCoeff;
+
+	// Setup Input scaling for joint inputs
+	fNUISANCEEvent->InputWeight = fStartingWeights[entry];
+
+	// Run Initial, FSI, Final, Other ordering.
+	fNUISANCEEvent-> OrderStack();
+
+	return fNUISANCEEvent;
+}
+
+double SplineInputHandler::GetInputWeight(int entry) {
+	double w = InputHandlerBase::GetInputWeight(entry);
+	return w * fNUISANCEEvent->SavedRWWeight;
+}
+
+void SplineInputHandler::Print() {}
+
+
diff --git a/src/InputHandler/SplineInputHandler.h b/src/InputHandler/SplineInputHandler.h
new file mode 100644
index 0000000..be6b681
--- /dev/null
+++ b/src/InputHandler/SplineInputHandler.h
@@ -0,0 +1,41 @@
+#ifndef SPLINE_INPUTHANDLER_H
+#define SPLINE_INPUTHANDLER_H
+
+#include "InputHandler.h"
+#include "FitEvent.h"
+#include "PlotUtils.h"
+
+/// Spline InputHandler. Almost functionally identical to FitEventInputHandler
+/// with an extension to handle the spline co-efficients.
+class SplineInputHandler : public InputHandlerBase {
+public:
+
+	/// Standard constructor with name and file input
+	SplineInputHandler(std::string const& handle, std::string const& rawinputs);
+	virtual ~SplineInputHandler();
+
+	/// Returns NUISANCE FitEvent with Spline Coefficients included.
+	/// If lightweight, only spline coefficients are updated.
+	FitEvent* GetNuisanceEvent(const UInt_t entry, const bool lightweight = false);
+
+		/// Create a TTree Cache to speed up file read
+	void CreateCache();
+
+	/// Remove TTree Cache to save memory
+	void RemoveCache();
+
+	/// Return extra input weighting
+	double GetInputWeight(int entry);
+
+	/// Prints Event/Spline Information
+	void Print();
+
+	TChain* fFitEventTree;   ///< Main Fit Event Tree
+	TTree* fSplTree;	     ///< Main Spline Coefficient Tree
+	SplineReader* fSplRead;  ///< Spline Reader Object used to interpret splines
+	float fSplineCoeff[1000];///< Coefficients. Currently a hardcoded limit of 1000.
+
+	/// Starting RW Input Weights corresponding to nominal spline weight
+	std::vector<float> fStartingWeights;
+};
+#endif
diff --git a/src/FitBase/StdHepEvt.cxx b/src/InputHandler/StdHepEvt.cxx
similarity index 100%
rename from src/FitBase/StdHepEvt.cxx
rename to src/InputHandler/StdHepEvt.cxx
diff --git a/src/FitBase/StdHepEvt.h b/src/InputHandler/StdHepEvt.h
similarity index 100%
rename from src/FitBase/StdHepEvt.h
rename to src/InputHandler/StdHepEvt.h
diff --git a/src/K2K/CMakeLists.txt b/src/K2K/CMakeLists.txt
index b4dcce3..37c56c5 100644
--- a/src/K2K/CMakeLists.txt
+++ b/src/K2K/CMakeLists.txt
@@ -1,52 +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 <http://www.gnu.org/licenses/>.
 ################################################################################
 set(IMPLFILES
 K2K_NC1pi0_Evt_1Dppi0_nu.cxx
 )
 
 set(HEADERFILES
 K2K_NC1pi0_Evt_1Dppi0_nu.h
 )
 
 set(LIBNAME expK2K)
 
 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(${RWENGINE_INCLUDE_DIRECTORIES})
 
 include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
+include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler)
+include_directories(${CMAKE_SOURCE_DIR}/src/Genie)
 include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
 include_directories(${CMAKE_SOURCE_DIR}/src/Reweight)
 include_directories(${CMAKE_SOURCE_DIR}/src/Splines)
 
 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/MCStudies/CMakeLists.txt b/src/MCStudies/CMakeLists.txt
index 2f6c882..3dd413b 100644
--- a/src/MCStudies/CMakeLists.txt
+++ b/src/MCStudies/CMakeLists.txt
@@ -1,69 +1,71 @@
 # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 ################################################################################
 #    This file is part of NUISANCE.
 #
 #    NUISANCE is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
 #    (at your option) any later version.
 #
 #    NUISANCE is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #    GNU General Public License for more details.
 #
 #    You should have received a copy of the GNU General Public License
 #    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 ################################################################################
 set(IMPLFILES
 ExpMultDist_CCQE_XSec_1DVar_FakeStudy.cxx
 ExpMultDist_CCQE_XSec_2DVar_FakeStudy.cxx
 GenericFlux_Tester.cxx
 #MCStudy_KaonPreSelection.cxx
 MCStudy_MuonValidation.cxx
 ElectronFlux_FlatTree.cxx
 T2K2017_FakeData.cxx
 MCStudy_CCQEHistograms.cxx
 )
 
 set(HEADERFILES
 ExpMultDist_CCQE_XSec_1DVar_FakeStudy.h
 ExpMultDist_CCQE_XSec_2DVar_FakeStudy.h
 GenericFlux_Tester.h
 #MCStudy_KaonPreSelection.h
 MCStudy_MuonValidation.h
 ElectronFlux_FlatTree.h
 T2K2017_FakeData.h
 MCStudy_CCQEHistograms.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(${RWENGINE_INCLUDE_DIRECTORIES})
 include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
+include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler)
+include_directories(${CMAKE_SOURCE_DIR}/src/Genie)
 include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
 include_directories(${CMAKE_SOURCE_DIR}/src/Reweight)
 include_directories(${CMAKE_SOURCE_DIR}/src/Splines)
 
 # Needed for experiment specific signal flags
 include_directories(${CMAKE_SOURCE_DIR}/src/T2K)
 include_directories(${CMAKE_SOURCE_DIR}/src/MINERvA)
 
 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/MCStudies/ElectronFlux_FlatTree.cxx b/src/MCStudies/ElectronFlux_FlatTree.cxx
index 726f642..5ccd5ea 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 <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
 #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 << endl;
+  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();
     eventVariables = new TTree((this->fName + "_VARS").c_str(),
                                (this->fName + "_VARS").c_str());
   }
 
-  LOG(SAM) << "Adding Event Variables" << endl;
+  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();
     eventVariables = new TTree((this->fName + "_VARS").c_str(),
                                (this->fName + "_VARS").c_str());
   }
 
-  LOG(SAM) << "Adding Samples" << endl;
+  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/ExpMultDist_CCQE_XSec_1DVar_FakeStudy.cxx b/src/MCStudies/ExpMultDist_CCQE_XSec_1DVar_FakeStudy.cxx
index 4b635f5..971fa22 100644
--- a/src/MCStudies/ExpMultDist_CCQE_XSec_1DVar_FakeStudy.cxx
+++ b/src/MCStudies/ExpMultDist_CCQE_XSec_1DVar_FakeStudy.cxx
@@ -1,153 +1,154 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
 #include "ExpMultDist_CCQE_XSec_1DVar_FakeStudy.h"
 
 //********************************************************************
 /// @brief Class to perform CCQE Fake Data Studies on a custom measurement
 ExpMultDist_CCQE_XSec_1DVar_FakeStudy::ExpMultDist_CCQE_XSec_1DVar_FakeStudy(std::string name, std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile){
 //********************************************************************
 
   // Measurement Details
   fName = name;
 
   // Define our energy range for flux calcs
   EnuMin = 0.;
   EnuMax = 6.;
 
   // 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);
 
 
   // Use the name to define what variable to measure
-  int nbins;
-  double binlow, binhigh;
+  int nbins = 0;
+  double binlow = 0.0;
+  double binhigh = 0.0;
 
   if (name.find("1DQ2") != std::string::npos){
     plottype = 1; fPlotTitles = "";
     nbins = 30;  binlow = 0.0;  binhigh = 2.0;
   } else if (name.find("1DTmu") != std::string::npos){
     plottype = 2; fPlotTitles = "";
     nbins = 20;  binlow = 0.0;  binhigh = 3.0;
   } else if (name.find("1DCos") != std::string::npos){
     plottype = 3;  fPlotTitles = "";
     nbins = 10;  binlow = -1.0; binhigh = 1.0;
   }
 
   // Setup the datahist as empty, we will use fake data to fill it.
   this->fDataHist = new TH1D((fName + "_data").c_str(), (fName + "_data" + fPlotTitles).c_str(), nbins, binlow, binhigh);
 
   // Once fDataHist is setup this function will automatically generate matching MC histograms
   this->SetupDefaultHist();
 
 
   // Setup Covariance assuming a diagonal covar.
   // If you want a full covariance to be used examples are given in the MINERvA 1D classes
   fFullCovar = StatUtils::MakeDiagonalCovarMatrix(fDataHist);
   covar     = StatUtils::GetInvert(fFullCovar);
 
 
   // 3. 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()*1E-38/(fNEvents+0.))  * (12.0 / 6.0)  /this->TotalIntegratedFlux();
 
 };
 
 
 
 //********************************************************************
 /// @details Extract Enu and totcrs from event assuming quasi-elastic scattering
 void ExpMultDist_CCQE_XSec_1DVar_FakeStudy::FillEventVariables(FitEvent *event){
 //********************************************************************
 
   // MUST be defined for each new sample.
   // This function reads in the FitEvent format and lets you grab any information you need
   // from the event. This function is only called during the first and last iteration of each fit so that
   // a vector of fXVar variables can be filled for the signal events.
 
   // Define empty variables
   fXVar = -1.0;
   double q2qe = 0.0;
   double CosThetaMu = -2.0;
   double TMu = 0.0;
 
   // Loop over the particle stack
   for (UInt_t j = 2; j < event->Npart(); ++j){
 
     // Look for the outgoing muon
     if ((event->PartInfo(j))->fPID != 13) continue;
 
     // Define any variables we may need
     ThetaMu     = (event->PartInfo(0))->fP.Vect().Angle((event->PartInfo(j))->fP.Vect());
 
     Enu_rec     = FitUtils::EnuQErec((event->PartInfo(j))->fP, cos(ThetaMu), 0.,true);
     q2qe        = FitUtils::Q2QErec( (event->PartInfo(j))->fP, cos(ThetaMu), 0.,true);
 
     CosThetaMu = cos(ThetaMu);
     TMu = FitUtils::T((event->PartInfo(j))->fP);
 
     // Once lepton is found, don't continue the loop
     break;
   }
 
   if (this->plottype == 1) fXVar = q2qe;
   else if (this->plottype == 2) fXVar = TMu;
   else if (this->plottype == 3) fXVar = CosThetaMu;
 
   return;
 };
 
 //********************************************************************
 /// @details Signal is true CCQE scattering
 ///
 /// @details Cut 1: numu event
 /// @details Cut 2: Mode == 1
 /// @details Cut 3: EnuMin < Enu < EnuMax
 bool ExpMultDist_CCQE_XSec_1DVar_FakeStudy::isSignal(FitEvent *event){
 //********************************************************************
 
   // Place cuts on each of the events here.
   // MUST be defined for all new samples, there is no default signal definition.
   // Check FitUtils and CutUtils for example cuts that can be used quickly.
 
   // During a fit isSignal is only used in the first fit function call to define
   // which of the events actually need to be considered, so don't worry too much if
   // this function is inefficient.
 
   // Mode and Enu are automatically avaialble in this function, they don't need to be set earlier.
 
   // Only look at numu events
   if ((event->PartInfo(0))->fPID != 14) return false;
 
   // Only look at CCQE Events and MEC Events
   if (Mode != 1 and Mode != 2) return false;
 
   // Restrict energy range
   if (Enu < this->EnuMin || Enu > this->EnuMax) return false;
 
   return true;
 };
 
diff --git a/src/MCStudies/ExpMultDist_CCQE_XSec_2DVar_FakeStudy.cxx b/src/MCStudies/ExpMultDist_CCQE_XSec_2DVar_FakeStudy.cxx
index 0fbb341..cc6d26d 100644
--- a/src/MCStudies/ExpMultDist_CCQE_XSec_2DVar_FakeStudy.cxx
+++ b/src/MCStudies/ExpMultDist_CCQE_XSec_2DVar_FakeStudy.cxx
@@ -1,169 +1,172 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
 #include "ExpMultDist_CCQE_XSec_2DVar_FakeStudy.h"
 
 //********************************************************************
 /// @brief Class to perform CCQE Fake Data Studies on a custom measurement
 ExpMultDist_CCQE_XSec_2DVar_FakeStudy::ExpMultDist_CCQE_XSec_2DVar_FakeStudy(std::string name, std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile){
 //********************************************************************
 
   // Measurement Details
   fName = name;
 
   // Define our energy range for flux calcs
   EnuMin = 0.;
   EnuMax = 6.;
 
   // 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.
   Measurement2D::SetupMeasurement(inputfile, type, rw, fakeDataFile);
 
   // Use the name to define what variable to measure
-  int nbinsx, nbinsy;
-  double binlowx, binhighx;
-  double binlowy, binhighy;
+  int nbinsx = 0;
+  int nbinsy = 0;
+  double binlowx = 0.0;
+  double binhighx = 0.0;
+  double binlowy = 0.0;
+  double binhighy = 0.0;
 
   if (name.find("Q2vsTmu") != std::string::npos){
     plottype = 1; fPlotTitles = "";
     nbinsx = 30; binlowx = 0.0; binhighx = 2.0;
     nbinsy = 20; binlowy = 0.0; binhighy = 3.0;
   } else if (name.find("Q2vsCos") != std::string::npos){
     plottype = 2; fPlotTitles = "";
     nbinsx = 30; binlowx = 0.0;binhighx = 2.0;
     nbinsy = 10;  binlowy = -1.0; binhighy = 1.0;
   } else if (name.find("TmuvsCos") != std::string::npos){
     plottype = 3; fPlotTitles = "";
     nbinsx = 20; binlowx = 0.0; binhighx = 3.0;
     nbinsy = 10;  binlowy = -1.0; binhighy = 1.0;
   }
 
   // Setup the datahist as empty, we will use fake data to fill it.
   this->fDataHist = new TH2D((fName + "_data").c_str(), (fName + "_data" + fPlotTitles).c_str(), nbinsx, binlowx, binhighx, nbinsy, binlowy, binhighy);
 
   // Once fDataHist is setup this function will automatically generate matching MC histograms
   this->SetupDefaultHist();
 
   double threshold = 10.0;
   for (int i = 0; i < this->fDataHist->GetNbinsX(); i++){
     for (int j = 0; j < this->fDataHist->GetNbinsY(); j++){
 
       if (fDataHist->GetBinContent(i+1,j+1) <= threshold){
 	fDataHist->SetBinError(i+1,j+1, 0.0);
 	fDataHist->SetBinContent(i+1,j+1, 0.0);
       }
     }
   }
 
 
   // Setup Covariance assuming a diagonal covar.
   // If you want a full covariance to be used examples are given in the MINERvA 2D classes
   //fFullCovar = StatUtils::MakeDiagonalCovarMatrix(fDataHist);
   //  covar     = StatUtils::GetInvert(fFullCovar);
 
 
   // 3. 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()*1E-38/(fNEvents+0.))  * (12.0 / 6.0)  /this->TotalIntegratedFlux();
 
 };
 
 
 
 //********************************************************************
 /// @details Extract Enu and totcrs from event assuming quasi-elastic scattering
 void ExpMultDist_CCQE_XSec_2DVar_FakeStudy::FillEventVariables(FitEvent *event){
 //********************************************************************
 
   // MUST be defined for each new sample.
   // This function reads in the FitEvent format and lets you grab any information you need
   // from the event. This function is only called during the first and last iteration of each fit so that
   // a vector of fXVar variables can be filled for the signal events.
 
   // Define empty variables
   fXVar = -1.0;
   fYVar = -1.0;
 
   double q2qe = 0.0;
   double CosThetaMu = -2.0;
   double TMu = 0.0;
 
   // Loop over the particle stack
   for (UInt_t j = 2; j < event->Npart(); ++j){
 
     // Look for the outgoing muon
     if ((event->PartInfo(j))->fPID != 13) continue;
 
     // Define any variables we may need
     ThetaMu     = (event->PartInfo(0))->fP.Vect().Angle((event->PartInfo(j))->fP.Vect());
 
     Enu_rec     = FitUtils::EnuQErec((event->PartInfo(j))->fP, cos(ThetaMu), 0.,true);
     q2qe        = FitUtils::Q2QErec( (event->PartInfo(j))->fP, cos(ThetaMu), 0.,true);
 
     CosThetaMu = cos(ThetaMu);
     TMu = FitUtils::T((event->PartInfo(j))->fP);
 
     // Once lepton is found, don't continue the loop
     break;
   }
 
   if (this->plottype == 1) {fXVar = q2qe; fYVar = TMu;}
   else if (this->plottype == 2) {fXVar = q2qe; fXVar = CosThetaMu;}
   else if (this->plottype == 3) {fXVar = TMu; fYVar = CosThetaMu;}
 
   return;
 };
 
 //********************************************************************
 /// @details Signal is true CCQE scattering
 ///
 /// @details Cut 1: numu event
 /// @details Cut 2: Mode == 1
 /// @details Cut 3: EnuMin < Enu < EnuMax
 bool ExpMultDist_CCQE_XSec_2DVar_FakeStudy::isSignal(FitEvent *event){
 //********************************************************************
 
   // Place cuts on each of the events here.
   // MUST be defined for all new samples, there is no default signal definition.
   // Check FitUtils and CutUtils for example cuts that can be used quickly.
 
   // During a fit isSignal is only used in the first fit function call to define
   // which of the events actually need to be considered, so don't worry too much if
   // this function is inefficient.
 
   // Mode and Enu are automatically avaialble in this function, they don't need to be set earlier.
 
   // Only look at numu events
   if ((event->PartInfo(0))->fPID != 14) return false;
 
   // Only look at CCQE Events and MEC Events
   if (Mode != 1 and Mode != 2) return false;
 
   // Restrict energy range
   if (Enu < this->EnuMin || Enu > this->EnuMax) return false;
 
   return true;
 };
 
diff --git a/src/MCStudies/GenericFlux_Tester.cxx b/src/MCStudies/GenericFlux_Tester.cxx
index fc1cffb..556fd43 100644
--- a/src/MCStudies/GenericFlux_Tester.cxx
+++ b/src/MCStudies/GenericFlux_Tester.cxx
@@ -1,559 +1,559 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
 #include "GenericFlux_Tester.h"
 
 //********************************************************************
 /// @brief Class to perform MC Studies on a custom measurement
 GenericFlux_Tester::GenericFlux_Tester(std::string name, std::string inputfile,
                                        FitWeight *rw, std::string type,
                                        std::string fakeDataFile) {
   //********************************************************************
 
   // Measurement Details
   fName = name;
   eventVariables = NULL;
 
   // Define our energy range for flux calcs
   EnuMin = 0.;
   EnuMax = 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 << endl;
+  LOG(SAM) << " Generic Flux Scaling Factor = " << fScaleFactor << std::endl;
 
   if (fScaleFactor <= 0.0) {
     ERR(WRN) << "SCALE FACTOR TOO LOW " << std::endl;
     sleep(20);
   }
 
   // Setup our TTrees
   this->AddEventVariablesToTree();
   this->AddSignalFlagsToTree();
 }
 
 void GenericFlux_Tester::AddEventVariablesToTree() {
   // Setup the TTree to save everything
   if (!eventVariables) {
     FitPar::Config().out->cd();
     eventVariables = new TTree((this->fName + "_VARS").c_str(),
                                (this->fName + "_VARS").c_str());
   }
 
-  LOG(SAM) << "Adding Event Variables" << endl;
+  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();
     eventVariables = new TTree((this->fName + "_VARS").c_str(),
                                (this->fName + "_VARS").c_str());
   }
 
-  LOG(SAM) << "Adding Samples" << endl;
+  LOG(SAM) << "Adding Samples" << std::endl;
 
   // Signal Definitions from SignalDef.cxx
   eventVariables->Branch("flagCCINC", &flagCCINC, "flagCCINC/O");
   eventVariables->Branch("flagNCINC", &flagNCINC, "flagNCINC/O");
   eventVariables->Branch("flagCCQE", &flagCCQE, "flagCCQE/O");
   eventVariables->Branch("flagCC0pi", &flagCC0pi, "flagCC0pi/O");
   eventVariables->Branch("flagCCQELike", &flagCCQELike, "flagCCQELike/O");
   eventVariables->Branch("flagNCEL", &flagNCEL, "flagNCEL/O");
   eventVariables->Branch("flagNC0pi", &flagNC0pi, "flagNC0pi/O");
   eventVariables->Branch("flagCCcoh", &flagCCcoh, "flagCCcoh/O");
   eventVariables->Branch("flagNCcoh", &flagNCcoh, "flagNCcoh/O");
   eventVariables->Branch("flagCC1pip", &flagCC1pip, "flagCC1pip/O");
   eventVariables->Branch("flagNC1pip", &flagNC1pip, "flagNC1pip/O");
   eventVariables->Branch("flagCC1pim", &flagCC1pim, "flagCC1pim/O");
   eventVariables->Branch("flagNC1pim", &flagNC1pim, "flagNC1pim/O");
   eventVariables->Branch("flagCC1pi0", &flagCC1pi0, "flagCC1pi0/O");
   eventVariables->Branch("flagNC1pi0", &flagNC1pi0, "flagNC1pi0/O");
 };
 
 //********************************************************************
 void GenericFlux_Tester::FillEventVariables(FitEvent *event) {
   //********************************************************************
 
   // Fill Signal Variables
   FillSignalFlags(event);
   LOG(DEB) << "Filling signal" << std::endl;
   // Function used to extract any variables of interest to the event
   Mode = event->Mode;
   Nleptons = 0;
   Nparticles = 0;
   PDGnu = 0;
   PDGLep = 0;
 
   Enu_true = Enu_QE = Q2_true = Q2_QE = TLep = TPr = TNe = TPiP = TPiN = TPi0 =
       -999.9;
 
   Nprotons = 0;
   PPr = EPr = MPr = CosPr = -999.9;
 
   Nneutrons = 0;
   PNe = ENe = MNe = CosNe = -999.9;
 
   Npiplus = 0;
   PPiP = EPiP = MPiP = CosPiP = -999.9;
 
   Npineg = 0;
   PPiN = EPiN = MPiN = CosPiN = -999.9;
 
   Npi0 = 0;
   PPi0 = EPi0 = MPi0 = CosPi0 = -999.9;
 
   // All of the angles Clarence added
   CosPmuPpip = CosPmuPpim = CosPmuPpi0 = CosPmuPprot = CosPmuPneut =
       CosPpipPprot = CosPpipPneut = CosPpipPpim = CosPpipPpi0 = CosPpimPprot =
           CosPpimPneut = CosPpimPpi0 = CosPi0Pprot = CosPi0Pneut =
               CosPprotPneut = -999.9;
 
   float proton_highmom = -999.9;
   float neutron_highmom = -999.9;
   float piplus_highmom = -999.9;
   float pineg_highmom = -999.9;
   float pi0_highmom = -999.9;
 
   (*nu_4mom) = event->PartInfo(0)->fP;
 
   if (!liteMode) {
     (*pmu) = TLorentzVector(0, 0, 0, 0);
     (*ppip) = TLorentzVector(0, 0, 0, 0);
     (*ppim) = TLorentzVector(0, 0, 0, 0);
     (*ppi0) = TLorentzVector(0, 0, 0, 0);
     (*pprot) = TLorentzVector(0, 0, 0, 0);
     (*pneut) = TLorentzVector(0, 0, 0, 0);
   }
 
   Enu_true = nu_4mom->E();
   PDGnu = event->PartInfo(0)->fPID;
 
   bool cc = (abs(event->Mode) < 30);
   (void)cc;
 
   // Add all pion distributions for the event.
 
   // Add classifier for CC0pi or CC1pi or CCOther
   // Save Modes Properly
   // Save low recoil measurements
 
   // Start Particle Loop
   UInt_t npart = event->Npart();
   for (UInt_t i = 0; i < npart; i++) {
     // Skip particles that weren't in the final state
     bool part_alive = event->PartInfo(i)->fIsAlive and event->PartInfo(i)->Status() == kFinalState;
     if (!part_alive) continue;
 
     // PDG Particle
     int PDGpart = event->PartInfo(i)->fPID;
     TLorentzVector part_4mom = event->PartInfo(i)->fP;
 
     Nparticles++;
 
     // Get Charged Lepton
     if (abs(PDGpart) == abs(PDGnu) - 1) {
       Nleptons++;
 
       PDGLep = PDGpart;
 
       TLep = FitUtils::T(part_4mom) * 1000.0;
       PLep = (part_4mom.Vect().Mag());
       ELep = (part_4mom.E());
       MLep = (part_4mom.Mag());
       CosLep = cos(part_4mom.Vect().Angle(nu_4mom->Vect()));
       pmu = &part_4mom;
 
       Q2_true = -1 * (part_4mom - (*nu_4mom)).Mag2();
 
       float ThetaLep = (event->PartInfo(0))
                            ->fP.Vect()
                            .Angle((event->PartInfo(i))->fP.Vect());
 
       q0_true = (part_4mom - (*nu_4mom)).E();
       q3_true = (part_4mom - (*nu_4mom)).Vect().Mag();
 
       // Get W_true with assumption of initial state nucleon at rest
       float m_n = (float)PhysConst::mass_proton * 1000.;
       W_nuc_rest = sqrt(-Q2_true + 2 * m_n * (Enu_true - ELep) + m_n * m_n);
 
       // Get the Bjorken x and y variables
       // Assume that E_had = Enu - Emu as in MINERvA
       bjorken_x = Q2_true / (2 * m_n * (Enu_true - ELep));
       bjorken_y = 1 - ELep / Enu_true;
 
       // Quasi-elastic ----------------------
       // ------------------------------------
 
       // Q2 QE Assuming Carbon Input. Should change this to be dynamic soon.
       Q2_QE =
           FitUtils::Q2QErec(part_4mom, cos(ThetaLep), 34., true) * 1000000.0;
       Enu_QE = FitUtils::EnuQErec(part_4mom, cos(ThetaLep), 34., true) * 1000.0;
 
       // Pion Production ----------------------
       // --------------------------------------
 
     } else if (PDGpart == 2212) {
       Nprotons++;
       if (part_4mom.Vect().Mag() > proton_highmom) {
         proton_highmom = part_4mom.Vect().Mag();
 
         PPr = (part_4mom.Vect().Mag());
         EPr = (part_4mom.E());
         TPr = FitUtils::T(part_4mom) * 1000.;
         MPr = (part_4mom.Mag());
         CosPr = cos(part_4mom.Vect().Angle(nu_4mom->Vect()));
 
         (*pprot) = part_4mom;
       }
     } else if (PDGpart == 2112) {
       Nneutrons++;
       if (part_4mom.Vect().Mag() > neutron_highmom) {
         neutron_highmom = part_4mom.Vect().Mag();
 
         PNe = (part_4mom.Vect().Mag());
         ENe = (part_4mom.E());
         TNe = FitUtils::T(part_4mom) * 1000.;
         MNe = (part_4mom.Mag());
         CosNe = cos(part_4mom.Vect().Angle(nu_4mom->Vect()));
 
         (*pneut) = part_4mom;
       }
     } else if (PDGpart == 211) {
       Npiplus++;
       if (part_4mom.Vect().Mag() > piplus_highmom) {
         piplus_highmom = part_4mom.Vect().Mag();
 
         PPiP = (part_4mom.Vect().Mag());
         EPiP = (part_4mom.E());
         TPiP = FitUtils::T(part_4mom) * 1000.;
         MPiP = (part_4mom.Mag());
         CosPiP = cos(part_4mom.Vect().Angle(nu_4mom->Vect()));
 
         (*ppip) = part_4mom;
       }
     } else if (PDGpart == -211) {
       Npineg++;
       if (part_4mom.Vect().Mag() > pineg_highmom) {
         pineg_highmom = part_4mom.Vect().Mag();
 
         PPiN = (part_4mom.Vect().Mag());
         EPiN = (part_4mom.E());
         TPiN = FitUtils::T(part_4mom) * 1000.;
         MPiN = (part_4mom.Mag());
         CosPiN = cos(part_4mom.Vect().Angle(nu_4mom->Vect()));
 
         (*ppim) = part_4mom;
       }
     } else if (PDGpart == 111) {
       Npi0++;
       if (part_4mom.Vect().Mag() > pi0_highmom) {
         pi0_highmom = part_4mom.Vect().Mag();
 
         PPi0 = (part_4mom.Vect().Mag());
         EPi0 = (part_4mom.E());
         TPi0 = FitUtils::T(part_4mom) * 1000.;
         MPi0 = (part_4mom.Mag());
         CosPi0 = cos(part_4mom.Vect().Angle(nu_4mom->Vect()));
 
         (*ppi0) = part_4mom;
       }
     } else {
       Nother++;
     }
   }
 
   // Get Recoil Definitions ------
   // -----------------------------
   Erecoil_true = FitUtils::GetErecoil_TRUE(event);
   Erecoil_charged = FitUtils::GetErecoil_CHARGED(event);
   Erecoil_minerva = FitUtils::GetErecoil_MINERvA_LowRecoil(event);
 
   // Do the angles between final state particles
   if (Nleptons > 0 && Npiplus > 0)
     CosPmuPpip = cos(pmu->Vect().Angle(ppip->Vect()));
   if (Nleptons > 0 && Npineg > 0)
     CosPmuPpim = cos(pmu->Vect().Angle(ppim->Vect()));
   if (Nleptons > 0 && Npi0 > 0)
     CosPmuPpi0 = cos(pmu->Vect().Angle(ppi0->Vect()));
   if (Nleptons > 0 && Nprotons > 0)
     CosPmuPprot = cos(pmu->Vect().Angle(pprot->Vect()));
   if (Nleptons > 0 && Nneutrons > 0)
     CosPmuPneut = cos(pmu->Vect().Angle(pneut->Vect()));
 
   if (Npiplus > 0 && Nprotons > 0)
     CosPpipPprot = cos(ppip->Vect().Angle(pprot->Vect()));
   if (Npiplus > 0 && Nneutrons > 0)
     CosPpipPneut = cos(ppip->Vect().Angle(pneut->Vect()));
   if (Npiplus > 0 && Npineg > 0)
     CosPpipPpim = cos(ppip->Vect().Angle(ppim->Vect()));
   if (Npiplus > 0 && Npi0 > 0)
     CosPpipPpi0 = cos(ppip->Vect().Angle(ppi0->Vect()));
 
   if (Npineg > 0 && Nprotons > 0)
     CosPpimPprot = cos(ppim->Vect().Angle(pprot->Vect()));
   if (Npineg > 0 && Nneutrons > 0)
     CosPpimPneut = cos(ppim->Vect().Angle(pneut->Vect()));
   if (Npineg > 0 && Npi0 > 0)
     CosPpimPpi0 = cos(ppim->Vect().Angle(ppi0->Vect()));
 
   if (Npi0 > 0 && Nprotons > 0)
     CosPi0Pprot = cos(ppi0->Vect().Angle(pprot->Vect()));
   if (Npi0 > 0 && Nneutrons > 0)
     CosPi0Pneut = cos(ppi0->Vect().Angle(pneut->Vect()));
 
   if (Nprotons > 0 && Nneutrons > 0)
     CosPprotPneut = cos(pprot->Vect().Angle(pneut->Vect()));
 
   // Event Weights ----
   // ------------------
   Weight = event->RWWeight * event->InputWeight;
   RWWeight = event->RWWeight;
   InputWeight = event->InputWeight;
   FluxWeight =
       GetFluxHistogram()->GetBinContent(GetFluxHistogram()->FindBin(Enu)) / GetFluxHistogram()->Integral();
 
   xsecScaling = fScaleFactor;
 
   if (fScaleFactor <= 0.0) {
     ERR(WRN) << "SCALE FACTOR TOO LOW " << std::endl;
     sleep(20);
   }
 
   // Fill the eventVariables Tree
   eventVariables->Fill();
   return;
 };
 
 //********************************************************************
 void GenericFlux_Tester::Write(std::string drawOpt) {
   //********************************************************************
 
   // First save the TTree
   eventVariables->Write();
 
   // Save Flux and Event Histograms too
   GetInput()->GetFluxHistogram()->Write();
   GetInput()->GetEventHistogram()->Write();
 
   return;
 }
 
 //********************************************************************
 void GenericFlux_Tester::FillSignalFlags(FitEvent *event) {
   //********************************************************************
 
   // Some example flags are given from SignalDef.
   // See src/Utils/SignalDef.cxx for more.
   int nuPDG = event->PartInfo(0)->fPID;
 
   // Generic signal flags
   flagCCINC = SignalDef::isCCINC(event, nuPDG);
   flagNCINC = SignalDef::isNCINC(event, nuPDG);
   flagCCQE = SignalDef::isCCQE(event, nuPDG);
   flagCCQELike = SignalDef::isCCQELike(event, nuPDG);
   flagCC0pi = SignalDef::isCC0pi(event, nuPDG);
   flagNCEL = SignalDef::isNCEL(event, nuPDG);
   flagNC0pi = SignalDef::isNC0pi(event, nuPDG);
   flagCCcoh = SignalDef::isCCCOH(event, nuPDG, 211);
   flagNCcoh = SignalDef::isNCCOH(event, nuPDG, 111);
   flagCC1pip = SignalDef::isCC1pi(event, nuPDG, 211);
   flagNC1pip = SignalDef::isNC1pi(event, nuPDG, 211);
   flagCC1pim = SignalDef::isCC1pi(event, nuPDG, -211);
   flagNC1pim = SignalDef::isNC1pi(event, nuPDG, -211);
   flagCC1pi0 = SignalDef::isCC1pi(event, nuPDG, 111);
   flagNC1pi0 = SignalDef::isNC1pi(event, nuPDG, 111);
 }
 
 // -------------------------------------------------------------------
 // Purely MC Plot
 // Following functions are just overrides to handle this
 // -------------------------------------------------------------------
 //********************************************************************
 /// Everything is classed as signal...
 bool GenericFlux_Tester::isSignal(FitEvent *event) {
   //********************************************************************
   (void)event;
   return true;
 };
 
 //********************************************************************
 void GenericFlux_Tester::ScaleEvents() {
   //********************************************************************
   // Saving everything to a TTree so no scaling required
   return;
 }
 
 //********************************************************************
 void GenericFlux_Tester::ApplyNormScale(float norm) {
   //********************************************************************
 
   // Saving everything to a TTree so no scaling required
   this->fCurrentNorm = norm;
   return;
 }
 
 //********************************************************************
 void GenericFlux_Tester::FillHistograms() {
   //********************************************************************
   // No Histograms need filling........
   return;
 }
 
 //********************************************************************
 void GenericFlux_Tester::ResetAll() {
   //********************************************************************
   eventVariables->Reset();
   return;
 }
 
 //********************************************************************
 float GenericFlux_Tester::GetChi2() {
   //********************************************************************
   // No Likelihood to test, purely MC
   return 0.0;
 }
diff --git a/src/MCStudies/T2K2017_FakeData.cxx b/src/MCStudies/T2K2017_FakeData.cxx
index b219ef1..6ef7186 100644
--- a/src/MCStudies/T2K2017_FakeData.cxx
+++ b/src/MCStudies/T2K2017_FakeData.cxx
@@ -1,243 +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 <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
 #include "T2K2017_FakeData.h"
 
 //********************************************************************
 /// @brief Class to perform MC Studies on a custom measurement
 T2K2017_FakeData::T2K2017_FakeData(nuiskey samplekey) {
 //********************************************************************
 
   // Sample overview ---------------------------------------------------
   std::string descrip = "T2K2017 Event Kinematics MC Study \n" \
                         "Target: CH/H2O \n" \
                         "Flux: T2K numu flux \n" \
                         "Signal: numuCC \n";
 
   // Setup common settings
   fSettings = LoadSampleSettings(samplekey);
 
   fSettings.SetTitle("T2K MC #nu_{#mu} CC");
   fSettings.SetDescription(descrip);
   fSettings.SetEnuRange(0.0, 6.0);
   fSettings.DefineAllowedTargets("H,C,O");
   fSettings.DefineAllowedSpecies("numu");
 
   FinaliseSampleSettings();
 
   // Scaling Setup ---------------------------------------------------
   fScaleFactor = GetEventHistogram()->Integral("width") * 1E-38 / (fNEvents + 0.) / TotalIntegratedFlux();
 
   // Setup some MC Histograms
   const int nbin_x = 14;
   const double binedge_x[15] = {0., 300., 400., 500., 600., 700., 800., 900., 1000., 1250., 1500., 2000., 3000., 5000., 30000.};
   const int nbin_y = 10;
   const double binedge_y[11] = { -1, 0.6, 0.7, 0.8, 0.85, 0.9, 0.92, 0.94, 0.96, 0.98, 1.};
 
   fMCHist_FGD1NuMuCC0Pi = new TH2D((fName + "_FGD1NuMuCC0Pi_MC").c_str(),
                                    (fName + "_FGD1NuMuCC0Pi_MC").c_str(),
                                    nbin_x, binedge_x, nbin_y, binedge_y);
 
   fMCHistPDG_FGD1NuMuCC0Pi = new TrueModeStack((fName + "_FGD1NuMuCC0Pi_MC_PDG").c_str(),
       (fName + "_FGD1NuMuCC0Pi_MC_PDG").c_str(),
       fMCHist_FGD1NuMuCC0Pi);
 
   fMCFine_FGD1NuMuCC0Pi = new TH2D((fName + "_FGD1NuMuCC0Pi_MC_FINE").c_str(),
                                    (fName + "_FGD1NuMuCC0Pi_MC_FINE").c_str(),
                                    40, 0., 1000., 40, -1., 1.);
 
   fMCFinePDG_FGD1NuMuCC0Pi = new TrueModeStack((fName + "_FGD1NuMuCC0Pi_MC_FINE_PDG").c_str(),
       (fName + "_FGD1NuMuCC0Pi_MC_FINE_PDG").c_str(),
       fMCFine_FGD1NuMuCC0Pi);
 
   SetAutoProcessTH1(fMCHist_FGD1NuMuCC0Pi);
   SetAutoProcessTH1(fMCHistPDG_FGD1NuMuCC0Pi);
   SetAutoProcessTH1(fMCFine_FGD1NuMuCC0Pi);
   SetAutoProcessTH1(fMCFinePDG_FGD1NuMuCC0Pi);
 
   // Setup TTree to Save -------------------------------------------
   SetEmptyData();
 
   if (samplekey.Has("saveflattree")) {
     fSaveEventTree = samplekey.GetI("saveflattree") > 0;
   } else {
     fSaveEventTree = false;
   }
 
 
   if (fSaveEventTree) {
     fEventTree = new TTree("EventTree", "EventTree");
     fEventTree->Branch("Enu", &fEnu, "Enu/D");
 
     fEventTree->Branch("Tmu", &fTMu, "Tmu/D");
     fEventTree->Branch("Cosmu", &fCosMu, "Cosmu/D");
 
     fEventTree->Branch("Ppip", &fPPip, "Ppip/D");
     fEventTree->Branch("Cospip", &fCosPip, "Cospip/D");
     fEventTree->Branch("Ppim", &fPPim, "Ppim/D");
     fEventTree->Branch("Cospim", &fCosPim, "Cospim/D");
     fEventTree->Branch("Ppi0", &fPPi0, "Ppi0/D");
     fEventTree->Branch("Cospi0", &fCosPi0, "Cospi0/D");
 
     fEventTree->Branch("Mode", &fMode, "Mode/I");
     fEventTree->Branch("NuPDG", &fNuPDG, "NuPDG/I");
     fEventTree->Branch("ScaleFactor", &fScaleFactor, "ScaleFactor/D");
   }
 
   // Final setup  ---------------------------------------------------
   FinaliseMeasurement();
 
 };
 
 //********************************************************************
 void T2K2017_FakeData::FillEventVariables(FitEvent *event) {
 //********************************************************************
 
   // Reset Variables
   fEnu    = -999.9;
 
   fTMu    = -999.9;
   fCosMu  = -999.9;
 
   fPPip   = -999.9;
   fCosPip = -999.9;
   fPPim   = -999.9;
   fCosPim = -999.9;
   fPPi0   = -999.9;
   fCosPi0 = -999.9;
 
   fMode  = 0;
   fNuPDG = 0;
 
   // Get neutrino information
   if (abs(event->PDGnu()) != 14) return;
   FitParticle* nu = event->GetNeutrinoIn();
   fEnu = nu->fP.E();
 
 
   // Get Muon Information
   if ((event->NumFSParticle(13) +
        event->NumFSParticle(-13)) < 1) { return; }
 
-  FitParticle* muon;
+  FitParticle* muon = NULL;
   if (nu->fPID == 14) {
     muon = event->GetHMFSParticle(13);
   } else if (nu->fPID == -14) {
     muon = event->GetHMFSParticle(-13);
   }
   fTMu = FitUtils::T(muon->fP) * 1.E3;
   fCosMu = cos(muon->fP.Vect().Angle(nu->fP.Vect()));
 
 
 
   // Get Pion+ Information
   if (event->NumFSParticle(211) >= 1) {
 
     FitParticle* pionp = event->GetHMFSParticle(211);
     fPPip   = pionp->fP.Vect().Mag();
     fCosPip = cos(pionp->fP.Vect().Angle(nu->fP.Vect()));
 
   }
 
   // Get Pion- Information
   if (event->NumFSParticle(-211) >= 1) {
 
     FitParticle* pionm = event->GetHMFSParticle(-211);
     fPPim   = pionm->fP.Vect().Mag();
     fCosPim = cos(pionm->fP.Vect().Angle(nu->fP.Vect()));
 
   }
 
   // Get Pion0 Information
   if (event->NumFSParticle(111) >= 1) {
 
     FitParticle* pion0 = event->GetHMFSParticle(111);
     fPPi0   = pion0->fP.Vect().Mag();
     fCosPi0 = cos(pion0->fP.Vect().Angle(nu->fP.Vect()));
 
   }
 
 
   return;
 };
 
 //********************************************************************
 void T2K2017_FakeData::Write(std::string drawOpt) {
 //********************************************************************
   if (fSaveEventTree) {
     fEventTree->Write();
   }
 
   fMCHist_FGD1NuMuCC0Pi->Write();
   fMCHistPDG_FGD1NuMuCC0Pi->Write();
 
   fMCFine_FGD1NuMuCC0Pi->Write();
   fMCFinePDG_FGD1NuMuCC0Pi->Write();
 
 
   return;
 }
 
 // -------------------------------------------------------------------
 // Purely MC Plot
 // Following functions are just overrides to handle this
 // -------------------------------------------------------------------
 //********************************************************************
 /// Everything is classed as signal...
 bool T2K2017_FakeData::isSignal(FitEvent *event) {
 //********************************************************************
 
   if (abs(event->PDGnu()) != 14) return false;
   if ((event->NumFSParticle(13) +
        event->NumFSParticle(-13)) < 1) { return false; }
 
   return true;
 };
 
 
 //********************************************************************
 void T2K2017_FakeData::FillHistograms() {
 //********************************************************************
 
   fMCHist_FGD1NuMuCC0Pi->Fill(fTMu, fCosMu, Weight);
   fMCHistPDG_FGD1NuMuCC0Pi->Fill(Mode, fTMu, fCosMu, Weight);
 
   fMCFine_FGD1NuMuCC0Pi->Fill(fTMu, fCosMu, Weight);
   fMCFinePDG_FGD1NuMuCC0Pi->Fill(Mode, fTMu, fCosMu, Weight);
 
   return;
 }
 
 //********************************************************************
 void T2K2017_FakeData::ResetAll() {
   //********************************************************************
   Measurement1D::ResetAll();
 
   if (fSaveEventTree) {
     fEventTree->Reset();
   }
   return;
 }
 
 //********************************************************************
 float T2K2017_FakeData::GetChi2() {
   //********************************************************************
   // No Likelihood to test, purely MC
   return 0.0;
 }
diff --git a/src/MINERvA/CMakeLists.txt b/src/MINERvA/CMakeLists.txt
index e23572d..c8b8028 100644
--- a/src/MINERvA/CMakeLists.txt
+++ b/src/MINERvA/CMakeLists.txt
@@ -1,129 +1,131 @@
 # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 ################################################################################
 #    This file is part of NUISANCE.
 #
 #    NUISANCE is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
 #    (at your option) any later version.
 #
 #    NUISANCE is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #    GNU General Public License for more details.
 #
 #    You should have received a copy of the GNU General Public License
 #    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 ################################################################################
 set(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_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_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_CC0pi_XSec_1DQ2_Tgt_nu.cxx
 MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu.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_CC0pi_XSec_1DQ2_Tgt_nu.h
 MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu.h
 
 MINERvA_SignalDef.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(${RWENGINE_INCLUDE_DIRECTORIES})
 
 include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
+include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler)
+include_directories(${CMAKE_SOURCE_DIR}/src/Genie)
 include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
 include_directories(${CMAKE_SOURCE_DIR}/src/Reweight)
 include_directories(${CMAKE_SOURCE_DIR}/src/Splines)
 
 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/MINERvA/MINERvA_CC0pi_XSec_1DQ2_Tgt_nu.cxx b/src/MINERvA/MINERvA_CC0pi_XSec_1DQ2_Tgt_nu.cxx
index 89470f9..61ef849 100644
--- a/src/MINERvA/MINERvA_CC0pi_XSec_1DQ2_Tgt_nu.cxx
+++ b/src/MINERvA/MINERvA_CC0pi_XSec_1DQ2_Tgt_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 <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
 #include <string>
 #include <sstream>
 
 #include "MINERvA_SignalDef.h"
 #include "MINERvA_CC0pi_XSec_1DQ2_Tgt_nu.h"
 
 //********************************************************************
 MINERvA_CC0pi_XSec_1DQ2_Tgt_nu::MINERvA_CC0pi_XSec_1DQ2_Tgt_nu(nuiskey samplekey) {
 //********************************************************************
 
   // Sample overview ---------------------------------------------------
   std::string descrip = "MINERvA_CC0pi_XSec_1DQ2_Tgt_nu sample. \n" \
     "Target: Either C, CH, Fe, Pb \n"						    \
-    "Flux: MINERvA Forward Horn numu \n";
+    "Flux: MINERvA Forward Horn 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} (cm^{2}/GeV^{2})");
   fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG/NORM", "FIX/DIAG");
   fSettings.SetEnuRange(0.0, 100.0);
   fSettings.DefineAllowedTargets("C,H");
 
   // CCQELike plot information
   fSettings.SetTitle("MINERvA_CC0pi_XSec_1DQ2_Tgt_nu");
   fSettings.DefineAllowedSpecies("numu");
 
 
   // Set Target From name
   if (fSettings.Found("name","_CH")){
     fTarget = 1; // kTargetCH;
     fSettings.SetDataInput(  FitPar::GetDataBase() + "/MINERvA/CC0pi/Q2_Tgt_CH_data.txt");
   } else if (fSettings.Found("name","TgtC")){
     fTarget = 2; //kTargetC;
     fSettings.SetDataInput(  FitPar::GetDataBase() + "/MINERvA/CC0pi/Q2_Tgt_C_data.txt");
     fSettings.SetCovarInput(  FitPar::GetDataBase() + "/MINERvA/CC0pi/Q2_Tgt_C_covar.txt");
   }  else if (fSettings.Found("name","TgtFe")){
     fTarget = 3; //kTargetFe;
     fSettings.SetDataInput(  FitPar::GetDataBase() + "/MINERvA/CC0pi/Q2_Tgt_Fe_data.txt");
     fSettings.SetCovarInput(  FitPar::GetDataBase() + "/MINERvA/CC0pi/Q2_Tgt_Fe_covar.txt");
   } else if (fSettings.Found("name","TgtPb")){
     fTarget = 4; //kTargetPb;
     fSettings.SetDataInput(  FitPar::GetDataBase() + "/MINERvA/CC0pi/Q2_Tgt_Pb_data.txt");
     fSettings.SetCovarInput(  FitPar::GetDataBase() + "/MINERvA/CC0pi/Q2_Tgt_Pb_covar.txt");
   } else {
     ERR(FTL) << "Target not found in name! " << std::endl;
     throw;
   }
 
 
   FinaliseSampleSettings();
 
   // Scaling Setup ---------------------------------------------------
   // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
   fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38/(fNEvents+0.))/TotalIntegratedFlux();
 
   // Plot Setup -------------------------------------------------------
   SetDataFromTextFile( fSettings.GetDataInput() );
   if (fTarget == 1){
     SetCovarFromDiagonal(fDataHist);
   } else {
     SetCorrelationFromTextFile(fSettings.GetCovarInput() );
   }
 
   // Final setup  ---------------------------------------------------
   FinaliseMeasurement();
 
 };
 
 void MINERvA_CC0pi_XSec_1DQ2_Tgt_nu::FillEventVariables(FitEvent *event){
 
   // Has NuMuCC1p
   if (event->HasISNuMuon() &&
       event->HasFSMuon() &&
       event->HasFSProton()){
 
     TLorentzVector pnu    = event->GetHMISNuMuon()->fP;
     TLorentzVector pprot  = event->GetHMFSProton()->fP;
     TLorentzVector pmu    = event->GetHMFSMuon()->fP;
 
     // Q2QE rec from leading proton assuming 34 MeV Eb
     double protmax = pprot.E();
     double q2qe    = FitUtils::ProtonQ2QErec(protmax, 34.);
 
     // Coplanar is angle between muon and proton plane
     TVector3 plnprotnu = pprot.Vect().Cross(pnu.Vect());
     TVector3 plnmunu   = pmu.Vect().Cross(pnu.Vect());
     double copl        = plnprotnu.Angle(plnmunu);
 
     // Fill X Variables
     fXVar = q2qe;
 
     // Save Coplanar into spare y variable
     fYVar = copl;
   }
 
   return;
 };
 
 
 bool MINERvA_CC0pi_XSec_1DQ2_Tgt_nu::isSignal(FitEvent *event){
 
   // IS NuMu + FS Muon
   if (!event->HasISNuMuon()) return false;
   if (!event->HasFSMuon()) return false;
 
   // No Pions
   if (!SignalDef::isCC0pi(event, 14, EnuMin, EnuMax)) return false;
 
   // Proton Threshold
   if (!SignalDef::HasProtonMomAboveThreshold(event, 450.0)){
     return false;
   }
 
   return true;
 };
diff --git a/src/MINERvA/MINERvA_CCQE_XSec_1DQ2_nu.cxx b/src/MINERvA/MINERvA_CCQE_XSec_1DQ2_nu.cxx
index 1dbf931..ff49990 100644
--- a/src/MINERvA/MINERvA_CCQE_XSec_1DQ2_nu.cxx
+++ b/src/MINERvA/MINERvA_CCQE_XSec_1DQ2_nu.cxx
@@ -1,148 +1,149 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
 #include "MINERvA_SignalDef.h"
 #include "MINERvA_CCQE_XSec_1DQ2_nu.h"
 
 //********************************************************************
 MINERvA_CCQE_XSec_1DQ2_nu::MINERvA_CCQE_XSec_1DQ2_nu(nuiskey samplekey) {
 //********************************************************************
 
   // Sample overview ---------------------------------------------------
   std::string descrip = "MINERvA_CCQE_XSec_1DQ2_nu sample. \n" \
                         "Target: CH \n" \
                         "Flux: MINERvA Forward Horn Current Numu \n" \
                         "Signal: True CCQE/2p2h defined at the vertex level \n";
 
   // Setup common 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,FULL/NORM/MASK", "FIX/FULL");
   fSettings.SetEnuRange(1.5, 10.0);
   fSettings.DefineAllowedTargets("C,H");
 
   isFluxFix      = !fSettings.Found("name", "_oldflux");
   fullphasespace = !fSettings.Found("name", "_20deg");
 
   // CCQELike plot information
   fSettings.SetTitle("MINERvA_CCQE_XSec_1DQ2_nu");
 
   std::string basedir = FitPar::GetDataBase() + "/MINERvA/CCQE/";
   std::string datafilename  = "";
   std::string covarfilename = "";
 
   // Full Phase Space
   if (fullphasespace) {
 
     if (isFluxFix) {
       if (fIsShape) {
         ERR(WRN) << "SHAPE likelihood comparison not available for MINERvA "
                  << "datasets with fixed flux information. NUISANCE will scale MC to match "
                  << "data normalization but full covariance will be used. " << std::endl;
       }
       datafilename  = "Q2QE_numu_data_fluxfix.txt";
       covarfilename = "Q2QE_numu_covar_fluxfix.txt";
 
     } else {
       if (fIsShape) {
         datafilename  = "Q2QE_numu_data_SHAPE-extracted.txt";
         covarfilename = "Q2QE_numu_covar_SHAPE-extracted.txt";
       } else {
         datafilename  = "Q2QE_numu_data.txt";
         covarfilename = "Q2QE_numu_covar.txt";
       }
     }
 
     // Restricted Phase Space
   } else {
     if (isFluxFix) {
       if (fIsShape) {
         ERR(WRN) << "SHAPE likelihood comparison not available for MINERvA "
                  << "datasets with fixed flux information. NUISANCE will scale MC to match "
                  << "data normalization but full covariance will be used. " << std::endl;
       }
       datafilename  = "20deg_Q2QE_numu_data_fluxfix.txt";
       covarfilename = "20deg_Q2QE_numu_covar_fluxfix.txt";
 
     } else {
       if (fIsShape) {
         datafilename  = "20deg_Q2QE_numu_data_SHAPE-extracted.txt";
         covarfilename = "20deg_Q2QE_numu_covar_SHAPE-extracted.txt";
       } else {
         datafilename  = "20deg_Q2QE_numu_data.txt";
         covarfilename = "20deg_Q2QE_numu_covar.txt";
       }
     }
   }
 
   fSettings.SetDataInput(  basedir + datafilename );
   fSettings.SetCovarInput( basedir + covarfilename );
   fSettings.DefineAllowedSpecies("numu");
 
   FinaliseSampleSettings();
 
   // Scaling Setup ---------------------------------------------------
   // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
   fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38 * 13.0 / 6.0 / (fNEvents + 0.)) / TotalIntegratedFlux();
 
   // Plot Setup -------------------------------------------------------
   SetDataFromTextFile( fSettings.GetDataInput() );
 
   if (!isFluxFix or !fullphasespace){ 
     SetCorrelationFromTextFile( fSettings.GetCovarInput() );
     ScaleCovar(1E76);
   } else {
     SetCovarFromTextFile( fSettings.GetCovarInput() );
   }
 
   // Final setup  ---------------------------------------------------
   FinaliseMeasurement();
 
 };
 
 
 
 //********************************************************************
 void MINERvA_CCQE_XSec_1DQ2_nu::FillEventVariables(FitEvent *event) {
 //********************************************************************
 
   if (event->NumFSParticle(13) == 0)
     return;
 
   TLorentzVector Pnu  = event->GetNeutrinoIn()->fP;
   TLorentzVector Pmu  = event->GetHMFSParticle(13)->fP;
 
   double ThetaMu  = Pnu.Vect().Angle(Pmu.Vect());
   double q2qe     = FitUtils::Q2QErec(Pmu, cos(ThetaMu), 34., true);
 
   // Set binning variable
   fXVar = q2qe;
+
   return;
 }
 
 
 
 //********************************************************************
 bool MINERvA_CCQE_XSec_1DQ2_nu::isSignal(FitEvent *event) {
 //*******************************************************************
   return SignalDef::isCCQEnumu_MINERvA(event, EnuMin, EnuMax, fullphasespace);
 }
 
diff --git a/src/MiniBooNE/CMakeLists.txt b/src/MiniBooNE/CMakeLists.txt
index 3e95124..256f82f 100644
--- a/src/MiniBooNE/CMakeLists.txt
+++ b/src/MiniBooNE/CMakeLists.txt
@@ -1,100 +1,102 @@
 # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 ################################################################################
 #    This file is part of NUISANCE.
 #
 #    NUISANCE is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
 #    (at your option) any later version.
 #
 #    NUISANCE is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #    GNU General Public License for more details.
 #
 #    You should have received a copy of the GNU General Public License
 #    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 ################################################################################
 set(IMPLFILES
 MiniBooNE_CC1pi0_XSec_1Dcosmu_nu.cxx
 MiniBooNE_CC1pip_XSec_2DTpiCospi_nu.cxx
 MiniBooNE_CC1pi0_XSec_1Dcospi0_nu.cxx
 MiniBooNE_CC1pip_XSec_2DTpiEnu_nu.cxx
 MiniBooNE_CC1pi0_XSec_1DEnu_nu.cxx
 MiniBooNE_CC1pip_XSec_2DTuCosmu_nu.cxx
 MiniBooNE_CC1pi0_XSec_1Dppi0_nu.cxx
 MiniBooNE_CC1pip_XSec_2DTuEnu_nu.cxx
 MiniBooNE_CC1pi0_XSec_1DQ2_nu.cxx
 MiniBooNE_CCQE_XSec_1DQ2_antinu.cxx
 MiniBooNE_CC1pi0_XSec_1DTu_nu.cxx
 MiniBooNE_CC1pip_XSec_1DEnu_nu.cxx
 MiniBooNE_CCQE_XSec_1DQ2_nu.cxx
 MiniBooNE_CC1pip_XSec_1DQ2_nu.cxx
 MiniBooNE_CCQE_XSec_2DTcos_antinu.cxx
 MiniBooNE_CC1pip_XSec_1DTpi_nu.cxx
 MiniBooNE_CCQE_XSec_2DTcos_nu.cxx
 MiniBooNE_CC1pip_XSec_1DTu_nu.cxx
 MiniBooNE_NCEL_XSec_Treco_nu.cxx
 MiniBooNE_CC1pip_XSec_2DQ2Enu_nu.cxx
 MiniBooNE_NC1pi0_XSec_1Dppi0_nu.cxx
 MiniBooNE_NC1pi0_XSec_1Dcospi0_nu.cxx
 MiniBooNE_NC1pi0_XSec_1Dppi0_antinu.cxx
 MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu.cxx
 )
 
 set(HEADERFILES
 MiniBooNE_CC1pi0_XSec_1Dcosmu_nu.h
 MiniBooNE_CC1pip_XSec_2DTpiCospi_nu.h
 MiniBooNE_CC1pi0_XSec_1Dcospi0_nu.h
 MiniBooNE_CC1pip_XSec_2DTpiEnu_nu.h
 MiniBooNE_CC1pi0_XSec_1DEnu_nu.h
 MiniBooNE_CC1pip_XSec_2DTuCosmu_nu.h
 MiniBooNE_CC1pi0_XSec_1Dppi0_nu.h
 MiniBooNE_CC1pip_XSec_2DTuEnu_nu.h
 MiniBooNE_CC1pi0_XSec_1DQ2_nu.h
 MiniBooNE_CCQE_XSec_1DQ2_antinu.h
 MiniBooNE_CC1pi0_XSec_1DTu_nu.h
 MiniBooNE_CC1pip_XSec_1DEnu_nu.h
 MiniBooNE_CCQE_XSec_1DQ2_nu.h
 MiniBooNE_CC1pip_XSec_1DQ2_nu.h
 MiniBooNE_CCQE_XSec_2DTcos_antinu.h
 MiniBooNE_CC1pip_XSec_1DTpi_nu.h
 MiniBooNE_CCQE_XSec_2DTcos_nu.h
 MiniBooNE_CC1pip_XSec_1DTu_nu.h
 MiniBooNE_NCEL_XSec_Treco_nu.h
 MiniBooNE_CC1pip_XSec_2DQ2Enu_nu.h
 MiniBooNE_NC1pi0_XSec_1Dppi0_nu.h
 MiniBooNE_NC1pi0_XSec_1Dcospi0_nu.h
 MiniBooNE_NC1pi0_XSec_1Dppi0_antinu.h
 MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu.h
 MiniBooNE_Boxes.h
 )
 
 set(LIBNAME expMiniBooNE)
 
 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(${RWENGINE_INCLUDE_DIRECTORIES})
 
 include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
+include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler)
+include_directories(${CMAKE_SOURCE_DIR}/src/Genie)
 include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
 include_directories(${CMAKE_SOURCE_DIR}/src/Reweight)
 include_directories(${CMAKE_SOURCE_DIR}/src/Splines)
 
 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/MiniBooNE/SampleSettings.h b/src/MiniBooNE/SampleSettings.h
index b5d8474..80b9fea 100644
--- a/src/MiniBooNE/SampleSettings.h
+++ b/src/MiniBooNE/SampleSettings.h
@@ -1,46 +1,46 @@
 #ifndef SAMPLESETTINGS_H
 #define SAMPLESETTINGS_H
 #include "NuisConfig.h"
 #include "NuisKey.h"
 #include "TH1D.h"
 #include "BeamUtils.h"
 class SampleSettings {
 public:
 	SampleSettings();
 	SampleSettings(nuiskey key);
 
 	inline std::string Name(){return GetName();};
 	std::string GetName();
 	void SetS(std::string name, std::string val);
 	void SetXTitle(std::string name);
 	void SetYTitle(std::string name);
 	void SetAllowedTypes(std::string allowed, std::string defaulttype="FIX");
 	void SetEnuRangeFromFlux(TH1D* fluxhist);
 	void SetEnuRange(double min, double max);
 	std::string Title();
 	void DefineAllowedTargets(std::string targ);
 
 	void FoundFill(std::string name, std::string substr, bool& cont, bool def);
 	void SetTitle(std::string val);
 	void SetDataInput(std::string val);
 	void SetCovarInput(std::string val);
 
 	void SetDefault(std::string name, std::string val);
 	void SetDefault(std::string name, double val);
 	void SetHasExtraHistograms(bool opt = true);
 	void DefineAllowedSpecies(std::string species);
 
 	bool Has(std::string name){return fKeyValues.Has(name);};
 
 	std::string GetDataInput();
 	std::string PlotTitles();
 	std::string GetS(std::string name);
 
 
 	std::vector<int> fAllowedTargets;
 	std::vector<int> fAllowedSpecies;
   	nuiskey fKeyValues;
   	bool fHasExtraHistograms;
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Reweight/CMakeLists.txt b/src/Reweight/CMakeLists.txt
index b559f48..dafd285 100644
--- a/src/Reweight/CMakeLists.txt
+++ b/src/Reweight/CMakeLists.txt
@@ -1,82 +1,84 @@
 # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 ################################################################################
 #    This file is part of NUISANCE.
 #
 #    NUISANCE is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
 #    (at your option) any later version.
 #
 #    NUISANCE is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #    GNU General Public License for more details.
 #
 #    You should have received a copy of the GNU General Public License
 #    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 ################################################################################
 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
 )
 
 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
 )
 
 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(${RWENGINE_INCLUDE_DIRECTORIES})
 
 include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
+include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler)
+include_directories(${CMAKE_SOURCE_DIR}/src/Genie)
 include_directories(${CMAKE_SOURCE_DIR}/src/Splines)
 include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
 include_directories(${CMAKE_CURRENT_SOURCE_DIR})
 
 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.h b/src/Reweight/FitWeight.h
index 5a77f46..20ecde0 100644
--- a/src/Reweight/FitWeight.h
+++ b/src/Reweight/FitWeight.h
@@ -1,72 +1,72 @@
 #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 <map>
 #include <vector>
 
 class FitWeight {
 public:
   FitWeight(std::string name = "") {};
 
   // Add a new RW engine given type
   void AddRWEngine(int rwtype);
 
   // 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);
 
   void SetAllDials(const double* x, int n);
 
   double GetSampleNorm(std::string name);
 
   void UpdateWeightEngine(const double* x);
 
   inline std::vector<int> GetDialEnums() { return fEnumList; };
   inline std::vector<std::string> GetDialNames() { return fNameList; };
   inline std::vector<double> GetDialValues() { return fValueList; };
   void GetAllDials(double* x, int n);
 
   void Print();
 
   std::vector<int> fEnumList;
   std::vector<std::string> fNameList;
   std::vector<double> fValueList;
 
   std::map<std::string, int> fAllEnums;
   std::map<int, double> fAllValues;
   std::map<int, WeightEngineBase*> fAllRW;
 
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Reweight/GENIEWeightEngine.cxx b/src/Reweight/GENIEWeightEngine.cxx
index e50c24e..2a2e73f 100644
--- a/src/Reweight/GENIEWeightEngine.cxx
+++ b/src/Reweight/GENIEWeightEngine.cxx
@@ -1,178 +1,178 @@
 #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 << endl;
+	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;
 
 	// 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_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 (xsec_dis)
 		fGenieRW->AdoptWghtCalc("xsec_dis", new genie::rew::GReWeightNuXSecDIS);
 	if (xsec_nc)
 		fGenieRW->AdoptWghtCalc("xsec_nc", new genie::rew::GReWeightNuXSecNC);
 	if (xsec_ccres)
 		fGenieRW->AdoptWghtCalc("xsec_ccres", new genie::rew::GReWeightNuXSecCCRES);
 	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<GReWeightNuXSecCCQE *> (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<GReWeightNuXSecCCRES *> (fGenieRW->WghtCalc("xsec_ccres"));
 	rwccres->SetMode(GReWeightNuXSecCCRES::kModeMaMv);
 
 	// Default to include shape and normalization changes for NCRES (can be changed downstream if desired)
 	GReWeightNuXSecNCRES * rwncres =
 	    dynamic_cast<GReWeightNuXSecNCRES *> (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<GReWeightNuXSecDIS *> (fGenieRW->WghtCalc("xsec_dis"));
 	rwdis->SetMode(GReWeightNuXSecDIS::kModeABCV12u);
 
 	// Final Reconfigure
 	fGenieRW->Reconfigure();
 
 	// 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(int nuisenum, double startval) {
 #ifdef __GENIE_ENABLED__
 
 	// Get RW Enum and name
 	int rwenum = (nuisenum % 1000);
 	genie::rew::GSyst_t rwsyst = static_cast<genie::rew::GSyst_t>(rwenum);
 	std::string name = GSyst::AsString(rwsyst);
 
 	// Fill Maps
 	fGenieNameSysts[name]     = rwsyst;
 	fGenieEnumSysts[nuisenum] = rwsyst;
 
 	// Initialize dial
 	fGenieRW->Systematics().Init( fGenieEnumSysts[nuisenum] );
 
 	// If Absolute
 	if (fIsAbsTwk) {
 		GSystUncertainty::Instance()->SetUncertainty( fGenieEnumSysts[nuisenum], 1.0, 1.0 );
 	}
 
 	// Set Value if given
 	if (startval != -999.9) {
 		SetDialValue(nuisenum, startval);
 	}
 
 #endif
 };
 
 
 void GENIEWeightEngine::SetDialValue(int nuisenum, double val) {
 #ifdef __GENIE_ENABLED__
 	// Set RW engine values
 	int rwenum = (nuisenum % 1000);
 	fGenieRW->Systematics().Set(static_cast<genie::rew::GSyst_t>(rwenum), val);
 #endif
 }
 
 
 void GENIEWeightEngine::Reconfigure(bool silent) {
 #ifdef __GENIE_ENABLED__
 	// Hush now...
 	if (silent) StopTalking();
 
 	// Reconf
 	fGenieRW->Reconfigure();
 
 	// 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
 	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/GENIEWeightEngine.h b/src/Reweight/GENIEWeightEngine.h
index 0bc1b5e..2211a68 100644
--- a/src/Reweight/GENIEWeightEngine.h
+++ b/src/Reweight/GENIEWeightEngine.h
@@ -1,58 +1,58 @@
 #ifndef WEIGHT_ENGINE_GENIE_H
 #define WEIGHT_ENGINE_GENIE_H
 
 #include "FitLogger.h"
 
 
 #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 "GeneratorUtils.h"
 #include "WeightEngineBase.h"
 #include "FitWeight.h"
 
 class GENIEWeightEngine : public WeightEngineBase {
 public:
 	GENIEWeightEngine(std::string name);
 	~GENIEWeightEngine() {};
 
 	void IncludeDial(int nuisenum, double startval);
 	void SetDialValue(int rwenum, double val);
 	void Reconfigure(bool silent = false);
 	double CalcWeight(BaseFitEvt* evt);
 	inline bool NeedsEventReWeight() { return true; };
 
 #ifdef __GENIE_ENABLED__
 	std::map<std::string, genie::rew::GSyst_t> fGenieNameSysts;
 	std::map<int, genie::rew::GSyst_t> fGenieEnumSysts;
 	genie::rew::GReWeight* fGenieRW;  //!< Genie RW Object
 #endif
 
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Reweight/LikelihoodWeightEngine.cxx b/src/Reweight/LikelihoodWeightEngine.cxx
index a327dbc..4640f38 100644
--- a/src/Reweight/LikelihoodWeightEngine.cxx
+++ b/src/Reweight/LikelihoodWeightEngine.cxx
@@ -1,58 +1,58 @@
 #include "LikelihoodWeightEngine.h"
 
 LikelihoodWeightEngine::LikelihoodWeightEngine(std::string name) {
 
 	// Setup the NEUT Reweight engien
 	fCalcName = name;
-	LOG(FIT) << "Setting up Likelihood Weight RW : " << fCalcName << endl;
+	LOG(FIT) << "Setting up Likelihood Weight RW : " << fCalcName << std::endl;
 
 	// Set Abs Twk Config
 	fIsAbsTwk = true;
 
 };
 
 
 void LikelihoodWeightEngine::IncludeDial(std::string name, double startval) {
 
 	// Get NUISANCE Enum
 	int nuisenum = Reweight::ConvDial(name, kNORM);
 
 	// Fill Maps
 	int index = fValues.size();
 	fValues.push_back(1.0);
 
 	fEnumIndex[nuisenum] = index;
 	fNameIndex[name] = index;
 
 	// Set Value if given
 	if (startval != -999.9) {
 		SetDialValue(name, startval);
 	}
 };
 
 
 void LikelihoodWeightEngine::SetDialValue(int nuisenum, double val) {
 	fValues[fEnumIndex[nuisenum]] = val;
 }
 
 void LikelihoodWeightEngine::SetDialValue(std::string name, double val){
 	fValues[fNameIndex[name]] = val;
 }
 
 void LikelihoodWeightEngine::Reconfigure(bool silent) {
 	// Empty placeholder incase we want print statements...
 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
diff --git a/src/Reweight/LikelihoodWeightEngine.h b/src/Reweight/LikelihoodWeightEngine.h
index 9b45d1e..8ae8917 100644
--- a/src/Reweight/LikelihoodWeightEngine.h
+++ b/src/Reweight/LikelihoodWeightEngine.h
@@ -1,25 +1,25 @@
 #ifndef LikelihoodWeightEngine_H
 #define LikelihoodWeightEngine_H
 
 #include "FitLogger.h"
 #include "GeneratorUtils.h"
 #include "WeightEngineBase.h"
 
 // Could probably just make a general weight engine for stuff like this...
 
 class LikelihoodWeightEngine : public WeightEngineBase {
 	public:
 		LikelihoodWeightEngine(std::string name);
 		~LikelihoodWeightEngine(){};
 
 		void IncludeDial(std::string name, double startval);
 				void SetDialValue(std::string name, double val);
 
 		void SetDialValue(int rwenum, double val);
 		void Reconfigure(bool silent = false);
 		inline double CalcWeight(BaseFitEvt* evt) {return 1.0;};
 		inline bool NeedsEventReWeight(){ return false; };
 
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Reweight/NEUTWeightEngine.cxx b/src/Reweight/NEUTWeightEngine.cxx
index f535cf9..6f5155d 100644
--- a/src/Reweight/NEUTWeightEngine.cxx
+++ b/src/Reweight/NEUTWeightEngine.cxx
@@ -1,155 +1,155 @@
 #include "NEUTWeightEngine.h"
 
 NEUTWeightEngine::NEUTWeightEngine(std::string name) {
 #ifdef __NEUT_ENABLED__
 
 	// Setup the NEUT Reweight engien
 	fCalcName = name;
-	LOG(FIT) << "Setting up NEUT RW : " << fCalcName << endl;
+	LOG(FIT) << "Setting up NEUT RW : " << fCalcName << std::endl;
 
 	// Create RW Engine suppressing cout
 	StopTalking();
 	fNeutRW = new neut::rew::NReWeight();
 	TDirectory* olddir = gDirectory;
 
 	// get list of vetoed calc engines (just for debug really)
 	std::string rw_engine_list = FitPar::Config().GetParS("FitWeight.fNeutRW_veto");
 	bool xsec_ccqe = rw_engine_list.find("xsec_ccqe") == std::string::npos;
 	bool xsec_res = rw_engine_list.find("xsec_res") == std::string::npos;
 	bool xsec_ccres = rw_engine_list.find("xsec_ccres") == std::string::npos;
 	bool xsec_coh = rw_engine_list.find("xsec_coh") == std::string::npos;
 	bool xsec_dis = rw_engine_list.find("xsec_dis") == std::string::npos;
 	bool xsec_ncel = rw_engine_list.find("xsec_ncel") == std::string::npos;
 	bool xsec_nc = rw_engine_list.find("xsec_nc") == std::string::npos;
 	bool xsec_ncres = rw_engine_list.find("xsec_ncres") == std::string::npos;
 	bool nucl_casc = rw_engine_list.find("nucl_casc") == std::string::npos;
 	bool nucl_piless = rw_engine_list.find("nucl_piless") == std::string::npos;
 
 	// Activate each calc engine
 	if (xsec_ccqe)
 		fNeutRW->AdoptWghtCalc("xsec_ccqe", new neut::rew::NReWeightNuXSecCCQE);
 	if (xsec_res)
 		fNeutRW->AdoptWghtCalc("xsec_res", new neut::rew::NReWeightNuXSecRES);
 	if (xsec_ccres)
 		fNeutRW->AdoptWghtCalc("xsec_ccres", new neut::rew::NReWeightNuXSecCCRES);
 	if (xsec_coh)
 		fNeutRW->AdoptWghtCalc("xsec_coh", new neut::rew::NReWeightNuXSecCOH);
 	if (xsec_dis)
 		fNeutRW->AdoptWghtCalc("xsec_dis", new neut::rew::NReWeightNuXSecDIS);
 	if (xsec_ncel)
 		fNeutRW->AdoptWghtCalc("xsec_ncel", new neut::rew::NReWeightNuXSecNCEL);
 	if (xsec_nc)
 		fNeutRW->AdoptWghtCalc("xsec_nc", new neut::rew::NReWeightNuXSecNC);
 	if (xsec_ncres)
 		fNeutRW->AdoptWghtCalc("xsec_ncres", new neut::rew::NReWeightNuXSecNCRES);
 	if (nucl_casc)
 		fNeutRW->AdoptWghtCalc("nucl_casc", new neut::rew::NReWeightCasc);
 	if (nucl_piless)
 		fNeutRW->AdoptWghtCalc("nucl_piless", new neut::rew::NReWeightNuclPiless);
 	fNeutRW->Reconfigure();
 	olddir->cd();
 
 	// Set Abs Twk Config
 	fIsAbsTwk = (FitPar::Config().GetParB("setabstwk"));
 
 	// allow cout again
 	StartTalking();
 
 #else
 	ERR(FTL) << "NEUT RW NOT ENABLED!" << std::endl;
 #endif
 
 };
 
 void NEUTWeightEngine::IncludeDial(std::string name, double startval) {
 #ifdef __NEUT_ENABLED__
 
 	// Get NEUT Syst.
 	neut::rew::NSyst_t gensyst = NSyst::FromString(name);
 	int nuisenum = Reweight::ConvDial(name, kNEUT);
 
 	// Fill Maps
 	int index = fValues.size();
 	fValues.push_back(0.0);
 	fNEUTSysts.push_back(gensyst);
 
 	fEnumIndex[nuisenum] = index;
 	fNameIndex[name] = index;
 
 	// Initialize dial
 	fNeutRW->Systematics().Init( fNEUTSysts[index] );
 
 	// If Absolute
 	if (fIsAbsTwk) {
 		NSystUncertainty::Instance()->SetUncertainty( fNEUTSysts[index], 1.0, 1.0 );
 	}
 
 	// Set Value if given
 	if (startval != -999.9) {
 		SetDialValue(nuisenum, startval);
 	}
 #endif
 }
 
 void NEUTWeightEngine::SetDialValue(int nuisenum, double val) {
 #ifdef __NEUT_ENABLED__
 	fValues[fEnumIndex[nuisenum]] = val;
 	fNeutRW->Systematics().Set(fNEUTSysts[fEnumIndex[nuisenum]], val);
 #endif
 }
 
 void NEUTWeightEngine::SetDialValue(std::string name, double val) {
 #ifdef __NEUT_ENABLED__
 	fValues[fNameIndex[name]] = val;
 	fNeutRW->Systematics().Set(fNEUTSysts[fNameIndex[name]], val);
 #endif
 }
 
 
 void NEUTWeightEngine::Reconfigure(bool silent) {
 #ifdef __NEUT_ENABLED__
 	// Hush now...
 	if (silent) StopTalking();
 
 	// Reconf
 	fNeutRW->Reconfigure();
 
 	// Shout again
 	if (silent) StartTalking();
 #endif
 }
 
 
 double NEUTWeightEngine::CalcWeight(BaseFitEvt* evt) {
 	double rw_weight = 1.0;
 
 #ifdef __NEUT_ENABLED__
 	// Skip Non GENIE
 	if (evt->fType != kNEUT) return 1.0;
 
 	// Hush now
 	StopTalking();
 
 	// Fill NEUT Common blocks
-	GeneratorUtils::FillNeutCommons(evt->fNeutVect);
+	NEUTUtils::FillNeutCommons(evt->fNeutVect);
 
 	// Call Weight calculation
 	rw_weight = fNeutRW->CalcWeight();
 
 	// Speak Now
 	StartTalking();
 #endif
 
 	// Return rw_weight
 	return rw_weight;
 }
 
 
 
 
 
 
 
 
 
 
diff --git a/src/Reweight/NEUTWeightEngine.h b/src/Reweight/NEUTWeightEngine.h
index fe24063..a4ad648 100644
--- a/src/Reweight/NEUTWeightEngine.h
+++ b/src/Reweight/NEUTWeightEngine.h
@@ -1,51 +1,53 @@
 #ifndef WEIGHT_ENGINE_NEUT_H
 #define WEIGHT_ENGINE_NEUT_H
 
 #include "FitLogger.h"
 
 #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"
+#include "NEUTInputHandler.h"
 #endif
 
+
 #include "GeneratorUtils.h"
 #include "WeightEngineBase.h"
 #include "FitWeight.h"
 
 class NEUTWeightEngine : public WeightEngineBase {
 public:
 	NEUTWeightEngine(std::string name);
 	~NEUTWeightEngine() {};
 
 	void IncludeDial(std::string name, double startval);
 
 	void SetDialValue(std::string name, double val);
 	void SetDialValue(int nuisenum, double val);
 
 	void Reconfigure(bool silent = false);
 
 	double CalcWeight(BaseFitEvt* evt);
 
 	inline bool NeedsEventReWeight() { return true; };
 
 
 #ifdef __NEUT_ENABLED__
 	std::vector<neut::rew::NSyst_t> fNEUTSysts;
 	neut::rew::NReWeight* fNeutRW;
 #endif
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Reweight/NIWGWeightEngine.cxx b/src/Reweight/NIWGWeightEngine.cxx
index 010eac5..bdce7ae 100644
--- a/src/Reweight/NIWGWeightEngine.cxx
+++ b/src/Reweight/NIWGWeightEngine.cxx
@@ -1,158 +1,158 @@
 #include "NEUTWeightEngine.h"
 
 NIWGWeightEngine::NIWGWeightEngine(std::string name) {
 #ifdef __NIWG_ENABLED__
 #ifdef __NEUT_ENABLED__
 	// Setup the NEUT Reweight engien
 	fCalcName = name;
-	LOG(FIT) << "Setting up NIWG RW : " << fCalcName << endl;
+	LOG(FIT) << "Setting up NIWG RW : " << fCalcName << std::endl;
 
 	// Create RW Engine suppressing cout
 	StopTalking();
 	fNIWGRW = new niwg::rew::NIWGReWeight();
 
 	// Get List of Veto Calcs (For Debugging)
 	std::string rw_engine_list =
 	    FitPar::Config().GetParS("FitWeight.fNIWGRW_veto");
 	bool niwg_2012a = rw_engine_list.find("niwg_2012a") == std::string::npos;
 	bool niwg_2014a = rw_engine_list.find("niwg_2014a") == std::string::npos;
 	bool niwg_pimult = rw_engine_list.find("niwg_pimult") == std::string::npos;
 	bool niwg_mec = rw_engine_list.find("niwg_mec") == std::string::npos;
 	bool niwg_rpa = rw_engine_list.find("niwg_rpa") == std::string::npos;
 	bool niwg_eff_rpa = rw_engine_list.find("niwg_eff_rpa") == std::string::npos;
 	bool niwg_proton =
 	    rw_engine_list.find("niwg_protonFSIbug") == std::string::npos;
 	bool niwg_hadron =
 	    rw_engine_list.find("niwg_HadronMultSwitch") == std::string::npos;
 
 	// Add the RW Calcs
 	if (niwg_2012a)
 		fNIWGRW->AdoptWghtCalc("niwg_2012a", new niwg::rew::NIWGReWeight2012a);
 	if (niwg_2014a)
 		fNIWGRW->AdoptWghtCalc("niwg_2014a", new niwg::rew::NIWGReWeight2014a);
 	if (niwg_pimult)
 		fNIWGRW->AdoptWghtCalc("niwg_pimult", new niwg::rew::NIWGReWeightPiMult);
 	if (niwg_mec)
 		fNIWGRW->AdoptWghtCalc("niwg_mec", new niwg::rew::NIWGReWeightMEC);
 	if (niwg_rpa)
 		fNIWGRW->AdoptWghtCalc("niwg_rpa", new niwg::rew::NIWGReWeightRPA);
 	if (niwg_eff_rpa)
 		fNIWGRW->AdoptWghtCalc("niwg_eff_rpa",
 		                       new niwg::rew::NIWGReWeightEffectiveRPA);
 	if (niwg_proton)
 		fNIWGRW->AdoptWghtCalc("niwg_protonFSIbug",
 		                       new niwg::rew::NIWGReWeightProtonFSIbug);
 	if (niwg_hadron)
 		fNIWGRW->AdoptWghtCalc("niwg_HadronMultSwitch",
 		                       new niwg::rew::NIWGReWeightHadronMultSwitch);
 
 	fNIWGRW->Reconfigure();
 
 	// Set Abs Twk Config
 	fIsAbsTwk = (FitPar::Config().GetParB("setabstwk"));
 
 	// allow cout again
 	StartTalking();
 #else
 	ERR(FTL) << "NIWG RW Enabled but NEUT RW is not!" << std::endl;
 #endif
 #else
 	ERR(FTL) << "NIWG RW NOT ENABLED!" << std::endl;
 #endif
 
 };
 
 void NIWGWeightEngine::IncludeDial(std::string name, double startval) {
 #ifdef __NIWG_ENABLED__
 
 	// Get NEUT Syst.
 	niwg::rew::NIWGSyst_t gensyst = niwg::rew::NIWGSyst::FromString(name);
 	int nuisenum = Reweight::ConvDial(name, kNIWG);
 
 	// Fill Maps
 	int index = fValues.size();
 	fValues.push_back(0.0);
 	fNIWGSysts.push_back(gensyst);
 
 	fEnumIndex[nuisenum] = index;
 	fNameIndex[name] = index;
 
 	// Initialize dial
 	fNIWGRW->Systematics().Init( fNIWGSysts[index] );
 
 	// If Absolute
 	if (fIsAbsTwk) {
 		niwg::rew::NIWGSystUncertainty::Instance()->SetUncertainty( fNIWGSysts[index], 1.0, 1.0 );
 	}
 
 	// Set Value if given
 	if (startval != -999.9) {
 		SetDialValue(nuisenum, startval);
 	}
 #endif
 }
 
 void NIWGWeightEngine::SetDialValue(int nuisenum, double val) {
 #ifdef __NIWG_ENABLED__
 	fValues[fEnumIndex[nuisenum]] = val;
 	fNIWGRW->Systematics().Set(fNIWGSysts[fEnumIndex[nuisenum]], val);
 #endif
 }
 
 void NIWGWeightEngine::SetDialValue(std::string name, double val) {
 #ifdef __NIWG_ENABLED__
 	fValues[fNameIndex[name]] = val;
 	fNIWGRW->Systematics().Set(fNIWGSysts[fNameIndex[name]], val);
 #endif
 }
 
 
 void NIWGWeightEngine::Reconfigure(bool silent) {
 #ifdef __NIWG_ENABLED__
 	// Hush now...
 	if (silent) StopTalking();
 
 	// Reconf
 	fNIWGRW->Reconfigure();
 
 	// Shout again
 	if (silent) StartTalking();
 #endif
 }
 
 
 double NIWGWeightEngine::CalcWeight(BaseFitEvt* evt) {
 	double rw_weight = 1.0;
 
 #ifdef __NEUT_ENABLED__
 #ifdef __NIWG_ENABLED__
 
 	// Skip Non GENIE
 	if (evt->fType != kNEUT) return 1.0;
 
 	// Hush now
 	StopTalking();
 
 	niwg::rew::NIWGEvent* niwg_event = GeneratorUtils::GetNIWGEvent(evt->fNeutVect);
 	rw_weight *= fNIWGRW->CalcWeight(*niwg_event);
 	delete niwg_event;
 
 	// Speak Now
 	StartTalking();
 
 #endif
 #endif
 
 	// Return rw_weight
 	return rw_weight;
 }
 
 
 
 
 
 
 
 
 
 
diff --git a/src/Reweight/NIWGWeightEngine.h b/src/Reweight/NIWGWeightEngine.h
index 22e01a9..8703b34 100644
--- a/src/Reweight/NIWGWeightEngine.h
+++ b/src/Reweight/NIWGWeightEngine.h
@@ -1,52 +1,52 @@
 #ifndef WEIGHT_ENGINE_NIWG_H
 #define WEIGHT_ENGINE_NIWG_H
 
 #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
 
 #include "FitLogger.h"
 
 #include "GeneratorUtils.h"
 #include "WeightEngineBase.h"
 #include "FitWeight.h"
 
 class NIWGWeightEngine : public WeightEngineBase {
 public:
 	NIWGWeightEngine(std::string name);
 	~NIWGWeightEngine() {};
 
 	void IncludeDial(std::string name, double startval);
 
 	void SetDialValue(std::string name, double val);
 	void SetDialValue(int nuisenum, double val);
 
 	void Reconfigure(bool silent = false);
 
 	double CalcWeight(BaseFitEvt* evt);
 
 	inline bool NeedsEventReWeight() { return true; };
 
 
 #ifdef __NIWG_ENABLED__
 	std::vector<niwg::rew::NIWGSyst_t> fNIWGSysts;
 	niwg::rew::NIWGReWeight* fNIWGRW;
 #endif
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Reweight/NUISANCEWeightEngine.cxx b/src/Reweight/NUISANCEWeightEngine.cxx
index 8af2021..1a45507 100644
--- a/src/Reweight/NUISANCEWeightEngine.cxx
+++ b/src/Reweight/NUISANCEWeightEngine.cxx
@@ -1,106 +1,106 @@
 #include "NUISANCEWeightEngine.h"
 #include "NUISANCEWeightCalcs.h"
 
 NUISANCEWeightEngine::NUISANCEWeightEngine(std::string name) {
 
 	// Setup the NUISANCE Reweight engine
 	fCalcName = name;
-	LOG(FIT) << "Setting up NUISANCE Custom RW : " << fCalcName << endl;
+	LOG(FIT) << "Setting up NUISANCE Custom RW : " << fCalcName << std::endl;
 
 	// Load in all Weight Calculations
 	fWeightCalculators.push_back( new GaussianModeCorr() );
 
 	// Set Abs Twk Config
 	fIsAbsTwk = true;
 
 };
 
 
 void NUISANCEWeightEngine::IncludeDial(std::string name, double startval) {
 
 	// Get NUISANCE Enum
 	int nuisenum = Reweight::ConvDial(name, kCUSTOM);
 
 	// Fill Maps
 	int index = fValues.size();
 	fValues.push_back(1.0);
 
 	fEnumIndex[nuisenum] = index;
 	fNameIndex[name] = index;
 
 	// Set Value if given
 	if (startval != -999.9) {
 		SetDialValue(name, startval);
 	}
 };
 
 
 void NUISANCEWeightEngine::SetDialValue(int nuisenum, double val) {
 	fValues[fEnumIndex[nuisenum]] = val;
 }
 
 void NUISANCEWeightEngine::SetDialValue(std::string name, double val) {
 	fValues[fNameIndex[name]] = val;
 }
 
 void NUISANCEWeightEngine::Reconfigure(bool silent) {
 
 	// Loop over all names
 	for (std::map<int, size_t>::iterator enumiter = fEnumIndex.begin();
 	        enumiter != fEnumIndex.end(); enumiter++) {
 
 		for (std::vector<NUISANCEWeightCalc*>::iterator calciter = fWeightCalculators.begin();
 		        calciter != fWeightCalculators.end(); calciter++) {
 
 			NUISANCEWeightCalc* nuiscalc = static_cast<NUISANCEWeightCalc*>(*calciter);
 			if (nuiscalc->IsHandled(enumiter->first)) {
 				nuiscalc->SetDialValue(enumiter->first, fValues[enumiter->second]);
 			}
 		}
 	}
 }
 
 
 
 double NUISANCEWeightEngine::CalcWeight(BaseFitEvt* evt) {
 	double rw_weight = 1.0;
 
 	// Cast as usable class
 	for (std::vector<NUISANCEWeightCalc*>::iterator iter = fWeightCalculators.begin();
 	        iter != fWeightCalculators.end(); iter++) {
 		NUISANCEWeightCalc* nuiscalc = static_cast<NUISANCEWeightCalc*>(*iter);
 
 		rw_weight *= nuiscalc->CalcWeight(evt);
 	}
 
 	// Return rw_weight
 	return rw_weight;
 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
diff --git a/src/Reweight/NUISANCEWeightEngine.h b/src/Reweight/NUISANCEWeightEngine.h
index 76ee471..bd19b60 100644
--- a/src/Reweight/NUISANCEWeightEngine.h
+++ b/src/Reweight/NUISANCEWeightEngine.h
@@ -1,33 +1,33 @@
 #ifndef WEIGHT_ENGINE_NUISANCE_H
 #define WEIGHT_ENGINE_NUISANCE_H
 
 #include "FitLogger.h"
 #include "GeneratorUtils.h"
 #include "WeightEngineBase.h"
 #include "FitWeight.h"
 #include "NUISANCESyst.h"
 #include "NUISANCEWeightCalcs.h"
 
 class NUISANCEWeightEngine : public WeightEngineBase {
 public:
 	NUISANCEWeightEngine(std::string name);
 	~NUISANCEWeightEngine() {};
 
 	void IncludeDial(std::string name, double startval);
 
 	void SetDialValue(std::string name, double val);
 	void SetDialValue(int nuisenum, double val);
 
 	void Reconfigure(bool silent = false);
 
 	double CalcWeight(BaseFitEvt* evt);
 
 	inline bool NeedsEventReWeight() { return true; };
 
 	std::vector<NUISANCEWeightCalc*> fWeightCalculators;
 };
 
 
 
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Reweight/NuWroWeightEngine.cxx b/src/Reweight/NuWroWeightEngine.cxx
index 9a1efe2..baab616 100644
--- a/src/Reweight/NuWroWeightEngine.cxx
+++ b/src/Reweight/NuWroWeightEngine.cxx
@@ -1,126 +1,126 @@
 #include "NuWroWeightEngine.h"
 
 NuWroWeightEngine::NuWroWeightEngine(std::string name) {
 #ifdef __NUWRO_REWEIGHT_ENABLED__
 
 	// Setup the NEUT Reweight engien
 	fCalcName = name;
-	LOG(FIT) << "Setting up NuWro RW : " << fCalcName << endl;
+	LOG(FIT) << "Setting up NuWro RW : " << fCalcName << std::endl;
 
 	// Create RW Engine suppressing cout
 	StopTalking();
 
 	// Create the engine
 	fNuwroRW = new nuwro::rew::NuwroReWeight();
 
 	// Get List of Veto Calcs (For Debugging)
 	std::string rw_engine_list =
 	    FitPar::Config().GetParS("FitWeight.fNuwroRW_veto");
 	bool xsec_qel = rw_engine_list.find("nuwro_QEL") == std::string::npos;
 	bool xsec_flag = rw_engine_list.find("nuwro_FlagNorm") == std::string::npos;
 	bool xsec_res = rw_engine_list.find("nuwro_RES") == std::string::npos;
 
 	// Add the RW Calcs
 	if (xsec_qel)
 		fNuwroRW->AdoptWghtCalc("nuwro_QEL", new nuwro::rew::NuwroReWeight_QEL);
 	if (xsec_flag)
 		fNuwroRW->AdoptWghtCalc("nuwro_FlagNorm",
 		                        new nuwro::rew::NuwroReWeight_FlagNorm);
 	if (xsec_res)  fNuwroRW->AdoptWghtCalc( "nuwro_RES",  new
 		                                        nuwro::rew::NuwroReWeight_SPP );
 
 	// Set Abs Twk Config
 	fIsAbsTwk = (FitPar::Config().GetParB("setabstwk"));
 
 	// allow cout again
 	StartTalking();
 #else
 	ERR(FTL) << "NUWRO RW NOT ENABLED! " << std::endl;
 #endif
 };
 
 
 void NuWroWeightEngine::IncludeDial(std::string name, double startval) {
 #ifdef __NUWRO_REWEIGHT_ENABLED__
 
 	// Get RW Enum and name
 	nuwro::rew::NuwroSyst_t gensyst = nuwro::rew::NuwroSyst::FromString(name);
 	int nuisenum = Reweight::ConvDial(name, kNUWRO);
 
 	// Fill Maps
 	int index = fValues.size();
 	fValues.push_back(0.0);
 	fNUWROSysts.push_back(gensyst);
 
 	fEnumIndex[nuisenum] = index;
 	fNameIndex[name] = index;
 
 	// Initialise Dial
 	fNuwroRW->Systematics().Add( fNUWROSysts[index] );
 
 	// If Absolute
 	if (fIsAbsTwk) {
 		nuwro::rew::NuwroSystUncertainty::Instance()->SetUncertainty( fNUWROSysts[index], 1.0, 1.0 );
 	}
 
 	// Set Value if given
 	if (startval != -999.9) {
 		SetDialValue(name, startval);
 	}
 #endif
 };
 
 
 void NuWroWeightEngine::SetDialValue(int nuisenum, double val) {
 #ifdef __NUWRO_REWEIGHT_ENABLED__
 	fValues[fEnumIndex[nuisenum]] = val;
 	fNuwroRW->Systematics().SetSystVal(fNUWROSysts[fEnumIndex[nuisenum]], val);
 #endif
 }
 
 void NuWroWeightEngine::SetDialValue(std::string name, double val) {
 #ifdef __NUWRO_REWEIGHT_ENABLED__
 	fValues[fNameIndex[name]] = val;
 	fNuwroRW->Systematics().SetSystVal(fNUWROSysts[fNameIndex[name]], val);
 #endif
 }
 
 
 void NuWroWeightEngine::Reconfigure(bool silent) {
 #ifdef __NUWRO_REWEIGHT_ENABLED__
 	// Hush now...
 	if (silent) StopTalking();
 
 	// Reconf
 	fNuwroRW->Reconfigure();
 
 	// Shout again
 	if (silent) StartTalking();
 #endif
 }
 
 
 double NuWroWeightEngine::CalcWeight(BaseFitEvt* evt) {
 	double rw_weight = 1.0;
 
 #ifdef __NUWRO_REWEIGHT_ENABLED__
 	// Skip Non GENIE
 	if (evt->fType != kNUWRO) return 1.0;
 
 	// Call Weight calculation
 	rw_weight = fNuwroRW->CalcWeight(evt->fNuwroEvent);
 #endif
 
 	// Return rw_weight
 	return rw_weight;
 }
 
 
 
 
 
 
 
 
 
 
diff --git a/src/Reweight/NuWroWeightEngine.h b/src/Reweight/NuWroWeightEngine.h
index d9d6453..ce69dc2 100644
--- a/src/Reweight/NuWroWeightEngine.h
+++ b/src/Reweight/NuWroWeightEngine.h
@@ -1,40 +1,40 @@
 #ifndef WEIGHT_ENGINE_NUWRO_H
 #define WEIGHT_ENGINE_NUWRO_H
 
 #include "FitLogger.h"
 #include "GeneratorUtils.h"
 #include "WeightEngineBase.h"
 #include "WeightUtils.h"
 
 #ifdef __NUWRO_REWEIGHT_ENABLED__
 #include "NuwroReWeight.h"
 #include "event1.h"
 #include "NuwroReWeight_FlagNorm.h"
 #include "NuwroReWeight_QEL.h"
 #include "NuwroReWeight_SPP.h"
 #include "NuwroSyst.h"
 #include "NuwroSystUncertainty.h"
 #endif
 
 class NuWroWeightEngine : public WeightEngineBase {
 public:
 	NuWroWeightEngine(std::string name);
 	~NuWroWeightEngine() {};
 
 	void IncludeDial(std::string name, double startval);
 
 	void SetDialValue(std::string name, double val);
 	void SetDialValue(int rwenum, double val);
 
 	void Reconfigure(bool silent = false);
 	double CalcWeight(BaseFitEvt* evt);
 
 	inline bool NeedsEventReWeight() { return true; };
 
 #ifdef __NUWRO_REWEIGHT_ENABLED__
 	std::vector<nuwro::rew::NuwroSyst_t> fNUWROSysts;
 	nuwro::rew::NuwroReWeight* fNuwroRW;
 #endif
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Reweight/SampleNormEngine.cxx b/src/Reweight/SampleNormEngine.cxx
index cefcd23..13d2acc 100644
--- a/src/Reweight/SampleNormEngine.cxx
+++ b/src/Reweight/SampleNormEngine.cxx
@@ -1,58 +1,58 @@
 #include "SampleNormEngine.h"
 
 SampleNormEngine::SampleNormEngine(std::string name) {
 
 	// Setup the NEUT Reweight engien
 	fCalcName = name;
-	LOG(FIT) << "Setting up Sample Norm RW : " << fCalcName << endl;
+	LOG(FIT) << "Setting up Sample Norm RW : " << fCalcName << std::endl;
 
 	// Set Abs Twk Config
 	fIsAbsTwk = true;
 
 };
 
 
 void SampleNormEngine::IncludeDial(std::string name, double startval) {
 
 	// Get NUISANCE Enum
 	int nuisenum = Reweight::ConvDial(name, kNORM);
 
 	// Fill Maps
 	int index = fValues.size();
 	fValues.push_back(1.0);
 
 	fEnumIndex[nuisenum] = index;
 	fNameIndex[name] = index;
 
 	// Set Value if given
 	if (startval != -999.9) {
 		SetDialValue(name, startval);
 	}
 };
 
 
 void SampleNormEngine::SetDialValue(int nuisenum, double val) {
 	fValues[fEnumIndex[nuisenum]] = val;
 }
 
 void SampleNormEngine::SetDialValue(std::string name, double val){
 	fValues[fNameIndex[name]] = val;
 }
 
 void SampleNormEngine::Reconfigure(bool silent) {
 	// Empty placeholder incase we want print statements...
 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
diff --git a/src/Reweight/SampleNormEngine.h b/src/Reweight/SampleNormEngine.h
index 2a91576..c341a71 100644
--- a/src/Reweight/SampleNormEngine.h
+++ b/src/Reweight/SampleNormEngine.h
@@ -1,22 +1,22 @@
 #ifndef SampleNormEngine_H
 #define SampleNormEngine_H
 
 #include "FitLogger.h"
 #include "GeneratorUtils.h"
 #include "WeightEngineBase.h"
 
 class SampleNormEngine : public WeightEngineBase {
 	public:
 		SampleNormEngine(std::string name);
 		~SampleNormEngine(){};
 
 		void IncludeDial(std::string name, double startval);
 		void SetDialValue(int rwenum, double val);
 		void SetDialValue(std::string name, double val);
 		
 		void Reconfigure(bool silent = false);
 		inline double CalcWeight(BaseFitEvt* evt) {return 1.0;};
 		inline bool NeedsEventReWeight(){ return false; };
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Reweight/SplineWeightEngine.cxx b/src/Reweight/SplineWeightEngine.cxx
index 6aeea6e..a2ec628 100644
--- a/src/Reweight/SplineWeightEngine.cxx
+++ b/src/Reweight/SplineWeightEngine.cxx
@@ -1,79 +1,79 @@
 #include "SplineWeightEngine.h"
 
 SplineWeightEngine::SplineWeightEngine(std::string name) {
 
   // Setup the Reweight engien
   fCalcName = name;
-  LOG(FIT) << "Setting up Spline RW : " << fCalcName << endl;
+  LOG(FIT) << "Setting up Spline RW : " << fCalcName << std::endl;
   
   // Set Abs Twk Config
   fIsAbsTwk = true;
 	
 };
 
 
 void SplineWeightEngine::IncludeDial(std::string name, double startval) {
 
   // Get NUISANCE Enum
   int nuisenum = Reweight::ConvDial(name, kSPLINEPARAMETER);
   
   // Fill Maps
   int index = fValues.size();
   fValues.push_back(0.0);
   
   fEnumIndex[nuisenum] = index;
   fNameIndex[name] = index;
   
   //	std::cout << "Inlcuded Spline Dial " << name << " " << nuisenum << " " << startval << " " << index << std::endl;
   
   // Set Value if given
   if (startval != -999.9) {
     SetDialValue(name, startval);
   }
 }
 
 
 void SplineWeightEngine::SetDialValue(int nuisenum, double val) {
   //  LOG(FIT) << "Enum Val " << nuisenum << std::endl;
   //  LOG(FIT) << fEnumIndex.size() << std::endl;
   //  LOG(FIT) << "Set Dial Value to " << nuisenum << " " << fEnumIndex[nuisenum] << " " << val << std::endl;
   fValues[fEnumIndex[nuisenum]] = val;
 }
 
 void SplineWeightEngine::SetDialValue(std::string name, double val){
   fValues[fNameIndex[name]] = val;
 }
 
 
 void SplineWeightEngine::Reconfigure(bool silent) {
   for (std::map<std::string, size_t>::iterator iter = fNameIndex.begin(); 
        iter != fNameIndex.end(); iter++){
     // LOG(FIT) << "Reconfiguring Spline " << iter->first << " to be " << fValues[ iter->second ] << " Inside SPL RW" << std::endl;
     fSplineValueMap[ iter->first ] = fValues[ iter->second ];
   }
 }
 
 
 double SplineWeightEngine::CalcWeight(BaseFitEvt* evt) {
 
   if (!evt->fSplineRead) return 1.0;
   
   if (evt->fSplineRead->NeedsReconfigure()) {
     evt->fSplineRead->Reconfigure(fSplineValueMap);
   }
   
   double rw_weight = evt->fSplineRead->CalcWeight( evt->fSplineCoeff );
   if (rw_weight < 0.0) rw_weight = 0.0;
 
   return rw_weight;
 }
 
 
 
 
 
 
 
 
 
 
diff --git a/src/Reweight/T2KWeightEngine.cxx b/src/Reweight/T2KWeightEngine.cxx
index dd5893e..8d1c761 100644
--- a/src/Reweight/T2KWeightEngine.cxx
+++ b/src/Reweight/T2KWeightEngine.cxx
@@ -1,126 +1,126 @@
 #include "T2KWeightEngine.h"
 
 T2KWeightEngine::T2KWeightEngine(std::string name) {
 #ifdef __T2KREW_ENABLED__
 
 	// Setup the NEUT Reweight engien
 	fCalcName = name;
-	LOG(FIT) << "Setting up T2K RW : " << fCalcName << endl;
+	LOG(FIT) << "Setting up T2K RW : " << fCalcName << std::endl;
 
 	// Create RW Engine suppressing cout
 	StopTalking();
 
 	// Create Main RW Engine
 	fT2KRW = new t2krew::T2KReWeight();
 
 	// Setup Sub RW Engines (Only activated for neut and niwg)
 	fT2KNeutRW = new t2krew::T2KNeutReWeight();
 	fT2KNIWGRW = new t2krew::T2KNIWGReWeight();
 
 	fT2KRW->AdoptWghtEngine("fNeutRW", fT2KNeutRW);
 	fT2KRW->AdoptWghtEngine("fNIWGRW", fT2KNIWGRW);
 
 	fT2KRW->Reconfigure();
 
 	// allow cout again
 	StartTalking();
 
 	// Set Abs Twk Config
 	fIsAbsTwk = (FitPar::Config().GetParB("setabstwk"));
 	
 #else	
 	ERR(FTL) << "T2K RW NOT ENABLED" << std::endl;
 	throw;
 #endif
 };
 
 void T2KWeightEngine::IncludeDial(std::string name, double startval) {
 #ifdef __T2KREW_ENABLED__
 	// Get NEUT Syst.
 	t2krew::T2KSyst_t gensyst = t2krew::T2KSyst::FromString(name);
 	int nuisenum = Reweight::ConvDial(name, kT2K);
 
 	// Fill Maps
 	int index = fValues.size();
 	fValues.push_back(0.0);
 	fT2KSysts.push_back(gensyst);
 
 	fEnumIndex[nuisenum] = index;
 	fNameIndex[name] = index;
 
 	// Initialize dial
 	fT2KRW->Systematics().Include(gensyst);
 
 	// If Absolute
 	if (fIsAbsTwk) {
 		fT2KRW->Systematics().SetAbsTwk(gensyst);
 	}
 
 	// Set Value if given
 	if (startval != -999.9) {
 		SetDialValue(nuisenum, startval);
 	}
 #endif
 }
 
 void T2KWeightEngine::SetDialValue(int nuisenum, double val) {
 #ifdef __T2KREW_ENABLED__
 	fValues[fEnumIndex[nuisenum]] = val;
 	fT2KRW->Systematics().SetTwkDial(fT2KSysts[fEnumIndex[nuisenum]], val);
 #endif
 }
 
 void T2KWeightEngine::SetDialValue(std::string name, double val) {
 #ifdef __T2KREW_ENABLED__
 	fValues[fNameIndex[name]] = val;
 	fT2KRW->Systematics().SetTwkDial(fT2KSysts[fNameIndex[name]], val);
 #endif
 }
 
 
 void T2KWeightEngine::Reconfigure(bool silent) {
 #ifdef __T2KREW_ENABLED__
 	// Hush now...
 	if (silent) StopTalking();
 
 	// Reconf
 	StopTalking();
 	fT2KRW->Reconfigure();
 	StartTalking();
 
 	// Shout again
 	if (silent) StartTalking();
 #endif
 }
 
 
 double T2KWeightEngine::CalcWeight(BaseFitEvt* evt) {
 	double rw_weight = 1.0;
 
 #ifdef __T2KREW_ENABLED__
 	// Skip Non GENIE
 	if (evt->fType != kNEUT) return 1.0;
 
 	// Hush now
 	StopTalking();
 
 	// Get Weight For NEUT
 	rw_weight = fT2KRW->CalcWeight(evt->fNeutVect);
 
 	// Speak Now
 	StartTalking();
 #endif
 
 	// Return rw_weight
 	return rw_weight;
 }
 
 
 
 
 
 
 
 
 
 
diff --git a/src/Reweight/T2KWeightEngine.h b/src/Reweight/T2KWeightEngine.h
index 6e73bfc..8c7ac67 100644
--- a/src/Reweight/T2KWeightEngine.h
+++ b/src/Reweight/T2KWeightEngine.h
@@ -1,44 +1,44 @@
 #ifndef WEIGHT_ENGINE_T2K_H
 #define WEIGHT_ENGINE_T2K_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
 
 #include "GeneratorUtils.h"
 #include "WeightEngineBase.h"
 #include "FitWeight.h"
 
 class T2KWeightEngine : public WeightEngineBase {
 public:
 	T2KWeightEngine(std::string name);
 	~T2KWeightEngine() {};
 
 	void IncludeDial(std::string name, double startval);
 
 	void SetDialValue(std::string name, double val);
 	void SetDialValue(int nuisenum, double val);
 
 	void Reconfigure(bool silent = false);
 
 	double CalcWeight(BaseFitEvt* evt);
 
 	inline bool NeedsEventReWeight() { return true; };
 	
 #ifdef __T2KREW_ENABLED__
 	std::vector<t2krew::T2KSyst_t> fT2KSysts;
 	t2krew::T2KReWeight* fT2KRW;  //!< T2K RW Object
 	t2krew::T2KNeutReWeight* fT2KNeutRW;
 	t2krew::T2KNIWGReWeight* fT2KNIWGRW;
 #endif
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Reweight/WeightEngineBase.cxx b/src/Reweight/WeightEngineBase.cxx
index 00c5f36..038a896 100644
--- a/src/Reweight/WeightEngineBase.cxx
+++ b/src/Reweight/WeightEngineBase.cxx
@@ -1,25 +1,25 @@
 #include "WeightEngineBase.h"
 
 bool WeightEngineBase::IsDialIncluded(std::string name) {
 	return (fNameIndex.find(name) != fNameIndex.end());
 }
 
 bool WeightEngineBase::IsDialIncluded(int nuisenum) {
 	return (fEnumIndex.find(nuisenum) != fEnumIndex.end());
 }
 
 double WeightEngineBase::GetDialValue(std::string name) {
 	if (!IsDialIncluded(name)) {
 		ERR(FTL) << "Dial " << name
 		         << " not included in " << fCalcName << std::endl;
 	}
 	return fValues[fNameIndex[name]];
 }
 
 double WeightEngineBase::GetDialValue(int nuisenum) {
 	if (!IsDialIncluded(nuisenum)) {
 		ERR(FTL) << "Dial Enum " << nuisenum
 		         << " not included in " << fCalcName << std::endl;
 	}
 	return fValues[fEnumIndex[nuisenum]];
-}
\ No newline at end of file
+}
diff --git a/src/Reweight/WeightUtils.cxx b/src/Reweight/WeightUtils.cxx
index 1658947..81d4fb3 100644
--- a/src/Reweight/WeightUtils.cxx
+++ b/src/Reweight/WeightUtils.cxx
@@ -1,487 +1,487 @@
 #include "WeightUtils.h"
 
 //********************************************************************
 TF1 FitBase::GetRWConvFunction(std::string type, std::string 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";
 
   string line;
   ifstream card(
     (GeneralUtils::GetTopLevelDir() + "/parameters/dial_conversion.card").c_str(),
     ifstream::in);
 
   while (std::getline(card >> std::ws, line, '\n')) {
 
     std::vector<std::string> 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 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<std::string> 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) {
   //********************************************************************
   TF1 f1 = GetRWConvFunction(type, name);
   double conv_val = f1.GetX(val);
   if (fabs(conv_val) < 1E-10) conv_val = 0.0;
   return conv_val;
 }
 
 //********************************************************************
 double FitBase::RWSigmaToAbs(std::string type, std::string 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) {
   //********************************************************************
   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) {
   //********************************************************************
   TF1 f1 = GetRWConvFunction(type, name);
   double conv_val = f1.Eval(val) / f1.Eval(0.0);
   return conv_val;
 }
 
 
 
 int FitBase::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("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 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";}
   default: return "unknown_parameter";
   }
 
 }
 
 int FitBase::GetDialEnum(std::string type, std::string name) {
   return FitBase::GetDialEnum( FitBase::ConvDialType(type), name );
 }
 
 
 
 int FitBase::GetDialEnum(int type, std::string name) {
 
   int offset = type * 1000;
   int this_enum = -1; //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
 #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;
 #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;
 #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;
 #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;
 #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 << endl;
+    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." << endl;
+               << "\" 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];
   }
 
   }
 
   // If Not Enabled
   if (this_enum == -2) {
-    ERR(FTL) << "RW Engine not supported for " << FitBase::ConvDialType(type) << endl;
-    ERR(FTL) << "Check dial " << name << endl;
+    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) {
-    ERR(FTL) << "Dial " << name << " not found." << endl;
+    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 return kUNKNOWN;
 
 }
 
 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";}
   default: return "unknown_parameter";
   }
 
 }
 
 
 
 
 
 
 
 int Reweight::NEUTEnumFromName(std::string name) {
 #ifdef __NEUT_ENABLED__
   int neutenum = (int)neut::rew::NSyst::FromString(name);
   return (neutenum > 0) ? neutenum : kNoDialFound;
 #else
   return kGeneratorNotBuilt;
 #endif
 }
 
 int Reweight::NIWGEnumFromName(std::string name) {
 #ifdef __NIWG_ENABLED__
   int niwgenum = (int)niwg::rew::NIWGSyst::FromString(name);
   return (niwgenum != 0) ? niwgenum : kNoDialFound;
 #else
   return kGeneratorNotBuilt;
 #endif
 }
 
 int Reweight::NUWROEnumFromName(std::string name) {
 #ifdef __NUWRO_REWEIGHT_ENABLED__
   int nuwroenum = (int)nuwro::rew::NuwroSyst::FromString(name);
   return (nuwroenum > 0) ? nuwroenum : kNoDialFound;
 #else
   return kGeneratorNotBuilt;
 #endif
 }
 
 int Reweight::GENIEEnumFromName(std::string name) {
 #ifdef __GENIE_ENABLED__
   int genieenum = (int)genie::rew::GSyst::FromString(name);
   return (genieenum > 0) ? genieenum : kNoDialFound;
 #else
   return kGeneratorNotBuilt;
 #endif
 }
 
 int Reweight::T2KEnumFromName(std::string name) {
 #ifdef __T2KREW_ENABLED__
   int t2kenum = (int)t2krew::T2KSyst::FromString(name);
   return (t2kenum > 0) ? t2kenum : kNoDialFound;
 #else
   return kGeneratorNotBuilt;
 #endif
 }
 
 int Reweight::NUISANCEEnumFromName(std::string name, int type) {
   int nuisenum = Reweight::DialList().EnumFromNameAndType(name, type);
   return nuisenum;
 }
 
 int Reweight::CustomEnumFromName(std::string name) {
   int custenum = Reweight::ConvertNUISANCEDial(name);
   return custenum;
 }
 
 int Reweight::ConvDial(std::string name, std::string type, bool exceptions) {
   return Reweight::ConvDial( name, Reweight::ConvDialType(type), exceptions );
 }
 
 int Reweight::ConvDial(std::string name, int type, bool exceptions) {
 
   // Produce offset seperating each type.
   int offset   = type * 1000;
   int genenum = 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;
 
   default:
     genenum = kNoTypeFound;
     break;
 
   }
 
   // Throw if required.
   if (exceptions) {
     // If Not Enabled
     if (genenum == kGeneratorNotBuilt) {
-      ERR(FTL) << "RW Engine not supported for " << FitBase::ConvDialType(type) << endl;
-      ERR(FTL) << "Check dial " << name << endl;
+      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) {
       ERR(FTL) << "Type mismatch inside ConvDialEnum" << std::endl;
       throw;
     }
 
     // If Not Found
     if (genenum == kNoDialFound) {
-      ERR(FTL) << "Dial " << name << " not found." << endl;
+      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) {
     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 8e77e7f..352c230 100644
--- a/src/Reweight/WeightUtils.h
+++ b/src/Reweight/WeightUtils.h
@@ -1,143 +1,143 @@
 #ifndef WEIGHTUTILS_H
 #define WEIGHTUTILS_H
 
 #include "FitLogger.h"
 #include "FitParameters.h"
 #include "FitEvent.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 "NUISANCESyst.h"
 #include "GlobalDialList.h"
 
 namespace FitBase {
 
 TF1 GetRWConvFunction(std::string type, std::string name);
 std::string GetRWUnits(std::string type, std::string name);
 
 double RWSigmaToFrac(std::string type, std::string name, double val);
 double RWSigmaToAbs(std::string type, std::string name, double val);
 double RWAbsToSigma(std::string type, std::string name, double val);
 double RWFracToSigma(std::string type, std::string name, double val);
 
  int ConvDialType(std::string type);
  std::string ConvDialType(int type);
  int GetDialEnum(std::string type, std::string name);
  int GetDialEnum(int type, std::string name);
  static std::map<std::string, int> gNormEnums;
  static std::map<std::string, int> gLikeWeightEnums;
  static std::map<std::string, int> gSplineParameterEnums;
 }
 
 
 namespace Reweight {
 
 	int ConvDial(std::string name, std::string type, bool exceptions=false);
 	int ConvDial(std::string name, int type, bool exceptions=false);
 	std::string ConvDial(int nuisenum);
 
     int ConvDialType(std::string type);
     std::string ConvDialType(int type);
 
 	int NEUTEnumFromName(std::string name);
 	int NIWGEnumFromName(std::string name);
 	int NUWROEnumFromName(std::string name);
 	int T2KEnumFromName(std::string name);
 	int GENIEEnumFromName(std::string name);
 	int CustomEnumFromName(std::string name); 
 	
 	int NUISANCEEnumFromName(std::string name, int type);
 
 	static const int kNoDialFound       = -1;
 	static const int kNoTypeFound       = -2;
 	static const int kGeneratorNotBuilt = -3;
 }
 
 
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/Routines/._CMakeLists.txt~ b/src/Routines/._CMakeLists.txt~
new file mode 100644
index 0000000..89a44f4
Binary files /dev/null and b/src/Routines/._CMakeLists.txt~ differ
diff --git a/src/Routines/CMakeLists.txt b/src/Routines/CMakeLists.txt
index 2f27767..342cc29 100644
--- a/src/Routines/CMakeLists.txt
+++ b/src/Routines/CMakeLists.txt
@@ -1,71 +1,71 @@
 # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 ################################################################################
 #    This file is part of NUISANCE.
 #
 #    NUISANCE is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
 #    (at your option) any later version.
 #
 #    NUISANCE is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #    GNU General Public License for more details.
 #
 #    You should have received a copy of the GNU General Public License
 #    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 ################################################################################
 set(IMPLFILES
 ComparisonRoutines.cxx
 SystematicRoutines.cxx
-ParserUtils.cxx
 SplineRoutines.cxx
 )
 
 if(USE_MINIMIZER)
   set(IMPLFILES ${IMPLFILES};MinimizerRoutines.cxx)
 endif()
 
 set(HEADERFILES
 ComparisonRoutines.h
 SystematicRoutines.h
-ParserUtils.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(${RWENGINE_INCLUDE_DIRECTORIES})
 include_directories(${EXP_INCLUDE_DIRECTORIES})
 
 include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
+include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler)
+include_directories(${CMAKE_SOURCE_DIR}/src/Genie)
 include_directories(${CMAKE_SOURCE_DIR}/src/FCN)
 include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
 include_directories(${CMAKE_SOURCE_DIR}/src/Reweight)
 include_directories(${CMAKE_SOURCE_DIR}/src/Splines)
 include_directories(${CMAKE_SOURCE_DIR}/src/MCStudies)
 
 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/Routines/ComparisonRoutines.cxx b/src/Routines/ComparisonRoutines.cxx
index 7f917c9..acc804d 100755
--- a/src/Routines/ComparisonRoutines.cxx
+++ b/src/Routines/ComparisonRoutines.cxx
@@ -1,534 +1,533 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
-#include "StatusMessage.h"
 #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<std::string> xmlcmds;
   std::vector<std::string> configargs;
 
   // Make easier to handle arguments.
   std::vector<std::string> args = GeneralUtils::LoadCharToVectStr(argc, argv);
   ParserUtils::ParseArgument(args, "-c", fCardFile, true);
   ParserUtils::ParseArgument(args, "-o", fOutputFile, false, false);
   ParserUtils::ParseArgument(args, "-n", maxevents, false, false);
   ParserUtils::ParseArgument(args, "-f", fStrategy, false, false);
   ParserUtils::ParseArgument(args, "-d", fFakeDataInput, false, false);
   ParserUtils::ParseArgument(args, "-i", xmlcmds);
   ParserUtils::ParseArgument(args, "-q", configargs);
   ParserUtils::ParseCounter(args, "e", errorcount);
   ParserUtils::ParseCounter(args, "v", verbocount);
   ParserUtils::CheckBadArguments(args);
 
   // Add extra defaults if none given
   if (fCardFile.empty() and xmlcmds.empty()) {
     ERR(FTL) << "No input supplied!" << std::endl;
     throw;
   }
 
   if (fOutputFile.empty() and !fCardFile.empty()) {
     fOutputFile = fCardFile + ".root";
     ERR(WRN) << "No output supplied so saving it to: " << fOutputFile << std::endl;
 
   } else if (fOutputFile.empty()) {
     ERR(FTL) << "No output file or cardfile supplied!" << std::endl;
     throw;
   }
 
   // Configuration Setup =============================
 
   // Check no comp key is available
   nuiskey fCompKey;
   if (Config::Get().GetNodes("nuiscomp").empty()) {
     fCompKey = Config::Get().CreateNode("nuiscomp");
   } else {
     fCompKey = Config::Get().GetNodes("nuiscomp")[0];
   }
 
   if (!fCardFile.empty())   fCompKey.AddS("cardfile", fCardFile);
   if (!fOutputFile.empty()) fCompKey.AddS("outputfile", fOutputFile);
   if (!fStrategy.empty())   fCompKey.AddS("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]);
   }
 
   // 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");
 
   // Add Error Verbo Lines
   verbocount += Config::Get().GetParI("VERBOSITY");
   errorcount += Config::Get().GetParI("ERROR");
   bool trace = Config::Get().GetParB("TRACE");
   std::cout << "[ NUISANCE ]: Setting VERBOSITY=" << verbocount << std::endl;
   std::cout << "[ NUISANCE ]: Setting ERROR=" << errorcount << std::endl;
   FitPar::log_verb = verbocount;
   LOG_VERB(verbocount);
   ERR_VERB(errorcount);
   SET_TRACE(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<nuiskey> parkeys = Config::QueryKeys("parameter");
   if (!parkeys.empty()) {
     LOG(FIT) << "Number of parameters :  " << parkeys.size() << std::endl;
   }
 
   for (size_t i = 0; i < parkeys.size(); i++) {
     nuiskey key = parkeys.at(i);
 
     // Check for type,name,nom
     if (!key.Has("type")) {
       ERR(FTL) << "No type given for parameter " << i << std::endl;
       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;
     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<nuiskey> samplekeys =  Config::QueryKeys("sample");
   if (!samplekeys.empty()) {
     LOG(FIT) << "Number of samples : " << samplekeys.size() << std::endl;
   }
 
   for (size_t i = 0; i < samplekeys.size(); i++) {
     nuiskey key = samplekeys.at(i);
 
     // Get Sample Options
     std::string samplename = key.GetS("name");
     std::string samplefile = key.GetS("input");
 
     std::string sampletype =
       key.Has("type") ? key.GetS("type") : "DEFAULT";
 
     double samplenorm =
       key.Has("norm") ? key.GetD("norm") : 1.0;
 
     // Print out
     LOG(FIT) << "Read Sample " << 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 + sampletype + "_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<nuiskey> fakekeys = Config::QueryKeys("fakeparameter");
   if (!fakekeys.empty()) {
     LOG(FIT) << "Number of fake parameters : " << fakekeys.size() << std::endl;
   }
 
   for (size_t i = 0; i < fakekeys.size(); i++) {
     nuiskey key = fakekeys.at(i);
 
     // Check for type,name,nom
     if (!key.Has("name")) {
       ERR(FTL) << "No name given for fakeparameter " << i << std::endl;
       throw;
     } else if (!key.Has("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;
   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<std::string, double>& updateVals) {
   //*************************************
 
   for (UInt_t i = 0; i < fParams.size(); i++) {
     std::string name = fParams[i];
 
     if (updateVals.find(name) == updateVals.end()) continue;
     FitBase::GetRW()->SetDialValue(name, updateVals.at(name));
   }
 
   FitBase::GetRW()->Reconfigure();
   return;
 }
 
 //*************************************
 void 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() << endl;
+    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 << endl;
+  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/MinimizerRoutines.cxx b/src/Routines/MinimizerRoutines.cxx
index 1e203cc..c0ac87b 100755
--- a/src/Routines/MinimizerRoutines.cxx
+++ b/src/Routines/MinimizerRoutines.cxx
@@ -1,1452 +1,1450 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
-#include "StatusMessage.h"
-
 #include "MinimizerRoutines.h"
 
 /*
   Constructor/Destructor
 */
 //************************
 void MinimizerRoutines::Init() {
 //************************
 
   fInputFile = "";
   fInputRootFile = NULL;
 
   fOutputFile = "";
   fOutputRootFile = NULL;
 
   fCovar      = NULL;
   fCovFree  = NULL;
   fCorrel     = NULL;
   fCorFree = NULL;
   fDecomp     = NULL;
   fDecFree = NULL;
 
   fStrategy = "Migrad,FixAtLimBreak,Migrad";
   fRoutines.clear();
 
   fCardFile = "";
 
   fFakeDataInput = "";
 
   fSampleFCN    = NULL;
 
   fMinimizer    = NULL;
   fMinimizerFCN = NULL;
   fCallFunctor  = NULL;
 
   fAllowedRoutines = ("Migrad,Simplex,Combined,"
                       "Brute,Fumili,ConjugateFR,"
                       "ConjugatePR,BFGS,BFGS2,"
                       "SteepDesc,GSLSimAn,FixAtLim,FixAtLimBreak"
                       "Chi2Scan1D,Chi2Scan2D,Contours,ErrorBands");
 };
 
 //*************************************
 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<std::string> xmlcmds;
   std::vector<std::string> configargs;
 
   // Make easier to handle arguments.
   std::vector<std::string> args = GeneralUtils::LoadCharToVectStr(argc, argv);
   ParserUtils::ParseArgument(args, "-c", fCardFile, true);
   ParserUtils::ParseArgument(args, "-o", fOutputFile, false, false);
   ParserUtils::ParseArgument(args, "-n", maxevents, false, false);
   ParserUtils::ParseArgument(args, "-f", fStrategy, false, false);
   ParserUtils::ParseArgument(args, "-d", fFakeDataInput, false, false);
   ParserUtils::ParseArgument(args, "-i", xmlcmds);
   ParserUtils::ParseArgument(args, "-q", configargs);
   ParserUtils::ParseCounter(args, "e", errorcount);
   ParserUtils::ParseCounter(args, "v", verbocount);
   ParserUtils::CheckBadArguments(args);
 
   // Add extra defaults if none given
   if (fCardFile.empty() and xmlcmds.empty()) {
     ERR(FTL) << "No input supplied!" << std::endl;
     throw;
   }
 
   if (fOutputFile.empty() and !fCardFile.empty()) {
     fOutputFile = fCardFile + ".root";
     ERR(WRN) << "No output supplied so saving it to: " << fOutputFile << std::endl;
 
   } else if (fOutputFile.empty()) {
     ERR(FTL) << "No output file or cardfile supplied!" << std::endl;
     throw;
   }
 
   // Configuration Setup =============================
 
   // Check no comp key is available
   nuiskey fCompKey;
   if (Config::Get().GetNodes("nuiscomp").empty()) {
     fCompKey = Config::Get().CreateNode("nuiscomp");
   } else {
     fCompKey = Config::Get().GetNodes("nuiscomp")[0];
   }
 
   if (!fCardFile.empty())   fCompKey.AddS("cardfile", fCardFile);
   if (!fOutputFile.empty()) fCompKey.AddS("outputfile", fOutputFile);
   if (!fStrategy.empty())   fCompKey.AddS("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]);
   }
 
   // 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");
 
   // Add Error Verbo Lines
   verbocount += Config::Get().GetParI("VERBOSITY");
   errorcount += Config::Get().GetParI("ERROR");
   std::cout << "[ NUISANCE ]: Setting VERBOSITY=" << verbocount << std::endl;
   std::cout << "[ NUISANCE ]: Setting ERROR=" << errorcount << std::endl;
   FitPar::log_verb = verbocount;
   LOG_VERB(verbocount);
   ERR_VERB(errorcount);
 
   // Minimizer Setup ========================================
   fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE");
   SetupMinimizerFromXML();
 
   SetupCovariance();
   SetupRWEngine();
   SetupFCN();
 
   return;
 };
 
 //*************************************
 void MinimizerRoutines::SetupMinimizerFromXML() {
 //*************************************
 
   LOG(FIT) << "Setting up nuismin" << std::endl;
 
   // Setup Parameters ------------------------------------------
   std::vector<nuiskey> parkeys = Config::QueryKeys("parameter");
   if (!parkeys.empty()) {
     LOG(FIT) << "Number of parameters :  " << parkeys.size() << std::endl;
   }
 
   for (size_t i = 0; i < parkeys.size(); i++) {
     nuiskey key = parkeys.at(i);
 
     // Check for type,name,nom
     if (!key.Has("type")) {
       ERR(FTL) << "No type given for parameter " << i << std::endl;
       throw;
     } else if (!key.Has("name")) {
       ERR(FTL) << "No name given for parameter " << i << std::endl;
       throw;
     } else if (!key.Has("nominal")) {
       ERR(FTL) << "No nominal given for parameter " << i << std::endl;
       throw;
     }
 
     // Get Inputs
     std::string partype = key.GetS("type");
     std::string parname = key.GetS("name");
     double parnom  = key.GetD("nominal");
     double parlow  = parnom - 1;
     double parhigh = parnom + 1;
     double parstep = 1;
     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<nuiskey> samplekeys =  Config::QueryKeys("sample");
   if (!samplekeys.empty()) {
     LOG(FIT) << "Number of samples : " << samplekeys.size() << std::endl;
   }
 
   for (size_t i = 0; i < samplekeys.size(); i++) {
     nuiskey key = samplekeys.at(i);
 
     // Get Sample Options
     std::string samplename = key.GetS("name");
     std::string samplefile = key.GetS("input");
 
     std::string sampletype =
       key.Has("type") ? key.GetS("type") : "DEFAULT";
 
     double samplenorm =
       key.Has("norm") ? key.GetD("norm") : 1.0;
 
     // Print out
     LOG(FIT) << "Read sample info " << i << " : "
              << samplename << std::endl
              << "\t\t input -> " << samplefile  << std::endl
              << "\t\t state -> " << sampletype << std::endl
              << "\t\t norm  -> " << samplenorm << std::endl;
 
     // If FREE add to parameters otherwise continue
     if (sampletype.find("FREE") == std::string::npos) {
       continue;
     }
 
     // Form norm dial from samplename + sampletype + "_norm";
     std::string normname = samplename + sampletype + "_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<nuiskey> fakekeys = Config::QueryKeys("fakeparameter");
   if (!fakekeys.empty()) {
     LOG(FIT) << "Number of fake parameters : " << fakekeys.size() << std::endl;
   }
 
   for (size_t i = 0; i < fakekeys.size(); i++) {
     nuiskey key = fakekeys.at(i);
 
     // Check for type,name,nom
     if (!key.Has("name")) {
       ERR(FTL) << "No name given for fakeparameter " << i << std::endl;
       throw;
     } else if (!key.Has("nom")) {
       ERR(FTL) << "No nominal given for fakeparameter " << i << std::endl;
       throw;
     }
 
     // Get Inputs
     std::string parname = key.GetS("name");
     double parnom  = key.GetD("nom");
 
     // Push into vectors
     fFakeVals[parname] = parnom;
   }
 
 
 }
 
 
 /*
   Setup Functions
 */
 //*************************************
 void MinimizerRoutines::SetupRWEngine() {
 //*************************************
 
   for (UInt_t i = 0; i < fParams.size(); i++) {
     std::string name = fParams[i];
     FitBase::GetRW() -> IncludeDial(name, fTypeVals.at(name) );
   }
   UpdateRWEngine(fStartVals);
 
   return;
 }
 
 //*************************************
 void MinimizerRoutines::SetupFCN() {
 //*************************************
 
   LOG(FIT) << "Making the jointFCN" << std::endl;
   if (fSampleFCN) delete fSampleFCN;
   // fSampleFCN = new JointFCN(fCardFile, fOutputRootFile);
   fSampleFCN = new JointFCN(fOutputRootFile);
   
   SetFakeData();
 
   fMinimizerFCN = new MinimizerFCN( fSampleFCN );
   fCallFunctor  = new ROOT::Math::Functor( *fMinimizerFCN, fParams.size() );
 
   fSampleFCN->CreateIterationTree( "fit_iterations", FitBase::GetRW() );
 
   return;
 }
 
 
 //******************************************
 void MinimizerRoutines::SetupFitter(std::string routine) {
 //******************************************
 
   // Make the fitter
   std::string fitclass = "";
   std::string fittype  = "";
 
   // Get correct types
   if      (!routine.compare("Migrad"))      {
     fitclass = "Minuit2"; fittype = "Migrad";
   } else if (!routine.compare("Simplex"))     {
     fitclass = "Minuit2"; fittype = "Simplex";
   } else if (!routine.compare("Combined"))    {
     fitclass = "Minuit2"; fittype = "Combined";
   } else if (!routine.compare("Brute"))       {
     fitclass = "Minuit2"; fittype = "Scan";
   } else if (!routine.compare("Fumili"))      {
     fitclass = "Minuit2"; fittype = "Fumili";
   } else if (!routine.compare("ConjugateFR")) {
     fitclass = "GSLMultiMin"; fittype = "ConjugateFR";
   } else if (!routine.compare("ConjugatePR")) {
     fitclass = "GSLMultiMin"; fittype = "ConjugatePR";
   } else if (!routine.compare("BFGS"))        {
     fitclass = "GSLMultiMin"; fittype = "BFGS";
   } else if (!routine.compare("BFGS2"))       {
     fitclass = "GSLMultiMin"; fittype = "BFGS2";
   } else if (!routine.compare("SteepDesc"))   {
     fitclass = "GSLMultiMin"; fittype = "SteepestDescent";
     //  } else if (!routine.compare("GSLMulti"))    { fitclass = "GSLMultiFit"; fittype = "";         // Doesn't work out of the box
   } else if (!routine.compare("GSLSimAn"))    { fitclass = "GSLSimAn"; fittype = "";   }
 
   // make minimizer
   if (fMinimizer) delete fMinimizer;
   fMinimizer = ROOT::Math::Factory::CreateMinimizer(fitclass, fittype);
 
   fMinimizer->SetMaxFunctionCalls(FitPar::Config().GetParI("minimizer.maxcalls"));
 
   if (!routine.compare("Brute")) {
     fMinimizer->SetMaxFunctionCalls(fParams.size() * fParams.size() * 4);
     fMinimizer->SetMaxIterations(fParams.size() * fParams.size() * 4);
   }
 
   fMinimizer->SetMaxIterations(FitPar::Config().GetParI("minimizer.maxiterations"));
   fMinimizer->SetTolerance(FitPar::Config().GetParD("minimizer.tolerance"));
   fMinimizer->SetStrategy(FitPar::Config().GetParI("minimizer.strategy"));
   fMinimizer->SetFunction(*fCallFunctor);
 
   int ipar = 0;
   //Add Fit Parameters
   for (UInt_t i = 0; i < fParams.size(); i++) {
     std::string syst = fParams.at(i);
 
     bool fixed = true;
     double vstart, vstep, vlow, vhigh;
     vstart = vstep = vlow = vhigh = 0.0;
 
     if (fCurVals.find(syst) != fCurVals.end()  ) vstart = fCurVals.at(syst);
     if (fMinVals.find(syst)  != fMinVals.end() ) vlow   = fMinVals.at(syst);
     if (fMaxVals.find(syst)  != fMaxVals.end() ) vhigh  = fMaxVals.at(syst);
     if (fStepVals.find(syst) != fStepVals.end()) vstep  = fStepVals.at(syst);
     if (fFixVals.find(syst)  != fFixVals.end() ) fixed  = fFixVals.at(syst);
 
     // fix for errors
     if (vhigh == vlow) vhigh += 1.0;
 
     fMinimizer->SetVariable(ipar, syst, vstart, vstep);
     fMinimizer->SetVariableLimits(ipar, vlow, vhigh);
 
     if (fixed) {
 
       fMinimizer->FixVariable(ipar);
       LOG(FIT) << "Fixed Param: " << syst << std::endl;
 
     } else {
 
       LOG(FIT) << "Free  Param: " << syst
                << " Start:" << vstart
                << " Range:" << vlow << " to " << vhigh
                << " Step:" << vstep << std::endl;
     }
 
     ipar++;
   }
 
   LOG(FIT) << "Setup Minimizer: " << fMinimizer->NDim() << "(NDim) " << fMinimizer->NFree() << "(NFree)" << std::endl;
 
   return;
 }
 
 //*************************************
 // Set fake data from user input
 void MinimizerRoutines::SetFakeData() {
 //*************************************
 
   // If the fake data input field (-d) isn't provided, return to caller
   if (fFakeDataInput.empty()) return;
 
   // If user specifies -d MC we set the data to the MC
   // User can also specify fake data parameters to reweight by doing "fake_parameter" in input card file
   // "fake_parameter" gets read in ReadCard function (reads to fFakeVals)
   if (fFakeDataInput.compare("MC") == 0) {
 
     LOG(FIT) << "Setting fake data from MC starting prediction." << std::endl;
     // fFakeVals get read in in ReadCard
     UpdateRWEngine(fFakeVals);
 
     // Reconfigure the reweight engine
     FitBase::GetRW()->Reconfigure();
     // Reconfigure all the samples to the new reweight
     fSampleFCN->ReconfigureAllEvents();
     // Feed on and set the fake-data in each measurement class
     fSampleFCN->SetFakeData("MC");
 
     // Changed the reweight engine values back to the current values
     // So we start the fit at a different value than what we set the fake-data to
     UpdateRWEngine(fCurVals);
 
     LOG(FIT) << "Set all data to fake MC predictions." << std::endl;
   } else {
     fSampleFCN->SetFakeData(fFakeDataInput);
   }
 
   return;
 }
 
 /*
   Fitting Functions
 */
 //*************************************
 void MinimizerRoutines::UpdateRWEngine(std::map<std::string, double>& updateVals) {
 //*************************************
 
   for (UInt_t i = 0; i < fParams.size(); i++) {
     std::string name = fParams[i];
 
     if (updateVals.find(name) == updateVals.end()) continue;
     FitBase::GetRW()->SetDialValue(name, updateVals.at(name));
   }
 
   FitBase::GetRW()->Reconfigure();
   return;
 }
 
 //*************************************
 void MinimizerRoutines::Run() {
 //*************************************
 
   LOG(FIT) << "Running MinimizerRoutines : " << fStrategy << std::endl;
   if (FitPar::Config().GetParB("save_nominal")) {
     SaveNominal();
   }
 
   // Parse given routines
   fRoutines = GeneralUtils::ParseToStr(fStrategy,",");
   if (fRoutines.empty()){
     ERR(FTL) << "Trying to run MinimizerRoutines with no routines given!" << std::endl;
     throw;
   }
 
   for (UInt_t i = 0; i < fRoutines.size(); i++) {
 
     std::string routine = fRoutines.at(i);
     int fitstate = kFitUnfinished;
     LOG(FIT) << "Running Routine: " << routine << std::endl;
 
     // Try Routines
     if (routine.find("LowStat") != std::string::npos) LowStatRoutine(routine);
     else if (routine == "FixAtLim")  FixAtLimit();
     else if (routine == "FixAtLimBreak") fitstate = FixAtLimit();
     else if (routine.find("ErrorBands") != std::string::npos) GenerateErrorBands();
     else if (!routine.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." << endl;
+      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 (fMinimizer->NFree() > 0) {
-      LOG(FIT) << StatusMessage(fMinimizer->Minimize()) << std::endl;
+      LOG(FIT) << fMinimizer->Minimize() << std::endl;
       GetMinimizerState();
     }
   }
 
   // other otptions
   else if (!routine.compare("Contour")) {
     CreateContours();
   }
 
   return endfits;
 }
 
 //*************************************
 void MinimizerRoutines::PrintState() {
 //*************************************
   LOG(FIT) << "------------" << std::endl;
 
   // Count max size
   int maxcount = 0;
   for (UInt_t i = 0; i < fParams.size(); i++) {
     maxcount = max(int(fParams[i].size()), maxcount);
   }
 
   // Header
   LOG(FIT) << " #    " << left << setw(maxcount) << "Parameter "
            << " = "
            << setw(10) << "Value"     << " +- "
            << setw(10) << "Error"     << " "
            << setw(8)  << "(Units)"   << " "
            << setw(10) << "Conv. Val" << " +- "
            << setw(10) << "Conv. Err" << " "
            << setw(8)  << "(Units)"   << std::endl;
 
   // Parameters
   for (UInt_t i = 0; i < fParams.size(); i++) {
     std::string syst = fParams.at(i);
 
     std::string typestr  = FitBase::ConvDialType(fTypeVals[syst]);
     std::string curunits = "(sig.)";
     double      curval   = fCurVals[syst];
     double      curerr   = fErrorVals[syst];
 
     if (fStateVals[syst].find("ABS") != std::string::npos) {
       curval = FitBase::RWSigmaToAbs(typestr, syst, curval);
       curerr = (FitBase::RWSigmaToAbs(typestr, syst, curerr) -
                 FitBase::RWSigmaToAbs(typestr, syst, 0.0));
       curunits = "(Abs.)";
     } else if (fStateVals[syst].find("FRAC") != std::string::npos) {
       curval = FitBase::RWSigmaToFrac(typestr, syst, curval);
       curerr = (FitBase::RWSigmaToFrac(typestr, syst, curerr) -
                 FitBase::RWSigmaToFrac(typestr, syst, 0.0));
       curunits = "(Frac)";
     }
 
     std::string convunits = "(" + FitBase::GetRWUnits(typestr, syst) + ")";
     double      convval   = FitBase::RWSigmaToAbs(typestr, syst, curval);
     double      converr   = (FitBase::RWSigmaToAbs(typestr, syst, curerr) -
                              FitBase::RWSigmaToAbs(typestr, syst, 0.0));
 
     std::ostringstream curparstring;
 
     curparstring << " " << setw(3) << left
                  << i << ". "
                  << setw(maxcount) << syst << " = "
                  << setw(10) << curval     << " +- "
                  << setw(10) << curerr     << " "
                  << setw(8)  << curunits   << " "
                  << setw(10) << convval    << " +- "
                  << setw(10) << converr    << " "
                  << setw(8)  << convunits;
 
 
-    LOG(FIT) << curparstring.str() << endl;
+    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 << 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();
   //  int ipar = 0;
 
   for (UInt_t i = 0; i < fParams.size(); i++) {
     std::string syst = fParams.at(i);
 
     fCurVals[syst]   = values[i];
     fErrorVals[syst] = errors[i];
   }
 
   PrintState();
 
   // Covar
   SetupCovariance();
   if (fMinimizer->CovMatrixStatus() > 0) {
 
     // Fill Full Covar
     for (int i = 0; i < fCovar->GetNbinsX(); i++) {
       for (int j = 0; j < fCovar->GetNbinsY(); j++) {
         fCovar->SetBinContent(i + 1, j + 1, fMinimizer->CovMatrix(i, j));
       }
     }
 
     int freex = 0;
     int freey = 0;
     for (int i = 0; i < fCovar->GetNbinsX(); i++) {
       if (fMinimizer->IsFixedVariable(i)) continue;
       freey = 0;
 
       for (int j = 0; j < fCovar->GetNbinsY(); j++) {
         if (fMinimizer->IsFixedVariable(j)) continue;
 
         fCovFree->SetBinContent(freex + 1, freey + 1, fMinimizer->CovMatrix(i, j));
         freey++;
       }
       freex++;
     }
 
     fCorrel     = PlotUtils::GetCorrelationPlot(fCovar, "correlation");
     fDecomp     = PlotUtils::GetDecompPlot(fCovar, "decomposition");
     if (fMinimizer->NFree() > 0) {
       fCorFree = PlotUtils::GetCorrelationPlot(fCovFree, "correlation_free");
       fDecFree = PlotUtils::GetDecompPlot(fCovFree, "decomposition_free");
     }
   }
 
 
   return;
 };
 
 //*************************************
 void MinimizerRoutines::LowStatRoutine(std::string routine) {
 //*************************************
 
   LOG(FIT) << "Running Low Statistics Routine: " << routine << std::endl;
   int lowstatsevents = FitPar::Config().GetParI("minimizer.lowstatevents");
   int maxevents      = FitPar::Config().GetParI("input.maxevents");
   int verbosity      = FitPar::Config().GetParI("VERBOSITY");
 
   std::string trueroutine = routine;
   std::string substring = "LowStat";
   trueroutine.erase( trueroutine.find(substring),
                      substring.length() );
 
   // Set MAX EVENTS=1000
   FitPar::Config().SetParI("input.maxevents", lowstatsevents);
   FitPar::Config().SetParI("VERBOSITY", 3);
   SetupFCN();
 
   RunFitRoutine(trueroutine);
 
   FitPar::Config().SetParI("input.maxevents", maxevents);
   SetupFCN();
 
   FitPar::Config().SetParI("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] << endl;
+    LOG(FIT) << "Running 1D Scan for " << fParams[i] << std::endl;
     fSampleFCN->CreateIterationTree(fParams[i] +
                                     "_scan1D_iterations",
                                     FitBase::GetRW());
 
     double scanmiddlepoint = fCurVals[fParams[i]];
 
     // Determine N points needed
     double limlow  = fMinVals[fParams[i]];
     double limhigh = fMaxVals[fParams[i]];
     double step    = fStepVals[fParams[i]];
 
     int npoints = int( fabs(limhigh - limlow) / (step + 0.) );
 
     TH1D* contour = new TH1D(("Chi2Scan1D_" + fParams[i]).c_str(),
                              ("Chi2Scan1D_" + fParams[i] +
                               ";" + fParams[i]).c_str(),
                              npoints, limlow, limhigh);
 
     // Fill bins
     for (int x = 0; x < contour->GetNbinsX(); x++) {
 
       // Set X Val
       fCurVals[fParams[i]] = contour->GetXaxis()->GetBinCenter(x + 1);
 
       // Run Eval
       double *vals = FitUtils::GetArrayFromMap( fParams, fCurVals );
       double  chi2 = fSampleFCN->DoEval( vals );
       delete vals;
 
       // Fill Contour
       contour->SetBinContent(x + 1, chi2);
     }
 
     // Save contour
     contour->Write();
 
     // Reset Parameter
     fCurVals[fParams[i]] = scanmiddlepoint;
 
     // Save TTree
     fSampleFCN->WriteIterationTree();
   }
 
   return;
 }
 
 //*************************************
 void MinimizerRoutines::Chi2Scan2D() {
 //*************************************
 
   // Chi2 Scan 2D
   // Creates a 2D chi2 scan by stepping through all free parameters
   // Works for all pairwise combos of free parameters
 
   // Scan I
   for (UInt_t i = 0; i < fParams.size(); i++) {
     if (fFixVals[fParams[i]]) continue;
 
     // Scan J
     for (UInt_t j = 0; j < i; j++) {
       if (fFixVals[fParams[j]]) continue;
 
       fSampleFCN->CreateIterationTree( fParams[i] + "_" +
                                        fParams[j] + "_" +
                                        "scan2D_iterations",
                                        FitBase::GetRW() );
 
       double scanmid_i = fCurVals[fParams[i]];
       double scanmid_j = fCurVals[fParams[j]];
 
       double limlow_i  = fMinVals[fParams[i]];
       double limhigh_i = fMaxVals[fParams[i]];
       double step_i    = fStepVals[fParams[i]];
 
       double limlow_j  = fMinVals[fParams[j]];
       double limhigh_j = fMaxVals[fParams[j]];
       double step_j    = fStepVals[fParams[j]];
 
       int npoints_i = int( fabs(limhigh_i - limlow_i) / (step_i + 0.) ) + 1;
       int npoints_j = int( fabs(limhigh_j - limlow_j) / (step_j + 0.) ) + 1;
 
       TH2D* contour = new TH2D(("Chi2Scan2D_" + fParams[i] + "_" + fParams[j]).c_str(),
                                ("Chi2Scan2D_" + fParams[i] + "_" + fParams[j] +
                                 ";" + fParams[i] + ";" + fParams[j]).c_str(),
                                npoints_i, limlow_i, limhigh_i,
                                npoints_j, limlow_j, limhigh_j );
 
       // Begin Scan
-      LOG(FIT) << "Running scan for " << fParams[i] << " " << fParams[j] << 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 );
           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!" << 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!" << endl;
+    LOG(FIT) << "No dials needed fixing!" << std::endl;
     return kNoChange;
   } else return kStateChange;
 }
 
 
 /*
   Write Functions
 */
 //*************************************
 void MinimizerRoutines::SaveResults() {
 //*************************************
 
   fOutputRootFile->cd();
 
   if (fMinimizer) {
     SetupCovariance();
     SaveMinimizerState();
   }
 
   SaveCurrentState();
 
 }
 
 //*************************************
 void MinimizerRoutines::SaveMinimizerState() {
 //*************************************
 
   if (!fMinimizer) {
-    ERR(FTL) << "Can't save minimizer state without min object" << endl;
+    ERR(FTL) << "Can't save minimizer state without min object" << std::endl;
     throw;
   }
 
   // Save main fit tree
   fSampleFCN->WriteIterationTree();
 
   // Get Vals and Errors
   GetMinimizerState();
 
   // Save tree with fit status
   std::vector<std::string> nameVect;
   std::vector<double>      valVect;
   std::vector<double>      errVect;
   std::vector<double>      minVect;
   std::vector<double>      maxVect;
   std::vector<double>      startVect;
   std::vector<int>      endfixVect;
   std::vector<int>      startfixVect;
 
   //  int NFREEPARS = fMinimizer->NFree();
   int NPARS = fMinimizer->NDim();
 
   int ipar = 0;
   // Dial Vals
   for (UInt_t i = 0; i < fParams.size(); i++) {
     std::string name = fParams.at(i);
 
     nameVect    .push_back( name );
 
     valVect     .push_back( fCurVals.at(name)   );
     errVect     .push_back( fErrorVals.at(name) );
     minVect     .push_back( fMinVals.at(name)   );
     maxVect     .push_back( fMaxVals.at(name)   );
 
     startVect   .push_back( fStartVals.at(name) );
     endfixVect  .push_back( fFixVals.at(name)      );
     startfixVect.push_back( fStartFixVals.at(name) );
 
     ipar++;
   }
 
   int NFREE = fMinimizer->NFree();
   int NDIM  = fMinimizer->NDim();
 
   double CHI2 = fSampleFCN->GetLikelihood();
   int NBINS = fSampleFCN->GetNDOF();
   int NDOF = NBINS - NFREE;
 
   // Write fit results
   TTree* fit_tree = new TTree("fit_result", "fit_result");
   fit_tree->Branch("parameter_names", &nameVect);
   fit_tree->Branch("parameter_values", &valVect);
   fit_tree->Branch("parameter_errors", &errVect);
   fit_tree->Branch("parameter_min", &minVect);
   fit_tree->Branch("parameter_max", &maxVect);
   fit_tree->Branch("parameter_start", &startVect);
   fit_tree->Branch("parameter_fix", &endfixVect);
   fit_tree->Branch("parameter_startfix", &startfixVect);
   fit_tree->Branch("CHI2", &CHI2, "CHI2/D");
   fit_tree->Branch("NDOF", &NDOF, "NDOF/I");
   fit_tree->Branch("NBINS", &NBINS, "NBINS/I");
   fit_tree->Branch("NDIM", &NDIM, "NDIM/I");
   fit_tree->Branch("NFREE", &NFREE, "NFREE/I");
   fit_tree->Fill();
   fit_tree->Write();
 
   // Make dial variables
   TH1D dialvar  = TH1D("fit_dials", "fit_dials", NPARS, 0, NPARS);
   TH1D startvar = TH1D("start_dials", "start_dials", NPARS, 0, NPARS);
   TH1D minvar   = TH1D("min_dials", "min_dials", NPARS, 0, NPARS);
   TH1D maxvar   = TH1D("max_dials", "max_dials", NPARS, 0, NPARS);
 
   TH1D dialvarfree  = TH1D("fit_dials_free", "fit_dials_free", NFREE, 0, NFREE);
   TH1D startvarfree = TH1D("start_dials_free", "start_dials_free", NFREE, 0, NFREE);
   TH1D minvarfree   = TH1D("min_dials_free", "min_dials_free", NFREE, 0, NFREE);
   TH1D maxvarfree   = TH1D("max_dials_free", "max_dials_free", NFREE, 0, NFREE);
 
   int freecount = 0;
 
   for (UInt_t i = 0; i < nameVect.size(); i++) {
     std::string name = nameVect.at(i);
 
     dialvar.SetBinContent(i + 1, valVect.at(i));
     dialvar.SetBinError(i + 1, errVect.at(i));
     dialvar.GetXaxis()->SetBinLabel(i + 1, name.c_str());
 
     startvar.SetBinContent(i + 1, startVect.at(i));
     startvar.GetXaxis()->SetBinLabel(i + 1, name.c_str());
 
     minvar.SetBinContent(i + 1,   minVect.at(i));
     minvar.GetXaxis()->SetBinLabel(i + 1, name.c_str());
 
     maxvar.SetBinContent(i + 1,   maxVect.at(i));
     maxvar.GetXaxis()->SetBinLabel(i + 1, name.c_str());
 
     if (NFREE > 0) {
       if (!startfixVect.at(i)) {
         freecount++;
 
         dialvarfree.SetBinContent(freecount, valVect.at(i));
         dialvarfree.SetBinError(freecount, errVect.at(i));
         dialvarfree.GetXaxis()->SetBinLabel(freecount, name.c_str());
 
         startvarfree.SetBinContent(freecount, startVect.at(i));
         startvarfree.GetXaxis()->SetBinLabel(freecount, name.c_str());
 
         minvarfree.SetBinContent(freecount,   minVect.at(i));
         minvarfree.GetXaxis()->SetBinLabel(freecount, name.c_str());
 
         maxvarfree.SetBinContent(freecount,   maxVect.at(i));
         maxvarfree.GetXaxis()->SetBinLabel(freecount, name.c_str());
 
       }
     }
   }
 
   // Save Dial Plots
   dialvar.Write();
   startvar.Write();
   minvar.Write();
   maxvar.Write();
 
   if (NFREE > 0) {
     dialvarfree.Write();
     startvarfree.Write();
     minvarfree.Write();
     maxvarfree.Write();
   }
 
   // Save fit_status plot
   TH1D statusplot = TH1D("fit_status", "fit_status", 8, 0, 8);
   std::string fit_labels[8] = {"status", "cov_status",  \
                                "maxiter", "maxfunc",  \
                                "iter",    "func", \
                                "precision", "tolerance"
                               };
   double fit_vals[8];
   fit_vals[0] = fMinimizer->Status() + 0.;
   fit_vals[1] = fMinimizer->CovMatrixStatus() + 0.;
   fit_vals[2] = fMinimizer->MaxIterations() + 0.;
   fit_vals[3] = fMinimizer->MaxFunctionCalls() + 0.;
   fit_vals[4] = fMinimizer->NIterations() + 0.;
   fit_vals[5] = fMinimizer->NCalls() + 0.;
   fit_vals[6] = fMinimizer->Precision() + 0.;
   fit_vals[7] = fMinimizer->Tolerance() + 0.;
 
   for (int i = 0; i < 8; i++) {
     statusplot.SetBinContent(i + 1, fit_vals[i]);
     statusplot.GetXaxis()->SetBinLabel(i + 1, fit_labels[i].c_str());
   }
 
   statusplot.Write();
 
   // Save Covars
   if (fCovar) fCovar->Write();
   if (fCovFree) fCovFree->Write();
   if (fCorrel) fCorrel->Write();
   if (fCorFree) fCorFree->Write();
   if (fDecomp) fDecomp->Write();
   if (fDecFree) fDecFree->Write();
 
   return;
 }
 
 //*************************************
 void MinimizerRoutines::SaveCurrentState(std::string subdir) {
 //*************************************
 
   LOG(FIT) << "Saving current full FCN predictions" << std::endl;
 
   // Setup DIRS
   TDirectory* curdir = gDirectory;
   if (!subdir.empty()) {
     TDirectory* newdir = (TDirectory*) gDirectory->mkdir(subdir.c_str());
     newdir->cd();
   }
 
   FitBase::GetRW()->Reconfigure();
   fSampleFCN->ReconfigureAllEvents();
   fSampleFCN->Write();
 
   // Change back to current DIR
   curdir->cd();
 
   return;
 }
 
 //*************************************
 void MinimizerRoutines::SaveNominal() {
 //*************************************
 
   fOutputRootFile->cd();
 
   LOG(FIT) << "Saving Nominal Predictions (be cautious with this)" << std::endl;
   FitBase::GetRW()->Reconfigure();
   SaveCurrentState("nominal");
 
 };
 
 //*************************************
 void MinimizerRoutines::SavePrefit() {
 //*************************************
 
   fOutputRootFile->cd();
 
   LOG(FIT) << "Saving Prefit Predictions" << std::endl;
   UpdateRWEngine(fStartVals);
   SaveCurrentState("prefit");
   UpdateRWEngine(fCurVals);
 
 };
 
 
 /*
   MISC Functions
 */
 //*************************************
 int MinimizerRoutines::GetStatus() {
 //*************************************
 
   return 0;
 }
 
 //*************************************
 void MinimizerRoutines::SetupCovariance() {
 //*************************************
 
   // Remove covares if they exist
   if (fCovar) delete fCovar;
   if (fCovFree) delete fCovFree;
   if (fCorrel) delete fCorrel;
   if (fCorFree) delete fCorFree;
   if (fDecomp) delete fDecomp;
   if (fDecFree) delete fDecFree;
 
-  LOG(FIT) << "Building covariance matrix.." << endl;
+  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) {
     NFREE = fMinimizer->NFree();
     NDIM  = fMinimizer->NDim();
   } else {
     NDIM = fParams.size();
     for (UInt_t i = 0; i < fParams.size(); i++) {
       if (!fFixVals[fParams[i]]) NFREE++;
     }
   }
 
   if (NDIM == 0) return;
-  LOG(FIT) << "NFREE == " << NFREE << endl;
+  LOG(FIT) << "NFREE == " << NFREE << std::endl;
   fCovar = new TH2D("covariance", "covariance", NDIM, 0, NDIM, NDIM, 0, NDIM);
   if (NFREE > 0) {
     fCovFree = new TH2D("covariance_free",
                         "covariance_free",
                         NFREE, 0, NFREE,
                         NFREE, 0, NFREE);
   } else {
     fCovFree = NULL;
   }
 
   // Set Bin Labels
   int countall = 0;
   int countfree = 0;
   for (UInt_t i = 0; i < fParams.size(); i++) {
 
     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++;
     }
   }
 
   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;
   }
 
   return;
 };
 
 //*************************************
 void MinimizerRoutines::ThrowCovariance(bool uniformly) {
 //*************************************
   std::vector<double> rands;
 
   if (!fDecFree) {
     ERR(WRN) << "Trying to throw 0 free parameters" << std::endl;
     return;
   }
 
   // Generate Random Gaussians
   for (Int_t i = 0; i < fDecFree->GetNbinsX(); i++) {
     rands.push_back(gRandom->Gaus(0.0, 1.0));
   }
 
   // Reset Thrown Values
   for (UInt_t i = 0; i < fParams.size(); i++) {
     fThrownVals[fParams[i]] = fCurVals[fParams[i]];
   }
 
   // Loop and get decomp
   for (Int_t i = 0; i < fDecFree->GetNbinsX(); i++) {
 
     std::string parname = std::string(fDecFree->GetXaxis()->GetBinLabel(i + 1));
     double mod = 0.0;
 
     if (!uniformly) {
       for (Int_t j = 0; j < fDecFree->GetNbinsY(); j++) {
         mod += rands[j] * fDecFree->GetBinContent(j + 1, i + 1);
       }
     }
 
     if (fCurVals.find(parname) != fCurVals.end()) {
 
       if (uniformly) fThrownVals[parname] = gRandom->Uniform(fMinVals[parname], fMaxVals[parname]);
       else {  fThrownVals[parname] =    fCurVals[parname] + mod; }
 
     }
   }
 
   // Check Limits
   for (UInt_t i = 0; i < fParams.size(); i++) {
     std::string syst = fParams[i];
     if (fFixVals[syst]) continue;
     if (fThrownVals[syst] < fMinVals[syst]) fThrownVals[syst] = fMinVals[syst];
     if (fThrownVals[syst] > fMaxVals[syst]) fThrownVals[syst] = fMaxVals[syst];
   }
 
   return;
 };
 
 //*************************************
 void MinimizerRoutines::GenerateErrorBands() {
 //*************************************
 
   TDirectory* errorDIR = (TDirectory*) fOutputRootFile->mkdir("error_bands");
   errorDIR->cd();
 
   // Make a second file to store throws 
   std::string tempFileName = fOutputFile;
   if (tempFileName.find(".root") != std::string::npos) tempFileName.erase(tempFileName.find(".root"), 5);
   tempFileName += ".throws.root";
   TFile* tempfile = new TFile(tempFileName.c_str(),"RECREATE");
 
   tempfile->cd();
   int nthrows = FitPar::Config().GetParI("error_throws");
 
   UpdateRWEngine(fCurVals);
   fSampleFCN->ReconfigureAllEvents();
 
   TDirectory* nominal = (TDirectory*) tempfile->mkdir("nominal");
   nominal->cd();
   fSampleFCN->Write();
 
 
   TDirectory* outnominal = (TDirectory*) fOutputRootFile->mkdir("nominal_throw");
   outnominal->cd();
   fSampleFCN->Write();
 
 
   errorDIR->cd();
   TTree* parameterTree = new TTree("throws", "throws");
   double chi2;
   for (UInt_t i = 0; i < fParams.size(); i++)
     parameterTree->Branch(fParams[i].c_str(), &fThrownVals[fParams[i]], (fParams[i] + "/D").c_str());
   parameterTree->Branch("chi2", &chi2, "chi2/D");
 
 
   bool uniformly = FitPar::Config().GetParB("error_uniform");
 
   // Run Throws and save
   for (Int_t i = 0; i < nthrows; i++) {
 
     TDirectory* throwfolder = (TDirectory*)tempfile->mkdir(Form("throw_%i", i));
     throwfolder->cd();
 
     // Generate Random Parameter Throw
     ThrowCovariance(uniformly);
 
     // Run Eval
     double *vals = FitUtils::GetArrayFromMap( fParams, fThrownVals );
     chi2 = fSampleFCN->DoEval( vals );
     delete vals;
 
     // Save the FCN
     fSampleFCN->Write();
 
     parameterTree->Fill();
   }
 
   errorDIR->cd();
   fDecFree->Write();
   fCovFree->Write();
   parameterTree->Write();
 
   delete parameterTree;
 
   // Now go through the keys in the temporary file and look for TH1D, and TH2D plots
   TIter next(nominal->GetListOfKeys());
   TKey *key;
   while ((key = (TKey*)next())) {
     TClass *cl = gROOT->GetClass(key->GetClassName());
     if (!cl->InheritsFrom("TH1D") and !cl->InheritsFrom("TH2D")) continue;
     TH1D *baseplot = (TH1D*)key->ReadObj();
     std::string plotname = std::string(baseplot->GetName());
 
     int nbins = baseplot->GetNbinsX() * baseplot->GetNbinsY();
 
     // Setup TProfile with RMS option
     TProfile* tprof = new TProfile((plotname + "_prof").c_str(), (plotname + "_prof").c_str(), nbins, 0, nbins, "S");
 
     // Setup The TTREE
     double* bincontents;
     bincontents = new double[nbins];
 
     double* binlowest;
     binlowest = new double[nbins];
 
     double* binhighest;
     binhighest = new double[nbins];
 
     errorDIR->cd();
     TTree* bintree = new TTree((plotname + "_tree").c_str(), (plotname + "_tree").c_str());
     for (Int_t i = 0; i < nbins; i++) {
       bincontents[i] = 0.0;
       binhighest[i] = 0.0;
       binlowest[i] = 0.0;
       bintree->Branch(Form("content_%i", i), &bincontents[i], Form("content_%i/D", i));
     }
 
     for (Int_t i = 0; i < nthrows; i++) {
       TH1* newplot = (TH1*)tempfile->Get(Form(("throw_%i/" + plotname).c_str(), i));
 
       for (Int_t j = 0; j < nbins; j++) {
         tprof->Fill(j + 0.5, newplot->GetBinContent(j + 1));
         bincontents[j] = newplot->GetBinContent(j + 1);
 
         if (bincontents[j] < binlowest[j] or i == 0) binlowest[j] = bincontents[j];
         if (bincontents[j] > binhighest[j] or i == 0) binhighest[j] = bincontents[j];
       }
 
       errorDIR->cd();
       bintree->Fill();
 
       delete newplot;
     }
 
     errorDIR->cd();
 
     for (Int_t j = 0; j < nbins; j++) {
 
       if (!uniformly) {
         baseplot->SetBinError(j + 1, tprof->GetBinError(j + 1));
 
       } else {
         baseplot->SetBinContent(j + 1, (binlowest[j] + binhighest[j]) / 2.0);
         baseplot->SetBinError(j + 1, (binhighest[j] - binlowest[j]) / 2.0);
       }
     }
 
     errorDIR->cd();
     baseplot->Write();
     tprof->Write();
     bintree->Write();
 
     delete baseplot;
     delete tprof;
     delete bintree;
     delete [] bincontents;
   }
 
   return;
 };
diff --git a/src/Routines/SplineRoutines.cxx b/src/Routines/SplineRoutines.cxx
index 2ec39fa..7b261ae 100755
--- a/src/Routines/SplineRoutines.cxx
+++ b/src/Routines/SplineRoutines.cxx
@@ -1,2608 +1,2593 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
-
-#include "StatusMessage.h"
-
 #include "SplineRoutines.h"
 
-/*
-  Constructor/Destructor
-*/
-//************************
 void SplineRoutines::Init() {
-  //************************
 
   fStrategy = "SaveEvents";
   fRoutines.clear();
 
   fCardFile = "";
 
   fSampleFCN = NULL;
   fRW = NULL;
 
   fAllowedRoutines = ("SaveEvents,TestEvents,SaveSplineEvents");
 };
 
-//*************************************
 SplineRoutines::~SplineRoutines() {
-  //*************************************
 };
 
-/*
-  Input Functions
-*/
-//*************************************
 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<std::string> xmlcmds;
   std::vector<std::string> configargs;
 
   // Make easier to handle arguments.
   std::vector<std::string> args = GeneralUtils::LoadCharToVectStr(argc, argv);
   ParserUtils::ParseArgument(args, "-c", fCardFile, true);
   ParserUtils::ParseArgument(args, "-o", fOutputFile, false, false);
   ParserUtils::ParseArgument(args, "-n", maxevents, false, false);
   ParserUtils::ParseArgument(args, "-f", fStrategy, false, false);
   ParserUtils::ParseArgument(args, "-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);
 
   // 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]);
   }
 
   // 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");
 
   // Add Error Verbo Lines
   verbocount += Config::Get().GetParI("VERBOSITY");
   errorcount += Config::Get().GetParI("ERROR");
   std::cout << "[ NUISANCE ]: Setting VERBOSITY=" << verbocount << std::endl;
   std::cout << "[ NUISANCE ]: Setting ERROR=" << errorcount << std::endl;
   FitPar::log_verb = verbocount;
   LOG_VERB(verbocount);
   ERR_VERB(errorcount);
 
   // Starting Setup
   // ---------------------------
   SetupRWEngine();
 
   return;
 };
 
 
 /*
   Setup Functions
 */
 //*************************************
 void SplineRoutines::SetupRWEngine() {
 //*************************************
 
   fRW = new FitWeight("splineweight");
   // std::vector<nuiskey> splinekeys    = Config::QueryKeys("spline");
   std::vector<nuiskey> 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<std::string, double>& updateVals) {
 //*************************************
 
   for (UInt_t i = 0; i < fParams.size(); i++) {
     std::string name = fParams[i];
 
     if (updateVals.find(name) == updateVals.end()) continue;
     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<nuiskey> 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<std::string> 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();
       i++;
     }
 
     // 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<nuiskey> testkeys = Config::QueryKeys("sampletest");
   for (std::vector<nuiskey>::iterator iter = testkeys.begin();
        iter != testkeys.end(); iter++) {
     nuiskey key = (*iter);
 
     // 0. Create new measurement list
     std::list<MeasurementBase*> 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<nuiskey> splinekeys = Config::QueryKeys("spline");
 
   // Add splines to splinewriter
   for (std::vector<nuiskey>::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<nuiskey> 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<std::string> 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);
+    // 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 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);
+      // 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<nuiskey> splinekeys = Config::QueryKeys("spline");
 
   // Add splines to splinewriter
   for (std::vector<nuiskey>::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<nuiskey> 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<std::string> 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();
+    // 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<nuiskey> splinekeys = Config::QueryKeys("spline");
 
   // Add splines to splinewriter
   for (std::vector<nuiskey>::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<SplineWriter*> splwriterlist;
 
   for (int i = 0; i < ncores; i++) {
     SplineWriter* tmpwriter = new SplineWriter(fRW);
 
     for (std::vector<nuiskey>::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<nuiskey> 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<std::string> 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<nuiskey> splinekeys = Config::QueryKeys("spline");
 
   // Add splines to splinewriter
   for (std::vector<nuiskey>::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<SplineWriter*> splwriterlist;
 
   for (int i = 0; i < ncores; i++) {
     SplineWriter* tmpwriter = new SplineWriter(fRW);
 
     for (std::vector<nuiskey>::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<nuiskey> 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 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);
+    // 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);
+      // 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];
+        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<nuiskey> splinekeys = Config::QueryKeys("spline");
 
   // Add splines to splinewriter
   for (std::vector<nuiskey>::iterator iter = splinekeys.begin();
        iter != splinekeys.end(); iter++) {
     nuiskey splkey = (*iter);
 
     // Add Spline Info To Reader
     splwrite->AddSpline(splkey);
   }
   splwrite->SetupSplineSet();
 
   std::vector<nuiskey> 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 countwidth = (nevents / 1000);
+    // int nweights = splwrite->GetNWeights();
     int npar = splwrite->GetNPars();
 
     // Make counter
-    int lasttime = time(NULL);
+    // 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<nuiskey> splinekeys = Config::QueryKeys("splinemerge");
   for (std::vector<nuiskey>::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<nuiskey> eventkeys = Config::QueryKeys("eventmerge");
   nuiskey key = eventkeys[0];
 
   std::string inputfilename  = key.GetS("input");
 
   // Make a new input handler
   std::vector<std::string> 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<nuiskey> splinekeys    = Config::QueryKeys("spline");
   std::vector<nuiskey> 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<double> nomvals = fRW->GetDialValues();
-  int testres = FitPar::Config().GetParI("spline_test_resolution");
+  // int testres = FitPar::Config().GetParI("spline_test_resolution");
 
   std::vector< std::vector<double> > 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<double> 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++) {
+  for (uint i = 0; i < scanparset_vals.size(); i++) {
     std::cout << "Parset " << i;
-    for (int j = 0 ; j < scanparset_vals[i].size(); j++) {
+    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();
+  // int NParSets = scanparset_vals.size();
 
   // Loop over all event I/O
   std::vector<nuiskey> 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<std::string> 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 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);
+      // 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<double> nomvals = fRW->GetDialValues();
   int testres = FitPar::Config().GetParI("spline_test_resolution");
 
   std::vector< std::vector<double> > 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<double> 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<nuiskey> 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<std::string> 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<nuiskey> 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<double> nomvals = fRW->GetDialValues();
-  int testres = FitPar::Config().GetParI("spline_test_resolution");
+  // int testres = FitPar::Config().GetParI("spline_test_resolution");
 
   std::vector< std::string > scanparset_names;
   std::vector< std::vector<double> > 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<double> 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 (int i = 0; i < scanparset_vals.size(); i++) {
+  for (uint i = 0; i < scanparset_vals.size(); i++) {
     std::cout << "Parset " << i;
-    for (int j = 0 ; j < scanparset_vals[i].size(); j++) {
+    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();
+  // int NParSets = scanparset_vals.size();
 
   // Loop over all event I/O
   std::vector<nuiskey> 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<std::string> 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 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);
+      // 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<nuiskey> splinekeys = Config::QueryKeys("spline");
 
   // Add splines to splinewriter
   for (std::vector<nuiskey>::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<nuiskey> 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<std::string> 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);
+    // 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<nuiskey> 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<double> nomvals = fRW->GetDialValues();
-  int testres = FitPar::Config().GetParI("spline_test_resolution");
+  // int testres = FitPar::Config().GetParI("spline_test_resolution");
 
   std::vector< std::string > scanparset_names;
   std::vector< std::vector<double> > 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<double> 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 (int i = 0; i < scanparset_vals.size(); i++) {
+  for (uint i = 0; i < scanparset_vals.size(); i++) {
     std::cout << "Parset " << i;
-    for (int j = 0 ; j < scanparset_vals[i].size(); j++) {
+    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<nuiskey> eventkeys = Config::QueryKeys("events");
   std::vector<nuiskey> testkeys  = Config::QueryKeys("sampletest");
 
   std::vector<nuiskey> rawkeys;
   std::vector<nuiskey> splkeys;
 
 
   for (std::vector<nuiskey>::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<nuiskey> splinekeys    = Config::QueryKeys("spline");
   std::vector<nuiskey> 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<double> nomvals = fRW->GetDialValues();
-  int testres = FitPar::Config().GetParI("spline_test_resolution");
+  // int testres = FitPar::Config().GetParI("spline_test_resolution");
 
   std::vector< std::vector<double> > 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<double> 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++) {
+  for (uint i = 0; i < scanparset_vals.size(); i++) {
     std::cout << "Parset " << i;
-    for (int j = 0 ; j < scanparset_vals[i].size(); j++) {
+    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<nuiskey> eventkeys = Config::QueryKeys("events");
   std::vector<nuiskey> testkeys  = Config::QueryKeys("sampletest");
 
   std::vector<nuiskey> rawkeys;
   std::vector<nuiskey> splkeys;
 
 
   for (std::vector<nuiskey>::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/SystematicRoutines.cxx b/src/Routines/SystematicRoutines.cxx
index ee063b0..ea21d2a 100755
--- a/src/Routines/SystematicRoutines.cxx
+++ b/src/Routines/SystematicRoutines.cxx
@@ -1,1528 +1,1510 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
-
-#include "StatusMessage.h"
 #include "SystematicRoutines.h"
 
-/*
-  Constructor/Destructor
-*/
-//************************
 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(){
-//*************************************
 };
 
-/*
-  Input Functions
-*/
-//*************************************
 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<std::string> xmlcmds;
   std::vector<std::string> configargs;
   fNThrows = 250;
   fStartThrows = 0;
   fThrowString = "";
   // Make easier to handle arguments.
   std::vector<std::string> args = GeneralUtils::LoadCharToVectStr(argc, argv);
   ParserUtils::ParseArgument(args, "-c", fCardFile, true);
   ParserUtils::ParseArgument(args, "-o", fOutputFile, false, false);
   ParserUtils::ParseArgument(args, "-n", maxevents, false, false);
   ParserUtils::ParseArgument(args, "-f", fStrategy, false, false);
   ParserUtils::ParseArgument(args, "-d", fFakeDataInput, false, false);
   ParserUtils::ParseArgument(args, "-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);
 
   // 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]);
   }
 
   // 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");
 
   // Add Error Verbo Lines
   verbocount += Config::Get().GetParI("VERBOSITY");
   errorcount += Config::Get().GetParI("ERROR");
   std::cout << "[ NUISANCE ]: Setting VERBOSITY=" << verbocount << std::endl;
   std::cout << "[ NUISANCE ]: Setting ERROR=" << errorcount << std::endl;
   FitPar::log_verb = verbocount;
   LOG_VERB(verbocount);
   ERR_VERB(errorcount);
   
   // 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<nuiskey> parkeys = Config::QueryKeys("parameter");
   if (!parkeys.empty()) {
     LOG(FIT) << "Number of parameters :  " << parkeys.size() << std::endl;
   }
 
   for (size_t i = 0; i < parkeys.size(); i++) {
     nuiskey key = parkeys.at(i);
 
     // Check for type,name,nom
     if (!key.Has("type")) {
       ERR(FTL) << "No type given for parameter " << i << std::endl;
       throw;
     } else if (!key.Has("name")) {
       ERR(FTL) << "No name given for parameter " << i << std::endl;
       throw;
     } else if (!key.Has("nominal")) {
       ERR(FTL) << "No nominal given for parameter " << i << std::endl;
       throw;
     }
 
     // Get Inputs
     std::string partype = key.GetS("type");
     std::string parname = key.GetS("name");
     double parnom  = key.GetD("nominal");
     double parlow  = parnom - 1;
     double parhigh = parnom + 1;
     double parstep = 1;
     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<nuiskey> samplekeys =  Config::QueryKeys("sample");
   if (!samplekeys.empty()) {
     LOG(FIT) << "Number of samples : " << samplekeys.size() << std::endl;
   }
 
   for (size_t i = 0; i < samplekeys.size(); i++) {
     nuiskey key = samplekeys.at(i);
 
     // Get Sample Options
     std::string samplename = key.GetS("name");
     std::string samplefile = key.GetS("input");
 
     std::string sampletype =
       key.Has("type") ? key.GetS("type") : "DEFAULT";
 
     double samplenorm =
       key.Has("norm") ? key.GetD("norm") : 1.0;
 
     // Print out
     LOG(FIT) << "Read sample info " << i << " : "
              << samplename << std::endl
              << "\t\t input -> " << samplefile  << std::endl
              << "\t\t state -> " << sampletype << std::endl
              << "\t\t norm  -> " << samplenorm << std::endl;
 
     // If FREE add to parameters otherwise continue
     if (sampletype.find("FREE") == std::string::npos) {
       continue;
     }
 
     // Form norm dial from samplename + sampletype + "_norm";
     std::string normname = samplename + sampletype + "_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<nuiskey> fakekeys = Config::QueryKeys("fakeparameter");
   if (!fakekeys.empty()) {
     LOG(FIT) << "Number of fake parameters : " << fakekeys.size() << std::endl;
   }
 
   for (size_t i = 0; i < fakekeys.size(); i++) {
     nuiskey key = fakekeys.at(i);
 
     // Check for type,name,nom
     if (!key.Has("name")) {
       ERR(FTL) << "No name given for fakeparameter " << i << std::endl;
       throw;
     } else if (!key.Has("nom")) {
       ERR(FTL) << "No nominal given for fakeparameter " << i << std::endl;
       throw;
     }
 
     // Get Inputs
     std::string parname = key.GetS("name");
     double parnom  = key.GetD("nom");
 
     // Push into vectors
     fFakeVals[parname] = parnom;
   }
 }
 
 
-//*************************************
 void SystematicRoutines::ReadCard(std::string cardfile){
-//*************************************
 
   // Read cardlines into vector
   std::vector<std::string> cardlines = GeneralUtils::ParseFileToStr(cardfile,"\n");
   FitPar::Config().cardLines = cardlines;
 
   // Read Samples first (norm params can be overridden)
   int linecount = 0;
   for (std::vector<std::string>::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<std::string>::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<std::string> 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<std::string> 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 <sample_name> <input_type>: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<std::string> 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"<<std::endl;
   if (fSampleFCN) delete fSampleFCN;
   fSampleFCN = new JointFCN(fOutputRootFile);
   SetFakeData();
 
   return;
 }
 
 
 //*************************************
 void SystematicRoutines::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 {
     fSampleFCN->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<std::string, std::string> dialthrowhandle;
 
   // Get Covariance Objects from FCN
   std::list<ParamPull*> 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<std::string,double>& updateVals){
 //*************************************
 
   for (UInt_t i = 0; i < fParams.size(); i++){
     std::string name = fParams[i];
 
     if (updateVals.find(name) == updateVals.end()) continue;
     FitBase::GetRW()->SetDialValue(name,updateVals.at(name));
   }
 
   FitBase::GetRW()->Reconfigure();
   return;
 }
 
 //*************************************
 void SystematicRoutines::PrintState(){
 //*************************************
   LOG(FIT)<<"------------"<<std::endl;
 
   // Count max size
   int maxcount = 0;
   for (UInt_t i = 0; i < fParams.size(); i++){
     maxcount = max(int(fParams[i].size()), maxcount);
   }
 
   // Header
   LOG(FIT) << " #    " << left << setw(maxcount) << "Parameter "
 	   << " = "
 	   << setw(10) << "Value"     << " +- "
 	   << setw(10) << "Error"     << " "
 	   << setw(8)  << "(Units)"   << " "
 	   << setw(10) << "Conv. Val" << " +- "
 	   << setw(10) << "Conv. Err" << " "
 	   << setw(8)  << "(Units)"   << std::endl;
 
   // Parameters
   for (UInt_t i = 0; i < fParams.size(); i++){
     std::string syst = fParams.at(i);
 
     std::string typestr  = FitBase::ConvDialType(fTypeVals[syst]);
     std::string curunits = "(sig.)";
     double      curval   = fCurVals[syst];
     double      curerr   = fErrorVals[syst];
 
     if (fStateVals[syst].find("ABS") != std::string::npos){
       curval = FitBase::RWSigmaToAbs(typestr, syst, curval);
       curerr = (FitBase::RWSigmaToAbs(typestr, syst, curerr) -
 		FitBase::RWSigmaToAbs(typestr, syst, 0.0));
       curunits = "(Abs.)";
     } else if (fStateVals[syst].find("FRAC") != std::string::npos){
       curval = FitBase::RWSigmaToFrac(typestr, syst, curval);
       curerr = (FitBase::RWSigmaToFrac(typestr, syst, curerr) -
 		FitBase::RWSigmaToFrac(typestr, syst, 0.0));
       curunits = "(Frac)";
     }
 
     std::string convunits = "(" + FitBase::GetRWUnits(typestr, syst) + ")";
     double      convval   = FitBase::RWSigmaToAbs(typestr, syst, curval);
     double      converr   = (FitBase::RWSigmaToAbs(typestr, syst, curerr) -
 			     FitBase::RWSigmaToAbs(typestr, syst, 0.0));
 
     std::ostringstream curparstring;
 
     curparstring << " " << setw(3) << left
 		 << i << ". "
 		 << setw(maxcount) << syst << " = "
 		 << setw(10) << curval     << " +- "
 		 << setw(10) << curerr     << " "
 		 << setw(8)  << curunits   << " "
                  << setw(10) << convval    << " +- "
                  << setw(10) << converr    << " "
                  << setw(8)  << convunits;
 
 
     LOG(FIT) << curparstring.str() << std::endl;
   }
 
   LOG(FIT)<<"------------"<<std::endl;
   double like = fSampleFCN->GetLikelihood();
-  LOG(FIT) << std::left << std::setw(46) << "Likelihood for JointFCN: " << like << endl;
+  LOG(FIT) << std::left << std::setw(46) << "Likelihood for JointFCN: " << like << std::endl;
   LOG(FIT)<<"------------"<<std::endl;
 }
 
 
 
 /*
   Write Functions
 */
 //*************************************
 void SystematicRoutines::SaveResults(){
 //*************************************
   if (!fOutputRootFile)
     fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE");  
 
   fOutputRootFile->cd();
 
   SaveCurrentState();
 
 }
 
 //*************************************
 void SystematicRoutines::SaveCurrentState(std::string subdir){
 //*************************************
 
   LOG(FIT)<<"Saving current full FCN predictions" <<std::endl;
 
   // Setup DIRS
   TDirectory* curdir = gDirectory;
   if (!subdir.empty()){
     TDirectory* newdir =(TDirectory*) gDirectory->mkdir(subdir.c_str());
     newdir->cd();
   }
 
   FitBase::GetRW()->Reconfigure();
   fSampleFCN->ReconfigureAllEvents();
   fSampleFCN->Write();
 
   // Change back to current DIR
   curdir->cd();
 
   return;
 }
 
 //*************************************
 void SystematicRoutines::SaveNominal(){
 //*************************************
   if (!fOutputRootFile)
     fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE");
 
   fOutputRootFile->cd();
 
   LOG(FIT)<<"Saving Nominal Predictions (be cautious with this)" <<std::endl;
   FitBase::GetRW()->Reconfigure();
   SaveCurrentState("nominal");
 
 };
 
 //*************************************
 void SystematicRoutines::SavePrefit(){
 //*************************************
   if (!fOutputRootFile)
     fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE");
 
   fOutputRootFile->cd();
 
   LOG(FIT)<<"Saving Prefit Predictions"<<std::endl;
   UpdateRWEngine(fStartVals);
   SaveCurrentState("prefit");
   UpdateRWEngine(fCurVals);
 
 };
 
 
 /*
   MISC Functions
 */
 //*************************************
 int SystematicRoutines::GetStatus(){
 //*************************************
 
   return 0;
 }
 
 //*************************************
 void SystematicRoutines::SetupCovariance(){
 //*************************************
 
   // Remove covares if they exist
   if (fCovar) delete fCovar;
   if (fCovarFree) delete fCovarFree;
   if (fCorrel) delete fCorrel;
   if (fCorrelFree) delete fCorrelFree;
   if (fDecomp) delete fDecomp;
   if (fDecompFree) delete fDecompFree;
 
   int NFREE = 0;
   int NDIM = 0;
 
   // Get NFREE from min or from vals (for cases when doing throws)
   NDIM = fParams.size();
   for (UInt_t i = 0; i < fParams.size(); i++){
     if (!fFixVals[fParams[i]]) NFREE++;
   }
 
   if (NDIM == 0) return;
 
   fCovar = new TH2D("covariance","covariance",NDIM,0,NDIM,NDIM,0,NDIM);
   if (NFREE > 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<std::string> 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: "<<routine<<std::endl;
 
     if (routine.compare("PlotLimits") == 0) PlotLimits();
     else if (routine.compare("ErrorBands") == 0) GenerateErrorBands();
     else if (routine.compare("ThrowErrors") == 0) GenerateThrows();
     else if (routine.compare("MergeErrors") == 0) MergeThrows();
     else {
       std::cout << "Unknown ROUTINE : " << routine << std::endl;
     }
 
     // If ending early break here
     if (fitstate == kFitFinished || fitstate == kNoChange){
       LOG(FIT) << "Ending fit routines loop." << std::endl;
       break;
     }
   }
 
   return;
 }
 
 void SystematicRoutines::GenerateErrorBands(){
   GenerateThrows();
   MergeThrows();
 }
 
 //*************************************
 void SystematicRoutines::GenerateThrows(){
 //*************************************
 
 
   TFile* tempfile = new TFile((fOutputFile + ".throws.root").c_str(),"RECREATE");
   tempfile->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;
   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();
   }
 
   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 (int i = 0; i < fThrowList.size(); i++){
+  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");
+  // 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 (int i = 0; i < fThrowList.size(); i++){
+  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 (badfilecount == fThrowList.size()){
+  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();
       }
     }
 
     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->SetBinError(j+1,tprof->GetBinError(j+1));
 	  //	}
       } else {
       	baseplot->SetBinContent(j+1, 0.0);//(binlowest[j] + binhighest[j]) / 2.0);
         baseplot->SetBinError(j+1, 0.0); //(binhighest[j] - binlowest[j])/2.0);
       }
     }
 
     errorDIR->cd();
     baseplot->Write();
     tprof->Write();
     bintree->Write();
 
     outnominal->cd();
     for (int i = 0; i < nbins; i++){
       baseplot->SetBinError(i+1, sqrt(pow(statplot->GetBinError(i+1),2) + pow(baseplot->GetBinError(i+1),2)));
     }
     baseplot->Write();
     
     delete statplot;
     delete baseplot;
     delete tprof;
     delete bintree;
     delete [] bincontents;
   }
 
   return;
 };
diff --git a/src/Splines/CMakeLists.txt b/src/Splines/CMakeLists.txt
index f176b0e..6836033 100644
--- a/src/Splines/CMakeLists.txt
+++ b/src/Splines/CMakeLists.txt
@@ -1,60 +1,62 @@
 # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 ################################################################################
 #    This file is part of NUISANCE.
 #
 #    NUISANCE is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
 #    (at your option) any later version.
 #
 #    NUISANCE is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #    GNU General Public License for more details.
 #
 #    You should have received a copy of the GNU General Public License
 #    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 ################################################################################
 set(IMPLFILES
 SplineReader.cxx
 SplineWriter.cxx
 SplineMerger.cxx
 SplineUtils.cxx
 Spline.cxx
 )
 
 set(HEADERFILES
 SplineReader.h
 SplineWriter.h
 SplineUtils.h
 SplineMerger.h
 Spline.h
 )
 
 set(LIBNAME Splines)
 
 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(${RWENGINE_INCLUDE_DIRECTORIES})
 include_directories(${CMAKE_CURRENT_SOURCE_DIR})
 include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
+include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler)
+include_directories(${CMAKE_SOURCE_DIR}/src/Genie)
 include_directories(${CMAKE_SOURCE_DIR}/src/Reweight)
 include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
 
 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/Splines/Spline.h b/src/Splines/Spline.h
index b1cfd9e..269ba3a 100644
--- a/src/Splines/Spline.h
+++ b/src/Splines/Spline.h
@@ -1,167 +1,168 @@
 #ifndef SPLINE_H
 #define SPLINE_H
 #include <vector>
 #include "TObject.h"
 #include "FitParameters.h"
 #include "stdint.h"
 #include "stdlib.h"
 #include "TCanvas.h"
 #include <list>
 #include "TF1.h"
 #include "TSpline.h"
 #include "SplineUtils.h"
 #include "TGraph2D.h"
 #include "TF2.h"
 
 #include "Math/Minimizer.h"
 #include "Math/Factory.h"
 #include "Math/Functor.h"
 #include "TH1D.h"
 #include "Math/IFunction.h"
 #include "Math/IParamFunction.h"
+#include "FitLogger.h"
 
 // Spline Class
 class Spline : public  ROOT::Math::ParamFunctor { 
 private:
 
    const double* pars;
  
 public:
    double DoEvalPar(const double* x, const double* p) const ;
  
    unsigned int NDim() const{
       return fNDim;
    }
    // ROOT::Math::IParametricFunctionMultiDim* Clone() const{
    //    return new Spline(this->fName, this->fForm, this->fPoints);
    // }
  
    const double* Parameters() const{
       return pars;
    }
  
    void SetParameters(const double* p){
       pars = p;
    }
  
    unsigned int NPar() const{
       return fNPar;
    }
  
   Spline(std::string splname, std::string form, std::string points);
   ~Spline() {};
 
   void Setup(int type, int ndim, int npar);
 
   double operator()(const Double_t* x, const Double_t* par);
   float operator()(const Float_t* x, const Float_t* par) const;
 
   float DoEval(const Float_t* x, const Float_t* par) const;
   float DoEval(const Float_t* par, bool checkresponse = true) const;
 
   //  void FitCoeff(int n, double* x, double* y, double* par, bool draw);
   void FitCoeff(std::vector< std::vector<double> > v, std::vector<double> w, float* coeff, bool draw);
 
   inline std::string GetName(void) { return fName; };
   inline int GetNDim(void) { return fNDim; };
   inline int GetType(void) { return fType; };
   inline int GetNPar(void) { return fNPar;  };
   inline std::string GetForm() {return fForm;};
 
   //void Reconfigure(double x);
   void Reconfigure(float x, int index = 0);
   void Reconfigure(std::string name, float x);
 
    // Available Spline Functions
   float Spline1DPol1(const Float_t* par) const;
   float Spline1DPol2(const Float_t* par) const;
   float Spline1DPol3(const Float_t* par) const;
   float Spline1DPol4(const Float_t* par) const;
   float Spline1DPol5(const Float_t* par) const;
   float Spline1DPol6(const Float_t* par) const;
   float Spline2DPol(const Float_t* par, int n) const;
   float Spline2DGaus(const Float_t* par) const;
 
   float Spline1DTSpline3(const Float_t* par) const;
   float Spline2DTSpline3(const Float_t* par) const;
 
 
   std::string fName;
   int fType;
   int fNDim;
   int fNPar;
   std::string fForm;
   std::string fPoints;
   bool fOutsideLimits;
 
   std::vector<std::string> fSplitNames;
   std::vector<std::string> fSplitPoints;
 
   mutable std::vector<float> fVal;
   mutable std::vector<float> fValMin;
   mutable std::vector<float> fValMax;
 
   mutable std::vector< std::vector<float> > fSplitScan;
 
   mutable std::vector<float> fXScan;
   mutable float fX;
   mutable float fXMin;
   mutable float fXMax;
 
   mutable std::vector<float> fYScan;
   mutable float fY;
   mutable float fYMin;
   mutable float fYMax;
 
   int  fSplineOffset;
 
   // TSpline3 Objects.
   mutable std::vector<float>::iterator iter_low;
   mutable std::vector<float>::iterator iter_high;
   mutable int off;
 
   // Create a new function for fitting.
   ROOT::Math::Minimizer* minimizer;
 
   TF1* fROOTFunction;
   TF1* GetFunction();
 
 };
 
 
 namespace SplineUtils {
 
   double Func2DWrapper(double* x, double* p);
   extern Spline* gSpline;
 
 }
 
 
 
 namespace SplineUtils {
 
 // Spline List
 enum spline_types {
   k1DPol1 = 1,
   k1DPol2,
   k1DPol3,
   k1DPol4,
   k1DPol5,
   k1DPol6,
   k1DPol1C,
   k1DPol2C,
   k1DPol3C,
   k1DPol4C,
   k1DPol5C,
   k1DPol5C_LX,
   k1DPol10,
   k1DTSpline3,
   k1DPol25,
   k2DPol6,
   k2DGaus,
   k2DTSpline3
 };
 
 }
 
 #endif
diff --git a/src/Splines/SplineReader.h b/src/Splines/SplineReader.h
index fe1706c..cc8ae28 100644
--- a/src/Splines/SplineReader.h
+++ b/src/Splines/SplineReader.h
@@ -1,38 +1,39 @@
 #ifndef SPLINEREADER_H
 #define SPLINEREADER_H
 // #include "FitWeight.h"
 #include "Spline.h"
 #include "TTree.h"
+#include "FitLogger.h"
 // #include "GeneralUtils.h"
 
 class SplineReader {
 public:
   SplineReader() {};
   ~SplineReader() {};
 
   void AddSpline(nuiskey splkey);
   void Read(TTree* tr);
 
   void Reconfigure(std::map< std::string, double >& vals);
   bool NeedsReconfigure();
   void SetNeedsReconfigure(bool val = true);
 
   int GetNPar();
   double CalcWeight(float* coeffs);
 
   std::vector<Spline> fAllSplines;
   std::vector<std::string> fSpline;
   std::vector<std::string> fType;
   std::vector<std::string> fForm;
   std::vector<std::string> fPoints;
 
   std::vector<double> fDialValues;
   std::vector<double> fParValues;
 
   bool fNeedsReconfigure;
 
 
 
 };
 
 #endif
diff --git a/src/Splines/SplineUtils.cxx b/src/Splines/SplineUtils.cxx
index 0c723ba..7b0c188 100644
--- a/src/Splines/SplineUtils.cxx
+++ b/src/Splines/SplineUtils.cxx
@@ -1,111 +1,111 @@
 #include "SplineUtils.h"
 
 
 // std::vector<int> SplineUtils::GetSplitDialPositions(FitWeight* rw, std::string names) {
 // 	std::vector<std::string> splitnames = GeneralUtils::ParseToStr(names, ";");
 // 	std::vector<int> splitpos;
 
 // 	for (size_t i = 0; i < splitnames.size(); i++) {
 // 		int pos = fRW->GetDialPos(splitnames[i]);
 // 		splitpos.push_back(pos);
 // 	}
 	
 // 	return splitpos;
 // }
 
 std::vector< std::vector<double> > SplineUtils::GetSplitDialPoints(std::string points) {
 
 	// Determine Type
 	std::vector<std::string> splittype = GeneralUtils::ParseToStr(points, ":");
 	std::string deftype = "";
 	if (splittype.size() == 1) {
 		deftype = "GRID";
 	} else if (splittype.size() > 1) {
 		deftype = splittype[0];
 		splittype.erase(splittype.begin());
 	} else {
 		throw;
 	}
 
 	// Make Grid
 	std::vector<std::vector<double> > gridpoints;
 
 	// Possible Point Types
 	if (!deftype.compare("GRID")) {
 
 		std::vector<std::string> splitpoints = GeneralUtils::ParseToStr(splittype[0], ";");
 
 		// CBA writing an ND iterator to build this grids. 1D, 2D, and 3D are below..
 		if (splitpoints.size() == 1) {
 			std::vector<double> tempcont = std::vector<double>(1, 0.0);
 			std::vector<double> tempsplit = GeneralUtils::ParseToDbl(splitpoints[0], ",");
 
 			for (size_t i = 0; i < tempsplit.size(); i++) {
 				tempcont[0] = tempsplit[i];
 				gridpoints.push_back(tempcont);
 			}
 
 			// 2D
 		} else if (splitpoints.size() == 2) {
 
 			std::vector<double> tempcont = std::vector<double>(2, 0.0);
 			std::vector<double> tempsplit1 = GeneralUtils::ParseToDbl(splitpoints[0],",");
 			std::vector<double> tempsplit2 = GeneralUtils::ParseToDbl(splitpoints[1],",");
 
 			for (size_t i = 0; i < tempsplit1.size(); i++) {
 				for (size_t j = 0; j < tempsplit2.size(); j++) {
 					tempcont[0] = tempsplit1[i];
 					tempcont[1] = tempsplit2[j];
 					gridpoints.push_back(tempcont);
 				}
 			}
 			// 3D
 		} else if (splitpoints.size() == 3) {
 
 			std::vector<double> tempcont = std::vector<double>(3, 0.0);
 			std::vector<double> tempsplit1 = GeneralUtils::ParseToDbl(splitpoints[0],",");
 			std::vector<double> tempsplit2 = GeneralUtils::ParseToDbl(splitpoints[1],",");
 			std::vector<double> tempsplit3 = GeneralUtils::ParseToDbl(splitpoints[2],",");
 
 			for (size_t i = 0; i < tempsplit1.size(); i++) {
 				for (size_t j = 0; j < tempsplit2.size(); j++) {
 					for (size_t k = 0; k < tempsplit3.size(); k++) {
 						tempcont[0] = tempsplit1[i];
 						tempcont[1] = tempsplit2[j];
 						tempcont[2] = tempsplit3[j];
 						gridpoints.push_back(tempcont);
 					}
 				}
 			}
 		}
 	} else if (!deftype.compare("DIAG2D")) {
 		std::vector<std::string> splitpoints = GeneralUtils::ParseToStr(splittype[0], ";");
 		
 		std::vector<double> tempcont = std::vector<double>(2, 0.0);
 		std::vector<double> tempsplit1 = GeneralUtils::ParseToDbl(splitpoints[0],",");
 
 		for (size_t i = 0; i < tempsplit1.size(); i++) {
 			tempcont[0] = tempsplit1[i];
 			tempcont[1] = 0.0;
 			gridpoints.push_back(tempcont);
 		}
 
 		for (size_t i = 0; i < tempsplit1.size(); i++) {
 			tempcont[0] = 0.0;
 			tempcont[1] = tempsplit1[i];
 			gridpoints.push_back(tempcont);
 		}
 		for (size_t i = 0; i < tempsplit1.size(); i++) {
 			tempcont[0] = tempsplit1[i];
 			tempcont[1] = tempsplit1[i];
 			gridpoints.push_back(tempcont);
 		}
 
 		for (size_t i = 0; i < tempsplit1.size(); i++) {
 			tempcont[0] = tempsplit1[i];
 			tempcont[1] = tempsplit1[ tempsplit1.size() - 1 - i];
 			gridpoints.push_back(tempcont);
 		}
 	}
 	return gridpoints;
-}
\ No newline at end of file
+}
diff --git a/src/Splines/SplineUtils.h b/src/Splines/SplineUtils.h
index 859f92d..45fdff4 100644
--- a/src/Splines/SplineUtils.h
+++ b/src/Splines/SplineUtils.h
@@ -1,12 +1,12 @@
 #ifndef SPLINE_UTILS_H
 #define SPLINE_UTILS_H
 
 //#include "FitWeight.h"
 #include "GeneralUtils.h"
 
 namespace SplineUtils {
 	//std::vector<int> GetSplitDialPositions(FitWeight* rw, std::string names);
 	std::vector< std::vector<double> > GetSplitDialPoints(std::string points);
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/src/T2K/CMakeLists.txt b/src/T2K/CMakeLists.txt
index 5656f6e..88d6e4f 100644
--- a/src/T2K/CMakeLists.txt
+++ b/src/T2K/CMakeLists.txt
@@ -1,89 +1,91 @@
 # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 ################################################################################
 #    This file is part of NUISANCE.
 #
 #    NUISANCE is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
 #    (at your option) any later version.
 #
 #    NUISANCE is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #    GNU General Public License for more details.
 #
 #    You should have received a copy of the GNU General Public License
 #    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 ################################################################################
 set(IMPLFILES
 T2K_CC0pi_XSec_2DPcos_nu.cxx
 T2K_CC1pip_CH_XSec_1DQ2_nu.cxx
 T2K_CC1pip_CH_XSec_1DWrec_nu.cxx
 T2K_CC1pip_CH_XSec_1Dpmu_nu.cxx
 T2K_CC1pip_CH_XSec_1Dppi_nu.cxx
 T2K_CC1pip_CH_XSec_1Dq3_nu.cxx
 T2K_CC1pip_CH_XSec_1Dthmupi_nu.cxx
 T2K_CC1pip_CH_XSec_1Dthpi_nu.cxx
 T2K_CC1pip_CH_XSec_1Dthq3pi_nu.cxx
 T2K_CC1pip_H2O_XSec_1DEnuDelta_nu.cxx
 T2K_CC1pip_H2O_XSec_1DEnuMB_nu.cxx
 T2K_CC1pip_H2O_XSec_1Dcosmu_nu.cxx
 T2K_CC1pip_H2O_XSec_1Dcosmupi_nu.cxx
 T2K_CC1pip_H2O_XSec_1Dcospi_nu.cxx
 T2K_CC1pip_H2O_XSec_1Dpmu_nu.cxx
 T2K_CC1pip_H2O_XSec_1Dppi_nu.cxx
 T2K_CC0pinp_STV_XSec_1Ddpt_nu.cxx
 T2K_CC0pi_XSec_2DPcos_nu_nonuniform.cxx
 T2K_SignalDef.cxx
 )
 
 set(HEADERFILES
 T2K_CC0pi_XSec_2DPcos_nu.h
 T2K_CC1pip_CH_XSec_1DQ2_nu.h
 T2K_CC1pip_CH_XSec_1DWrec_nu.h
 T2K_CC1pip_CH_XSec_1Dpmu_nu.h
 T2K_CC1pip_CH_XSec_1Dppi_nu.h
 T2K_CC1pip_CH_XSec_1Dq3_nu.h
 T2K_CC1pip_CH_XSec_1Dthmupi_nu.h
 T2K_CC1pip_CH_XSec_1Dthpi_nu.h
 T2K_CC1pip_CH_XSec_1Dthq3pi_nu.h
 T2K_CC1pip_H2O_XSec_1DEnuDelta_nu.h
 T2K_CC1pip_H2O_XSec_1DEnuMB_nu.h
 T2K_CC1pip_H2O_XSec_1Dcosmu_nu.h
 T2K_CC1pip_H2O_XSec_1Dcosmupi_nu.h
 T2K_CC1pip_H2O_XSec_1Dcospi_nu.h
 T2K_CC1pip_H2O_XSec_1Dpmu_nu.h
 T2K_CC1pip_H2O_XSec_1Dppi_nu.h
 T2K_CC0pinp_STV_XSec_1Ddpt_nu.h
 T2K_CC0pi_XSec_2DPcos_nu_nonuniform.h
 T2K_SignalDef.h
 )
 
 set(LIBNAME expT2K)
 
 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(${RWENGINE_INCLUDE_DIRECTORIES})
 
 include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
+include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler)
+include_directories(${CMAKE_SOURCE_DIR}/src/Genie)
 include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
 include_directories(${CMAKE_SOURCE_DIR}/src/Reweight)
 include_directories(${CMAKE_SOURCE_DIR}/src/Splines)
 
 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/T2K/T2K_CC0pi_XSec_2DPcos_nu.cxx b/src/T2K/T2K_CC0pi_XSec_2DPcos_nu.cxx
index 36220b3..e1ed1d0 100644
--- a/src/T2K/T2K_CC0pi_XSec_2DPcos_nu.cxx
+++ b/src/T2K/T2K_CC0pi_XSec_2DPcos_nu.cxx
@@ -1,271 +1,275 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
 #include "T2K_SignalDef.h"
 
 #include "T2K_CC0pi_XSec_2DPcos_nu.h"
 
 
 
 //********************************************************************
 T2K_CC0pi_XSec_2DPcos_nu::T2K_CC0pi_XSec_2DPcos_nu(nuiskey samplekey) {
 //********************************************************************
 
   // Sample overview ---------------------------------------------------
   std::string descrip = "T2K_CC0pi_XSec_2DPcos_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("P_{#mu} (GeV)");
   fSettings.SetYTitle("cos#theta_{#mu}");
   fSettings.SetZTitle("d^{2}#sigma/dP_{#mu}dcos#theta_{#mu} (cm^{2}/GeV)");
   fSettings.SetAllowedTypes("DIAG,FULL/FREE,SHAPE,FIX/SYSTCOV/STATCOV","FIX");
   fSettings.SetEnuRange(0.0, 10.0);
   fSettings.DefineAllowedTargets("C,H");
 
  if (fName == "T2K_CC0pi_XSec_2DPcos_nu_I") fAnalysis = 1;
   else fAnalysis = 2;
 
 
   // CCQELike plot information
   fSettings.SetTitle("T2K_CC0pi_XSec_2DPcos_nu");
   fSettings.DefineAllowedSpecies("numu");
 
   forwardgoing = (fSettings.GetS("type").find("REST") != std::string::npos);
 
   FinaliseSampleSettings();
 
   // Scaling Setup ---------------------------------------------------
   // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon
   fScaleFactor = ((GetEventHistogram()->Integral("width")/(fNEvents+0.)) * 1E-38 / (TotalIntegratedFlux()));
 
   // Setup Histograms
   SetHistograms();
   StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, fMapHist, 1E-38);
 
   // Final setup  ---------------------------------------------------
   FinaliseMeasurement();
 
 };
 
 
 bool T2K_CC0pi_XSec_2DPcos_nu::isSignal(FitEvent *event){
   return SignalDef::isT2K_CC0pi(event, EnuMin, EnuMax, forwardgoing);
 };
 
 void T2K_CC0pi_XSec_2DPcos_nu::FillEventVariables(FitEvent* event){
 
   if (event->NumFSParticle(13) == 0)
     return;
 
   TLorentzVector Pnu = event->GetNeutrinoIn()->fP;
   TLorentzVector Pmu = event->GetHMFSParticle(13)->fP;
 
   double pmu = Pmu.Vect().Mag()/1000.;
   double CosThetaMu = cos(Pnu.Vect().Angle(Pmu.Vect()));
 
   fXVar = pmu;
   fYVar = CosThetaMu;
 
   return;
 };
 
 // Modification is needed after the full reconfigure to move bins around
 // Otherwise this would need to be replaced by a TH2Poly which is too awkward.
 void T2K_CC0pi_XSec_2DPcos_nu::ConvertEventRates(){
 
   // Do standard conversion.
   Measurement2D::ConvertEventRates();
 
   if (fAnalysis == 1){
 
     // Following code handles weird ND280 Binning
     int nbins = this->fMCHist->GetNbinsX() + 1;
     double total = 0.0;
 
     // Y = 1
     total = 0.0;
     for (int i = 3; i < nbins; i++){
 
       double width = this->fMCHist->GetXaxis()->GetBinWidth(i) * this->fMCHist->GetYaxis()->GetBinWidth(1);
       total += this->fMCHist->GetBinContent(i, 1) * width;
       this->fMCHist->SetBinContent(i,1,0);
     }
     this->fMCHist->SetBinContent(3, 1, total / (1.0 * 29.6));
 
     // Y = 2
     total = 0.0;
     for (int i = 5; i < nbins; i++){
       double width = this->fMCHist->GetXaxis()->GetBinWidth(i) * this->fMCHist->GetYaxis()->GetBinWidth(2);
       total += this->fMCHist->GetBinContent(i, 2)* width;
       this->fMCHist->SetBinContent(i,2,0);
     }
     this->fMCHist->SetBinContent(5, 2, total / (0.6 *29.4));
 
     // Y = 3
     total = 0.0;
     for (int i = 7; i < nbins; i++){
       double width = this->fMCHist->GetXaxis()->GetBinWidth(i) * this->fMCHist->GetYaxis()->GetBinWidth(3);
       total += this->fMCHist->GetBinContent(i, 3)* width;
       this->fMCHist->SetBinContent(i, 3,0);
     }
     this->fMCHist->SetBinContent(7, 3, total/ (0.1 * 29.2));
 
     // Y = 4
     total = 0.0;
     for (int i = 7; i < nbins; i++){
       double width = this->fMCHist->GetXaxis()->GetBinWidth(i) * this->fMCHist->GetYaxis()->GetBinWidth(4);
       total += this->fMCHist->GetBinContent(i, 4)* width;
       this->fMCHist->SetBinContent(i, 4,0);
     }
     this->fMCHist->SetBinContent(7, 4, total / (0.1 * 29.2));
 
     // Y = 5
     total = 0.0;
     for (int i = 8; i < nbins; i++){
       double width = this->fMCHist->GetXaxis()->GetBinWidth(i) * this->fMCHist->GetYaxis()->GetBinWidth(5);
       total += this->fMCHist->GetBinContent(i, 5)* width;
       this->fMCHist->SetBinContent(i,5,0);
     }
     this->fMCHist->SetBinContent(8, 5, total / (0.05 * 29.0));
 
     // Y = 6
     total = 0.0;
     for (int i = 9; i < nbins; i++){
       double width = this->fMCHist->GetXaxis()->GetBinWidth(i) * this->fMCHist->GetYaxis()->GetBinWidth(6);
       total += this->fMCHist->GetBinContent(i, 6)* width;
       this->fMCHist->SetBinContent(i, 6,0);
     }
     this->fMCHist->SetBinContent(9, 6, total / (0.05 * 28.5));
 
     // Y = 7
     total = 0.0;
     for (int i = 8; i < nbins; i++){
       double width = this->fMCHist->GetXaxis()->GetBinWidth(i) * this->fMCHist->GetYaxis()->GetBinWidth(7);
       total += this->fMCHist->GetBinContent(i, 7)* width;
       this->fMCHist->SetBinContent(i, 7,0);
     }
     this->fMCHist->SetBinContent(8, 7, total/ (0.04 * 28.0));
 
     // Y = 8
     total = 0.0;
     for (int i = 11; i < nbins; i++){
       double width = this->fMCHist->GetXaxis()->GetBinWidth(i) * this->fMCHist->GetYaxis()->GetBinWidth(8);
       total += this->fMCHist->GetBinContent(i, 8)* width;
       this->fMCHist->SetBinContent(i, 8,0);
     }
     this->fMCHist->SetBinContent(11, 8, total / (0.4 * 27.0));
 
     // Y = 9
     total = 0.0;
     for (int i = 9; i < nbins; i++){
       double width = this->fMCHist->GetXaxis()->GetBinWidth(i) * this->fMCHist->GetYaxis()->GetBinWidth(9);
       total += this->fMCHist->GetBinContent(i, 9)* width;
       this->fMCHist->SetBinContent(i,9,0);
     }
     this->fMCHist->SetBinContent(9, 9, total / (0.02 * 25.0));
   }
 
   return;
 }
 
 
 void T2K_CC0pi_XSec_2DPcos_nu::SetHistograms(){
 
   fIsSystCov = fSettings.GetS("type").find("SYSTCOV") != std::string::npos;
   fIsStatCov = fSettings.GetS("type").find("STATCOV") != std::string::npos;
   fIsNormCov = fSettings.GetS("type").find("NORMCOV") != std::string::npos;
   fNDataPointsX = 12;
   fNDataPointsY = 10;
 
   // Open file
   std::string infile = FitPar::GetDataBase()+"/T2K/CC0pi/T2K_CC0PI_2DPmuCosmu_Data.root";
   TFile* rootfile = new TFile(infile.c_str(), "READ");
-  TH2D* tempcov;
+  TH2D* tempcov = NULL;
 
   // ANALYSIS 2
   if (fAnalysis == 2){
 
     // Get Data
     fDataHist = (TH2D*) rootfile->Get("analysis2_data");
     fDataHist->SetDirectory(0);
     fDataHist->SetNameTitle((fName + "_data").c_str(),
 			    (fName + "_data" + fPlotTitles).c_str());
 
     // Get Map
     fMapHist = (TH2I*) rootfile->Get("analysis2_map");
     fMapHist->SetDirectory(0);
     fMapHist->SetNameTitle((fName + "_map").c_str(),
 			    (fName + "_map" + fPlotTitles).c_str());
 
     // Get Syst/Stat Covar
     TH2D* tempsyst = (TH2D*) rootfile->Get("analysis2_systcov");
     TH2D* tempstat = (TH2D*) rootfile->Get("analysis2_statcov");
     TH2D* tempnorm = (TH2D*) rootfile->Get("analysis2_normcov");
 
     // Create covar [Default is both]
     tempcov = (TH2D*) tempsyst->Clone();
     tempcov->Reset();
 
     if (fIsSystCov) tempcov->Add(tempsyst);
     if (fIsStatCov) tempcov->Add(tempstat);
     if (fIsNormCov) tempcov->Add(tempnorm);
 
     if (!fIsSystCov && !fIsStatCov && !fIsNormCov){
       tempcov->Add(tempsyst);
       tempcov->Add(tempstat);
       tempcov->Add(tempnorm);
     }
 
     // SARAS ANALYSIS
   } else if (fAnalysis == 1){
 
     //TODO (P.Stowell) Add a TH2Poly Measurement class
-    ERR(FTL) << "T2K CC0Pi Analysis 1 is not yet available due to its awkward binning!" << endl;
-    ERR(FTL) << "If you want to use it, add a TH2Poly Class!" << endl;
+    ERR(FTL) << "T2K CC0Pi Analysis 1 is not yet available due to its awkward binning!" << std::endl;
+    ERR(FTL) << "If you want to use it, add a TH2Poly Class!" << std::endl;
     throw;
 
   }
 
+  if (!tempcov){
+    ERR(FTL) << "TEMPCOV NOT SET" << std::endl;
+    throw;
+  }
 
   // Setup Covar
   int nbins = tempcov->GetNbinsX();
   fFullCovar = new TMatrixDSym(nbins);
 
   for (int i = 0; i < nbins; i++){
     for (int j = 0; j < nbins; j++){
 
       (*fFullCovar)(i,j) = tempcov->GetBinContent(i+1,j+1);
 
     }
   }
   covar = StatUtils::GetInvert(fFullCovar);
   fDecomp = StatUtils::GetDecomp(covar);
 
   // Set Data Errors
   StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, fMapHist, 1E-38);
 
   // Remove root file
   rootfile->Close();
   return;
 };
diff --git a/src/Tests/CMakeLists.txt b/src/Tests/CMakeLists.txt
index 65eb3d3..f830fb7 100644
--- a/src/Tests/CMakeLists.txt
+++ b/src/Tests/CMakeLists.txt
@@ -1,43 +1,45 @@
 # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 ################################################################################
 #    This file is part of NUISANCE.
 #
 #    NUISANCE is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
 #    (at your option) any later version.
 #
 #    NUISANCE is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #    GNU General Public License for more details.
 #
 #    You should have received a copy of the GNU General Public License
 #    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 ################################################################################
 
 include_directories(${RWENGINE_INCLUDE_DIRECTORIES})
 include_directories(${CMAKE_SOURCE_DIR}/src/Routines)
 include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
+include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler)
+include_directories(${CMAKE_SOURCE_DIR}/src/Genie)
 include_directories(${CMAKE_SOURCE_DIR}/src/Utils)
 include_directories(${CMAKE_SOURCE_DIR}/src/Reweight)
 include_directories(${CMAKE_SOURCE_DIR}/src/Splines)
 include_directories(${CMAKE_SOURCE_DIR}/src/FCN)
 include_directories(${CMAKE_SOURCE_DIR}/src/MCStudies)
 include_directories(${EXP_INCLUDE_DIRECTORIES})
 
 SET(TESTAPPS SignalDefTests ParserTests)
 
 foreach(appimpl ${TESTAPPS})
   add_executable(${appimpl} ${appimpl}.cxx)
   set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};${appimpl})
   target_link_libraries(${appimpl} ${MODULETargets})
   target_link_libraries(${appimpl} ${CMAKE_DEPENDLIB_FLAGS})
   target_link_libraries(${appimpl} ${ROOT_LIBS})
   if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
     set_target_properties(${appimpl} PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
   endif()
   install(TARGETS ${appimpl} DESTINATION tests)
   add_test(${appimpl} ${appimpl} 1)
 endforeach()
diff --git a/src/Utils/CMakeLists.txt b/src/Utils/CMakeLists.txt
index 7cc3624..81dbced 100644
--- a/src/Utils/CMakeLists.txt
+++ b/src/Utils/CMakeLists.txt
@@ -1,92 +1,95 @@
 # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 ################################################################################
 #    This file is part of NUISANCE.
 #
 #    NUISANCE is free software: you can redistribute it and/or modify
 #    it under the terms of the GNU General Public License as published by
 #    the Free Software Foundation, either version 3 of the License, or
 #    (at your option) any later version.
 #
 #    NUISANCE is distributed in the hope that it will be useful,
 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #    GNU General Public License for more details.
 #
 #    You should have received a copy of the GNU General Public License
 #    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 ################################################################################
 set(HEADERFILES
 FitLogger.h
 FitParameters.h
 FitUtils.h
 GeneralUtils.h
+ParserUtils.h
 PlotUtils.h
 StatUtils.h
 SignalDef.h
 NuisConfig.h
 NuisKey.h
 BeamUtils.h
 TargetUtils.h
 StackBase.h
 StandardStacks.h
 OpenMPWrapper.h
 )
 
 set(IMPLFILES
 PythiaQuiet.f
 FitLogger.cxx
 FitParameters.cxx
 FitUtils.cxx
 GeneralUtils.cxx
 PlotUtils.cxx
 StatUtils.cxx
 SignalDef.cxx
 NuisConfig.cxx
 NuisKey.cxx
 BeamUtils.cxx
 TargetUtils.cxx
 StackBase.cxx
+ParserUtils.cxx
 StandardStacks.cxx
 )
 
 set(LIBNAME Utils)
 
 if(CMAKE_BUILD_TYPE MATCHES DEBUG)
   add_library(${LIBNAME} STATIC ${IMPLFILES})
 else(CMAKE_BUILD_TYPE MATCHES RELEASE)
   add_library(${LIBNAME} SHARED ${IMPLFILES})
 endif()
 
 target_include_directories(${LIBNAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
 target_include_directories(${LIBNAME} PUBLIC ${CMAKE_SOURCE_DIR}/src/Splines)
+target_include_directories(${LIBNAME} PUBLIC ${CMAKE_SOURCE_DIR}/src/InputHandler)
 target_include_directories(${LIBNAME} PUBLIC ${CMAKE_SOURCE_DIR}/src/FitBase)
 target_include_directories(${LIBNAME} PUBLIC ${RWENGINE_INCLUDE_DIRECTORIES})
 
 # if(USE_NuWro AND NUWRO_BUILT_FROM_FILE)
 #   target_include_directories(${LIBNAME} PUBLIC ${CMAKE_BINARY_DIR}/NuWro_event1)
 # endif()
 
 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)
 
 #add_executable(DumpROOTClassesFromVector DumpROOTClassesFromVector.cxx GeneralUtils.cxx FitLogger.cxx PythiaQuiet.f)
 
 #target_link_libraries(DumpROOTClassesFromVector ${ROOT_LIBS})
 #if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
 #  set_target_properties(DumpROOTClassesFromVector PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
 #endif()
 #set_target_properties(DumpROOTClassesFromVector PROPERTIES LINK_FLAGS ${ROOT_LD_FLAGS})
 
 #install(TARGETS DumpROOTClassesFromVector DESTINATION bin)
diff --git a/src/Utils/FitUtils.h b/src/Utils/FitUtils.h
index bc24910..5ac8046 100644
--- a/src/Utils/FitUtils.h
+++ b/src/Utils/FitUtils.h
@@ -1,172 +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 <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
 #ifndef FITUTILS_H_SEEN
 #define FITUTILS_H_SEEN
 
 // C Includes
 #include <math.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <ctime>
 #include <iostream>
 #include <numeric>
 
 // ROOT includes
 #include <TChain.h>
 #include <TFile.h>
 #include <TH1D.h>
 #include <TH2D.h>
 #include <THStack.h>
 #include <TKey.h>
 #include <TLegend.h>
 #include <TList.h>
 #include <TLorentzVector.h>
 #include <TObjArray.h>
 #include <TROOT.h>
 #include <TRandom3.h>
 #include <TTree.h>
 #include "FitEvent.h"
 #include "TGraph.h"
 #include "TH2Poly.h"
+#include "FitEvent.h"
 
 // Fit  includes
 #include "FitParameters.h"
 #include "FitLogger.h"
 
 /*!
  *  \addtogroup Utils
  *  @{
  */
 
 //! Functions needed by individual samples for calculating kinematic quantities.
 namespace FitUtils {
 
 /*
   MISC
 */
 
 //! Return a vector of all values saved in map
 double *GetArrayFromMap(std::vector<std::string> invals,
                         std::map<std::string, double> inmap);
 
 /*
   MISC Event
 */
 
 //! Returns kinetic energy of particle
 double T(TLorentzVector part);
 
 //! Returns momentum of particle
 double p(TLorentzVector part);
 
 //! Returns angle between particles (_NOT_ cosine!)
 double th(TLorentzVector part, TLorentzVector part2);
 
 //! Hadronic mass reconstruction
 double Wrec(TLorentzVector pnu, TLorentzVector pmu);
 
 //! Hadronic mass true from initial state particles and muon; useful if the full
 //! FSI vectors aren't not saved and we for some reasons need W_true
 double Wtrue(TLorentzVector pnu, TLorentzVector pmu, TLorentzVector pnuc);
 
 /*
   E Recoil
 */
 double GetErecoil_TRUE(FitEvent *event);
 double GetErecoil_CHARGED(FitEvent *event);
 
 /*
   CCQE MiniBooNE/MINERvA
 */
 //! Function to calculate the reconstructed Q^{2}_{QE}
 double Q2QErec(TLorentzVector pmu, double costh, double binding,
                bool neutrino = true);
 
 //! Function returns the reconstructed E_{nu} values
 double EnuQErec(TLorentzVector pmu, double costh, double binding,
                 bool neutrino = true);
 
 /*
   CCQE1p MINERvA
 */
 //! Reconstruct Q2QE given just the maximum energy proton.
 double ProtonQ2QErec(double pE, double binding);
 
 /*
   E Recoil MINERvA
 */
 double GetErecoil_MINERvA_LowRecoil(FitEvent *event);
 
 /*
   CC1pi0 MiniBooNE
 */
 //! Reconstruct Enu from CCpi0 vectors and binding energy
 double EnuCC1pi0rec(TLorentzVector pnu, TLorentzVector pmu,
                     TLorentzVector ppi0 = TLorentzVector(0, 0, 0, 0));
 
 //! Reconstruct Q2 from CCpi0 vectors and binding energy
 double Q2CC1pi0rec(TLorentzVector pnu, TLorentzVector pmu,
                    TLorentzVector ppi0 = TLorentzVector(0, 0, 0, 0));
 
 /*
   CC1pi+ MiniBooNE
 */
 
 //! returns reconstructed Enu a la MiniBooNE CCpi+
 //! returns reconstructed Enu a la MiniBooNE CCpi+
 // Also for when not having pion info (so when we have a Michel tag in T2K)
 double EnuCC1piprec(TLorentzVector pnu, TLorentzVector pmu, TLorentzVector ppip,
                     bool pionInfo = true);
 
 //! returns reconstructed Enu assumming resonance interaction where intermediate
 //! resonance was a Delta
 double EnuCC1piprecDelta(TLorentzVector pnu, TLorentzVector pmu);
 
 //! returns reconstructed in a variety of flavours
 double Q2CC1piprec(TLorentzVector pnu, TLorentzVector pmu, TLorentzVector ppip,
                    int enuType = 0, bool pionInfo = true);
 
 /*
   T2K CC1pi+ on CH
 */
 double thq3pi_CC1pip_T2K(TLorentzVector pnu, TLorentzVector pmu,
                          TLorentzVector ppi);
 double q3_CC1pip_T2K(TLorentzVector pnu, TLorentzVector pmu,
                      TLorentzVector ppi);
 double WrecCC1pip_T2K_MB(TLorentzVector pnu, TLorentzVector pmu,
                          TLorentzVector ppip);
 double EnuCC1piprec_T2K_eMB(TLorentzVector pnu, TLorentzVector pmu,
                             TLorentzVector ppi);
 
 /*
   nucleon single pion
 */
 double MpPi(TLorentzVector pp, TLorentzVector ppi);
 
 /// Gets delta p T as defined in Phys.Rev. C94 (2016) no.1, 015503
 double Get_STV_dpt(FitEvent *event, int ISPDG, bool Is0pi);
 /// Gets delta phi T as defined in Phys.Rev. C94 (2016) no.1, 015503
 double Get_STV_dphit(FitEvent *event, int ISPDG, bool Is0pi);
 /// Gets delta alpha T as defined in Phys.Rev. C94 (2016) no.1, 015503
 double Get_STV_dalphat(FitEvent *event, int ISPDG, bool Is0pi);
 }
 
 /*! @} */
 #endif
diff --git a/src/Utils/GeneralUtils.h b/src/Utils/GeneralUtils.h
index 99454f1..ef1826f 100644
--- a/src/Utils/GeneralUtils.h
+++ b/src/Utils/GeneralUtils.h
@@ -1,164 +1,166 @@
 // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
 
 /*******************************************************************************
 *    This file is part of NUISANCE.
 *
 *    NUISANCE is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    NUISANCE is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with NUISANCE.  If not, see <http://www.gnu.org/licenses/>.
 *******************************************************************************/
 
 #ifndef GENERALUTILS_H_SEEN
 #define GENERALUTILS_H_SEEN
 
 #include <math.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <cstring>
 #include <fstream>
 #include <iostream>
 #include <iostream>
 #include <numeric>
 #include <limits>
 #include <sstream>
 #include <string>
 #include <vector>
 #include "FitLogger.h"
 
 /*!
  *  \addtogroup Utils
  *  @{
  */
 
 /// Functions which deal with basic string and file handling. They should have
 /// no dependence on the other NUISANCE files!
 namespace GeneralUtils {
 
 /*!
   String handling and file parsing functions
 */
 
 /// Parse a string into a vector of doubles given a delimiter "del"
 std::vector<double> ParseToDbl(std::string str, const char* del);
 
 /// Parse a string into a vector of ints given a delimiter "del"
 std::vector<int> ParseToInt(std::string str, const char* del);
 
 /// Parse a string into a vector of strings given a delimiter "del"
 std::vector<std::string> ParseToStr(std::string str, const char* del);
 
 /// Parse text file into a vector of strings 
 std::vector<std::string> ParseFileToStr(std::string str, const char* del);
 
 /// Convert a string to a double
 double StrToDbl(std::string str);
 
 /// Convert a string to an int
 int StrToInt(std::string str);
 
 /// Convert a string to an bool
 bool StrToBool(std::string str);
 
 /// Convert a bool to string
 std::string BoolToStr(bool val);
 
 /// Convert Int to string
 std::string IntToStr(int val);
 
 /// Convert Double to String
 std::string DblToStr(double val);
 
 /// Return the top level environmental variable for the fitter
 std::string GetTopLevelDir();
 
 // /// A utility function to return a std::vector from an array
 // template <typename T, size_t N>
 // std::vector<T> makeVector(const T (&data)[N]) {
 //   return std::vector<T>(data, data + N);
 // }
 
 std::vector<std::string> LoadCharToVectStr(int argc, char* argv[]);
 
 
 template <typename T, size_t N>
 size_t GetArraySize(const T (&data)[N]) {
   return N;
 }
 template <typename T>
 size_t GetHammingWeight(T const& d) {
   T c = d;
   size_t w = 0;
   while (bool(c)) {
     w += c & 1;
     c = (c >> 1);
   }
   return w;
 }
 
 template <typename T>
 size_t GetFirstOnBit(T const& d) {
   T c = d;
   size_t fob = 0;
   while (bool(c)) {
     if (c & 1) {
       return fob;
     } else {
       c = (c >> 1);
     }
     fob++;
   }
   return fob;
 }
 
 template <typename T>
 size_t IsSmallNum(T const& d) {
   if (std::numeric_limits<T>::is_integer) {
     return (d == 0);
   }
   return (((d > 0) && (d < std::numeric_limits<T>::epsilon())) ||
           ((d < 0) && (d > -std::numeric_limits<T>::epsilon())));
 }
 }
 
 
 /// namespace to contain all physical constants used by NUISANCE
 namespace PhysConst {
 const double mass_proton = 0.93827203;   // Proton mass in GeV
 const double mass_neutron = 0.93956536;  // Neutron mass in GeV
 const double mass_delta = 1.232;         // Delta mass in GeV
 const double mass_muon = 0.10565837;     // Muon mass in GeV
-const int pdg_neutrinos[] = {12, -12, 14, -14 /*, 16, -16*/};
-const int pdg_muons[] = {13, -13};
-const int pdg_leptons[] = {11, -11, 13, -13, 15, -15};
+
+ const int pdg_neutrinos[] = {12, -12, 14, -14 /*, 16, -16*/};
+ const int pdg_muons[] = {13, -13};
+ const int pdg_leptons[] = {11, -11, 13, -13, 15, -15};
+
 const int pdg_pions[] = {211, -211, 111};
 const int pdg_charged_pions[] = {211, -211};
 const int 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};
 
 // Just *-1 to cover possibility
 const int pdg_kplus = 321;
 const int pdg_antistrangemesons[] = {
     -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};
 }
 
 /*! @} */
 #endif
diff --git a/src/Routines/ParserUtils.cxx b/src/Utils/ParserUtils.cxx
similarity index 100%
rename from src/Routines/ParserUtils.cxx
rename to src/Utils/ParserUtils.cxx
diff --git a/src/Routines/ParserUtils.h b/src/Utils/ParserUtils.h
similarity index 99%
rename from src/Routines/ParserUtils.h
rename to src/Utils/ParserUtils.h
index ecf5021..d1225e9 100644
--- a/src/Routines/ParserUtils.h
+++ b/src/Utils/ParserUtils.h
@@ -1,25 +1,25 @@
 #ifndef PARSER_UTILS_H
 #define PARSER_UTILS_H
 #include "FitParameters.h"
 #include "GeneralUtils.h"
 #include <vector>
 namespace ParserUtils {
 
 void CheckBadArguments(std::vector<std::string> args);
 
 void ParseArgument(std::vector<std::string>& args, std::string opt, 
 	int& val, bool required = false, bool duplicates=true);
 
 void ParseArgument(std::vector<std::string>& args, std::string opt, 
 	std::string& val, bool required = false, bool duplicates=true);
 
 void ParseSplitArgument(std::vector<std::string>& args, std::string opt, std::string& val, bool required = false, bool duplicates=true);
 void ParseSplitArgument(std::vector<std::string>& args, std::string opt, std::vector<std::string>& val, bool required=false, bool duplicates=true);
 void ParseRemainingXML(std::vector<std::string>& args, std::vector<std::string>& cmds);
 void ParseCounter(std::vector<std::string>& args, std::string opt, int& count);
 void ParseArgument(std::vector<std::string>& args, std::string opt, std::vector<std::string>& val, bool required = false, bool duplicates=true);
 };
 
 
 
-#endif
\ No newline at end of file
+#endif