Page Menu
Home
HEPForge
Search
Configure Global Search
Log In
Files
F10881680
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
168 KB
Subscribers
None
View Options
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index 3983c0a..c260ba6 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -1,178 +1,192 @@
# Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
################################################################################
# This file is part of NUISANCE.
#
# NUISANCE is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# NUISANCE is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU 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(${CMAKE_SOURCE_DIR}/src/Smearceptance)
include_directories(${EXP_INCLUDE_DIRECTORIES})
if (USE_NuWro AND NOT NUWRO_BUILT_FROM_FILE)
add_executable(nuwro_nuisance nuwro_NUISANCE.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuwro_nuisance)
target_link_libraries(nuwro_nuisance ${MODULETargets})
target_link_libraries(nuwro_nuisance ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(nuwro_nuisance ${ROOT_LIBS})
include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(nuwro_nuisance PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
endif()
if (USE_NEUT)
add_executable(neut_nuisance neut_NUISANCE.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};neut_nuisance)
target_link_libraries(neut_nuisance ${MODULETargets})
target_link_libraries(neut_nuisance ${CMAKE_DEPENDLIB_FLAGS})
target_link_libraries(neut_nuisance ${ROOT_LIBS})
include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(neut_nuisance PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
endif()
if (BUILD_GEVGEN)
add_executable(gevgen_nuisance gEvGen_NUISANCE.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};gevgen_nuisance)
target_link_libraries(gevgen_nuisance ${MODULETargets})
target_link_libraries(gevgen_nuisance ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(gevgen_nuisance ${ROOT_LIBS})
include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
include_directories(${GENIE_INCLUDES}/Apps)
include_directories(${GENIE_INCLUDES}/FluxDrivers)
include_directories(${GENIE_INCLUDES}/EVGDrivers)
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(gevgen_nuisance PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
+
+
+ add_executable(gevgen_nuisance_mixed gEvGen_NUISANCE_MIXED.cxx)
+ set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};gevgen_nuisance_mixed)
+ target_link_libraries(gevgen_nuisance_mixed ${MODULETargets})
+ target_link_libraries(gevgen_nuisance_mixed ${CMAKE_DEPENDLIB_FLAGS})
+ # target_link_libraries(gevgen_nuisance_mixed ${ROOT_LIBS})
+ include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
+ include_directories(${GENIE_INCLUDES}/Apps)
+ include_directories(${GENIE_INCLUDES}/FluxDrivers)
+ include_directories(${GENIE_INCLUDES}/EVGDrivers)
+ if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
+ set_target_properties(gevgen_nuisance_mixed PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
+ endif()
endif()
if (USE_GiBUU)
add_executable(DumpGiBUUEvents DumpGiBUUEvents.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};DumpGiBUUEvents)
target_link_libraries(DumpGiBUUEvents ${MODULETargets})
target_link_libraries(DumpGiBUUEvents ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(DumpGiBUUEvents ${ROOT_LIBS})
include_directories(${CMAKE_SOURCE_DIR}/src/FitBase)
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(DumpGiBUUEvents PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
endif()
add_executable(nuiscomp nuiscomp.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuiscomp)
target_link_libraries(nuiscomp ${MODULETargets})
target_link_libraries(nuiscomp ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(nuiscomp ${ROOT_LIBS})
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(nuiscomp PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
add_executable(nuisflat nuisflat.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuisflat)
target_link_libraries(nuisflat ${MODULETargets})
target_link_libraries(nuisflat ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(nuisflat ${ROOT_LIBS})
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(nuisflat PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
add_executable(nuissmear nuissmear.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuissmear)
target_link_libraries(nuissmear ${MODULETargets})
target_link_libraries(nuissmear ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(nuissmear ${ROOT_LIBS})
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(nuissmear PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
add_executable(nuissyst nuissyst.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};nuissyst)
target_link_libraries(nuissyst ${MODULETargets})
target_link_libraries(nuissyst ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(nuissyst ${ROOT_LIBS})
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(nuissyst PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
if(USE_GENIE)
add_executable(PrepareGENIE PrepareGENIE.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};PrepareGENIE)
target_link_libraries(PrepareGENIE ${MODULETargets})
target_link_libraries(PrepareGENIE ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(PrepareGENIE ${ROOT_LIBS})
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(PrepareGENIE PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
endif()
if(USE_NEUT)
add_executable(PrepareNEUT PrepareNEUT.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};PrepareNEUT)
target_link_libraries(PrepareNEUT ${MODULETargets})
target_link_libraries(PrepareNEUT ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(PrepareNEUT ${ROOT_LIBS})
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(PrepareNEUT PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
endif()
# PREPARE NUWRO
# Commented out for the time being until it is finished..
if(USE_NuWro)
add_executable(PrepareNuwro PrepareNuwroEvents.cxx)
set(TARGETS_TO_BUILD ${TARGETS_TO_BUILD};PrepareNuwro)
target_link_libraries(PrepareNuwro ${MODULETargets})
target_link_libraries(PrepareNuwro ${CMAKE_DEPENDLIB_FLAGS})
# target_link_libraries(PrepareNuwro ${ROOT_LIBS})
if(NOT "${CMAKE_LINK_FLAGS}" STREQUAL "")
set_target_properties(PrepareNuwro PROPERTIES LINK_FLAGS ${CMAKE_LINK_FLAGS})
endif()
endif()
install(TARGETS ${TARGETS_TO_BUILD} DESTINATION bin)
diff --git a/app/gEvGen_NUISANCE_MIXED.cxx b/app/gEvGen_NUISANCE_MIXED.cxx
new file mode 100644
index 0000000..c0969c7
--- /dev/null
+++ b/app/gEvGen_NUISANCE_MIXED.cxx
@@ -0,0 +1,1001 @@
+#ifdef __GENIE_ENABLED__
+//____________________________________________________________________________
+/*!
+
+\program gevgen
+
+\brief A simple 'generic' GENIE v+A event generation driver (gevgen).
+
+ It handles:
+ a) event generation for a fixed init state (v+A) at fixed energy, or
+ b) event generation for simple fluxes (specified either via some
+ functional form, tabular text file or a ROOT histogram) and for
+ simple 'geometries' (a target mix with its corresponding weights)
+
+ See the GENIE manual for other apps handling experiment-specific
+ event generation cases using the outputs of detailed neutrino flux
+ simulations and realistic detector geometry descriptions.
+
+ Syntax :
+ gevgen [-h]
+ [-r run#]
+ -n nev
+ -e energy (or energy range)
+ -p neutrino_pdg
+ -t target_pdg
+ [-f flux_description]
+ [-w]
+ [--seed random_number_seed]
+ [--cross-sections xml_file]
+ [--event-generator-list list_name]
+ [--tune genie_tune]
+ [--message-thresholds xml_file]
+ [--unphysical-event-mask mask]
+ [--event-record-print-level level]
+ [--mc-job-status-refresh-rate rate]
+ [--cache-file root_file]
+
+ Options :
+ [] Denotes an optional argument.
+ -h
+ Prints-out help on using gevgen and exits.
+ -n
+ Specifies the number of events to generate.
+ -r
+ Specifies the MC run number.
+ -e
+ Specifies the neutrino energy.
+ If what follows the -e option is a comma separated pair of values
+ it will be interpreted as an energy range for the flux specified
+ via the -f option (see below).
+ -p
+ Specifies the neutrino PDG code.
+ -t
+ Specifies the target PDG code (pdg format: 10LZZZAAAI) _or_ a target
+ mix (pdg codes with corresponding weights) typed as a comma-separated
+ list of pdg codes with the corresponding weight fractions in brackets,
+ eg code1[fraction1],code2[fraction2],...
+ For example, to use a target mix of 95% O16 and 5% H type:
+ `-t 1000080160[0.95],1000010010[0.05]'.
+ -f
+ Specifies the neutrino flux spectrum.
+ It can be any of:
+ -- A function:
+ eg ` -f x*x+4*exp(-x)'
+ -- A vector file:
+ The vector file should contain 2 columns corresponding to
+ energy,flux (see $GENIE/data/flux/ for few examples).
+ -- A 1-D ROOT histogram (TH1D):
+ The general syntax is `-f /full/path/file.root,object_name'
+ -w
+ Forces generation of weighted events.
+ This option is relevant only if a neutrino flux is specified.
+ Note that 'weighted' refers to the selection of the primary
+ flux neutrino + target that were forced to interact. A weighting
+ scheme for the generated kinematics of individual processes can
+ still be in effect if enabled..
+ ** Only use that option if you understand what it means **
+ --seed
+ Random number seed.
+ --cross-sections
+ Name (incl. full path) of an XML file with pre-computed
+ cross-section values used for constructing splines.
+ --event-generator-list
+ List of event generators to load in event generation drivers.
+ [default: "Default"].
+ --tune
+ Specifies a GENIE comprehensive neutrino interaction model tune.
+ [default: "Default"].
+ --message-thresholds
+ Allows users to customize the message stream thresholds.
+ The thresholds are specified using an XML file.
+ See $GENIE/config/Messenger.xml for the XML schema.
+ --unphysical-event-mask
+ Allows users to specify a 16-bit mask to allow certain types of
+ unphysical events to be written in the output file.
+ [default: all unphysical events are rejected]
+ --event-record-print-level
+ Allows users to set the level of information shown when the event
+ record is printed in the screen. See GHepRecord::Print().
+ --mc-job-status-refresh-rate
+ Allows users to customize the refresh rate of the status file.
+ --cache-file
+ Allows users to specify a cache file so that the cache can be
+ re-used in subsequent MC jobs.
+
+ *** See the User Manual for more details and examples. ***
+
+\author Costas Andreopoulos <costas.andreopoulos \at stfc.ac.uk>
+ University of Liverpool & STFC Rutherford Appleton Lab
+
+\created October 05, 2004
+
+\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
+*/
+//____________________________________________________________________________
+
+#include <cstdlib>
+#include <cassert>
+#include <sstream>
+#include <string>
+#include <vector>
+#include <map>
+
+#if defined(HAVE_FENV_H) && defined(HAVE_FEENABLEEXCEPT)
+#include <fenv.h> // for `feenableexcept`
+#endif
+
+#include <TFile.h>
+#include <TTree.h>
+#include <TSystem.h>
+#include <TVector3.h>
+#include <TH1.h>
+#include <TF1.h>
+
+#include "Conventions/XmlParserStatus.h"
+#include "Conventions/GBuild.h"
+#include "Conventions/Controls.h"
+#include "Conventions/Units.h"
+
+#include "EVGCore/EventRecord.h"
+#include "EVGDrivers/GFluxI.h"
+#include "EVGDrivers/GEVGDriver.h"
+//#include "EVGDrivers/GMCJDriver.h"
+#include "GNUISANCEMCJDriver.h"
+#include "EVGDrivers/GMCJMonitor.h"
+#include "Interaction/Interaction.h"
+#include "Messenger/Messenger.h"
+#include "Ntuple/NtpWriter.h"
+#include "Ntuple/NtpMCFormat.h"
+#include "Numerical/RandomGen.h"
+#include "Numerical/Spline.h"
+#include "PDG/PDGCodes.h"
+#include "PDG/PDGUtils.h"
+#include "Utils/AppInit.h"
+#include "Utils/RunOpt.h"
+#include "Utils/XSecSplineList.h"
+#include "Utils/StringUtils.h"
+#include "Utils/PrintUtils.h"
+#include "Utils/SystemUtils.h"
+#include "Utils/CmdLnArgParser.h"
+
+//#include "FitBase/GNUISANCEFlux.h"
+#include "GNUISANCEFlux.h"
+
+//#ifdef __GENIE_FLUX_DRIVERS_ENABLED__
+//#ifdef __GENIE_GEOM_DRIVERS_ENABLED__
+#define __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__
+#include "GNUISANCEFlux.h"
+#include "FluxDrivers/GMonoEnergeticFlux.h"
+#include "Geo/PointGeomAnalyzer.h"
+//#endif
+//#endif
+
+using std::string;
+using std::vector;
+using std::map;
+using std::ostringstream;
+
+using namespace genie;
+using namespace genie::controls;
+using namespace genie::flux;
+
+void GetCommandLineArgs (int argc, char ** argv);
+void Initialize (void);
+void PrintSyntax (void);
+
+#ifdef __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__
+void GenerateEventsUsingFluxOrTgtMix();
+GeomAnalyzerI * GeomDriver (void);
+GFluxI * FluxDriver (void);
+GFluxI * MonoEnergeticFluxDriver (void);
+GFluxI * TH1FluxDriver (void);
+string ConvertTargetIDs (string);
+string ConvertFluxIDs (string);
+void ListTargetIDs(void);
+void ListFluxIDs(void);
+#endif
+
+void GenerateEventsAtFixedInitState (void);
+
+//Default options (override them using the command line arguments):
+int kDefOptNevents = 0; // n-events to generate
+NtpMCFormat_t kDefOptNtpFormat = kNFGHEP; // ntuple format
+Long_t kDefOptRunNu = 0; // default run number
+
+//User-specified options:
+int gOptNevents; // n-events to generate
+double gOptNuEnergy; // neutrino E, or min neutrino energy in spectrum
+double gOptNuEnergyRange;// energy range in input spectrum
+int gOptNuPdgCode; // neutrino PDG code
+map<int,double> gOptTgtMix; // target mix (each with its relative weight)
+Long_t gOptRunNu; // run number
+string gOptFlux; //
+bool gOptWeighted; //
+bool gOptUsingFluxOrTgtMix = false;
+long int gOptRanSeed; // random number seed
+string gOptInpXSecFile; // cross-section splines
+
+
+vector<int> gOptNuPDGs; // Beam PDGS
+vector<TH1D*> gOptNuFluxs; // Beam Fluxes
+vector<int> gOptTgtPDGs; // Target PDGS
+int gOptNumberNucleons; // Total number of target nucleons
+
+//____________________________________________________________________________
+int main(int argc, char ** argv)
+{
+ GetCommandLineArgs(argc,argv);
+ Initialize();
+
+ // throw on NaNs and Infs...
+#if defined(HAVE_FENV_H) && defined(HAVE_FEENABLEEXCEPT)
+ feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
+#endif
+ //
+ // Generate neutrino events
+ //
+
+ if(gOptUsingFluxOrTgtMix) {
+#ifdef __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__
+ GenerateEventsUsingFluxOrTgtMix();
+#else
+ LOG("gevgen", pERROR)
+ << "\n To be able to generate neutrino events from a flux and/or a target mix"
+ << "\n you need to add the following config options at your GENIE installation:"
+ << "\n --enable-flux-drivers --enable-geom-drivers \n" ;
+#endif
+ } else {
+ GenerateEventsAtFixedInitState();
+ }
+ return 0;
+}
+//____________________________________________________________________________
+void Initialize()
+{
+ // Initialization of random number generators, cross-section table,
+ // messenger thresholds, cache file
+ utils::app_init::MesgThresholds(RunOpt::Instance()->MesgThresholdFiles());
+ utils::app_init::CacheFile(RunOpt::Instance()->CacheFile());
+ utils::app_init::RandGen(gOptRanSeed);
+ utils::app_init::XSecTable(gOptInpXSecFile, false);
+
+ // Set GHEP print level
+ GHepRecord::SetPrintLevel(RunOpt::Instance()->EventRecordPrintLevel());
+}
+//____________________________________________________________________________
+void GenerateEventsAtFixedInitState(void)
+{
+ int neutrino = gOptNuPdgCode;
+ int target = gOptTgtMix.begin()->first;
+ double Ev = gOptNuEnergy;
+ TLorentzVector nu_p4(0.,0.,Ev,Ev); // px,py,pz,E (GeV)
+
+ // Create init state
+ InitialState init_state(target, neutrino);
+
+ // Create/config event generation driver
+ GEVGDriver evg_driver;
+ evg_driver.SetEventGeneratorList(RunOpt::Instance()->EventGeneratorList());
+ evg_driver.SetUnphysEventMask(*RunOpt::Instance()->UnphysEventMask());
+ evg_driver.Configure(init_state);
+
+ // Initialize an Ntuple Writer
+ NtpWriter ntpw(kDefOptNtpFormat, gOptRunNu);
+ ntpw.Initialize();
+
+ // Create an MC Job Monitor
+ GMCJMonitor mcjmonitor(gOptRunNu);
+ mcjmonitor.SetRefreshRate(RunOpt::Instance()->MCJobStatusRefreshRate());
+
+ LOG("gevgen", pNOTICE)
+ << "\n ** Will generate " << gOptNevents << " events for \n"
+ << init_state << " at Ev = " << Ev << " GeV";
+
+ // Generate events / print the GHEP record / add it to the ntuple
+ int ievent = 0;
+ while (ievent < gOptNevents) {
+ LOG("gevgen", pNOTICE)
+ << " *** Generating event............ " << ievent;
+
+ // generate a single event
+ EventRecord * event = evg_driver.GenerateEvent(nu_p4);
+
+ if(!event) {
+ LOG("gevgen", pNOTICE)
+ << "Last attempt failed. Re-trying....";
+ continue;
+ }
+
+ LOG("gevgen", pNOTICE)
+ << "Generated Event GHEP Record: " << *event;
+
+ // add event at the output ntuple, refresh the mc job monitor & clean up
+ ntpw.AddEventRecord(ievent, event);
+ mcjmonitor.Update(ievent,event);
+ ievent++;
+ delete event;
+ }
+
+ // Save the generated MC events
+ ntpw.Save();
+}
+//____________________________________________________________________________
+
+#ifdef __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__
+//............................................................................
+void GenerateEventsUsingFluxOrTgtMix(void)
+{
+ // Get flux and geom drivers
+ GFluxI * flux_driver = FluxDriver();
+ GeomAnalyzerI * geom_driver = GeomDriver();
+
+ // Create the monte carlo job driver
+ GNUISANCEMCJDriver * mcj_driver = new GNUISANCEMCJDriver;
+ mcj_driver->SetEventGeneratorList(RunOpt::Instance()->EventGeneratorList());
+ mcj_driver->SetUnphysEventMask(*RunOpt::Instance()->UnphysEventMask());
+ mcj_driver->UseFluxDriver(flux_driver);
+ mcj_driver->UseGeomAnalyzer(geom_driver);
+ mcj_driver->Configure();
+ mcj_driver->UseSplines();
+ if(!gOptWeighted)
+ mcj_driver->ForceSingleProbScale();
+
+ // Initialize an Ntuple Writer to save GHEP records into a TTree
+ NtpWriter ntpw(kDefOptNtpFormat, gOptRunNu);
+ ntpw.Initialize();
+
+ // Now Create flux histograms
+ TH1D* totalflux = static_cast<GNUISANCEFlux*>(flux_driver)->GetTotalSpectrum();
+ vector<TH1D*> fluxinputs = static_cast<GNUISANCEFlux*>(flux_driver)->GetSpectrum();
+ totalflux->SetNameTitle("nuisance_flux","NUISANCE Total Flux");
+
+ TH1D* totalevent = (TH1D*) totalflux->Clone();
+ totalevent->SetNameTitle("nuisance_events", "NUISANCE Total Events");
+ // totalevent->Reset();
+
+ TH1D* totalxsec = (TH1D*)totalflux->Clone();
+ totalxsec->SetNameTitle("nuisance_xsec", "NUISANCE Total XSec");
+ totalxsec->Reset();
+
+ // Calculate fractional target nucleon integral
+ double tfracintegral = 0.0;
+ for (UInt_t j = 0; j < gOptTgtPDGs.size(); j++){
+ int tpdg = gOptTgtPDGs[j];
+ int tnucl = tpdg % 10000 / 10;
+ double mixfrac = gOptTgtMix[tpdg];
+ tfracintegral += mixfrac * tnucl;
+ }
+
+ // Save the cross-section histograms
+ for (UInt_t i = 0; i < gOptNuPDGs.size(); i++){
+ for (UInt_t j = 0; j < gOptTgtPDGs.size(); j++){
+
+ int npdg = gOptNuPDGs[i];
+ TH1D* fluxhist = gOptNuFluxs[i];
+
+ int tpdg = gOptTgtPDGs[j];
+
+ // Determine the total number of these targets by using the tgt ratios backwards
+ double mixfrac = gOptTgtMix[tpdg];
+
+ int tnucl = tpdg % 10000 / 10; // Total Single Target Nucleons
+ double enucl = double(mixfrac * double(gOptNumberNucleons)); // Expected nucleons from weight fractions
+
+ // double tfrac = double(enucl) / double(tnucl); // Scaling factor.
+ double tfrac = mixfrac;
+
+
+ // Get Initial state driver
+ InitialState init_state(tpdg, npdg);
+ GEVGPool* gpool = mcj_driver->GetConfigPool();
+ GEVGDriver * evgdriver = gpool->FindDriver(init_state);
+ const Spline * totxsecspl = evgdriver->XSecSumSpline();
+
+ // make new empty xsec hist
+ TH1D* xsechist = (TH1D*) totalflux->Clone();
+ xsechist->SetNameTitle((init_state.AsString()+"_xsec").c_str(),init_state.AsString().c_str());
+ xsechist->Reset();
+
+ TH1D* eventhist = (TH1D*) totalflux->Clone();
+ eventhist->SetNameTitle((init_state.AsString()+"_events").c_str(),init_state.AsString().c_str());
+ eventhist->Reset();
+
+ std::cout << "Total Frac for " << init_state.AsString() << " = " << tfrac << std::endl;
+ std::cout << "TNUCL = " << tnucl << std::endl;
+ std::cout << "ENUCL = " << enucl << std::endl;
+ std::cout << "MIXFRAC = " << mixfrac << std::endl;
+ std::cout << "TPDG = " << tpdg << std::endl;
+
+ // Fill xsec hist
+ for (int k = 0; k < totalflux->GetNbinsX(); k++){
+ double avgxsec = 0.0;
+
+
+ int res = 1000;
+ for (int l = 0; l < res; l++){
+ double E = fluxhist->GetXaxis()->GetBinLowEdge(k+1) + (double(l)*fluxhist->GetXaxis()->GetBinWidth(k+1) / double(res));
+ double xsec = totxsecspl->Evaluate( E ) / (1E-38 * genie::units::cm2);
+ avgxsec += xsec;
+ }
+ avgxsec /= double(res);
+
+ // double E = fluxhist->GetXaxis()->GetBinCenter(k+1);
+ // avgxsec = totxsecspl->Evaluate( E ) / (1E-38 * genie::units::cm2);
+
+ xsechist->SetBinContent(k+1, avgxsec);
+ eventhist->SetBinContent(k+1, avgxsec * fluxhist->GetBinContent(k+1));
+
+ }
+
+ // Scale totals by target fractions
+ xsechist->Scale(tfrac);
+ eventhist->Scale(tfrac);
+
+ // Add to totals
+ totalxsec->Add(xsechist);
+ //totalevent->Add(eventhist);
+
+ std::cout << "Total XSec Hist for " << init_state.AsString() << " = " << xsechist->Integral("width") << std::endl;
+
+ // Scale by nnucleons
+ // xsechist->Scale(1.0 / double(gOptNumberNucleons));
+ // eventhist->Scale(1.0 / double(gOptNumberNucleons));
+
+ // Write our new xsec histto file
+ fluxhist->SetNameTitle((init_state.AsString()+"_flux").c_str(),init_state.AsString().c_str());
+ fluxhist->Write();
+ xsechist->Write();
+ eventhist->Write();
+
+ delete xsechist;
+ delete eventhist;
+
+ // sleep(10);
+ }
+ }
+
+ // Determine NUISANCE Style Histograms
+ totalevent->SetNameTitle("nuisance_events", "NUISANCE Total Events");
+ totalevent->Multiply(totalxsec);
+ // totalevent->Scale(1.0 / double(gOptNumberNucleons));
+ totalevent->Scale(1.0 / tfracintegral);
+ std::cout << "GOPTNumberNucleons = " << gOptNumberNucleons << std::endl;
+ std::cout << "Inclusive XSec Per Nucleon = " << totalevent->Integral("width") * 1E-38 / totalflux->Integral("width") << std::endl;
+ std::cout << "XSec Hist Integral = " << totalxsec->Integral("width") << std::endl;
+ // sleep(20);
+
+ // totalxsec->Scale(1.0/double(gOptNumberNucleons));
+ // totalevent->Scale(1.0/double(gOptNumberNucleons));
+
+ // Create an MC Job Monitor
+ GMCJMonitor mcjmonitor(gOptRunNu);
+ mcjmonitor.SetRefreshRate(RunOpt::Instance()->MCJobStatusRefreshRate());
+
+ // Generate events / print the GHEP record / add it to the ntuple
+ int ievent = 0;
+ while ( ievent < gOptNevents) {
+
+ LOG("gevgen", pNOTICE) << " *** Generating event............ " << ievent;
+
+ // generate a single event for neutrinos coming from the specified flux
+ EventRecord * event = mcj_driver->GenerateEvent();
+
+ LOG("gevgen", pNOTICE) << "Generated Event GHEP Record: " << *event;
+
+ // add event at the output ntuple, refresh the mc job monitor & clean-up
+ ntpw.AddEventRecord(ievent, event);
+ mcjmonitor.Update(ievent,event);
+ ievent++;
+ delete event;
+ }
+
+ // Save the generated MC events
+ ntpw.Save();
+
+
+ delete flux_driver;
+ delete geom_driver;
+ delete mcj_driver;;
+}
+//____________________________________________________________________________
+GeomAnalyzerI * GeomDriver(void)
+{
+// create a trivial point geometry with the specified target or target mix
+
+ GeomAnalyzerI * geom_driver = new geometry::PointGeomAnalyzer(gOptTgtMix);
+ return geom_driver;
+}
+//____________________________________________________________________________
+GFluxI * FluxDriver(void)
+{
+// create & configure one of the generic flux drivers
+//
+ GFluxI * flux_driver = 0;
+
+ if(gOptNuEnergyRange<0) flux_driver = MonoEnergeticFluxDriver();
+ else flux_driver = TH1FluxDriver();
+
+ return flux_driver;
+}
+//____________________________________________________________________________
+GFluxI * MonoEnergeticFluxDriver(void)
+{
+//
+//
+ flux::GMonoEnergeticFlux * flux =
+ new flux::GMonoEnergeticFlux(gOptNuEnergy, gOptNuPdgCode);
+ GFluxI * flux_driver = dynamic_cast<GFluxI *>(flux);
+ return flux_driver;
+}
+//____________________________________________________________________________
+GFluxI * TH1FluxDriver(void)
+{
+
+ // GeVGEN NUISANCE Can only Read flux files from ROOT
+ flux::GNUISANCEFlux * flux = new flux::GNUISANCEFlux;
+
+ // Initial beam directions
+ TVector3 bdir (0,0,1);
+ TVector3 bspot(0,0,0);
+
+ flux->SetNuDirection (bdir);
+ flux->SetBeamSpot (bspot);
+ flux->SetTransverseRadius (-1);
+
+ // Flux inputs
+ int flux_entries = 100000;
+
+ double emin = gOptNuEnergy;
+ double emax = gOptNuEnergy+gOptNuEnergyRange;
+ double de = gOptNuEnergyRange;
+
+ // check whether the input flux is a file or a functional form
+ bool input_is_root_file = gOptFlux.find(".root") != string::npos &&
+ gOptFlux.find(",") != string::npos;
+
+ if (!input_is_root_file){
+ std::cout << "ONLY ROOT INPUTS ALLOWED" << std::endl;
+ throw;
+ }
+
+ //
+ // ** extract specified flux histogram from the input root file
+ //
+ vector<string> fv = utils::str::Split(gOptFlux,",");
+
+ assert(fv.size()>=2);
+ assert( !gSystem->AccessPathName(fv[0].c_str()) );
+
+ // First entry is the root file
+ LOG("gevgen", pNOTICE) << "Getting input flux from root file: " << fv[0];
+ TFile * flux_file = new TFile(fv[0].c_str(),"read");
+
+ // Later entries are flux inputs
+ for (UInt_t i = 1; i < fv.size(); i++){
+ string fluxid = fv[i];
+
+ // Parse out the beam pdg and flux name
+ string flux_with_pdg = fluxid;
+ string::size_type open_bracket = flux_with_pdg.find("[");
+ string::size_type close_bracket = flux_with_pdg.find("]");
+ string::size_type ibeg = 0;
+ string::size_type iend = open_bracket;
+ string::size_type jbeg = open_bracket+1;
+ string::size_type jend = close_bracket-1;
+
+ string fluxname = flux_with_pdg.substr(ibeg,iend);
+ int fluxpdg = atoi(flux_with_pdg.substr(jbeg,jend).c_str());
+
+ // Get histogram
+ LOG("gevgen", pNOTICE) << "Flux name: " << fluxname << " pdg = " << fluxpdg;
+ TH1D * hst = (TH1D *)flux_file->Get(fluxname.c_str());
+ assert(hst);
+
+ LOG("gevgen", pNOTICE) << hst->GetEntries();
+
+
+ // Copy in the flux histogram from the root file and remove bins outside the emin,emax range
+ TH1D* spectrum = (TH1D*)hst->Clone();
+ spectrum->SetNameTitle("spectrum","neutrino_flux");
+ spectrum->SetDirectory(0);
+ for(int ibin = 1; ibin <= hst->GetNbinsX(); ibin++) {
+ if(spectrum->GetBinCenter(ibin) > emax ||
+ spectrum->GetBinCenter(ibin) < emin){
+ spectrum->SetBinContent(ibin, 0);
+ }
+ }
+
+ LOG("gevgen", pNOTICE) << spectrum->GetEntries();
+
+
+ // Add energy spectrum to the flux driver.
+ flux->AddEnergySpectrum( fluxpdg, spectrum );
+
+ gOptNuPDGs.push_back(fluxpdg);
+ gOptNuFluxs.push_back(spectrum);
+
+ }
+ // flux->AddAllFluxes();
+
+ // Close inputs
+ flux_file->Close();
+ delete flux_file;
+
+ // Return flux driver.
+ GFluxI * flux_driver = dynamic_cast<GFluxI *>(flux);
+ return flux_driver;
+}
+
+///____________________________________________________________________________
+void ListTargetIDs(){
+
+ // Keep in sync with ConvertTargetIDs
+ LOG("gevgen", pNOTICE) << "Possible Target IDs: \n"
+ << "\n H : " << ConvertTargetIDs("H")
+ << "\n C : " << ConvertTargetIDs("C")
+ << "\n CH : " << ConvertTargetIDs("CH")
+ << "\n CH2 : " << ConvertTargetIDs("CH2")
+ << "\n H2O : " << ConvertTargetIDs("H2O")
+ << "\n Fe : " << ConvertTargetIDs("Fe")
+ << "\n Pb : " << ConvertTargetIDs("Pb")
+ << "\n D2 : " << ConvertTargetIDs("D2")
+ << "\n D2-free : " << ConvertTargetIDs("D2-free");
+}
+
+
+//____________________________________________________________________________
+string ConvertTargetIDs(string id){
+
+ if (!id.compare("H")) return "1000010010";
+ else if (!id.compare("C")) return "1000060120";
+ else if (!id.compare("CH")) return "13,1000060120[0.9231],1000010010[0.0769]";
+ else if (!id.compare("CH2")) return "14,1000060120[0.8571],1000010010[0.1429]";
+ else if (!id.compare("H2O")) return "18,1000080160[0.8888],1000010010[0.1111]";
+ else if (!id.compare("Fe")) return "1000260560";
+ else if (!id.compare("Pb")) return "1000822070";
+ else if (!id.compare("D2")) return "1000010020";
+ else if (!id.compare("D2-free")) return "2,1000010010[0.5],1000000010[0.5]";
+ else return "";
+
+};
+
+///____________________________________________________________________________
+void ListFluxIDs(){
+
+ // Keep in sync with ConvertTargetIDs
+ LOG("gevgen", pNOTICE) << "Possible Flux IDs: \n"
+ << "\n MINERvA_fhc_numu : " << ConvertFluxIDs("MINERvA_fhc_numu")
+ << "\n MINERvA_fhc_numunumubar : " << ConvertFluxIDs("MINERvA_fhc_numunumubar")
+ << "\n MINERvA_fhc_nue : " << ConvertFluxIDs("MINERvA_fhc_nue")
+ << "\n MINERvA_fhc_nuenuebar : " << ConvertFluxIDs("MINERvA_fhc_nuenuebar")
+ << "\n MINERvA_fhc_all : " << ConvertFluxIDs("MINERvA_fhc_all")
+
+ << "\n MINERvA_rhc_numubar : " << ConvertFluxIDs("MINERvA_rhc_numubar")
+ << "\n MINERvA_rhc_numubarnumu : " << ConvertFluxIDs("MINERvA_rhc_numubarnumu")
+ << "\n MINERvA_rhc_nuebar : " << ConvertFluxIDs("MINERvA_rhc_nuebar")
+ << "\n MINERvA_rhc_nuebarnue : " << ConvertFluxIDs("MINERvA_rhc_nuebarnue")
+ << "\n MINERvA_rhc_all : " << ConvertFluxIDs("MINERvA_rhc_all")
+
+ << "\n ANL_fhc_numu : " << ConvertFluxIDs("ANL_fhc_numu")
+ << "\n BNL_fhc_numu : " << ConvertFluxIDs("BNL_fhc_numu")
+ << "\n BNL_fhc_numu_ALT1986 : " << ConvertFluxIDs("BNL_fhc_numu_ALT1986")
+ << "\n BNL_fhc_numu_ALT1981 : " << ConvertFluxIDs("BNL_fhc_numu_ALT1981")
+ << "\n BEBC_fhc_numu : " << ConvertFluxIDs("BEBC_fhc_numu")
+ << "\n FNAL_fhc_numu : " << ConvertFluxIDs("FNAL_fhc_numu")
+ << "\n FNAL_rhc_numub : " << ConvertFluxIDs("FNAL_rhc_numub")
+ << "\n GGM_fhc_numu : " << ConvertFluxIDs("GGM_fhc_numu");
+
+}
+
+
+//____________________________________________________________________________
+string ConvertFluxIDs(string id){
+
+ char * const var = getenv("NUISANCE");
+ if (!var) {
+ std::cout << "Cannot find top level directory! Set the NUISANCE environmental variable" << std::endl;
+ exit(-1);
+ }
+ string topnuisancedir = string(var);
+ string fluxfolder = topnuisancedir + "/data/flux/";
+ string inputs = "";
+
+ if (!id.compare("MINERvA_fhc_numu")) inputs="minerva_flux.root,numu_fhc[14]";
+ else if (!id.compare("MINERvA_fhc_numunumubar")) inputs="minerva_flux.root,numu_fhc[14],numubar_fhc[-14]";
+ else if (!id.compare("MINERvA_fhc_numu")) inputs="minerva_flux.root,nue_fhc[12]";
+ else if (!id.compare("MINERvA_fhc_nuenuebar")) inputs="minerva_flux.root,nue_fhc[12],nuebar_fhc[-12]";
+ else if (!id.compare("MINERvA_fhc_all")) inputs="minerva_flux.root,numu_fhc[14],numubar_fhc[-14],nue_fhc[12],nuebar_fhc[-12]";
+
+ else if (!id.compare("MINERvA_rhc_numubar")) inputs="minerva_flux.root,numubar_rhc[-14]";
+ else if (!id.compare("MINERvA_rhc_numubarnumu")) inputs="minerva_flux.root,numubar_rhc[-14],numu_rhc[14]";
+ else if (!id.compare("MINERvA_rhc_nuebar")) inputs="minerva_flux.root,nuebar_rhc[-12]";
+ else if (!id.compare("MINERvA_rhc_nuebarnue")) inputs="minerva_flux.root,nuebar_rhc[-12],nue_rhc[12]";
+ else if (!id.compare("MINERvA_rhc_all")) inputs="minerva_flux.root,numu_rhc[14],numubar_rhc[-14],nue_rhc[12],nuebar_rhc[-12]";
+
+ else if (!id.compare("ANL_fhc_numu")) inputs="ANL_1977_2horn_rescan.root,numu_flux[14]";
+ else if (!id.compare("BNL_fhc_numu")) inputs="BNL_NuInt02_rescan.root,numu_flux[14]";
+ else if (!id.compare("BNL_fhc_numu_ALT1986")) inputs="BNL_1986_flux-ALTERNATIVE.root,numu_flux[14]";
+ else if (!id.compare("BNL_fhc_numu_ALT1981")) inputs="BNL_CCQE_1981_rescan-ALTERNATIVE.root,numu_flux[14]";
+
+ else if (!id.compare("BEBC_fhc_numu")) inputs="BEBC_Wachsmuth_numubar_table.root,numu_flux[14]";
+ else if (!id.compare("FNAL_fhc_numu")) inputs="FNAL_CCinc_1982_nu_MCadj.root,numu_flux[14]";
+ else if (!id.compare("FNAL_rhc_numub")) inputs="FNAL_coh_1993_anu.root,numu_flux[-14]";
+ else if (!id.compare("GGM_fhc_numu")) inputs="GGM_nu_flux_1979_rescan.root,numu_flux[14]";
+ else return "";
+
+ return fluxfolder + inputs;
+
+};
+
+
+
+//............................................................................
+#endif
+
+
+//____________________________________________________________________________
+void GetCommandLineArgs(int argc, char ** argv)
+{
+ LOG("gevgen", pINFO) << "Parsing command line arguments";
+
+ // Common run options. Set defaults and read.
+ RunOpt::Instance()->EnableBareXSecPreCalc(true);
+ RunOpt::Instance()->ReadFromCommandLine(argc,argv);
+
+ // Parse run options for this app
+
+ CmdLnArgParser parser(argc,argv);
+
+ // help?
+ bool help = parser.OptionExists('h');
+ if(help) {
+ PrintSyntax();
+ exit(0);
+ }
+
+ // number of events
+ if( parser.OptionExists('n') ) {
+ LOG("gevgen", pINFO) << "Reading number of events to generate";
+ gOptNevents = parser.ArgAsInt('n');
+ } else {
+ LOG("gevgen", pINFO)
+ << "Unspecified number of events to generate - Using default";
+ gOptNevents = kDefOptNevents;
+ }
+
+ // run number
+ if( parser.OptionExists('r') ) {
+ LOG("gevgen", pINFO) << "Reading MC run number";
+ gOptRunNu = parser.ArgAsLong('r');
+ } else {
+ LOG("gevgen", pINFO) << "Unspecified run number - Using default";
+ gOptRunNu = kDefOptRunNu;
+ }
+
+ // flux functional form
+ bool using_flux = false;
+ if( parser.OptionExists('f') ) {
+ LOG("gevgen", pINFO) << "Reading flux function";
+ gOptFlux = parser.ArgAsString('f');
+
+ // Convert for known strings.
+ string fluxid = ConvertFluxIDs(gOptFlux);
+ if (!fluxid.empty()) gOptFlux = fluxid;
+
+ using_flux = true;
+ }
+
+ if(parser.OptionExists('s')) {
+ LOG("gevgen", pWARN)
+ << "-s option no longer available. Please read the revised code documentation";
+ gAbortingInErr = true;
+ exit(1);
+ }
+
+
+ // generate weighted events option (only relevant if using a flux)
+ gOptWeighted = parser.OptionExists('w');
+
+ // neutrino energy
+ if( parser.OptionExists('e') ) {
+ LOG("gevgen", pINFO) << "Reading neutrino energy";
+ string nue = parser.ArgAsString('e');
+
+ // is it just a value or a range (comma separated set of values)
+ if(nue.find(",") != string::npos) {
+ // split the comma separated list
+ vector<string> nurange = utils::str::Split(nue, ",");
+ assert(nurange.size() == 2);
+ double emin = atof(nurange[0].c_str());
+ double emax = atof(nurange[1].c_str());
+ assert(emax>emin && emin>=0);
+ gOptNuEnergy = emin;
+ gOptNuEnergyRange = emax-emin;
+ if(!using_flux) {
+ LOG("gevgen", pWARN)
+ << "No flux was specified but an energy range was input!";
+ LOG("gevgen", pWARN)
+ << "Events will be generated at fixed E = " << gOptNuEnergy << " GeV";
+ gOptNuEnergyRange = -1;
+ }
+ } else {
+ gOptNuEnergy = atof(nue.c_str());
+ gOptNuEnergyRange = -1;
+ }
+ } else {
+ LOG("gevgen", pFATAL) << "Unspecified neutrino energy - Exiting";
+ PrintSyntax();
+ exit(1);
+ }
+
+ // neutrino PDG code
+ if( parser.OptionExists('p') && !parser.OptionExists('f')) {
+ LOG("gevgen", pINFO) << "Reading neutrino PDG code";
+ gOptNuPdgCode = parser.ArgAsInt('p');
+ } else if (!parser.OptionExists('p') && !parser.OptionExists('f')){
+ LOG("gevgen", pFATAL) << "Unspecified neutrino PDG code or Flux Inputs - Exiting";
+ PrintSyntax();
+ exit(1);
+ }
+
+ // target mix (their PDG codes with their corresponding weights)
+ bool using_tgtmix = false;
+ if( parser.OptionExists('t') ) {
+ LOG("gevgen", pINFO) << "Reading target mix";
+ string stgtmix = parser.ArgAsString('t');
+ gOptTgtMix.clear();
+
+ // Check for ID Strings
+ string tgtids = ConvertTargetIDs(stgtmix);
+ if (!tgtids.empty()){
+ stgtmix = tgtids;
+ }
+
+ // Parse Targets
+ vector<string> tgtmix = utils::str::Split(stgtmix,",");
+ if(tgtmix.size()==1) {
+ int pdg = atoi(tgtmix[0].c_str());
+ double wgt = 1.0;
+ gOptTgtPDGs.push_back(pdg);
+ gOptTgtMix.insert(map<int, double>::value_type(pdg, wgt));
+
+ // For single target number of free nucleons
+ // automatic
+ gOptNumberNucleons = pdg % 10000/ 10;
+
+ } else {
+ using_tgtmix = true;
+ vector<string>::const_iterator tgtmix_iter = tgtmix.begin();
+
+ // For multiple targets N nucleons must be specified first.
+ gOptNumberNucleons = atoi((*tgtmix_iter).c_str());
+ tgtmix_iter++;
+
+ // Now remainder is the full target list
+ for( ; tgtmix_iter != tgtmix.end(); ++tgtmix_iter) {
+ string tgt_with_wgt = *tgtmix_iter;
+ string::size_type open_bracket = tgt_with_wgt.find("[");
+ string::size_type close_bracket = tgt_with_wgt.find("]");
+ string::size_type ibeg = 0;
+ string::size_type iend = open_bracket;
+ string::size_type jbeg = open_bracket+1;
+ string::size_type jend = close_bracket-1;
+ int pdg = atoi(tgt_with_wgt.substr(ibeg,iend).c_str());
+ double wgt = atof(tgt_with_wgt.substr(jbeg,jend).c_str());
+ LOG("Main", pNOTICE)
+ << "Adding to target mix: pdg = " << pdg << ", wgt = " << wgt;
+ gOptTgtPDGs.push_back(pdg);
+ gOptTgtMix.insert(map<int, double>::value_type(pdg, wgt));
+ }//tgtmix_iter
+ }//>1
+
+ } else {
+ LOG("gevgen", pFATAL) << "Unspecified target PDG code - Exiting";
+ PrintSyntax();
+ exit(1);
+ }
+
+ gOptUsingFluxOrTgtMix = using_flux || using_tgtmix;
+
+ // random number seed
+ if( parser.OptionExists("seed") ) {
+ LOG("gevgen", pINFO) << "Reading random number seed";
+ gOptRanSeed = parser.ArgAsLong("seed");
+ } else {
+ LOG("gevgen", pINFO) << "Unspecified random number seed - Using default";
+ gOptRanSeed = -1;
+ }
+
+ // input cross-section file
+ if( parser.OptionExists("cross-sections") ) {
+ LOG("gevgen", pINFO) << "Reading cross-section file";
+ gOptInpXSecFile = parser.ArgAsString("cross-sections");
+ } else {
+ LOG("gevgen", pINFO) << "Unspecified cross-section file";
+ gOptInpXSecFile = "";
+ }
+
+ //
+ // print-out the command line options
+ //
+ LOG("gevgen", pNOTICE)
+ << "\n"
+ << utils::print::PrintFramedMesg("gevgen job configuration");
+ LOG("gevgen", pNOTICE)
+ << "MC Run Number: " << gOptRunNu;
+ if(gOptRanSeed != -1) {
+ LOG("gevgen", pNOTICE)
+ << "Random number seed: " << gOptRanSeed;
+ } else {
+ LOG("gevgen", pNOTICE)
+ << "Random number seed was not set, using default";
+ }
+ LOG("gevgen", pNOTICE)
+ << "Number of events requested: " << gOptNevents;
+ if(gOptInpXSecFile.size() > 0) {
+ LOG("gevgen", pNOTICE)
+ << "Using cross-section splines read from: " << gOptInpXSecFile;
+ } else {
+ LOG("gevgen", pNOTICE)
+ << "No input cross-section spline file";
+ }
+ LOG("gevgen", pNOTICE)
+ << "Flux: " << gOptFlux;
+ LOG("gevgen", pNOTICE)
+ << "Generate weighted events? " << gOptWeighted;
+ if(gOptNuEnergyRange>0) {
+ LOG("gevgen", pNOTICE)
+ << "Neutrino energy: ["
+ << gOptNuEnergy << ", " << gOptNuEnergy+gOptNuEnergyRange << "]";
+ } else {
+ LOG("gevgen", pNOTICE)
+ << "Neutrino energy: " << gOptNuEnergy;
+ }
+ LOG("gevgen", pNOTICE)
+ << "Neutrino code (PDG): " << gOptNuPdgCode;
+ LOG("gevgen", pNOTICE)
+ << "Target code (PDG) & weight fraction (in case of multiple targets): ";
+ map<int,double>::const_iterator iter;
+ for(iter = gOptTgtMix.begin(); iter != gOptTgtMix.end(); ++iter) {
+ int tgtpdgc = iter->first;
+ double wgt = iter->second;
+ LOG("gevgen", pNOTICE)
+ << " >> " << tgtpdgc << " (weight fraction = " << wgt << ")";
+ }
+ LOG("gevgen", pNOTICE) << "\n";
+
+ LOG("gevgen", pNOTICE) << *RunOpt::Instance();
+
+}
+//____________________________________________________________________________
+void PrintSyntax(void)
+{
+ LOG("gevgen", pNOTICE)
+ << "\n\n" << "Syntax:" << "\n"
+ << "\n gevgen [-h]"
+ << "\n [-r run#]"
+ << "\n -n nev"
+ << "\n -e energy (or energy range) "
+ << "\n -p neutrino_pdg"
+ << "\n -t target_pdg "
+ << "\n [-f flux_description]"
+ << "\n [-w]"
+ << "\n [--seed random_number_seed]"
+ << "\n [--cross-sections xml_file]"
+ << "\n [--event-generator-list list_name]"
+ << "\n [--message-thresholds xml_file]"
+ << "\n [--unphysical-event-mask mask]"
+ << "\n [--event-record-print-level level]"
+ << "\n [--mc-job-status-refresh-rate rate]"
+ << "\n [--cache-file root_file]"
+ << "\n\n" ;
+ ListTargetIDs();
+ ListFluxIDs();
+
+
+}
+//____________________________________________________________________________
+#endif
diff --git a/src/FCN/JointFCN.cxx b/src/FCN/JointFCN.cxx
index a4136e2..31023b2 100755
--- a/src/FCN/JointFCN.cxx
+++ b/src/FCN/JointFCN.cxx
@@ -1,1087 +1,1010 @@
#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;
+ fIterationTree = false;
fDialVals = NULL;
fNDials = 0;
fUsingEventManager = FitPar::Config().GetParB("EventManager");
fOutputDir->cd();
}
+//***************************************************
JointFCN::JointFCN(std::vector<nuiskey> samplekeys, TFile* outfile) {
+//***************************************************
+
fOutputDir = gDirectory;
if (outfile) FitPar::Config().out = outfile;
LoadSamples(samplekeys);
fCurIter = 0;
fMCFilled = false;
fOutputDir->cd();
- fIterationTree = NULL;
+ fIterationTree = false;
fDialVals = NULL;
fNDials = 0;
fUsingEventManager = FitPar::Config().GetParB("EventManager");
fOutputDir->cd();
}
//***************************************************
JointFCN::~JointFCN() {
//***************************************************
// Delete Samples
for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
iter++) {
MeasurementBase* exp = *iter;
delete exp;
}
for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) {
ParamPull* pull = *iter;
delete pull;
}
// Sort Tree
if (fIterationTree) DestroyIterationTree();
if (fDialVals) delete fDialVals;
if (fSampleLikes) delete fSampleLikes;
};
//***************************************************
void JointFCN::CreateIterationTree(std::string name, FitWeight* rw) {
- //***************************************************
-
- LOG(FIT) << " Creating new iteration 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();
+ LOG(FIT) << " Creating new iteration container! " << std::endl;
+ DestroyIterationTree();
+ fIterationTreeName = name;
- // Setup Sample Branches
- int count = 0;
- for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
+ // Add sample likelihoods and ndof
+ for (MeasListConstIter iter = fSamples.begin();
+ iter != fSamples.end();
iter++) {
- MeasurementBase* exp = *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());
+ std::string liketag = name + "_likelihood";
+ fNameValues.push_back(liketag);
+ fCurrentValues.push_back(0.0);
- count++;
+ std::string ndoftag = name + "_ndof";
+ fNameValues.push_back(ndoftag);
+ fCurrentValues.push_back(0.0);
}
- for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) {
- ParamPull* pull = *iter;
+ // Add Pull terms
+ for (PullListConstIter iter = fPulls.begin();
+ iter != fPulls.end(); iter++) {
+ ParamPull* pull = *iter;
std::string name = pull->GetName();
+
std::string liketag = name + "_likelihood";
+ fNameValues.push_back(liketag);
+ fCurrentValues.push_back(0.0);
+
std::string ndoftag = name + "_ndof";
+ fNameValues.push_back(ndoftag);
+ fCurrentValues.push_back(0.0);
+ }
- fIterationTree->Branch(liketag.c_str(), &fSampleLikes[count],
- (liketag + "/D").c_str());
- fIterationTree->Branch(ndoftag.c_str(), &fSampleNDOF[count],
- (ndoftag + "/D").c_str());
+ // Add Likelihoods
+ fNameValues.push_back("total_likelihood");
+ fCurrentValues.push_back(0.0);
- count++;
- }
+ fNameValues.push_back("total_ndof");
+ fCurrentValues.push_back(0.0);
- // Add Dial Branches
- std::vector<std::string> dials = rw->GetDialNames();
- fNDials = dials.size();
- fDialVals = new double[fNDials];
+ // Setup Containers
+ fSampleN = fSamples.size() + fPulls.size();
+ fSampleLikes = new double[fSampleN];
+ fSampleNDOF = new int[fSampleN];
- for (int i = 0; i < fNDials; i++) {
- fIterationTree->Branch(dials[i].c_str(), &fDialVals[i],
- (dials[i] + "/D").c_str());
+ // Add Dials
+ std::vector<std::string> dials = rw->GetDialNames();
+ for (size_t i = 0; i < dials.size(); i++){
+ fNameValues.push_back( dials[i] );
+ fCurrentValues.push_back( 0.0 );
}
+ fNDials = dials.size();
+ fDialVals = new double[fNDials];
+
+ // Set IterationTree Flag
+ fIterationTree = true;
+
}
//***************************************************
void JointFCN::DestroyIterationTree() {
- //***************************************************
+//***************************************************
+
+ fIterationCount.clear();
+ fCurrentValues.clear();
+ fNameValues.clear();
+ fIterationValues.clear();
- if (!fIterationTree) {
- delete fIterationTree;
- }
}
//***************************************************
void JointFCN::WriteIterationTree() {
- //***************************************************
+//***************************************************
+ LOG(FIT) << "Writing iteration tree" << std::endl;
+
+ // Make a new TTree
+ TTree* itree = new TTree(fIterationTreeName.c_str(),
+ fIterationTreeName.c_str());
+
+ double* vals = new double[fNameValues.size()];
+ int count = 0;
+
+ itree->Branch("iteration",&count,"Iteration/I");
+ for (int i = 0; i < fNameValues.size(); i++) {
+ itree->Branch( fNameValues[i].c_str(),
+ &vals[i],
+ (fNameValues[i] + "/D").c_str() );
+ }
+
+ // Fill Iterations
+ for (size_t i = 0; i < fIterationValues.size(); i++){
+ std::vector<double> itervals = fIterationValues[i];
+
+ // Fill iteration state
+ count = fIterationCount[i];
+ for (size_t j = 0; j < itervals.size(); j++){
+ vals[j] = itervals[j];
+ }
- if (!fIterationTree) {
- ERR(FTL) << "Can't save empty iteration tree!" << std::endl;
- throw;
+ // Save to TTree
+ itree->Fill();
}
- fIterationTree->Write();
+
+ // Write to file
+ itree->Write();
}
//***************************************************
void JointFCN::FillIterationTree(FitWeight* rw) {
- //***************************************************
+//***************************************************
- if (!fIterationTree) {
- ERR(FTL) << "Trying to fill iteration_tree when it is NULL!" << std::endl;
- throw;
+ // Loop over samples count
+ int count = 0;
+ for (int i = 0; i < fSampleN; i++){
+ fCurrentValues[count++] = fSampleLikes[i];
+ fCurrentValues[count++] = double(fSampleNDOF[i]);
}
+ // Fill Totals
+ fCurrentValues[count++] = fLikelihood;
+ fCurrentValues[count++] = double(fNDOF);
+
+ // Loop Over Parameter Counts
rw->GetAllDials(fDialVals, fNDials);
- fIterationTree->Fill();
+ for (int i = 0; i < fNDials; i++){
+ fCurrentValues[count++] = double(fDialVals[i]);
+ }
+
+ // Push Back Into Container
+ fIterationCount.push_back( fCurIter );
+ fIterationValues.push_back(fCurrentValues);
}
//***************************************************
double JointFCN::DoEval(const double* x) {
//***************************************************
// WEIGHT ENGINE
fDialChanged = FitBase::GetRW()->HasRWDialChanged(x);
FitBase::GetRW()->UpdateWeightEngine(x);
if (fDialChanged) {
FitBase::GetRW()->Reconfigure();
FitBase::EvtManager().ResetWeightFlags();
}
if (LOG_LEVEL(REC)) {
FitBase::GetRW()->Print();
}
// SORT SAMPLES
ReconfigureSamples();
// GET TEST STAT
fLikelihood = GetLikelihood();
-
+ fNDOF = GetNDOF();
+
// PRINT PROGRESS
LOG(FIT) << "Current Stat (iter. " << this->fCurIter << ") = " << fLikelihood
<< std::endl;
// UPDATE TREE
if (fIterationTree) FillIterationTree(FitBase::GetRW());
return fLikelihood;
}
//***************************************************
int JointFCN::GetNDOF() {
//***************************************************
int totaldof = 0;
int count = 0;
// Total number of Free bins in each MC prediction
for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
iter++) {
MeasurementBase* exp = *iter;
int dof = exp->GetNDOF();
// Save Seperate DOF
if (fIterationTree) {
fSampleNDOF[count] = dof;
}
// Add to total
totaldof += dof;
count++;
}
// Loop over pulls
for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) {
ParamPull* pull = *iter;
double dof = pull->GetLikelihood();
// Save seperate DOF
if (fIterationTree) {
fSampleNDOF[count] = dof;
}
// Add to total
totaldof += dof;
count++;
}
// Set Data Variable
- fNDOF = totaldof;
+ fSampleNDOF[count] = totaldof;
return totaldof;
}
//***************************************************
double JointFCN::GetLikelihood() {
//***************************************************
LOG(MIN) << std::left << std::setw(43) << "Getting likelihoods..."
<< " : "
<< "-2logL" << std::endl;
// Loop and add up likelihoods in an uncorrelated way
double like = 0.0;
int count = 0;
for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
iter++) {
MeasurementBase* exp = *iter;
double newlike = exp->GetLikelihood();
int ndof = exp->GetNDOF();
// Save seperate likelihoods
if (fIterationTree) {
fSampleLikes[count] = newlike;
}
LOG(MIN) << "-> " << std::left << std::setw(40) << exp->GetName() << " : "
<< newlike << "/" << ndof << std::endl;
// Add Weight Scaling
// like *= FitBase::GetRW()->GetSampleLikelihoodWeight(exp->GetName());
// Add to total
like += newlike;
count++;
}
// Loop over pulls
for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) {
ParamPull* pull = *iter;
double newlike = pull->GetLikelihood();
// Save seperate likelihoods
if (fIterationTree) {
fSampleLikes[count] = newlike;
}
// Add to total
like += newlike;
count++;
}
// Set Data Variable
fLikelihood = like;
return like;
};
void JointFCN::LoadSamples(std::vector<nuiskey> samplekeys) {
LOG(MIN) << "Loading Samples : " << samplekeys.size() << std::endl;
for (size_t i = 0; i < samplekeys.size(); i++) {
nuiskey key = samplekeys[i];
// Get Sample Options
std::string samplename = key.GetS("name");
std::string samplefile = key.GetS("input");
std::string sampletype = key.GetS("type");
std::string fakeData = "";
LOG(MIN) << "Loading Sample : " << samplename << std::endl;
fOutputDir->cd();
MeasurementBase* NewLoadedSample = SampleUtils::CreateSample(key);
if (!NewLoadedSample) {
ERR(FTL) << "Could not load sample provided: " << samplename << std::endl;
ERR(FTL) << "Check spelling with that in src/FCN/SampleList.cxx"
<< std::endl;
throw;
} else {
fSamples.push_back(NewLoadedSample);
}
}
}
+//***************************************************
void JointFCN::LoadPulls(std::vector<nuiskey> pullkeys) {
+//***************************************************
for (size_t i = 0; i < pullkeys.size(); i++) {
nuiskey key = pullkeys[i];
std::string pullname = key.GetS("name");
std::string pullfile = key.GetS("input");
std::string pulltype = key.GetS("type");
fOutputDir->cd();
- std::cout << "Creating Pull Term : " << std::endl;
- sleep(1);
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"
-// << 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 << std::endl;
// std::cout << fUsingEventManager << " " << fullconfig << " " << fMCFilled <<
// std::endl;
// Event Manager Reconf
if (fUsingEventManager) {
if (!fullconfig and fMCFilled)
ReconfigureFastUsingManager();
else
ReconfigureUsingManager();
} else {
// Loop over all Measurement Classes
for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
iter++) {
MeasurementBase* exp = *iter;
// If RW Either do signal or full reconfigure.
if (fDialChanged or !fMCFilled or fullconfig) {
if (!fullconfig and fMCFilled)
exp->ReconfigureFast();
else
exp->Reconfigure();
// If RW Not needed just do normalisation
} else {
exp->Renormalise();
}
}
}
// Loop over pulls and update
for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) {
ParamPull* pull = *iter;
pull->Reconfigure();
}
fMCFilled = true;
LOG(MIN) << "Finished Reconfigure iter. " << fCurIter << " in "
<< time(NULL) - starttime << "s" << std::endl;
fCurIter++;
}
//***************************************************
void JointFCN::ReconfigureSignal() {
- //***************************************************
- this->ReconfigureSamples(false);
+//***************************************************
+ ReconfigureSamples(false);
}
//***************************************************
void JointFCN::ReconfigureAllEvents() {
//***************************************************
FitBase::GetRW()->Reconfigure();
FitBase::EvtManager().ResetWeightFlags();
ReconfigureSamples(true);
}
std::vector<InputHandlerBase*> JointFCN::GetInputList() {
std::vector<InputHandlerBase*> InputList;
fIsAllSplines = true;
MeasListConstIter iterSam = fSamples.begin();
for (; iterSam != fSamples.end(); iterSam++) {
MeasurementBase* exp = (*iterSam);
std::vector<MeasurementBase*> subsamples = exp->GetSubSamples();
for (size_t i = 0; i < subsamples.size(); i++) {
InputHandlerBase* inp = subsamples[i]->GetInput();
if (std::find(InputList.begin(), InputList.end(), inp) ==
InputList.end()) {
if (subsamples[i]->GetInput()->GetType() != kSPLINEPARAMETER)
fIsAllSplines = false;
InputList.push_back(subsamples[i]->GetInput());
}
}
}
return InputList;
}
std::vector<MeasurementBase*> JointFCN::GetSubSampleList() {
std::vector<MeasurementBase*> SampleList;
MeasListConstIter iterSam = fSamples.begin();
for (; iterSam != fSamples.end(); iterSam++) {
MeasurementBase* exp = (*iterSam);
std::vector<MeasurementBase*> subsamples = exp->GetSubSamples();
for (size_t i = 0; i < subsamples.size(); i++) {
SampleList.push_back(subsamples[i]);
}
}
return SampleList;
}
//***************************************************
void JointFCN::ReconfigureUsingManager() {
- //***************************************************
+//***************************************************
// 'Slow' Event Manager Reconfigure
LOG(REC) << "Event Manager Reconfigure" << std::endl;
int timestart = time(NULL);
// Reset all samples
MeasListConstIter iterSam = fSamples.begin();
for (; iterSam != fSamples.end(); iterSam++) {
MeasurementBase* exp = (*iterSam);
exp->ResetAll();
}
// If we are siving signal, reset all containers.
bool savesignal = (FitPar::Config().GetParB("SignalReconfigures"));
if (savesignal) {
// Reset all of our event signal vectors
fSignalEventBoxes.clear();
fSignalEventFlags.clear();
fSampleSignalFlags.clear();
fSignalEventSplines.clear();
}
// Make sure we have a list of inputs
if (fInputList.empty()) {
fInputList = GetInputList();
fSubSampleList = GetSubSampleList();
}
// If all inputs are splines make sure the readers are told
// they need to be reconfigured.
std::vector<InputHandlerBase*>::iterator inp_iter = fInputList.begin();
if (fIsAllSplines) {
for (; inp_iter != fInputList.end(); inp_iter++) {
InputHandlerBase* curinput = (*inp_iter);
// Tell reader in each BaseEvent it needs a Reconfigure next weight calc.
BaseFitEvt* curevent = curinput->FirstBaseEvent();
if (curevent->fSplineRead) {
curevent->fSplineRead->SetNeedsReconfigure(true);
}
}
}
// MAIN INPUT LOOP ====================
int fillcount = 0;
int inputcount = 0;
inp_iter = fInputList.begin();
// Loop over each input in manager
for (; inp_iter != fInputList.end(); inp_iter++) {
InputHandlerBase* curinput = (*inp_iter);
// Get event information
FitEvent* curevent = curinput->FirstNuisanceEvent();
curinput->CreateCache();
int i = 0;
int nevents = curinput->GetNEvents();
int countwidth = nevents / 5;
// Start event loop iterating until we get a NULL pointer.
while (curevent) {
// Get Event Weight
curevent->RWWeight = FitBase::GetRW()->CalcWeight(curevent);
curevent->Weight = curevent->RWWeight * curevent->InputWeight;
double rwweight = curevent->Weight;
// std::cout << "RWWeight = " << curevent->RWWeight << " " <<
// curevent->InputWeight << std::endl;
// Logging
// std::cout << CHECKLOG(1) << std::endl;
if (LOGGING(REC)) {
if (i % countwidth == 0) {
QLOG(REC, curinput->GetName()
- << " : Processed " << i << " events. [M, W] = ["
- << curevent->Mode << ", " << rwweight << "]");
+ << " : Processed " << i << " events. [M, W] = ["
+ << curevent->Mode << ", " << rwweight << "]");
}
}
// Setup flag for if signal found in at least one sample
bool foundsignal = false;
// Create a new signal bitset for this event
std::vector<bool> signalbitset(fSubSampleList.size());
// Create a new signal box vector for this event
std::vector<MeasurementVariableBox*> signalboxes;
// Start measurement iterator
size_t measitercount = 0;
std::vector<MeasurementBase*>::iterator meas_iter =
- fSubSampleList.begin();
+ fSubSampleList.begin();
// Loop over all subsamples (sub in JointMeas)
for (; meas_iter != fSubSampleList.end(); meas_iter++) {
MeasurementBase* curmeas = (*meas_iter);
// Compare input pointers, to current input, skip if not.
// Pointer tells us if it matches without doing ID checks.
if (curinput != curmeas->GetInput()) {
if (savesignal) {
// Set bit to 0 as definitely not signal
signalbitset[measitercount] = 0;
}
// Count up what measurement we are on.
measitercount++;
// Skip sample as input not signal.
continue;
}
// Fill events for matching inputs.
MeasurementVariableBox* box = curmeas->FillVariableBox(curevent);
bool signal = curmeas->isSignal(curevent);
curmeas->SetSignal(signal);
curmeas->FillHistograms(curevent->Weight);
// If its Signal tally up fills
if (signal) {
fillcount++;
}
// If we are saving signal/splines fill the bitset
if (savesignal) {
signalbitset[measitercount] = signal;
}
// If signal save a clone of the event box for use later.
if (savesignal and signal) {
foundsignal = true;
signalboxes.push_back(box->CloneSignalBox());
}
// Keep track of Measurement we are on.
measitercount++;
}
// Once we've filled the measurements, if saving signal
// push back if any sample flagged this event as signal
if (savesignal) {
fSignalEventFlags.push_back(foundsignal);
}
// Save the vector of signal boxes for this event
if (savesignal and foundsignal) {
fSignalEventBoxes.push_back(signalboxes);
fSampleSignalFlags.push_back(signalbitset);
}
// If all inputs are splines we can save the spline coefficients
// for fast in memory reconfigures later.
if (fIsAllSplines and savesignal and foundsignal) {
// Make temp vector to push back with
std::vector<float> coeff;
for (size_t l = 0; l < (UInt_t)curevent->fSplineRead->GetNPar(); l++) {
coeff.push_back(curevent->fSplineCoeff[l]);
}
// Push back to signal event splines. Kept in sync with
// fSignalEventBoxes size.
// int splinecount = fSignalEventSplines.size();
fSignalEventSplines.push_back(coeff);
// if (splinecount % 1000 == 0) {
// std::cout << "Pushed Back Coeff " << splinecount << " : ";
// for (size_t l = 0; l < fSignalEventSplines[splinecount].size(); l++)
// {
// std::cout << " " << fSignalEventSplines[splinecount][l];
// }
// std::cout << std::endl;
// }
}
// Clean up vectors once done with this event
signalboxes.clear();
signalbitset.clear();
// Iterate to the next event.
curevent = curinput->NextNuisanceEvent();
i++;
}
curinput->RemoveCache();
// Keep track of what input we are on.
inputcount++;
}
// End of Event Loop ===============================
// Now event loop is finished loop over all Measurements
// Converting Binned events to XSec Distributions
iterSam = fSamples.begin();
for (; iterSam != fSamples.end(); iterSam++) {
MeasurementBase* exp = (*iterSam);
exp->ConvertEventRates();
}
// Print out statements on approximate memory usage for profiling.
LOG(REC) << "Filled " << fillcount << " signal events." << std::endl;
if (savesignal) {
int mem =
- ( // sizeof(fSignalEventBoxes) +
- // fSignalEventBoxes.size() * sizeof(fSignalEventBoxes.at(0)) +
- sizeof(MeasurementVariableBox1D) * fillcount) *
- 1E-6;
+ ( // sizeof(fSignalEventBoxes) +
+ // fSignalEventBoxes.size() * sizeof(fSignalEventBoxes.at(0)) +
+ sizeof(MeasurementVariableBox1D) * fillcount) *
+ 1E-6;
LOG(REC) << " -> Saved " << fillcount
<< " signal boxes for faster access. (~" << mem << " MB)"
<< std::endl;
if (fIsAllSplines and !fSignalEventSplines.empty()) {
int splmem = sizeof(float) * fSignalEventSplines.size() *
fSignalEventSplines[0].size() * 1E-6;
LOG(REC) << " -> Saved " << fillcount << " " << fSignalEventSplines.size()
<< " spline sets into memory. (~" << splmem << " MB)"
<< std::endl;
}
}
LOG(REC) << "Time taken ReconfigureUsingManager() : "
<< time(NULL) - timestart << std::endl;
// Check SignalReconfigures works for all samples
- if (savesignal){
+ if (savesignal) {
double likefull = GetLikelihood();
ReconfigureFastUsingManager();
double likefast = GetLikelihood();
-
+
if (fabs(likefull - likefast) > 0.0001)
- {
- ERROR(FTL,"Fast and Full Likelihoods DIFFER! : " << likefull << " : " << likefast);
- ERROR(FTL,"This means some samples you are using are not setup to use SignalReconfigures=1");
- ERROR(FTL,"Please turn OFF signal reconfigures.");
- throw;
- } else {
+ {
+ ERROR(FTL, "Fast and Full Likelihoods DIFFER! : " << likefull << " : " << likefast);
+ ERROR(FTL, "This means some samples you are using are not setup to use SignalReconfigures=1");
+ ERROR(FTL, "Please turn OFF signal reconfigures.");
+ throw;
+ } else {
LOG(FIT) << "Likelihoods for FULL and FAST match. Will use FAST next time." << std::endl;
}
}
// End of reconfigure
return;
};
//***************************************************
void JointFCN::ReconfigureFastUsingManager() {
- //***************************************************
+//***************************************************
LOG(FIT) << " -> Doing FAST using manager" << std::endl;
// Get Start time for profilling
int timestart = time(NULL);
// Reset all samples
MeasListConstIter iterSam = fSamples.begin();
for (; iterSam != fSamples.end(); iterSam++) {
MeasurementBase* exp = (*iterSam);
exp->ResetAll();
}
// Check for saved variables if not do a full reconfigure.
if (fSignalEventFlags.empty()) {
ERR(WRN) << "Signal Flags Empty! Using normal manager." << std::endl;
ReconfigureUsingManager();
return;
}
bool fFillNuisanceEvent =
- FitPar::Config().GetParB("FullEventOnSignalReconfigure");
+ FitPar::Config().GetParB("FullEventOnSignalReconfigure");
// Setup fast vector iterators.
std::vector<bool>::iterator inpsig_iter = fSignalEventFlags.begin();
std::vector<std::vector<MeasurementVariableBox*> >::iterator box_iter =
- fSignalEventBoxes.begin();
+ fSignalEventBoxes.begin();
std::vector<std::vector<float> >::iterator spline_iter =
- fSignalEventSplines.begin();
+ fSignalEventSplines.begin();
std::vector<std::vector<bool> >::iterator samsig_iter =
- fSampleSignalFlags.begin();
+ fSampleSignalFlags.begin();
int splinecount = 0;
// Setup stuff for logging
int fillcount = 0;
int nevents = fSignalEventFlags.size();
int countwidth = nevents / 20;
// If All Splines tell splines they need a reconfigure.
std::vector<InputHandlerBase*>::iterator inp_iter = fInputList.begin();
if (fIsAllSplines) {
LOG(REC) << "All Spline Inputs so using fast spline loop." << std::endl;
for (; inp_iter != fInputList.end(); inp_iter++) {
InputHandlerBase* curinput = (*inp_iter);
// Tell each fSplineRead in BaseFitEvent to reconf next weight calc
BaseFitEvt* curevent = curinput->FirstBaseEvent();
if (curevent->fSplineRead)
curevent->fSplineRead->SetNeedsReconfigure(true);
}
}
// Loop over all possible spline inputs
double* coreeventweights = new double[fSignalEventBoxes.size()];
splinecount = 0;
inp_iter = fInputList.begin();
inpsig_iter = fSignalEventFlags.begin();
spline_iter = fSignalEventSplines.begin();
// Loop over all signal flags
// For each valid signal flag add one to splinecount
// Get Splines from that count and add to weight
// Add splinecount
int sigcount = 0;
splinecount = 0;
// #pragma omp parallel for shared(splinecount,sigcount)
for (uint iinput = 0; iinput < fInputList.size(); iinput++) {
InputHandlerBase* curinput = fInputList[iinput];
BaseFitEvt* curevent = curinput->FirstBaseEvent();
for (int i = 0; i < curinput->GetNEvents(); i++) {
double rwweight = 0.0;
if (fSignalEventFlags[sigcount]) {
// Get Event Info
if (!fIsAllSplines) {
if (fFillNuisanceEvent)
curinput->GetNuisanceEvent(i);
else
curevent = curinput->GetBaseEvent(i);
} else {
curevent->fSplineCoeff = &fSignalEventSplines[splinecount][0];
}
curevent->RWWeight = FitBase::GetRW()->CalcWeight(curevent);
curevent->Weight = curevent->RWWeight * curevent->InputWeight;
rwweight = curevent->Weight;
coreeventweights[splinecount] = rwweight;
if (splinecount % countwidth == 0) {
LOG(REC) << "Processed " << splinecount
<< " event weights. W = " << rwweight << std::endl;
}
// #pragma omp atomic
splinecount++;
}
// #pragma omp atomic
sigcount++;
}
}
LOG(SAM) << "Processed event weights." << std::endl;
// #pragma omp barrier
// Reset Iterators
inpsig_iter = fSignalEventFlags.begin();
spline_iter = fSignalEventSplines.begin();
box_iter = fSignalEventBoxes.begin();
samsig_iter = fSampleSignalFlags.begin();
int nsplineweights = splinecount;
splinecount = 0;
// Start of Fast Event Loop ============================
// Start input iterators
// Loop over number of inputs
for (int ispline = 0; ispline < nsplineweights; ispline++) {
double rwweight = coreeventweights[ispline];
// Get iterators for this event
std::vector<bool>::iterator subsamsig_iter = (*samsig_iter).begin();
std::vector<MeasurementVariableBox*>::iterator subbox_iter =
- (*box_iter).begin();
+ (*box_iter).begin();
// Loop over all sub measurements.
std::vector<MeasurementBase*>::iterator meas_iter = fSubSampleList.begin();
for (; meas_iter != fSubSampleList.end(); meas_iter++, subsamsig_iter++) {
MeasurementBase* curmeas = (*meas_iter);
// If event flagged as signal for this sample fill from the box.
if (*subsamsig_iter) {
curmeas->SetSignal(true);
curmeas->FillHistogramsFromBox((*subbox_iter), rwweight);
// Move onto next box if there is one.
subbox_iter++;
fillcount++;
}
}
if (ispline % countwidth == 0) {
LOG(REC) << "Filled " << ispline << " sample weights." << std::endl;
}
// Iterate over the main signal event containers.
samsig_iter++;
box_iter++;
spline_iter++;
splinecount++;
}
// End of Fast Event Loop ===================
LOG(SAM) << "Filled sample distributions." << std::endl;
// Now loop over all Measurements
// Convert Binned events
iterSam = fSamples.begin();
for (; iterSam != fSamples.end(); iterSam++) {
MeasurementBase* exp = (*iterSam);
exp->ConvertEventRates();
}
// Cleanup coreeventweights
if (fIsAllSplines) {
delete coreeventweights;
}
// Print some reconfigure profiling.
LOG(REC) << "Filled " << fillcount << " signal events." << std::endl;
LOG(REC) << "Time taken ReconfigureFastUsingManager() : "
<< time(NULL) - timestart << std::endl;
}
//***************************************************
void JointFCN::Write() {
- //***************************************************
+//***************************************************
// Save a likelihood/ndof plot
LOG(MIN) << "Writing likelihood plot.." << std::endl;
std::vector<double> likes;
std::vector<double> ndofs;
std::vector<std::string> names;
for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
- iter++){
+ iter++) {
MeasurementBase* exp = *iter;
double like = exp->GetLikelihood();
double ndof = exp->GetNDOF();
std::string name = exp->GetName();
likes.push_back(like);
ndofs.push_back(ndof);
names.push_back(name);
}
- TH1D likehist = TH1D("likelihood_hist","likelihood_hist",
- likes.size(), 0.0, double(likes.size()));
- TH1D ndofhist = TH1D("ndof_hist","ndof_hist",
- ndofs.size(), 0.0, double(ndofs.size()));
- TH1D divhist = TH1D("likedivndof_hist","likedivndof_hist",
- likes.size(), 0.0, double(likes.size()));
- for (size_t i = 0; i < likehist.GetNbinsX(); i++){
- likehist.SetBinContent(i+1, likes[i]);
- ndofhist.SetBinContent(i+1, ndofs[i]);
- if (ndofs[i] != 0.0){
- divhist.SetBinContent(i+1, likes[i]/ndofs[i]);
+ TH1D likehist = TH1D("likelihood_hist", "likelihood_hist",
+ likes.size(), 0.0, double(likes.size()));
+ TH1D ndofhist = TH1D("ndof_hist", "ndof_hist",
+ ndofs.size(), 0.0, double(ndofs.size()));
+ TH1D divhist = TH1D("likedivndof_hist", "likedivndof_hist",
+ likes.size(), 0.0, double(likes.size()));
+ for (size_t i = 0; i < likehist.GetNbinsX(); i++) {
+ likehist.SetBinContent(i + 1, likes[i]);
+ ndofhist.SetBinContent(i + 1, ndofs[i]);
+ if (ndofs[i] != 0.0) {
+ divhist.SetBinContent(i + 1, likes[i] / ndofs[i]);
}
- likehist.GetXaxis()->SetBinLabel(i+1, names[i].c_str());
- ndofhist.GetXaxis()->SetBinLabel(i+1, names[i].c_str());
- divhist.GetXaxis()->SetBinLabel(i+1, names[i].c_str());
+ likehist.GetXaxis()->SetBinLabel(i + 1, names[i].c_str());
+ ndofhist.GetXaxis()->SetBinLabel(i + 1, names[i].c_str());
+ divhist.GetXaxis()->SetBinLabel(i + 1, names[i].c_str());
}
likehist.Write();
ndofhist.Write();
divhist.Write();
// Loop over individual experiments and call Write
LOG(MIN) << "Writing each of the data classes..." << std::endl;
for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
iter++) {
MeasurementBase* exp = *iter;
exp->Write();
}
// Save Pull Terms
for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) {
ParamPull* pull = *iter;
pull->Write();
}
if (FitPar::Config().GetParB("EventManager")) {
// Get list of inputs
std::map<int, InputHandlerBase*> fInputs =
- FitBase::EvtManager().GetInputs();
+ FitBase::EvtManager().GetInputs();
std::map<int, InputHandlerBase*>::const_iterator iterInp;
for (iterInp = fInputs.begin(); iterInp != fInputs.end(); iterInp++) {
InputHandlerBase* input = (iterInp->second);
input->GetFluxHistogram()->Write();
input->GetXSecHistogram()->Write();
input->GetEventHistogram()->Write();
}
}
};
//***************************************************
void JointFCN::SetFakeData(std::string fakeinput) {
- //***************************************************
+//***************************************************
LOG(MIN) << "Setting fake data from " << fakeinput << std::endl;
for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
iter++) {
MeasurementBase* exp = *iter;
exp->SetFakeDataValues(fakeinput);
}
return;
}
//***************************************************
void JointFCN::ThrowDataToy() {
- //***************************************************
+//***************************************************
for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end();
iter++) {
MeasurementBase* exp = *iter;
exp->ThrowDataToy();
}
return;
}
diff --git a/src/FCN/JointFCN.h b/src/FCN/JointFCN.h
index 361a75a..bf87424 100755
--- a/src/FCN/JointFCN.h
+++ b/src/FCN/JointFCN.h
@@ -1,165 +1,176 @@
#ifndef _JOINT_FCN_H_
#define _JOINT_FCN_H_
/*!
* \addtogroup FCN
* @{
*/
#include <iostream>
#include <vector>
#include <fstream>
#include <list>
// ROOT headers
#include "TTree.h"
#include "TH1D.h"
#include "TH2D.h"
#include <TMatrixDSym.h>
#include "TGraphErrors.h"
#include <TVectorD.h>
#include <TMath.h>
#include "FitUtils.h"
// External fitter headers
#include "MeasurementBase.h"
#include "SampleList.h"
#define GetCurrentDir getcwd
#include "EventManager.h"
#include "Math/Functor.h"
#include "ParamPull.h"
#include "NuisConfig.h"
#include "NuisKey.h"
#include "MeasurementVariableBox.h"
#include "MeasurementVariableBox1D.h"
using namespace FitUtils;
using namespace FitBase;
//! Main FCN Class which ROOT's joint function needs to evaulate the chi2 at each stage of the fit.
class JointFCN
{
public:
//! Constructor
//! cardfile = Path to input card file listing samples
JointFCN(std::vector<nuiskey> samplekeys, TFile* outfile=NULL);
JointFCN(TFile* outfile=NULL); // Loads from global config
//! Destructor
~JointFCN();
//! Create sample list from cardfile
void LoadSamples(std::vector<nuiskey> samplekeys);
void LoadPulls(std::vector<nuiskey> pullkeys);
//! Main Likelihood evaluation FCN
double DoEval(const double *x);
//! Func Wrapper for ROOT
inline double operator() (const std::vector<double> & x) {
double* x_array = new double[x.size()];
return this->DoEval(x_array);
};
//! Func Wrapper for ROOT
inline double operator() (const double *x) {
return this->DoEval(x);
};
//! Create a TTree to save all dial value iterations for this FCN
void CreateIterationTree(std::string name, FitWeight* rw);
//! Fills dial values and sample likelihoods into tree
void FillIterationTree(FitWeight* rw);
//! Writes TTree to fOutput directory
void WriteIterationTree();
//! Deletes TTree
void DestroyIterationTree();
//! Get Degrees of Freedom for samples (NBins)
int GetNDOF();
//! Return NDOF wrapper
inline unsigned int NDim() {return this->GetNDOF();};
//! Reconfigure samples where we force all events to be looped over.
void ReconfigureAllEvents() ;
//! Call Reconfigure on samples.
//! Choice of reconfigure type depends on whether dials have changed
//! and the MC has been filled.
void ReconfigureSamples(bool fullconfig = false);
//! Call reconfigure on only signal events (defaults to all events if CurIter=0)
void ReconfigureSignal();
//! Gets likelihood for all samples in FCN (assuming uncorrelated)
double GetLikelihood();
//! Returns list of pointers to the samples
inline std::list<MeasurementBase*> GetSampleList(){ return fSamples; }
//! Return list of pointers to all the pulls
inline std::list<ParamPull*> GetPullList(){ return fPulls; };
//! Write all samples to output DIR
void Write();
//! Set Fake data from file/MC
void SetFakeData(std::string fakeinput);
//! Reconfigure looping over duplicate inputs
void ReconfigureUsingManager();
//! Reconfigure Fast looping over duplicate inputs
void ReconfigureFastUsingManager();
/// Throws data according to current stats
void ThrowDataToy();
std::vector<MeasurementBase*> GetSubSampleList();
std::vector<InputHandlerBase*> GetInputList();
private:
//! Append the experiments to include in the fit to this list
std::list<MeasurementBase*> fSamples;
//! Append parameter pull terms to include penalties in the fit to this list
std::list<ParamPull*> fPulls;
TDirectory *fOutputDir; //!< Directory to save contents
std::string fCardFile; //!< Input Card text file
bool fDialChanged; //!< Flag for if RW dials changed
UInt_t fCurIter; //!< Counter for how many times reconfigure called
bool fMCFilled; //!< Check MC has at least been filled once
- TTree* fIterationTree; //!< Tree to save RW values on each function call
+ bool fIterationTree; //!< Tree to save RW values on each function call
int fNDials; //!< Number of RW Dials in FitWeight
double* fDialVals; //!< Current Values of RW Dials
double fLikelihood; //!< Current likelihood for joint sample likelihood
double fNDOF; //!< Total NDOF
double* fSampleLikes; //!< Likelihoods for each individual measurement in list
int * fSampleNDOF; //!< NDOF for each individual measurement in list
bool fUsingEventManager; //!< Flag for doing joint comparisons
std::vector< std::vector<float> > fSignalEventSplines;
std::vector< std::vector<MeasurementVariableBox*> > fSignalEventBoxes;
std::vector< bool > fSignalEventFlags;
std::vector< std::vector<bool> > fSampleSignalFlags;
std::vector<InputHandlerBase*> fInputList;
std::vector<MeasurementBase*> fSubSampleList;
bool fIsAllSplines;
+
+ std::vector< int > fIterationCount;
+ std::vector< double > fCurrentValues;
+ std::vector< std::string > fNameValues;
+ std::vector< std::vector<double> > fIterationValues;
+ int fSampleN;
+ std::string fIterationTreeName;
+
+
+
+
};
/*! @} */
#endif // _JOINT_FCN_H_
diff --git a/src/FitBase/ParamPull.cxx b/src/FitBase/ParamPull.cxx
index 4a0c6bc..8f9cb6e 100644
--- a/src/FitBase/ParamPull.cxx
+++ b/src/FitBase/ParamPull.cxx
@@ -1,810 +1,844 @@
// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
/*******************************************************************************
* This file is part of NUISANCE.
*
* NUISANCE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* NUISANCE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU 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 "ParamPull.h"
//*******************************************************************************
ParamPull::ParamPull(std::string name, std::string inputfile, std::string type, std::string dials) {
//*******************************************************************************
fMinHist = NULL;
fMaxHist = NULL;
fTypeHist = NULL;
fDialSelection = dials;
+ fLimitHist = NULL;
fName = name;
fInput = inputfile;
fType = type;
// Set the pull type
SetType(fType);
std::cout << fType << std::endl;
// Setup Histograms from input file
SetupHistograms(fInput);
};
//*******************************************************************************
void ParamPull::SetType(std::string type) {
//*******************************************************************************
fType = type;
// Assume Default if empty
if (type.empty() || type == "DEFAULT") {
ERR(WRN) << "No type specified for ParmPull class " << fName << std::endl;
ERR(WRN) << "Assuming GAUSTHROW/GAUSPULL" << std::endl;
type = "GAUSTHROW/GAUSPULL";
}
// Set Dial options
if (type.find("FRAC") != std::string::npos) {
fDialOptions = "FRAC";
fPlotTitles = ";; Fractional RW Value";
} else if (type.find("ABS") != std::string::npos) {
fDialOptions = "ABS";
fPlotTitles = ";; ABS RW Value";
} else {
fDialOptions = "";
fPlotTitles = ";; RW Value";
}
// Parse throw types
if (type.find("GAUSPULL") != std::string::npos) fCalcType = kGausPull;
else fCalcType = kNoPull;
if (type.find("GAUSTHROW") != std::string::npos) fThrowType = kGausThrow;
+ else if (type.find("FLATTHROW") != std::string::npos) fThrowType = kFlatThrow;
else fThrowType = kNoThrow;
// Extra check to see if throws or pulls are turned off
if (type.find("NOPULL") != std::string::npos) fCalcType = kNoPull;
if (type.find("NOTHROW") != std::string::npos) fThrowType = kNoThrow;
}
//*******************************************************************************
void ParamPull::SetupHistograms(std::string input) {
//*******************************************************************************
// Extract Types from Input
fFileType = "";
const int nfiletypes = 4;
const std::string filetypes[nfiletypes] = {"FIT", "ROOT", "TXT", "DIAL"};
for (int i = 0; i < nfiletypes; i++) {
std::string tempTypes = filetypes[i] + ":";
if (input.find(tempTypes) != std::string::npos) {
fFileType = filetypes[i];
input.replace(input.find(tempTypes), tempTypes.size(), "");
break;
}
}
// Read Files
if (!fFileType.compare("FIT")) ReadFitFile(input);
else if (!fFileType.compare("ROOT")) ReadRootFile(input);
else if (!fFileType.compare("VECT")) ReadVectFile(input);
else if (!fFileType.compare("DIAL")) ReadDialInput(input);
else {
ERR(FTL) << "Unknown ParamPull Type: " << input << std::endl;
throw;
}
// Check Dials are all good
CheckDialsValid();
// Setup MC Histogram
fMCHist = (TH1D*) fDataHist->Clone();
fMCHist->Reset();
fMCHist->SetNameTitle( (fName + "_MC").c_str(),
(fName + " MC" + fPlotTitles).c_str() );
// If no Covar input make an uncorrelated one
if (!fCovar) {
fCovar = StatUtils::MakeDiagonalCovarMatrix(fDataHist, 1.0);
}
// If no types or limits are provided give them a default option
if (!fMinHist) {
fMinHist = (TH1D*) fDataHist->Clone();
fMinHist->SetNameTitle( (fName + "_min").c_str(),
(fName + " min" + fPlotTitles).c_str() );
for (int i = 0; i < fMinHist->GetNbinsX(); i++) {
// TODO (P.Stowell) Change this to a NULL system where limits are actually free!
fMinHist->SetBinContent(i + 1, fDataHist->GetBinContent(i + 1) - 1E6);
}
}
if (!fMaxHist) {
fMaxHist = (TH1D*) fDataHist->Clone();
fMaxHist->SetNameTitle( (fName + "_min").c_str(),
(fName + " min" + fPlotTitles).c_str() );
for (int i = 0; i < fMaxHist->GetNbinsX(); i++) {
fMaxHist->SetBinContent(i + 1, fDataHist->GetBinContent(i + 1) - 1E6);
}
}
// Set types from state, or to unknown
if (!fTypeHist) {
int deftype = -1;
if (fType.find("T2K") != std::string::npos) { deftype = kT2K; }
else if (fType.find("NEUT") != std::string::npos) { deftype = kNEUT; }
else if (fType.find("NIWG") != std::string::npos) { deftype = kNIWG; }
else if (fType.find("GENIE") != std::string::npos) { deftype = kGENIE; }
else if (fType.find("NORM") != std::string::npos) { deftype = kNORM; }
else if (fType.find("NUWRO") != std::string::npos) { deftype = kNUWRO; }
fTypeHist = new TH1I( (fName + "_type").c_str(),
(fName + " type" + fPlotTitles).c_str(),
fDataHist->GetNbinsX(), 0, fDataHist->GetNbinsX() );
for (int i = 0; i < fTypeHist->GetNbinsX(); i++) {
fTypeHist->SetBinContent(i + 1, deftype );
}
}
// Sort Covariances
fInvCovar = StatUtils::GetInvert(fCovar);
fDecomp = StatUtils::GetDecomp(fCovar);
// Create DataTrue for Throws
fDataTrue = (TH1D*) fDataHist->Clone();
fDataTrue->SetNameTitle( (fName + "_truedata").c_str(),
(fName + " truedata" + fPlotTitles).c_str() );
fDataOrig = (TH1D*) fDataHist->Clone();
fDataOrig->SetNameTitle( (fName + "_origdata").c_str(),
(fName + " origdata" + fPlotTitles).c_str() );
// Select only dials we want
if (!fDialSelection.empty()) {
(*fDataHist) = RemoveBinsNotInString(*fDataHist, fDialSelection);
}
}
//*******************************************************************************
TH1D ParamPull::RemoveBinsNotInString(TH1D hist, std::string mystr) {
//*******************************************************************************
// Make list of allowed bins
std::vector<std::string> allowedbins;
for (int i = 0; i < hist.GetNbinsX(); i++) {
std::string syst = std::string(hist.GetXaxis()->GetBinLabel(i + 1));
if (mystr.find(syst) != std::string::npos) {
allowedbins.push_back(syst);
}
}
// Make new histogram
UInt_t nbins = allowedbins.size();
TH1D newhist = TH1D( hist.GetName(), hist.GetTitle(),
(Int_t)nbins, 0.0, (Double_t)nbins);
// Setup bins
for (UInt_t i = 0; i < nbins; i++) {
// Set Labels
newhist.GetXaxis()->SetBinLabel(i + 1, allowedbins[i].c_str());
// Copy Values
for (Int_t j = 0; j < hist.GetNbinsX(); j++) {
if (!allowedbins[i].compare(hist.GetXaxis()->GetBinLabel(j + 1))) {
newhist.SetBinContent(i + 1, hist.GetBinContent(j + 1) );
newhist.SetBinError(i + 1, hist.GetBinError(j + 1) );
}
}
}
return newhist;
}
//*******************************************************************************
TH1I ParamPull::RemoveBinsNotInString(TH1I hist, std::string mystr) {
//*******************************************************************************
// Make list of allowed bins
std::vector<std::string> allowedbins;
for (int i = 0; i < hist.GetNbinsX(); i++) {
std::string syst = std::string(hist.GetXaxis()->GetBinLabel(i + 1));
if (mystr.find(syst) != std::string::npos) {
allowedbins.push_back(syst);
}
}
// Make new histogram
UInt_t nbins = allowedbins.size();
TH1I newhist = TH1I( hist.GetName(), hist.GetTitle(),
(Int_t)nbins, 0.0, (Int_t)nbins);
// Setup bins
for (UInt_t i = 0; i < nbins; i++) {
// Set Labels
newhist.GetXaxis()->SetBinLabel(i + 1, allowedbins[i].c_str());
// Copy Values
for (Int_t j = 0; j < hist.GetNbinsX(); j++) {
if (!allowedbins[i].compare(hist.GetXaxis()->GetBinLabel(j + 1))) {
newhist.SetBinContent(i + 1, hist.GetBinContent(j + 1) );
newhist.SetBinError(i + 1, hist.GetBinError(j + 1) );
}
}
}
return newhist;
}
//*******************************************************************************
void ParamPull::ReadFitFile(std::string input) {
//*******************************************************************************
TFile* tempfile = new TFile(input.c_str(), "READ");
// Read Data
fDataHist = (TH1D*) tempfile->Get("fit_dials_free");
if (!fDataHist) {
ERR(FTL) << "Can't find TH1D hist fit_dials in " << fName << std::endl;
ERR(FTL) << "File Entries:" << std::endl;
tempfile->ls();
throw;
}
fDataHist->SetDirectory(0);
fDataHist->SetNameTitle( (fName + "_data").c_str(),
(fName + " data" + fPlotTitles).c_str() );
// Read Covar
TH2D* tempcov = (TH2D*) tempfile->Get("covariance_free");
if (!tempcov) {
ERR(FTL) << "Can't find TH2D covariance_free in " << fName << std::endl;
ERR(FTL) << "File Entries:" << std::endl;
tempfile->ls();
throw;
}
// Setup Covar
int nbins = fDataHist->GetNbinsX();
fCovar = new TMatrixDSym( nbins );
for (int i = 0; i < nbins; i++) {
for (int j = 0; j < nbins; j++) {
(*fCovar)(i, j) = tempcov->GetBinContent(i + 1, j + 1);
}
}
return;
}
//*******************************************************************************
void ParamPull::ReadRootFile(std::string input) {
//*******************************************************************************
std::vector<std::string> inputlist = GeneralUtils::ParseToStr(input, ";");
// Check all given
if (inputlist.size() < 2) {
ERR(FTL) << "Covar supplied in 'ROOT' format should have 3 semi-colon seperated entries!" << std::endl
<< "ROOT:filename;histname[;covarname]" << std::endl;
ERR(FTL) << "histname = TH1D, covarname = TH2D" << std::endl;
throw;
}
// Get Entries
std::string filename = inputlist[0];
LOG(DEB) << filename << std::endl;
std::string histname = inputlist[1];
LOG(DEB) << histname << std::endl;
LOG(DEB) << input << std::endl;
// Read File
TFile* tempfile = new TFile(filename.c_str(), "READ");
if (tempfile->IsZombie()) {
ERR(FTL) << "Can't find file in " << fName << std::endl;
ERR(FTL) << "location = " << filename << std::endl;
throw;
}
// Read Hist
fDataHist = (TH1D*) tempfile->Get(histname.c_str());
if (!fDataHist) {
ERR(FTL) << "Can't find TH1D hist " << histname << " in " << fName << std::endl;
ERR(FTL) << "File Entries:" << std::endl;
tempfile->ls();
throw;
}
fDataHist->SetDirectory(0);
fDataHist->SetNameTitle( (fName + "_data").c_str(),
(fName + " data" + fPlotTitles).c_str() );
LOG(DEB) << "READING COVAR" << std::endl;
// Read Covar
if (inputlist.size() > 2) {
std::string covarname = inputlist[2];
LOG(DEB) << "COVARNAME = " << covarname << std::endl;
TH2D* tempcov = (TH2D*) tempfile->Get(covarname.c_str());
if (!tempcov) {
ERR(FTL) << "Can't find TH2D covar " << covarname << " in " << fName << std::endl;
ERR(FTL) << "File Entries:" << std::endl;
tempfile->ls();
throw;
}
// Setup Covar
int nbins = fDataHist->GetNbinsX();
fCovar = new TMatrixDSym( nbins );
for (int i = 0; i < nbins; i++) {
for (int j = 0; j < nbins; j++) {
(*fCovar)(i, j) = tempcov->GetBinContent(i + 1, j + 1);
}
}
// Uncorrelated
} else {
LOG(SAM) << "No Covar provided so using diagonal errors for "
<< fName << std::endl;
fCovar = NULL;
}
}
//*******************************************************************************
void ParamPull::ReadVectFile(std::string input) {
//*******************************************************************************
std::vector<std::string> inputlist = GeneralUtils::ParseToStr(input, ";");
if (inputlist.size() < 4) {
ERR(FTL) << "Need 3 inputs for vector input in " << fName << std::endl;
ERR(FTL) << "Inputs: " << input << std::endl;
throw;
}
// Open File
std::string rootname = inputlist[0];
TFile* tempfile = new TFile(rootname.c_str(), "READ");
if (tempfile->IsZombie()) {
ERR(FTL) << "Can't find file in " << fName << std::endl;
ERR(FTL) << "location = " << rootname << std::endl;
throw;
}
// Get Name
std::string tagname = inputlist[1];
// TVector<std::string> dialtags = tempfile->Get(tagname.c_str());
// if (!dialtags){
// ERR(FTL) << "Can't find list of dial names!" << std::endl;
// }
// Get Values
std::string valuename = inputlist[2];
TVectorD* dialvals = (TVectorD*)tempfile->Get(valuename.c_str());
if (!dialvals) {
ERR(FTL) << "Can't find dial values" << std::endl;
}
// Get Matrix
std::string matrixname = inputlist[3];
TMatrixD* matrixvals = (TMatrixD*)tempfile->Get(matrixname.c_str());
if (!matrixvals) {
ERR(FTL) << "Can't find matirx values" << std::endl;
}
// Get Types
if (inputlist.size() > 4) {
std::string typesname = inputlist[3];
}
// Get Minimum
if (inputlist.size() > 5) {
std::string minname = inputlist[4];
}
// Get Maximum
if (inputlist.size() > 6) {
std::string maxname = inputlist[5];
}
}
//*******************************************************************************
void ParamPull::ReadDialInput(std::string input) {
//*******************************************************************************
std::vector<std::string> inputlist = GeneralUtils::ParseToStr(input, ";");
if (inputlist.size() < 3) {
ERR(FTL) << "Need 3 inputs for dial input in " << fName << std::endl;
ERR(FTL) << "Inputs: " << input << std::endl;
throw;
}
std::vector<double> inputvals = GeneralUtils::ParseToDbl(input, ";");
std::string dialname = inputlist[0];
double val = inputvals[1];
double err = inputvals[2];
fDataHist = new TH1D( (fName + "_data").c_str(),
(fName + "_data" + fPlotTitles).c_str(), 1, 0, 1);
fDataHist->SetBinContent(1, val);
fDataHist->SetBinError(1, err);
fDataHist->GetXaxis()->SetBinLabel(1, dialname.c_str());
+
+ fLimitHist = new TH1D( (fName + "_limits").c_str(),
+ (fName + "_limits" + fPlotTitles).c_str(), 1, 0, 1);
+ fLimitHist->Reset();
+ if (inputvals.size() > 4) {
+ fLimitHist->SetBinContent(1, (inputvals[3] + inputvals[4]) / 2.0);
+ fLimitHist->SetBinError(1, (inputvals[4] - inputvals[3]) / 2.0);
+ }
+
fCovar = NULL;
}
//*******************************************************************************
std::map<std::string, int> ParamPull::GetAllDials() {
//*******************************************************************************
std::map<std::string, int> dialtypemap;
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
std::string name = fDataHist->GetXaxis()->GetBinLabel(i + 1);
int type = fTypeHist->GetBinContent(i + 1);
dialtypemap[name] = type;
}
return dialtypemap;
}
//*******************************************************************************
bool ParamPull::CheckDialsValid() {
//*******************************************************************************
return true;
std::string helpstring = "";
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
std::string name = std::string(fDataHist->GetXaxis()->GetBinLabel(i + 1));
// If dial exists its all good
if (FitBase::GetRW()->DialIncluded(name)) continue;
// If it doesn't but its a sample norm also continue
if (name.find("_norm") != std::string::npos) {
ERR(WRN) << "Norm dial included in covar but not set in FitWeight." << std::endl;
ERR(WRN) << "Assuming its a sample norm and skipping..." << std::endl;
}
// Dial unknown so print a help statement
std::ostringstream tempstr;
tempstr << "unknown_parameter " << name << " "
<< fDataHist->GetBinContent(i + 1) << " "
<< fDataHist->GetBinContent(i + 1) - fDataHist->GetBinError(i + 1) << " "
<< fDataHist->GetBinContent(i + 1) + fDataHist->GetBinError(i + 1) << " "
<< fDataHist->GetBinError(i + 1) << " ";
if (!fType.empty()) tempstr << fType << std::endl;
else tempstr << "FREE" << std::endl;
helpstring += tempstr.str();
}
// Show statement before failing
if (!helpstring.empty()) {
ERR(WRN) << "Dial(s) included in covar but not set in FitWeight." << std::endl
<< "ParamPulls needs to know how you want it to be treated." << std::endl
<< "Include the following lines into your card:" << std::endl;
ERR(WRN) << helpstring << std::endl;
throw;
return false;
} else {
return true;
}
}
//*******************************************************************************
void ParamPull::Reconfigure() {
//*******************************************************************************
FitWeight* rw = FitBase::GetRW();
// Get Dial Names that are valid
std::vector<std::string> namevec = rw->GetDialNames();
std::vector<double> valuevec = rw->GetDialValues();
// Set Bin Values from RW
for (UInt_t i = 0; i < namevec.size(); i++) {
// Loop over bins and check name matches
std::string syst = namevec.at(i);
double systval = valuevec.at(i);
std::vector<std::string> allsyst = GeneralUtils::ParseToStr(syst, ",");
// Proper Reconf using RW
for (int j = 0; j < fMCHist->GetNbinsX(); j++) {
// Search for the name of this bin in the corrent dial
std::string binname = std::string(fMCHist->GetXaxis()->GetBinLabel(j + 1) );
// Check Full Name
if (!syst.compare(binname.c_str())) {
fMCHist->SetBinContent(j + 1, systval);
break;
}
std::vector<std::string> splitbinname = GeneralUtils::ParseToStr(binname, ",");
for (size_t l = 0; l < splitbinname.size(); l++) {
std::string singlebinname = splitbinname[l];
for (size_t k = 0; k < allsyst.size(); k++) {
if (!allsyst[k].compare(singlebinname.c_str())) {
fMCHist->SetBinContent(j + 1, systval);
}
}
}
}
}
return;
};
//*******************************************************************************
void ParamPull::ResetToy(void) {
//*******************************************************************************
if (fDataHist) delete fDataHist;
LOG(DEB) << "Resetting toy" << std::endl;
LOG(DEB) << fDataTrue << std::endl;
fDataHist = (TH1D*)fDataTrue->Clone();
LOG(DEB) << "Setting name" << std::endl;
fDataHist->SetNameTitle( (fName + "_data").c_str(),
(fName + " data" + fPlotTitles).c_str() );
}
//*******************************************************************************
void ParamPull::SetFakeData(std::string fakeinput) {
//*******************************************************************************
// Set from MC Setting
if (!fakeinput.compare("MC")) {
// Copy MC into data
if (fDataHist) delete fDataHist;
fDataHist = (TH1D*)fMCHist->Clone();
fDataHist->SetNameTitle( (fName + "_data").c_str(),
(fName + " fakedata" + fPlotTitles).c_str() );
// Copy original data errors
for (int i = 0; i < fDataOrig->GetNbinsX(); i++) {
fDataHist->SetBinError(i + 1, fDataOrig->GetBinError(i + 1) );
}
// Make True Toy Central Value Hist
fDataTrue = (TH1D*) fDataHist->Clone();
fDataTrue->SetNameTitle( (fName + "_truedata").c_str(),
(fName + " truedata" + fPlotTitles).c_str() );
} else {
ERR(FTL) << "Trying to set fake data for ParamPulls not from MC!" << std::endl;
ERR(FTL) << "Not currently implemented.." << std::endl;
throw;
}
}
//*******************************************************************************
void ParamPull::RemoveFakeData() {
//*******************************************************************************
delete fDataHist;
fDataHist = (TH1D*)fDataOrig->Clone();
fDataHist->SetNameTitle( (fName + "_data").c_str(),
(fName + " data" + fPlotTitles).c_str() );
fDataTrue = (TH1D*) fDataHist->Clone();
fDataTrue->SetNameTitle( (fName + "_truedata").c_str(),
(fName + " truedata" + fPlotTitles).c_str() );
}
//*******************************************************************************
double ParamPull::GetLikelihood() {
//*******************************************************************************
double like = 0.0;
switch (fCalcType) {
// Gaussian Calculation with correlations
case kGausPull:
like = StatUtils::GetChi2FromCov(fDataHist, fMCHist, fInvCovar, NULL);
like *= 1E-76;
break;
// Default says this has no pull
case kNoThrow:
default:
like = 0.0;
break;
}
LOG(DEB) << "Likelihood = " << like << " " << fCalcType << std::endl;
return like;
};
//*******************************************************************************
int ParamPull::GetNDOF() {
//*******************************************************************************
int ndof = 0;
if (fCalcType != kNoThrow) {
- ndof += fDataHist->GetNbinsX();
+ ndof = fDataHist->GetNbinsX();
}
return ndof;
};
//*******************************************************************************
void ParamPull::ThrowCovariance() {
//*******************************************************************************
// Reset toy for throw
ResetToy();
- LOG(DEB) << "Toy Reset " << std::endl;
+ LOG(FIT) << "Creating new toy dataset" << std::endl;
// Generate random Gaussian throws
std::vector<double> randthrows;
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
double randtemp = 0.0;
switch (fThrowType) {
// Gaussian Throws
case kGausThrow:
randtemp = gRandom->Gaus(0.0, 1.0);
break;
+ // Uniform Throws
+ case kFlatThrow:
+ randtemp = gRandom->Uniform(0.0, 1.0);
+ if (fLimitHist) {
+ randtemp = fLimitHist->GetBinContent(i + 1) + fLimitHist->GetBinError(i + 1) * ( randtemp * 2 - 1 );
+ }
+ break;
+
// No Throws (DEFAULT)
default:
break;
}
randthrows.push_back(randtemp);
}
// Create Bin Modifications
double totalres = 0.0;
for (int i = 0; i < fDataHist->GetNbinsX(); i++) {
// Calc Bin Mod
double binmod = 0.0;
- for (int j = 0; j < fDataHist->GetNbinsX(); j++) {
- // std::cout << "DECOMP " << j << " " << i << " " << randthrows.at(j) << std::endl;
- binmod += (*fDecomp)(j, i) * randthrows.at(j);
+
+ if (fThrowType == kGausThrow) {
+ for (int j = 0; j < fDataHist->GetNbinsX(); j++) {
+ binmod += (*fDecomp)(j, i) * randthrows.at(j);
+ }
+ } else if (fThrowType == kFlatThrow) {
+ binmod = randthrows.at(i) - fDataHist->GetBinContent(i + 1);
}
+
// Add up fraction dif
totalres += binmod;
// Add to current data
fDataHist->SetBinContent(i + 1, fDataHist->GetBinContent(i + 1) + binmod);
}
// Rename
fDataHist->SetNameTitle( (fName + "_data").c_str(),
(fName + " toydata" + fPlotTitles).c_str() );
- // Print Status
- LOG(REC) << "Created new toy histogram. Total Dif = "
- << totalres << std::endl;
+ // Check Limits
+ if (fLimitHist) {
+ for (int i = 0; i < fLimitHist->GetNbinsX(); i++) {
+ if (fLimitHist->GetBinError(i + 1) == 0.0) continue;
+ if (fDataHist->GetBinContent(i + 1) > fLimitHist->GetBinContent(i + 1) + fLimitHist->GetBinError(i + 1) ||
+ fDataHist->GetBinContent(i + 1) < fLimitHist->GetBinContent(i + 1) - fLimitHist->GetBinError(i + 1)) {
+ this->ThrowCovariance();
+ }
+ }
+ }
+
return;
};
//*******************************************************************************
TH2D ParamPull::GetCovar() {
//*******************************************************************************
TH2D tempCov = TH2D(*fInvCovar);
for (int i = 0; i < tempCov.GetNbinsX(); i++) {
tempCov.GetXaxis()->SetBinLabel(i + 1, fDataHist->GetXaxis()->GetBinLabel(i + 1));
tempCov.GetYaxis()->SetBinLabel(i + 1, fDataHist->GetXaxis()->GetBinLabel(i + 1));
}
tempCov.SetNameTitle((fName + "_INVCOV").c_str(),
(fName + " InvertedCovariance;Dials;Dials").c_str());
return tempCov;
}
//*******************************************************************************
TH2D ParamPull::GetFullCovar() {
//*******************************************************************************
TH2D tempCov = TH2D(*fCovar);
for (int i = 0; i < tempCov.GetNbinsX(); i++) {
tempCov.GetXaxis()->SetBinLabel(i + 1, fDataHist->GetXaxis()->GetBinLabel(i + 1));
tempCov.GetYaxis()->SetBinLabel(i + 1, fDataHist->GetXaxis()->GetBinLabel(i + 1));
}
tempCov.SetNameTitle((fName + "_COV").c_str(),
(fName + " Covariance;Dials;Dials").c_str());
return tempCov;
}
//*******************************************************************************
TH2D ParamPull::GetDecompCovar() {
//*******************************************************************************
TH2D tempCov = TH2D(*fCovar);
for (int i = 0; i < tempCov.GetNbinsX(); i++) {
tempCov.GetXaxis()->SetBinLabel(i + 1, fDataHist->GetXaxis()->GetBinLabel(i + 1));
tempCov.GetYaxis()->SetBinLabel(i + 1, fDataHist->GetXaxis()->GetBinLabel(i + 1));
}
tempCov.SetNameTitle((fName + "_DEC").c_str(),
(fName + " Decomposition;Dials;Dials").c_str());
return tempCov;
}
//*******************************************************************************
void ParamPull::Write(std::string writeoptt) {
//*******************************************************************************
fDataHist->Write();
fMCHist->Write();
-
+ if (fLimitHist) {
+ fLimitHist->Write();
+ }
GetCovar().Write();
GetFullCovar().Write();
GetDecompCovar().Write();
return;
};
diff --git a/src/FitBase/ParamPull.h b/src/FitBase/ParamPull.h
index 22e707d..7da9eac 100644
--- a/src/FitBase/ParamPull.h
+++ b/src/FitBase/ParamPull.h
@@ -1,188 +1,193 @@
// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
/*******************************************************************************
* This file is part of NUISANCE.
*
* NUISANCE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* NUISANCE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NUISANCE. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
#ifndef PARAM_PULL_H_SEEN
#define PARAM_PULL_H_SEEN
/*!
* \addtogroup FitBase
* @{
*/
#include <stdlib.h>
#include <numeric>
#include <math.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <list>
#include <vector>
// ROOT includes
#include <TROOT.h>
#include <TH1D.h>
#include <TTree.h>
#include <TFile.h>
#include <TMatrixDSym.h>
#include <TDecompSVD.h>
#include <TVectorD.h>
// Fit Includes
#include "PlotUtils.h"
#include "StatUtils.h"
#include "FitWeight.h"
#include "FitLogger.h"
#include "EventManager.h"
#include "TVector.h"
using namespace std;
//! Enums to allow Non Guassian Pulls in Future
enum FitPullTypes {
kUnknownPull = -1,
kNoPull = 0,
kGausPull = 1
};
enum FitThrowTypes {
kUnknownThrow = -1,
kNoThrow = 0,
- kGausThrow = 1
+ kGausThrow = 1,
+ kFlatThrow = 2
};
//! Used to produce gaussian penalty terms in the fit.
class ParamPull {
public:
//! Default Constructor
ParamPull(std::string name, std::string inputfile, std::string type, std::string dials="");
//! Default destructor
virtual ~ParamPull(void) {};
// Set dial types (DEFAULT,ABS,FRAC)
void SetType(std::string type);
// Setup Histogram inputs (from previous fit file, or ROOT file)
void SetupHistograms(std::string input);
// Read a previous NUISANCE file
void ReadFitFile(std::string input);
// Read a ROOT file with any histograms in
void ReadRootFile(std::string input);
// Read Text file
void ReadVectFile(std::string input);
// Read a single dial central value and error
void ReadDialInput(std::string input);
//! Reconfigure function reads in current RW engine dials and sets their value to MC
void Reconfigure(void);
//! Get likelihood given the current values
double GetLikelihood(void);
//! Get NDOF if used in likelihoods
int GetNDOF(void);
// Get Covariance Matrices as plots
TH2D GetCovar(void);
TH2D GetFullCovar(void);
TH2D GetDecompCovar(void);
// Get Covariance Matrices
inline TMatrixDSym GetCovarMatrix (void) const { return *fInvCovar; };
inline TMatrixDSym GetFullCovarMatrix (void) const { return *fCovar; };
inline TMatrixDSym GetDecompCovarMatrix (void) const { return *fDecomp; };
//! Save the histograms
void Write(std::string writeopt="");
//! Throw the dial values using the current covariance. Useful for parameter throws.
void ThrowCovariance(void);
//! Compare dials to RW
bool CheckDialsValid(void);
//! Reset toy data back to original data
void ResetToy(void);
//! Read fake data from MC
void SetFakeData(std::string fakeinput);
//! Reset fake data back to original data (before fake data or throws)
void RemoveFakeData();
// Get Functions
inline std::string GetName (void) const { return fName; };
inline std::string GetInput (void) const { return fInput; };
inline std::string GetType (void) const { return fType; };
inline std::string GetFileType (void) const { return fFileType; };
inline std::string GetDialOptions (void) const { return fDialOptions; };
std::map<std::string, int> GetAllDials();
inline TH1D GetDataHist (void) const { return *fDataHist; };
inline TH1D GetDataTrue (void) const { return *fDataTrue; };
inline TH1D GetDataOrig (void) const { return *fDataOrig; };
inline TH1D GetMCHist (void) const { return *fMCHist; };
inline TH1D GetMaxHist (void) const { return *fMaxHist; };
inline TH1D GetMinHist (void) const { return *fMinHist; };
inline TH1I GetDialTypes (void) const { return *fTypeHist; };
+ inline TH1D GetLimitHist (void) const { return *fLimitHist; };
+
private:
TH1D RemoveBinsNotInString(TH1D hist, std::string mystr);
TH1I RemoveBinsNotInString(TH1I hist, std::string mystr);
std::string fName; //!< Pull Name
std::string fInput; //!< Pull input string
std::string fType; //!< Pull options type
std::string fFileType; //!< Pull input file types
std::string fPlotTitles; //! Axis format
std::string fDialOptions; //!< Dial handling options
std::string fDialSelection; //!< Dial Selection
TH1D* fMCHist; //!< Current MC Histogram
TH1D* fDataHist; //!< Current data Histogram
TH1D* fDataTrue; //!< True Data (before histogram throws)
TH1D* fDataOrig; //!< Orig Data (without toys or fake data)
TH1D* fMaxHist; //!< Maximum limit on MC/Data
TH1D* fMinHist; //!< Maximum limit on MC/Data
TH1I* fTypeHist; //!< Dial Types
int fCalcType; //!< Method to calculate likelihood
int fThrowType; //!< Method to calculate throws
TMatrixDSym* fCovar; //!< Covariance
TMatrixDSym* fInvCovar; //!< Inverted Covariance
TMatrixDSym* fDecomp; //!< Decomposition
+
+ TH1D* fLimitHist;
};
// Class TypeDefs
typedef std::list<ParamPull*>::const_iterator PullListConstIter;
typedef std::list<ParamPull*>::iterator PullListIter;
typedef std::vector<ParamPull*>::const_iterator PullVectConstIter;
typedef std::vector<ParamPull*>::iterator PullVectIter;
/*! @} */
#endif
diff --git a/src/Routines/SystematicRoutines.cxx b/src/Routines/SystematicRoutines.cxx
index 4c846a5..d33b35e 100755
--- a/src/Routines/SystematicRoutines.cxx
+++ b/src/Routines/SystematicRoutines.cxx
@@ -1,1516 +1,1517 @@
// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret
/*******************************************************************************
* This file is part of NUISANCE.
*
* NUISANCE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* NUISANCE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NUISANCE. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "SystematicRoutines.h"
void SystematicRoutines::Init(){
fInputFile = "";
fInputRootFile = NULL;
fOutputFile = "";
fOutputRootFile = NULL;
fCovar = fCovarFree = NULL;
fCorrel = fCorrelFree = NULL;
fDecomp = fDecompFree = NULL;
fStrategy = "ErrorBands";
fRoutines.clear();
fRoutines.push_back("ErrorBands");
fCardFile = "";
fFakeDataInput = "";
fSampleFCN = NULL;
fAllowedRoutines = ("ErrorBands,PlotLimits");
};
SystematicRoutines::~SystematicRoutines(){
};
SystematicRoutines::SystematicRoutines(int argc, char* argv[]){
// Initialise Defaults
Init();
nuisconfig configuration = Config::Get();
// Default containers
std::string cardfile = "";
std::string maxevents = "-1";
int errorcount = 0;
int verbocount = 0;
std::vector<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;
SETVERBOSITY(verbocount);
// Proper Setup
if (fStrategy.find("ErrorBands") != std::string::npos ||
fStrategy.find("MergeErrors") != std::string::npos){
fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE");
}
// fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE");
SetupSystematicsFromXML();
SetupCovariance();
SetupRWEngine();
SetupFCN();
GetCovarFromFCN();
// Run();
return;
};
void SystematicRoutines::SetupSystematicsFromXML(){
LOG(FIT) << "Setting up nuismin" << std::endl;
// Setup Parameters ------------------------------------------
std::vector<nuiskey> parkeys = Config::QueryKeys("parameter");
if (!parkeys.empty()) {
LOG(FIT) << "Number of parameters : " << parkeys.size() << std::endl;
}
for (size_t i = 0; i < parkeys.size(); i++) {
nuiskey key = parkeys.at(i);
// Check for type,name,nom
if (!key.Has("type")) {
ERR(FTL) << "No type given for parameter " << i << std::endl;
throw;
} else if (!key.Has("name")) {
ERR(FTL) << "No name given for parameter " << i << std::endl;
throw;
} else if (!key.Has("nominal")) {
ERR(FTL) << "No nominal given for parameter " << i << std::endl;
throw;
}
// Get Inputs
std::string partype = key.GetS("type");
std::string parname = key.GetS("name");
double parnom = key.GetD("nominal");
double parlow = parnom - 1;
double parhigh = parnom + 1;
double parstep = 1;
// Override if state not given
if (!key.Has("state")){
key.SetS("state","FIX");
}
std::string parstate = key.GetS("state");
// Extra limits
if (key.Has("low")) {
parlow = key.GetD("low");
parhigh = key.GetD("high");
parstep = key.GetD("step");
LOG(FIT) << "Read " << partype << " : "
<< parname << " = "
<< parnom << " : "
<< parlow << " < p < " << parhigh
<< " : " << parstate << std::endl;
} else {
LOG(FIT) << "Read " << partype << " : "
<< parname << " = "
<< parnom << " : "
<< parstate << std::endl;
}
// Run Parameter Conversion if needed
if (parstate.find("ABS") != std::string::npos) {
parnom = FitBase::RWAbsToSigma( partype, parname, parnom );
parlow = FitBase::RWAbsToSigma( partype, parname, parlow );
parhigh = FitBase::RWAbsToSigma( partype, parname, parhigh );
parstep = FitBase::RWAbsToSigma( partype, parname, parstep );
} else if (parstate.find("FRAC") != std::string::npos) {
parnom = FitBase::RWFracToSigma( partype, parname, parnom );
parlow = FitBase::RWFracToSigma( partype, parname, parlow );
parhigh = FitBase::RWFracToSigma( partype, parname, parhigh );
parstep = FitBase::RWFracToSigma( partype, parname, parstep );
}
// Push into vectors
fParams.push_back(parname);
fTypeVals[parname] = FitBase::ConvDialType(partype);;
fStartVals[parname] = parnom;
fCurVals[parname] = parnom;
fErrorVals[parname] = 0.0;
fStateVals[parname] = parstate;
bool fixstate = parstate.find("FIX") != std::string::npos;
fFixVals[parname] = fixstate;
fStartFixVals[parname] = fFixVals[parname];
fMinVals[parname] = parlow;
fMaxVals[parname] = parhigh;
fStepVals[parname] = parstep;
}
// Setup Samples ----------------------------------------------
std::vector<nuiskey> samplekeys = Config::QueryKeys("sample");
if (!samplekeys.empty()) {
LOG(FIT) << "Number of samples : " << samplekeys.size() << std::endl;
}
for (size_t i = 0; i < samplekeys.size(); i++) {
nuiskey key = samplekeys.at(i);
// Get Sample Options
std::string samplename = key.GetS("name");
std::string samplefile = key.GetS("input");
std::string sampletype =
key.Has("type") ? key.GetS("type") : "DEFAULT";
double samplenorm =
key.Has("norm") ? key.GetD("norm") : 1.0;
// Print out
LOG(FIT) << "Read sample info " << i << " : "
<< samplename << std::endl
<< "\t\t input -> " << samplefile << std::endl
<< "\t\t state -> " << sampletype << std::endl
<< "\t\t norm -> " << samplenorm << std::endl;
// If FREE add to parameters otherwise continue
if (sampletype.find("FREE") == std::string::npos) {
continue;
}
// Form norm dial from samplename + sampletype + "_norm";
std::string normname = samplename + "_norm";
// Check normname not already present
if (fTypeVals.find(normname) != fTypeVals.end()) {
continue;
}
// Add new norm dial to list if its passed above checks
fParams.push_back(normname);
fTypeVals[normname] = kNORM;
fStateVals[normname] = sampletype;
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 << 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();
}
+ tempfile->cd();
fSampleFCN->WriteIterationTree();
tempfile->Close();
}
void SystematicRoutines::MergeThrows(){
fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE");
fOutputRootFile->cd();
// Make a container folder
TDirectory* errorDIR = (TDirectory*) fOutputRootFile->mkdir("error_bands");
errorDIR->cd();
TDirectory* outnominal = (TDirectory*) fOutputRootFile->mkdir("nominal_throw");
outnominal->cd();
// Split Input Files
if (!fThrowString.empty()) fThrowList = GeneralUtils::ParseToStr(fThrowString,",");
// Add default if no throwlist given
if (fThrowList.size() < 1) fThrowList.push_back( fOutputFile + ".throws.root" );
/// Save location of file containing nominal
std::string nominalfile;
bool nominalfound;
// Loop over files and check they exist.
for (uint i = 0; i < fThrowList.size(); i++){
std::string file = fThrowList[i];
bool found = false;
// normal
std::string newfile = file;
TFile* throwfile = new TFile(file.c_str(),"READ");
if (throwfile and !throwfile->IsZombie()){
found = true;
}
// normal.throws.root
if (!found){
newfile = file + ".throws.root";
throwfile = new TFile((file + ".throws.root").c_str(),"READ");
if (throwfile and !throwfile->IsZombie()) {
found = true;
}
}
// If its found save to throwlist, else save empty.
// Also search for nominal
if (found){
fThrowList[i] = newfile;
LOG(FIT) << "Throws File :" << newfile << std::endl;
// Find input which contains nominal
if (throwfile->Get("nominal")){
nominalfound = true;
nominalfile = newfile;
}
throwfile->Close();
} else {
fThrowList[i] = "";
}
delete throwfile;
}
// Make sure we have a nominal file
if (!nominalfound or nominalfile.empty()){
ERR(FTL) << "No nominal found when mergining! Exiting!" << std::endl;
throw;
}
// Get the nominal throws file
TFile* tempfile = new TFile((nominalfile).c_str(),"READ");
tempfile->cd();
TDirectory* nominal = (TDirectory*)tempfile->Get("nominal");
// int nthrows = FitPar::Config().GetParI("error_throws");
bool uniformly = FitPar::Config().GetParB("error_uniform");
// Check percentage of bad files is okay.
int badfilecount = 0;
for (uint i = 0; i < fThrowList.size(); i++){
if (!fThrowList[i].empty()){
LOG(FIT) << "Loading Throws From File " << i << " : "
<< fThrowList[i] << std::endl;
} else {
badfilecount++;
}
}
// Check we have at least one good file
if ((uint)badfilecount == fThrowList.size()){
ERR(FTL) << "Found no good throw files for MergeThrows" << std::endl;
throw;
} else if (badfilecount > fThrowList.size()*0.25){
ERR(WRN) << "Over 25% of your throw files are dodgy. Please check this is okay!" << std::endl;
ERR(WRN) << "Will continue for the time being..." << std::endl;
sleep(5);
}
// Now go through the keys in the temporary file and look for TH1D, and TH2D plots
TIter next(nominal->GetListOfKeys());
TKey *key;
while ((key = (TKey*)next())) {
TClass *cl = gROOT->GetClass(key->GetClassName());
if (!cl->InheritsFrom("TH1D") and !cl->InheritsFrom("TH2D")) continue;
TH1* baseplot = (TH1D*)key->ReadObj();
std::string plotname = std::string(baseplot->GetName());
LOG(FIT) << "Creating error bands for " << plotname;
if (LOG_LEVEL(FIT)){
if (!uniformly) std::cout << " : Using COVARIANCE Throws! " << std::endl;
else std::cout << " : Using UNIFORM THROWS!!! " << std::endl;
}
int nbins = 0;
if (cl->InheritsFrom("TH1D")) nbins = ((TH1D*)baseplot)->GetNbinsX();
else nbins = ((TH1D*)baseplot)->GetNbinsX()* ((TH1D*)baseplot)->GetNbinsY();
// Setup TProfile with RMS option
TProfile* tprof = new TProfile((plotname + "_prof").c_str(),(plotname + "_prof").c_str(),nbins, 0, nbins, "S");
// Setup The TTREE
double* bincontents;
bincontents = new double[nbins];
double* binlowest;
binlowest = new double[nbins];
double* binhighest;
binhighest = new double[nbins];
errorDIR->cd();
TTree* bintree = new TTree((plotname + "_tree").c_str(), (plotname + "_tree").c_str());
for (Int_t i = 0; i < nbins; i++){
bincontents[i] = 0.0;
binhighest[i] = 0.0;
binlowest[i] = 0.0;
bintree->Branch(Form("content_%i",i),&bincontents[i],Form("content_%i/D",i));
}
// Make new throw plot
TH1* newplot;
// Run Throw Merging.
for (UInt_t i = 0; i < fThrowList.size(); i++){
TFile* throwfile = new TFile(fThrowList[i].c_str(), "READ");
// Loop over all throws in a folder
TIter nextthrow(throwfile->GetListOfKeys());
TKey *throwkey;
while ((throwkey = (TKey*)nextthrow())) {
// Skip non throw folders
if (std::string(throwkey->GetName()).find("throw_") == std::string::npos) continue;
// Get Throw DIR
TDirectory* throwdir = (TDirectory*)throwkey->ReadObj();
// Get Plot From Throw
newplot = (TH1*)throwdir->Get(plotname.c_str());
if (!newplot) continue;
// Loop Over Plot
for (Int_t j = 0; j < nbins; j++){
tprof->Fill(j+0.5, newplot->GetBinContent(j+1));
bincontents[j] = newplot->GetBinContent(j+1);
if (bincontents[j] < binlowest[j] or i == 0) binlowest[j] = bincontents[j];
if (bincontents[j] > binhighest[j] or i == 0) binhighest[j] = bincontents[j];
}
errorDIR->cd();
bintree->Fill();
}
}
errorDIR->cd();
if (uniformly){
LOG(FIT) << "Uniformly Calculating Plot Errors!" << std::endl;
}
TH1* statplot = (TH1*) baseplot->Clone();
for (Int_t j = 0; j < nbins; j++){
if (!uniformly){
// if ((baseplot->GetBinError(j+1)/baseplot->GetBinContent(j+1)) < 1.0) {
// baseplot->SetBinError(j+1,sqrt(pow(tprof->GetBinError(j+1),2) + pow(baseplot->GetBinError(j+1),2)));
// } else {
baseplot->SetBinContent(j+1,tprof->GetBinContent(j+1));
baseplot->SetBinError(j+1,tprof->GetBinError(j+1));
// }
} else {
baseplot->SetBinContent(j+1, 0.0);//(binlowest[j] + binhighest[j]) / 2.0);
baseplot->SetBinError(j+1, 0.0); //(binhighest[j] - binlowest[j])/2.0);
}
}
errorDIR->cd();
baseplot->Write();
tprof->Write();
bintree->Write();
outnominal->cd();
for (int i = 0; i < nbins; i++){
baseplot->SetBinError(i+1, sqrt(pow(statplot->GetBinError(i+1),2) + pow(baseplot->GetBinError(i+1),2)));
}
baseplot->Write();
delete statplot;
delete baseplot;
delete tprof;
delete bintree;
delete [] bincontents;
}
return;
};
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, May 3, 6:41 AM (1 d, 7 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4982757
Default Alt Text
(168 KB)
Attached To
rNUISANCEGIT nuisancegit
Event Timeline
Log In to Comment