diff --git a/cmake/NuWroSetup.cmake b/cmake/NuWroSetup.cmake index 149bfb9..f649bff 100644 --- a/cmake/NuWroSetup.cmake +++ b/cmake/NuWroSetup.cmake @@ -1,93 +1,112 @@ # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret ################################################################################ # This file is part of NUISANCE. # # NUISANCE is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # NUISANCE is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with NUISANCE. If not, see . ################################################################################ if(NOT NUWRO_INPUT_FILE STREQUAL "") if(NOT EXISTS ${NUWRO_INPUT_FILE}) cmessage(FATAL_ERROR "Expected -DNUWRO_INPUT_FILE to point to a valid input file. Cannot find: '${NUWRO_INPUT_FILE}'") endif() if(CMAKE_BUILD_TYPE MATCHES DEBUG) BuildROOTProject(NuWro_event1 ${NUWRO_INPUT_FILE} "event,vec,vect,particle,flags,params,line" STATIC) SET(ROOTLIBNAME "libNuWro_event1.a") else(CMAKE_BUILD_TYPE MATCHES RELEASE) BuildROOTProject(NuWro_event1 ${NUWRO_INPUT_FILE} "event,vec,vect,particle,flags,params,line" SHARED) SET(ROOTLIBNAME "libNuWro_event1.so") endif() ADD_CUSTOM_TARGET(NuWro_event1HeaderLink ALL COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_BINARY_DIR}/NuWro_event1/event.h ${CMAKE_BINARY_DIR}/NuWro_event1/event1.h DEPENDS NuWro_event1) LIST(APPEND EXTRA_CXX_FLAGS -D__NUWRO_ENABLED__) LIST(APPEND RWENGINE_INCLUDE_DIRECTORIES ${CMAKE_BINARY_DIR}/NuWro_event1) LIST(APPEND EXTRA_LINK_DIRS ${CMAKE_BINARY_DIR}) LIST(APPEND EXTRA_LIBS NuWro_event1) LIST(APPEND PROJECTWIDE_EXTRA_DEPENDENCIES NuWro_event1HeaderLink ) install(TARGETS NuWro_event1 DESTINATION lib) SET(NUWRO_BUILT_FROM_FILE TRUE) else() if(NUWRO STREQUAL "") cmessage(FATAL_ERROR "Variable NUWRO is not defined. " "This must be set to point to a prebuilt NuWro instance.") endif() - if(NUWRO_INC STREQUAL "") - cmessage(FATAL_ERROR "Variable NUWRO_INC is not defined. " - "This must be set to point to an installed NuWro instance.") - endif() # If you are using a version of NuWro without reweighting use this to compile. if(USE_NuWro_RW) + if(NUWRO_INC STREQUAL "") + cmessage(FATAL_ERROR "Variable NUWRO_INC is not defined. " + "This must be set to point to an installed NuWro instance.") + endif() + LIST(APPEND EXTRA_CXX_FLAGS -D__NUWRO_ENABLED__ -D__NUWRO_REWEIGHT_ENABLED__) if(USE_NuWro_SRW_Event) LIST(APPEND EXTRA_CXX_FLAGS -D__USE_NUWRO_SRW_EVENTS__) endif() LIST(APPEND RWENGINE_INCLUDE_DIRECTORIES ${NUWRO}/src ${NUWRO}/src/reweight ${NUWRO_INC}/nuwro) LIST(APPEND EXTRA_LINK_DIRS ${NUWRO}/build/${CMAKE_SYSTEM_NAME}/lib) LIST(APPEND EXTRA_LIBS reweight event) else () LIST(APPEND EXTRA_CXX_FLAGS -D__NUWRO_ENABLED__) LIST(APPEND RWENGINE_INCLUDE_DIRECTORIES ${NUWRO}/src) - LIST(APPEND EXTRA_SHAREDOBJS ${NUWRO}/bin/event1.so) + if(NOT EXISTS ${NUWRO}/bin/event1.so) + if(EXISTS ${NUWRO}/build/${CMAKE_SYSTEM_NAME}/lib) + + if(NUWRO_INC STREQUAL "") + cmessage(FATAL_ERROR "Variable NUWRO_INC is not defined. " + "This must be set to point to an installed NuWro instance.") + endif() + + LIST(APPEND RWENGINE_INCLUDE_DIRECTORIES ${NUWRO_INC}/nuwro) + + LIST(APPEND EXTRA_LINK_DIRS ${NUWRO}/build/${CMAKE_SYSTEM_NAME}/lib) + LIST(APPEND EXTRA_LIBS event) + else() + cmessage(FATAL_ERROR "Expected to find the NuWro event library in: ${NUWRO}/bin/event1.so, or if using NuWro with reweight support: ${NUWRO}/build/${CMAKE_SYSTEM_NAME}/lib/libevent.a. Is NuWro built?") + endif() + else() + LIST(APPEND EXTRA_SHAREDOBJS ${NUWRO}/bin/event1.so) + endif() + endif() set(NEED_PYTHIA6 TRUE) set(NEED_ROOTPYTHIA6 TRUE) endif() diff --git a/cmake/setup.sh.in b/cmake/setup.sh.in index 9acb3f8..f5ef12e 100644 --- a/cmake/setup.sh.in +++ b/cmake/setup.sh.in @@ -1,130 +1,134 @@ # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret ################################################################################ # This file is part of NUISANCE. # # NUISANCE is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # NUISANCE is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with NUISANCE. If not, see . ################################################################################ #!/bin/sh if ! [[ ":$PATH:" == *":@CMAKE_INSTALL_PREFIX@/bin:"* ]]; then export PATH=@CMAKE_INSTALL_PREFIX@/bin:$PATH fi if ! [[ ":$LD_LIBRARY_PATH:" == *":@CMAKE_INSTALL_PREFIX@/lib:"* ]]; then export LD_LIBRARY_PATH=@CMAKE_INSTALL_PREFIX@/lib:$LD_LIBRARY_PATH fi if [[ ! "${ROOTSYS}" ]]; then echo "[INFO]: Sourcing ROOT from: @CMAKE_ROOTSYS@" source "@CMAKE_ROOTSYS@/bin/thisroot.sh" fi if [[ "@USE_NEUT@" != "FALSE" ]]; then echo "[INFO]: Adding NEUT library paths to the environment." export NEUT_ROOT=@NEUT_ROOT@ export CERN=@CERN@ export CERN_LEVEL=@CERN_LEVEL@ if ! [[ ":$LD_LIBRARY_PATH:" == *":${NEUT_ROOT}/lib/Linux_pc:"* ]]; then export LD_LIBRARY_PATH=${NEUT_ROOT}/lib/Linux_pc:$LD_LIBRARY_PATH fi if ! [[ ":$LD_LIBRARY_PATH:" == *":${NEUT_ROOT}/src/reweight:"* ]]; then export LD_LIBRARY_PATH=${NEUT_ROOT}/src/reweight:$LD_LIBRARY_PATH fi fi if [[ "@USE_NuWro@" != "FALSE" ]]; then if [[ "@NUWRO_BUILT_FROM_FILE@" == "FALSE" ]]; then echo "[INFO]: Adding NuWro library paths to the environment." export NUWRO="@NUWRO@" if ! [[ ":$LD_LIBRARY_PATH:" == *":@NUWRO@/build/@CMAKE_SYSTEM_NAME@/lib:"* ]]; then export LD_LIBRARY_PATH=@NUWRO@/build/@CMAKE_SYSTEM_NAME@/lib:$LD_LIBRARY_PATH fi + + if [[ "@NUWRO_INC@" ]]; then + export NUWRO_INC=@NUWRO_INC@ + fi else echo "[INFO]: NuWro support included from input event file." fi fi if [[ "@NEED_PYTHIA6@" != "FALSE" ]]; then echo "[INFO]: Adding PYTHIA6 library paths to the environment." export PYTHIA6="@PYTHIA6@" if ! [[ ":$LD_LIBRARY_PATH:" == *":@PYTHIA6@:"* ]]; then export LD_LIBRARY_PATH=@PYTHIA6@:$LD_LIBRARY_PATH fi fi if [[ "@USE_GENIE@" != "FALSE" ]]; then echo "[INFO]: Adding GENIE paths to the environment." export GENIE="@GENIE@" export LHAPDF_LIB="@LHAPDF_LIB@" export LHAPDF_INC="@LHAPDF_INC@" export LIBXML2_LIB="@LIBXML2_LIB@" export LIBXML2_INC="@LIBXML2_INC@" export LOG4CPP_LIB="@LOG4CPP_LIB@" export LOG4CPP_INC="@LOG4CPP_INC@" if [[ "@LHAPATH@" ]]; then export LHAPATH="@LHAPATH@" fi if ! [[ ":$PATH:" == *":@GENIE@/bin:"* ]]; then export PATH=@GENIE@/bin:$PATH fi if ! [[ ":$LD_LIBRARY_PATH:" == *":@GENIE@/lib:"* ]]; then export LD_LIBRARY_PATH=@GENIE@/lib:$LD_LIBRARY_PATH fi if ! [[ ":$LD_LIBRARY_PATH:" == *":@LHAPDF_LIB@:"* ]]; then export LD_LIBRARY_PATH=@LHAPDF_LIB@:$LD_LIBRARY_PATH fi if ! [[ ":$LD_LIBRARY_PATH:" == *":@LIBXML2_LIB@:"* ]]; then export LD_LIBRARY_PATH=@LIBXML2_LIB@:$LD_LIBRARY_PATH fi if ! [[ ":$LD_LIBRARY_PATH:" == *":@LOG4CPP_LIB@:"* ]]; then export LD_LIBRARY_PATH=@LOG4CPP_LIB@:$LD_LIBRARY_PATH fi fi if [[ "@USE_NIWG@" != "FALSE" ]]; then echo "[INFO]: Adding NIWG paths to the environment." export NIWG=@NIWG_ROOT@ export NIWGREWEIGHT_INPUTS=@NIWG_ROOT@/inputs if ! [[ ":$LD_LIBRARY_PATH:" == *":@NIWG_ROOT@:"* ]]; then export LD_LIBRARY_PATH=${NIWG}:${LD_LIBRARY_PATH} fi fi if [[ "@USE_T2K@" != "FALSE" ]]; then echo "[INFO]: Adding T2K paths to the environment." export T2KREWEIGHT=@T2KREWEIGHT@ if ! [[ ":$LD_LIBRARY_PATH:" == *":@T2KREWEIGHT@/lib:"* ]]; then export LD_LIBRARY_PATH=${T2KREWEIGHT}/lib:${LD_LIBRARY_PATH} fi fi if [[ "@BUILD_GiBUU@" != "FALSE" ]]; then echo "[INFO]: Sourcing GiBUU tools." source @CMAKE_BINARY_DIR@/GiBUUTools/src/GiBUUTools-build/Linux/setup.sh fi export NUISANCE="@CMAKE_SOURCE_DIR@" diff --git a/src/FCN/JointFCN.cxx b/src/FCN/JointFCN.cxx index 31023b2..54593b9 100755 --- a/src/FCN/JointFCN.cxx +++ b/src/FCN/JointFCN.cxx @@ -1,1010 +1,1014 @@ #include "JointFCN.h" #include #include "FitUtils.h" //*************************************************** JointFCN::JointFCN(TFile* outfile) { //*************************************************** fOutputDir = gDirectory; if (outfile) FitPar::Config().out = outfile; std::vector samplekeys = Config::QueryKeys("sample"); LoadSamples(samplekeys); std::vector covarkeys = Config::QueryKeys("covar"); LoadPulls(covarkeys); fCurIter = 0; fMCFilled = false; fIterationTree = false; fDialVals = NULL; fNDials = 0; fUsingEventManager = FitPar::Config().GetParB("EventManager"); fOutputDir->cd(); } //*************************************************** JointFCN::JointFCN(std::vector samplekeys, TFile* outfile) { //*************************************************** fOutputDir = gDirectory; if (outfile) FitPar::Config().out = outfile; LoadSamples(samplekeys); fCurIter = 0; fMCFilled = false; fOutputDir->cd(); fIterationTree = false; fDialVals = NULL; fNDials = 0; fUsingEventManager = FitPar::Config().GetParB("EventManager"); fOutputDir->cd(); } //*************************************************** JointFCN::~JointFCN() { //*************************************************** // Delete Samples for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase* exp = *iter; delete exp; } for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull* pull = *iter; delete pull; } // Sort Tree if (fIterationTree) DestroyIterationTree(); if (fDialVals) delete fDialVals; if (fSampleLikes) delete fSampleLikes; }; //*************************************************** void JointFCN::CreateIterationTree(std::string name, FitWeight* rw) { //*************************************************** LOG(FIT) << " Creating new iteration container! " << std::endl; DestroyIterationTree(); fIterationTreeName = name; // Add sample likelihoods and ndof for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase* exp = *iter; std::string name = exp->GetName(); std::string liketag = name + "_likelihood"; fNameValues.push_back(liketag); fCurrentValues.push_back(0.0); std::string ndoftag = name + "_ndof"; fNameValues.push_back(ndoftag); fCurrentValues.push_back(0.0); } // Add Pull terms for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull* pull = *iter; std::string name = pull->GetName(); std::string liketag = name + "_likelihood"; fNameValues.push_back(liketag); fCurrentValues.push_back(0.0); std::string ndoftag = name + "_ndof"; fNameValues.push_back(ndoftag); fCurrentValues.push_back(0.0); } // Add Likelihoods fNameValues.push_back("total_likelihood"); fCurrentValues.push_back(0.0); fNameValues.push_back("total_ndof"); fCurrentValues.push_back(0.0); // Setup Containers fSampleN = fSamples.size() + fPulls.size(); fSampleLikes = new double[fSampleN]; fSampleNDOF = new int[fSampleN]; // Add Dials std::vector dials = rw->GetDialNames(); for (size_t i = 0; i < dials.size(); i++){ fNameValues.push_back( dials[i] ); fCurrentValues.push_back( 0.0 ); } fNDials = dials.size(); fDialVals = new double[fNDials]; // Set IterationTree Flag fIterationTree = true; } //*************************************************** void JointFCN::DestroyIterationTree() { //*************************************************** fIterationCount.clear(); fCurrentValues.clear(); fNameValues.clear(); fIterationValues.clear(); } //*************************************************** void JointFCN::WriteIterationTree() { //*************************************************** LOG(FIT) << "Writing iteration tree" << std::endl; // Make a new TTree TTree* itree = new TTree(fIterationTreeName.c_str(), fIterationTreeName.c_str()); double* vals = new double[fNameValues.size()]; int count = 0; itree->Branch("iteration",&count,"Iteration/I"); for (int i = 0; i < fNameValues.size(); i++) { itree->Branch( fNameValues[i].c_str(), &vals[i], (fNameValues[i] + "/D").c_str() ); } // Fill Iterations for (size_t i = 0; i < fIterationValues.size(); i++){ std::vector itervals = fIterationValues[i]; // Fill iteration state count = fIterationCount[i]; for (size_t j = 0; j < itervals.size(); j++){ vals[j] = itervals[j]; } // Save to TTree itree->Fill(); } // Write to file itree->Write(); } //*************************************************** void JointFCN::FillIterationTree(FitWeight* rw) { //*************************************************** // Loop over samples count int count = 0; for (int i = 0; i < fSampleN; i++){ fCurrentValues[count++] = fSampleLikes[i]; fCurrentValues[count++] = double(fSampleNDOF[i]); } // Fill Totals fCurrentValues[count++] = fLikelihood; fCurrentValues[count++] = double(fNDOF); // Loop Over Parameter Counts rw->GetAllDials(fDialVals, fNDials); for (int i = 0; i < fNDials; i++){ fCurrentValues[count++] = double(fDialVals[i]); } // Push Back Into Container fIterationCount.push_back( fCurIter ); fIterationValues.push_back(fCurrentValues); } //*************************************************** double JointFCN::DoEval(const double* x) { //*************************************************** // WEIGHT ENGINE fDialChanged = FitBase::GetRW()->HasRWDialChanged(x); FitBase::GetRW()->UpdateWeightEngine(x); if (fDialChanged) { FitBase::GetRW()->Reconfigure(); FitBase::EvtManager().ResetWeightFlags(); } if (LOG_LEVEL(REC)) { FitBase::GetRW()->Print(); } // SORT SAMPLES ReconfigureSamples(); // GET TEST STAT fLikelihood = GetLikelihood(); fNDOF = GetNDOF(); // PRINT PROGRESS LOG(FIT) << "Current Stat (iter. " << this->fCurIter << ") = " << fLikelihood << std::endl; // UPDATE TREE if (fIterationTree) FillIterationTree(FitBase::GetRW()); return fLikelihood; } //*************************************************** int JointFCN::GetNDOF() { //*************************************************** int totaldof = 0; int count = 0; // Total number of Free bins in each MC prediction for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase* exp = *iter; int dof = exp->GetNDOF(); // Save Seperate DOF if (fIterationTree) { fSampleNDOF[count] = dof; } // Add to total totaldof += dof; count++; } // Loop over pulls for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull* pull = *iter; double dof = pull->GetLikelihood(); // Save seperate DOF if (fIterationTree) { fSampleNDOF[count] = dof; } // Add to total totaldof += dof; count++; } // Set Data Variable + if (fIterationTree){ fSampleNDOF[count] = totaldof; - + } return totaldof; } //*************************************************** double JointFCN::GetLikelihood() { //*************************************************** LOG(MIN) << std::left << std::setw(43) << "Getting likelihoods..." << " : " << "-2logL" << std::endl; // Loop and add up likelihoods in an uncorrelated way double like = 0.0; int count = 0; for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase* exp = *iter; double newlike = exp->GetLikelihood(); int ndof = exp->GetNDOF(); // Save seperate likelihoods if (fIterationTree) { fSampleLikes[count] = newlike; } LOG(MIN) << "-> " << std::left << std::setw(40) << exp->GetName() << " : " << newlike << "/" << ndof << std::endl; // Add Weight Scaling // like *= FitBase::GetRW()->GetSampleLikelihoodWeight(exp->GetName()); // Add to total like += newlike; count++; } // Loop over pulls for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull* pull = *iter; double newlike = pull->GetLikelihood(); // Save seperate likelihoods if (fIterationTree) { fSampleLikes[count] = newlike; } // Add to total like += newlike; count++; } // Set Data Variable fLikelihood = like; + if (fIterationTree){ + fSampleLikes[count] = fLikelihood; + } return like; }; void JointFCN::LoadSamples(std::vector samplekeys) { LOG(MIN) << "Loading Samples : " << samplekeys.size() << std::endl; for (size_t i = 0; i < samplekeys.size(); i++) { nuiskey key = samplekeys[i]; // Get Sample Options std::string samplename = key.GetS("name"); std::string samplefile = key.GetS("input"); std::string sampletype = key.GetS("type"); std::string fakeData = ""; LOG(MIN) << "Loading Sample : " << samplename << std::endl; fOutputDir->cd(); MeasurementBase* NewLoadedSample = SampleUtils::CreateSample(key); if (!NewLoadedSample) { ERR(FTL) << "Could not load sample provided: " << samplename << std::endl; ERR(FTL) << "Check spelling with that in src/FCN/SampleList.cxx" << std::endl; throw; } else { fSamples.push_back(NewLoadedSample); } } } //*************************************************** void JointFCN::LoadPulls(std::vector pullkeys) { //*************************************************** for (size_t i = 0; i < pullkeys.size(); i++) { nuiskey key = pullkeys[i]; std::string pullname = key.GetS("name"); std::string pullfile = key.GetS("input"); std::string pulltype = key.GetS("type"); fOutputDir->cd(); fPulls.push_back(new ParamPull(pullname, pullfile, pulltype)); } } //*************************************************** void JointFCN::ReconfigureSamples(bool fullconfig) { //*************************************************** int starttime = time(NULL); LOG(REC) << "Starting Reconfigure iter. " << this->fCurIter << std::endl; // std::cout << fUsingEventManager << " " << fullconfig << " " << fMCFilled << // std::endl; // Event Manager Reconf if (fUsingEventManager) { if (!fullconfig and fMCFilled) ReconfigureFastUsingManager(); else ReconfigureUsingManager(); } else { // Loop over all Measurement Classes for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase* exp = *iter; // If RW Either do signal or full reconfigure. if (fDialChanged or !fMCFilled or fullconfig) { if (!fullconfig and fMCFilled) exp->ReconfigureFast(); else exp->Reconfigure(); // If RW Not needed just do normalisation } else { exp->Renormalise(); } } } // Loop over pulls and update for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull* pull = *iter; pull->Reconfigure(); } fMCFilled = true; LOG(MIN) << "Finished Reconfigure iter. " << fCurIter << " in " << time(NULL) - starttime << "s" << std::endl; fCurIter++; } //*************************************************** void JointFCN::ReconfigureSignal() { //*************************************************** ReconfigureSamples(false); } //*************************************************** void JointFCN::ReconfigureAllEvents() { //*************************************************** FitBase::GetRW()->Reconfigure(); FitBase::EvtManager().ResetWeightFlags(); ReconfigureSamples(true); } std::vector JointFCN::GetInputList() { std::vector InputList; fIsAllSplines = true; MeasListConstIter iterSam = fSamples.begin(); for (; iterSam != fSamples.end(); iterSam++) { MeasurementBase* exp = (*iterSam); std::vector subsamples = exp->GetSubSamples(); for (size_t i = 0; i < subsamples.size(); i++) { InputHandlerBase* inp = subsamples[i]->GetInput(); if (std::find(InputList.begin(), InputList.end(), inp) == InputList.end()) { if (subsamples[i]->GetInput()->GetType() != kSPLINEPARAMETER) fIsAllSplines = false; InputList.push_back(subsamples[i]->GetInput()); } } } return InputList; } std::vector JointFCN::GetSubSampleList() { std::vector SampleList; MeasListConstIter iterSam = fSamples.begin(); for (; iterSam != fSamples.end(); iterSam++) { MeasurementBase* exp = (*iterSam); std::vector subsamples = exp->GetSubSamples(); for (size_t i = 0; i < subsamples.size(); i++) { SampleList.push_back(subsamples[i]); } } return SampleList; } //*************************************************** void JointFCN::ReconfigureUsingManager() { //*************************************************** // 'Slow' Event Manager Reconfigure LOG(REC) << "Event Manager Reconfigure" << std::endl; int timestart = time(NULL); // Reset all samples MeasListConstIter iterSam = fSamples.begin(); for (; iterSam != fSamples.end(); iterSam++) { MeasurementBase* exp = (*iterSam); exp->ResetAll(); } // If we are siving signal, reset all containers. bool savesignal = (FitPar::Config().GetParB("SignalReconfigures")); if (savesignal) { // Reset all of our event signal vectors fSignalEventBoxes.clear(); fSignalEventFlags.clear(); fSampleSignalFlags.clear(); fSignalEventSplines.clear(); } // Make sure we have a list of inputs if (fInputList.empty()) { fInputList = GetInputList(); fSubSampleList = GetSubSampleList(); } // If all inputs are splines make sure the readers are told // they need to be reconfigured. std::vector::iterator inp_iter = fInputList.begin(); if (fIsAllSplines) { for (; inp_iter != fInputList.end(); inp_iter++) { InputHandlerBase* curinput = (*inp_iter); // Tell reader in each BaseEvent it needs a Reconfigure next weight calc. BaseFitEvt* curevent = curinput->FirstBaseEvent(); if (curevent->fSplineRead) { curevent->fSplineRead->SetNeedsReconfigure(true); } } } // MAIN INPUT LOOP ==================== int fillcount = 0; int inputcount = 0; inp_iter = fInputList.begin(); // Loop over each input in manager for (; inp_iter != fInputList.end(); inp_iter++) { InputHandlerBase* curinput = (*inp_iter); // Get event information FitEvent* curevent = curinput->FirstNuisanceEvent(); curinput->CreateCache(); int i = 0; int nevents = curinput->GetNEvents(); int countwidth = nevents / 5; // Start event loop iterating until we get a NULL pointer. while (curevent) { // Get Event Weight curevent->RWWeight = FitBase::GetRW()->CalcWeight(curevent); curevent->Weight = curevent->RWWeight * curevent->InputWeight; double rwweight = curevent->Weight; // std::cout << "RWWeight = " << curevent->RWWeight << " " << // curevent->InputWeight << std::endl; // Logging // std::cout << CHECKLOG(1) << std::endl; if (LOGGING(REC)) { if (i % countwidth == 0) { QLOG(REC, curinput->GetName() << " : Processed " << i << " events. [M, W] = [" << curevent->Mode << ", " << rwweight << "]"); } } // Setup flag for if signal found in at least one sample bool foundsignal = false; // Create a new signal bitset for this event std::vector signalbitset(fSubSampleList.size()); // Create a new signal box vector for this event std::vector signalboxes; // Start measurement iterator size_t measitercount = 0; std::vector::iterator meas_iter = fSubSampleList.begin(); // Loop over all subsamples (sub in JointMeas) for (; meas_iter != fSubSampleList.end(); meas_iter++) { MeasurementBase* curmeas = (*meas_iter); // Compare input pointers, to current input, skip if not. // Pointer tells us if it matches without doing ID checks. if (curinput != curmeas->GetInput()) { if (savesignal) { // Set bit to 0 as definitely not signal signalbitset[measitercount] = 0; } // Count up what measurement we are on. measitercount++; // Skip sample as input not signal. continue; } // Fill events for matching inputs. MeasurementVariableBox* box = curmeas->FillVariableBox(curevent); bool signal = curmeas->isSignal(curevent); curmeas->SetSignal(signal); curmeas->FillHistograms(curevent->Weight); // If its Signal tally up fills if (signal) { fillcount++; } // If we are saving signal/splines fill the bitset if (savesignal) { signalbitset[measitercount] = signal; } // If signal save a clone of the event box for use later. if (savesignal and signal) { foundsignal = true; signalboxes.push_back(box->CloneSignalBox()); } // Keep track of Measurement we are on. measitercount++; } // Once we've filled the measurements, if saving signal // push back if any sample flagged this event as signal if (savesignal) { fSignalEventFlags.push_back(foundsignal); } // Save the vector of signal boxes for this event if (savesignal and foundsignal) { fSignalEventBoxes.push_back(signalboxes); fSampleSignalFlags.push_back(signalbitset); } // If all inputs are splines we can save the spline coefficients // for fast in memory reconfigures later. if (fIsAllSplines and savesignal and foundsignal) { // Make temp vector to push back with std::vector coeff; for (size_t l = 0; l < (UInt_t)curevent->fSplineRead->GetNPar(); l++) { coeff.push_back(curevent->fSplineCoeff[l]); } // Push back to signal event splines. Kept in sync with // fSignalEventBoxes size. // int splinecount = fSignalEventSplines.size(); fSignalEventSplines.push_back(coeff); // if (splinecount % 1000 == 0) { // std::cout << "Pushed Back Coeff " << splinecount << " : "; // for (size_t l = 0; l < fSignalEventSplines[splinecount].size(); l++) // { // std::cout << " " << fSignalEventSplines[splinecount][l]; // } // std::cout << std::endl; // } } // Clean up vectors once done with this event signalboxes.clear(); signalbitset.clear(); // Iterate to the next event. curevent = curinput->NextNuisanceEvent(); i++; } curinput->RemoveCache(); // Keep track of what input we are on. inputcount++; } // End of Event Loop =============================== // Now event loop is finished loop over all Measurements // Converting Binned events to XSec Distributions iterSam = fSamples.begin(); for (; iterSam != fSamples.end(); iterSam++) { MeasurementBase* exp = (*iterSam); exp->ConvertEventRates(); } // Print out statements on approximate memory usage for profiling. LOG(REC) << "Filled " << fillcount << " signal events." << std::endl; if (savesignal) { int mem = ( // sizeof(fSignalEventBoxes) + // fSignalEventBoxes.size() * sizeof(fSignalEventBoxes.at(0)) + sizeof(MeasurementVariableBox1D) * fillcount) * 1E-6; LOG(REC) << " -> Saved " << fillcount << " signal boxes for faster access. (~" << mem << " MB)" << std::endl; if (fIsAllSplines and !fSignalEventSplines.empty()) { int splmem = sizeof(float) * fSignalEventSplines.size() * fSignalEventSplines[0].size() * 1E-6; LOG(REC) << " -> Saved " << fillcount << " " << fSignalEventSplines.size() << " spline sets into memory. (~" << splmem << " MB)" << std::endl; } } LOG(REC) << "Time taken ReconfigureUsingManager() : " << time(NULL) - timestart << std::endl; // Check SignalReconfigures works for all samples if (savesignal) { double likefull = GetLikelihood(); ReconfigureFastUsingManager(); double likefast = GetLikelihood(); if (fabs(likefull - likefast) > 0.0001) { ERROR(FTL, "Fast and Full Likelihoods DIFFER! : " << likefull << " : " << likefast); ERROR(FTL, "This means some samples you are using are not setup to use SignalReconfigures=1"); ERROR(FTL, "Please turn OFF signal reconfigures."); throw; } else { LOG(FIT) << "Likelihoods for FULL and FAST match. Will use FAST next time." << std::endl; } } // End of reconfigure return; }; //*************************************************** void JointFCN::ReconfigureFastUsingManager() { //*************************************************** LOG(FIT) << " -> Doing FAST using manager" << std::endl; // Get Start time for profilling int timestart = time(NULL); // Reset all samples MeasListConstIter iterSam = fSamples.begin(); for (; iterSam != fSamples.end(); iterSam++) { MeasurementBase* exp = (*iterSam); exp->ResetAll(); } // Check for saved variables if not do a full reconfigure. if (fSignalEventFlags.empty()) { ERR(WRN) << "Signal Flags Empty! Using normal manager." << std::endl; ReconfigureUsingManager(); return; } bool fFillNuisanceEvent = FitPar::Config().GetParB("FullEventOnSignalReconfigure"); // Setup fast vector iterators. std::vector::iterator inpsig_iter = fSignalEventFlags.begin(); std::vector >::iterator box_iter = fSignalEventBoxes.begin(); std::vector >::iterator spline_iter = fSignalEventSplines.begin(); std::vector >::iterator samsig_iter = fSampleSignalFlags.begin(); int splinecount = 0; // Setup stuff for logging int fillcount = 0; int nevents = fSignalEventFlags.size(); int countwidth = nevents / 20; // If All Splines tell splines they need a reconfigure. std::vector::iterator inp_iter = fInputList.begin(); if (fIsAllSplines) { LOG(REC) << "All Spline Inputs so using fast spline loop." << std::endl; for (; inp_iter != fInputList.end(); inp_iter++) { InputHandlerBase* curinput = (*inp_iter); // Tell each fSplineRead in BaseFitEvent to reconf next weight calc BaseFitEvt* curevent = curinput->FirstBaseEvent(); if (curevent->fSplineRead) curevent->fSplineRead->SetNeedsReconfigure(true); } } // Loop over all possible spline inputs double* coreeventweights = new double[fSignalEventBoxes.size()]; splinecount = 0; inp_iter = fInputList.begin(); inpsig_iter = fSignalEventFlags.begin(); spline_iter = fSignalEventSplines.begin(); // Loop over all signal flags // For each valid signal flag add one to splinecount // Get Splines from that count and add to weight // Add splinecount int sigcount = 0; splinecount = 0; // #pragma omp parallel for shared(splinecount,sigcount) for (uint iinput = 0; iinput < fInputList.size(); iinput++) { InputHandlerBase* curinput = fInputList[iinput]; BaseFitEvt* curevent = curinput->FirstBaseEvent(); for (int i = 0; i < curinput->GetNEvents(); i++) { double rwweight = 0.0; if (fSignalEventFlags[sigcount]) { // Get Event Info if (!fIsAllSplines) { if (fFillNuisanceEvent) curinput->GetNuisanceEvent(i); else curevent = curinput->GetBaseEvent(i); } else { curevent->fSplineCoeff = &fSignalEventSplines[splinecount][0]; } curevent->RWWeight = FitBase::GetRW()->CalcWeight(curevent); curevent->Weight = curevent->RWWeight * curevent->InputWeight; rwweight = curevent->Weight; coreeventweights[splinecount] = rwweight; if (splinecount % countwidth == 0) { LOG(REC) << "Processed " << splinecount << " event weights. W = " << rwweight << std::endl; } // #pragma omp atomic splinecount++; } // #pragma omp atomic sigcount++; } } LOG(SAM) << "Processed event weights." << std::endl; // #pragma omp barrier // Reset Iterators inpsig_iter = fSignalEventFlags.begin(); spline_iter = fSignalEventSplines.begin(); box_iter = fSignalEventBoxes.begin(); samsig_iter = fSampleSignalFlags.begin(); int nsplineweights = splinecount; splinecount = 0; // Start of Fast Event Loop ============================ // Start input iterators // Loop over number of inputs for (int ispline = 0; ispline < nsplineweights; ispline++) { double rwweight = coreeventweights[ispline]; // Get iterators for this event std::vector::iterator subsamsig_iter = (*samsig_iter).begin(); std::vector::iterator subbox_iter = (*box_iter).begin(); // Loop over all sub measurements. std::vector::iterator meas_iter = fSubSampleList.begin(); for (; meas_iter != fSubSampleList.end(); meas_iter++, subsamsig_iter++) { MeasurementBase* curmeas = (*meas_iter); // If event flagged as signal for this sample fill from the box. if (*subsamsig_iter) { curmeas->SetSignal(true); curmeas->FillHistogramsFromBox((*subbox_iter), rwweight); // Move onto next box if there is one. subbox_iter++; fillcount++; } } if (ispline % countwidth == 0) { LOG(REC) << "Filled " << ispline << " sample weights." << std::endl; } // Iterate over the main signal event containers. samsig_iter++; box_iter++; spline_iter++; splinecount++; } // End of Fast Event Loop =================== LOG(SAM) << "Filled sample distributions." << std::endl; // Now loop over all Measurements // Convert Binned events iterSam = fSamples.begin(); for (; iterSam != fSamples.end(); iterSam++) { MeasurementBase* exp = (*iterSam); exp->ConvertEventRates(); } // Cleanup coreeventweights if (fIsAllSplines) { delete coreeventweights; } // Print some reconfigure profiling. LOG(REC) << "Filled " << fillcount << " signal events." << std::endl; LOG(REC) << "Time taken ReconfigureFastUsingManager() : " << time(NULL) - timestart << std::endl; } //*************************************************** void JointFCN::Write() { //*************************************************** // Save a likelihood/ndof plot LOG(MIN) << "Writing likelihood plot.." << std::endl; std::vector likes; std::vector ndofs; std::vector names; for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase* exp = *iter; double like = exp->GetLikelihood(); double ndof = exp->GetNDOF(); std::string name = exp->GetName(); likes.push_back(like); ndofs.push_back(ndof); names.push_back(name); } TH1D likehist = TH1D("likelihood_hist", "likelihood_hist", likes.size(), 0.0, double(likes.size())); TH1D ndofhist = TH1D("ndof_hist", "ndof_hist", ndofs.size(), 0.0, double(ndofs.size())); TH1D divhist = TH1D("likedivndof_hist", "likedivndof_hist", likes.size(), 0.0, double(likes.size())); for (size_t i = 0; i < likehist.GetNbinsX(); i++) { likehist.SetBinContent(i + 1, likes[i]); ndofhist.SetBinContent(i + 1, ndofs[i]); if (ndofs[i] != 0.0) { divhist.SetBinContent(i + 1, likes[i] / ndofs[i]); } likehist.GetXaxis()->SetBinLabel(i + 1, names[i].c_str()); ndofhist.GetXaxis()->SetBinLabel(i + 1, names[i].c_str()); divhist.GetXaxis()->SetBinLabel(i + 1, names[i].c_str()); } likehist.Write(); ndofhist.Write(); divhist.Write(); // Loop over individual experiments and call Write LOG(MIN) << "Writing each of the data classes..." << std::endl; for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase* exp = *iter; exp->Write(); } // Save Pull Terms for (PullListConstIter iter = fPulls.begin(); iter != fPulls.end(); iter++) { ParamPull* pull = *iter; pull->Write(); } if (FitPar::Config().GetParB("EventManager")) { // Get list of inputs std::map fInputs = FitBase::EvtManager().GetInputs(); std::map::const_iterator iterInp; for (iterInp = fInputs.begin(); iterInp != fInputs.end(); iterInp++) { InputHandlerBase* input = (iterInp->second); input->GetFluxHistogram()->Write(); input->GetXSecHistogram()->Write(); input->GetEventHistogram()->Write(); } } }; //*************************************************** void JointFCN::SetFakeData(std::string fakeinput) { //*************************************************** LOG(MIN) << "Setting fake data from " << fakeinput << std::endl; for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase* exp = *iter; exp->SetFakeDataValues(fakeinput); } return; } //*************************************************** void JointFCN::ThrowDataToy() { //*************************************************** for (MeasListConstIter iter = fSamples.begin(); iter != fSamples.end(); iter++) { MeasurementBase* exp = *iter; exp->ThrowDataToy(); } return; } diff --git a/src/FitBase/JointMeas1D.cxx b/src/FitBase/JointMeas1D.cxx index 8374aa4..6700a10 100644 --- a/src/FitBase/JointMeas1D.cxx +++ b/src/FitBase/JointMeas1D.cxx @@ -1,2290 +1,2303 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This ile is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "JointMeas1D.h" //******************************************************************** JointMeas1D::JointMeas1D(void) { //******************************************************************** // XSec Scalings fScaleFactor = -1.0; fCurrentNorm = 1.0; // Histograms fDataHist = NULL; fDataTrue = NULL; fMCHist = NULL; fMCFine = NULL; fMCWeighted = NULL; fMaskHist = NULL; // Covar covar = NULL; fFullCovar = NULL; fCovar = NULL; fInvert = NULL; fDecomp = NULL; // Fake Data fFakeDataInput = ""; fFakeDataFile = NULL; // Options fDefaultTypes = "FIX/FULL/CHI2"; fAllowedTypes = "FIX,FREE,SHAPE/FULL,DIAG/CHI2/NORM/ENUCORR/Q2CORR/ENU1D/MASK"; fIsFix = false; fIsShape = false; fIsFree = false; fIsDiag = false; fIsFull = false; fAddNormPen = false; fIsMask = false; fIsChi2SVD = false; fIsRawEvents = false; fIsDifXSec = false; fIsEnu1D = false; // Inputs fInput = NULL; fRW = NULL; // Extra Histograms fMCHist_Modes = NULL; for (std::vector::const_iterator iter = fSubChain.begin(); iter != fSubChain.end(); iter++) { MeasurementBase* exp = *iter; if (exp) delete exp; } fSubChain.clear(); // Flags for Joint Measurements fIsRatio = false; fIsSummed = false; fSaveSubMeas = false; fIsJoint = true; } //******************************************************************** void JointMeas1D::SetupDefaultHist() { //******************************************************************** // Setup fMCHist fMCHist = (TH1D*)fDataHist->Clone(); fMCHist->SetNameTitle((fName + "_MC").c_str(), (fName + "_MC" + fPlotTitles).c_str()); // Setup fMCFine Int_t nBins = fMCHist->GetNbinsX(); fMCFine = new TH1D( (fName + "_MC_FINE").c_str(), (fName + "_MC_FINE" + fPlotTitles).c_str(), nBins * 6, fMCHist->GetBinLowEdge(1), fMCHist->GetBinLowEdge(nBins + 1)); fMCStat = (TH1D*)fMCHist->Clone(); fMCStat->Reset(); fMCHist->Reset(); fMCFine->Reset(); // Setup the NEUT Mode Array PlotUtils::CreateNeutModeArray((TH1D*)fMCHist, (TH1**)fMCHist_PDG); PlotUtils::ResetNeutModeArray((TH1**)fMCHist_PDG); // Setup bin masks using sample name if (fIsMask) { std::string maskloc = FitPar::Config().GetParDIR(fName + ".mask"); if (maskloc.empty()) { maskloc = FitPar::GetDataBase() + "/masks/" + fName + ".mask"; } SetBinMask(maskloc); } fMCHist_Modes = new TrueModeStack( (fName + "_MODES").c_str(), ("True Channels"), fMCHist); SetAutoProcessTH1(fMCHist_Modes); return; } //******************************************************************** JointMeas1D::~JointMeas1D(void) { //******************************************************************** if (fDataHist) delete fDataHist; if (fDataTrue) delete fDataTrue; if (fMCHist) delete fMCHist; if (fMCFine) delete fMCFine; if (fMCWeighted) delete fMCWeighted; if (fMaskHist) delete fMaskHist; if (covar) delete covar; if (fFullCovar) delete fFullCovar; if (fCovar) delete fCovar; if (fInvert) delete fInvert; if (fDecomp) delete fDecomp; for (std::vector::const_iterator iter = fSubChain.begin(); iter != fSubChain.end(); iter++) { MeasurementBase* exp = *iter; if (exp) delete exp; } fSubChain.clear(); } //******************************************************************** SampleSettings JointMeas1D::LoadSampleSettings(nuiskey samplekey){ //******************************************************************** SampleSettings s = MeasurementBase::LoadSampleSettings(samplekey); // Parse Inputs fSubInFiles.clear(); std::vector entries = GeneralUtils::ParseToStr(s.GetS("input"), ";"); if (entries.size() < 2) { ERR(FTL) << "Joint measurement expected to recieve at least two semi-colon " "separated input files, but recieved: \"" << s.GetS("input") << "\"" << std::endl; throw; } std::vector first_file_descriptor = GeneralUtils::ParseToStr(entries.front(), ":"); if (first_file_descriptor.size() != 2) { ERR(FTL) << "Found Joint measurement where the input file had no type: \"" << s.GetS("input") << "\", expected \"INPUTTYPE:File.root;File2.root\"." << std::endl; throw; } std::string inpType = first_file_descriptor[0]; for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { if (GeneralUtils::ParseToStr(*iter, ":").size() != 2) { std::stringstream ss(""); ss << inpType << ":" << (*iter); fSubInFiles.push_back(ss.str()); } else { fSubInFiles.push_back(*iter); } } return s; } //******************************************************************** void JointMeas1D::FinaliseSampleSettings() { //******************************************************************** // Setup naming + renaming fName = fSettings.GetName(); fSettings.SetS("originalname", fName); if (fSettings.Has("rename")) { fName = fSettings.GetS("rename"); fSettings.SetS("name", fName); } // Setup all other options LOG(SAM) << "Finalising Sample Settings: " << fName << std::endl; if ((fSettings.GetS("originalname").find("Evt") != std::string::npos)) { fIsRawEvents = true; LOG(SAM) << "Found event rate measurement but using poisson likelihoods." << std::endl; } if (fSettings.GetS("originalname").find("XSec_1DEnu") != std::string::npos) { fIsEnu1D = true; LOG(SAM) << "::" << fName << "::" << std::endl; LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, " << "not flux averaged!" << std::endl; } if (fIsEnu1D && fIsRawEvents) { LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this " "really correct?!" << std::endl; LOG(SAM) << "Check experiment constructor for " << fName << " and correct this!" << std::endl; LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl; exit(-1); } // Parse Inputs fSubInFiles.clear(); std::vector entries = GeneralUtils::ParseToStr(fSettings.GetS("input"), ";"); if (entries.size() < 2) { ERR(FTL) << "Joint measurement expected to recieve at least two semi-colon " "separated input files, but recieved: \"" << fSettings.GetS("input") << "\"" << std::endl; throw; } std::vector first_file_descriptor = GeneralUtils::ParseToStr(entries.front(), ":"); if (first_file_descriptor.size() != 2) { ERR(FTL) << "Found Joint measurement where the input file had no type: \"" << fSettings.GetS("input") << "\", expected \"INPUTTYPE:File.root;File2.root\"." << std::endl; throw; } std::string inpType = first_file_descriptor[0]; for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { if (GeneralUtils::ParseToStr(*iter, ":").size() != 2) { std::stringstream ss(""); ss << inpType << ":" << (*iter); fSubInFiles.push_back(ss.str()); } else { fSubInFiles.push_back(*iter); } } // Setup options SetFitOptions(fDefaultTypes); // defaults SetFitOptions(fSettings.GetS("type")); // user specified EnuMin = GeneralUtils::StrToDbl(fSettings.GetS("enu_min")); EnuMax = GeneralUtils::StrToDbl(fSettings.GetS("enu_max")); if (fAddNormPen) { if (fNormError <= 0.0) { ERR(WRN) << "Norm error for class " << fName << " is 0.0!" << std::endl; ERR(WRN) << "If you want to use it please add fNormError=VAL" << std::endl; throw; } } if (!fRW) fRW = FitBase::GetRW(); LOG(SAM) << "Finalised Sample Settings" << std::endl; } //******************************************************************** void JointMeas1D::SetDataFromTextFile(std::string datafile) { //******************************************************************** LOG(SAM) << "Reading data from text file: " << datafile << std::endl; fDataHist = PlotUtils::GetTH1DFromFile(datafile, fSettings.GetName() + "_data", fSettings.GetFullTitles()); } //******************************************************************** void JointMeas1D::SetDataFromRootFile(std::string datafile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading data from root file: " << datafile << ";" << histname << std::endl; fDataHist = PlotUtils::GetTH1DFromRootFile(datafile, histname); fDataHist->SetNameTitle((fSettings.GetName() + "_data").c_str(), (fSettings.GetFullTitles()).c_str()); return; }; //******************************************************************** void JointMeas1D::SetPoissonErrors() { //******************************************************************** if (!fDataHist) { ERR(FTL) << "Need a data hist to setup possion errors! " << std::endl; ERR(FTL) << "Setup Data First!" << std::endl; throw; } for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) { fDataHist->SetBinError(i + 1, sqrt(fDataHist->GetBinContent(i + 1))); } } //******************************************************************** void JointMeas1D::SetCovarFromDiagonal(TH1D* data) { //******************************************************************** if (!data and fDataHist) { data = fDataHist; } if (data) { LOG(SAM) << "Setting diagonal covariance for: " << data->GetName() << std::endl; fFullCovar = StatUtils::MakeDiagonalCovarMatrix(data); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } else { ERR(FTL) << "No data input provided to set diagonal covar from!" << std::endl; } if (!fIsDiag) { ERR(FTL) << "SetCovarMatrixFromDiag called for measurement " << "that is not set as diagonal." << std::endl; throw; } } //******************************************************************** void JointMeas1D::SetCovarFromTextFile(std::string covfile, int dim) { //******************************************************************** LOG(SAM) << "Reading covariance from text file: " << covfile << std::endl; fFullCovar = StatUtils::GetCovarFromTextFile(covfile, dim); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void JointMeas1D::SetCovarFromMultipleTextFiles(std::string covfiles, int dim) { //******************************************************************** if (dim == -1) { dim = fDataHist->GetNbinsX(); } std::vector covList = GeneralUtils::ParseToStr(covfiles, ";"); fFullCovar = new TMatrixDSym(dim); for (uint i = 0; i < covList.size(); ++i){ LOG(SAM) << "Reading covariance from text file: " << covList[i] << std::endl; TMatrixDSym* temp_cov = StatUtils::GetCovarFromTextFile(covList[i], dim); (*fFullCovar) += (*temp_cov); delete temp_cov; } covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void JointMeas1D::SetCovarFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading covariance from text file: " << covfile << ";" << histname << std::endl; fFullCovar = StatUtils::GetCovarFromRootFile(covfile, histname); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void JointMeas1D::SetCovarInvertFromTextFile(std::string covfile, int dim) { //******************************************************************** LOG(SAM) << "Reading inverted covariance from text file: " << covfile << std::endl; covar = StatUtils::GetCovarFromTextFile(covfile, dim); fFullCovar = StatUtils::GetInvert(covar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void JointMeas1D::SetCovarInvertFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading inverted covariance from text file: " << covfile << ";" << histname << std::endl; covar = StatUtils::GetCovarFromRootFile(covfile, histname); fFullCovar = StatUtils::GetInvert(covar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void JointMeas1D::SetCorrelationFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) dim = fDataHist->GetNbinsX(); LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << dim << std::endl; TMatrixDSym* correlation = StatUtils::GetCovarFromTextFile(covfile, dim); if (!fDataHist) { ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n" << "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl; throw; } // Fill covar from data errors and correlations fFullCovar = new TMatrixDSym(dim); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { (*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76; } } // Fill other covars. covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete correlation; } //******************************************************************** void JointMeas1D::SetCorrelationFromMultipleTextFiles(std::string corrfiles, int dim) { //******************************************************************** if (dim == -1) { dim = fDataHist->GetNbinsX(); } std::vector corrList = GeneralUtils::ParseToStr(corrfiles, ";"); fFullCovar = new TMatrixDSym(dim); for (uint i = 0; i < corrList.size(); ++i){ LOG(SAM) << "Reading covariance from text file: " << corrList[i] << std::endl; TMatrixDSym* temp_cov = StatUtils::GetCovarFromTextFile(corrList[i], dim); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { // Note that there is a factor of 1E76 here. It is very silly indeed. // However, if you remove it, you also need to fix the factors of 1E38 added to the chi2 calculations! (*temp_cov)(i, j) = (*temp_cov)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1E76; } } (*fFullCovar) += (*temp_cov); delete temp_cov; } covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void JointMeas1D::SetCorrelationFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << histname << std::endl; TMatrixDSym* correlation = StatUtils::GetCovarFromRootFile(covfile, histname); if (!fDataHist) { ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n" << "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl; throw; } // Fill covar from data errors and correlations fFullCovar = new TMatrixDSym(fDataHist->GetNbinsX()); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { (*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76; } } // Fill other covars. covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete correlation; } +void JointMeas1D::SetShapeCovar(){ + + // Return if this is missing any pre-requisites + if (!fFullCovar) return; + if (!fDataHist) return; + + // Also return if it's bloody stupid under the circumstances + if (fIsDiag) return; + + fShapeCovar = StatUtils::ExtractShapeOnlyCovar(fFullCovar, fDataHist); + return; +} + //******************************************************************** void JointMeas1D::SetCholDecompFromTextFile(std::string covfile, int dim) { //******************************************************************** LOG(SAM) << "Reading cholesky from text file: " << covfile << std::endl; TMatrixD* temp = StatUtils::GetMatrixFromTextFile(covfile, dim, dim); TMatrixD* trans = (TMatrixD*)temp->Clone(); trans->T(); (*trans) *= (*temp); fFullCovar = new TMatrixDSym(dim, trans->GetMatrixArray(), ""); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete temp; delete trans; } //******************************************************************** void JointMeas1D::SetCholDecompFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading cholesky decomp from root file: " << covfile << ";" << histname << std::endl; TMatrixD* temp = StatUtils::GetMatrixFromRootFile(covfile, histname); TMatrixD* trans = (TMatrixD*)temp->Clone(); trans->T(); (*trans) *= (*temp); fFullCovar = new TMatrixDSym(temp->GetNrows(), trans->GetMatrixArray(), ""); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete temp; delete trans; } //******************************************************************** void JointMeas1D::ScaleData(double scale) { //******************************************************************** fDataHist->Scale(scale); } //******************************************************************** void JointMeas1D::ScaleCovar(double scale) { //******************************************************************** (*fFullCovar) *= scale; (*covar) *= 1.0 / scale; (*fDecomp) *= sqrt(scale); } //******************************************************************** void JointMeas1D::SetBinMask(std::string maskfile) { //******************************************************************** if (!fIsMask) return; LOG(SAM) << "Reading bin mask from file: " << maskfile << std::endl; // Create a mask histogram with dim of data int nbins = fDataHist->GetNbinsX(); fMaskHist = new TH1I((fSettings.GetName() + "_BINMASK").c_str(), (fSettings.GetName() + "_BINMASK; Bin; Mask?").c_str(), nbins, 0, nbins); std::string line; std::ifstream mask(maskfile.c_str(), ifstream::in); if (!mask.is_open()) { LOG(FTL) << " Cannot find mask file." << std::endl; throw; } while (std::getline(mask >> std::ws, line, '\n')) { std::vector entries = GeneralUtils::ParseToInt(line, " "); // Skip lines with poorly formatted lines if (entries.size() < 2) { LOG(WRN) << "JointMeas1D::SetBinMask(), couldn't parse line: " << line << std::endl; continue; } // The first index should be the bin number, the second should be the mask // value. int val = 0; if (entries[1] > 0) val = 1; fMaskHist->SetBinContent(entries[0], val); } // Apply masking by setting masked data bins to zero PlotUtils::MaskBins(fDataHist, fMaskHist); return; } //******************************************************************** void JointMeas1D::FinaliseMeasurement() { //******************************************************************** LOG(SAM) << "Finalising Measurement: " << fName << std::endl; // Make sure data is setup if (!fDataHist) { ERR(FTL) << "No data has been setup inside " << fName << " constructor!" << std::endl; throw; } // Make sure covariances are setup if (!fFullCovar) { fIsDiag = true; SetCovarFromDiagonal(fDataHist); } if (!covar) { covar = StatUtils::GetInvert(fFullCovar); } if (!fDecomp) { fDecomp = StatUtils::GetDecomp(fFullCovar); } // Push the diagonals of fFullCovar onto the data histogram // Comment out until scaling is used consistently... - // StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar); + StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, 1E-38); // Setup fMCHist from data fMCHist = (TH1D*)fDataHist->Clone(); fMCHist->SetNameTitle((fSettings.GetName() + "_MC").c_str(), (fSettings.GetFullTitles()).c_str()); fMCHist->Reset(); // Setup fMCFine fMCFine = new TH1D("mcfine", "mcfine", fDataHist->GetNbinsX(), fMCHist->GetBinLowEdge(1), fMCHist->GetBinLowEdge(fDataHist->GetNbinsX() + 1)); fMCFine->SetNameTitle((fSettings.GetName() + "_MC_FINE").c_str(), (fSettings.GetFullTitles()).c_str()); fMCFine->Reset(); // Setup MC Stat fMCStat = (TH1D*)fMCHist->Clone(); fMCStat->Reset(); // Search drawopts for possible types to include by default std::string drawopts = FitPar::Config().GetParS("drawopts"); if (drawopts.find("MODES") != std::string::npos) { fMCHist_Modes = new TrueModeStack( (fSettings.GetName() + "_MODES").c_str(), ("True Channels"), fMCHist); SetAutoProcessTH1(fMCHist_Modes); } // Setup bin masks using sample name if (fIsMask) { std::string curname = fName; std::string origname = fSettings.GetS("originalname"); // Check rename.mask std::string maskloc = FitPar::Config().GetParDIR(curname + ".mask"); // Check origname.mask if (maskloc.empty()) maskloc = FitPar::Config().GetParDIR(origname + ".mask"); // Check database if (maskloc.empty()) { maskloc = FitPar::GetDataBase() + "/masks/" + origname + ".mask"; } // Setup Bin Mask SetBinMask(maskloc); } /* if (fScaleFactor < 0) { ERR(FTL) << "I found a negative fScaleFactor in " << __FILE__ << ":" << __LINE__ << std::endl; ERR(FTL) << "fScaleFactor = " << fScaleFactor << std::endl; ERR(FTL) << "EXITING" << std::endl; throw; } */ // Create and fill Weighted Histogram if (!fMCWeighted) { fMCWeighted = (TH1D*)fMCHist->Clone(); fMCWeighted->SetNameTitle((fName + "_MCWGHTS").c_str(), (fName + "_MCWGHTS" + fPlotTitles).c_str()); fMCWeighted->GetYaxis()->SetTitle("Weighted Events"); } } //******************************************************************** void JointMeas1D::SetFitOptions(std::string opt) { //******************************************************************** // Do nothing if default given if (opt == "DEFAULT") return; // CHECK Conflicting Fit Options std::vector fit_option_allow = GeneralUtils::ParseToStr(fAllowedTypes, "/"); for (UInt_t i = 0; i < fit_option_allow.size(); i++) { std::vector fit_option_section = GeneralUtils::ParseToStr(fit_option_allow.at(i), ","); bool found_option = false; for (UInt_t j = 0; j < fit_option_section.size(); j++) { std::string av_opt = fit_option_section.at(j); if (!found_option and opt.find(av_opt) != std::string::npos) { found_option = true; } else if (found_option and opt.find(av_opt) != std::string::npos) { ERR(FTL) << "ERROR: Conflicting fit options provided: " << opt << std::endl << "Conflicting group = " << fit_option_section.at(i) << std::endl << "You should only supply one of these options in card file." << std::endl; throw; } } } // Check all options are allowed std::vector fit_options_input = GeneralUtils::ParseToStr(opt, "/"); for (UInt_t i = 0; i < fit_options_input.size(); i++) { if (fAllowedTypes.find(fit_options_input.at(i)) == std::string::npos) { ERR(FTL) << "ERROR: Fit Option '" << fit_options_input.at(i) << "' Provided is not allowed for this measurement." << std::endl; ERR(FTL) << "Fit Options should be provided as a '/' seperated list " "(e.g. FREE/DIAG/NORM)" << std::endl; ERR(FTL) << "Available options for " << fName << " are '" << fAllowedTypes << "'" << std::endl; throw; } } // Set TYPE fFitType = opt; // FIX,SHAPE,FREE if (opt.find("FIX") != std::string::npos) { fIsFree = fIsShape = false; fIsFix = true; } else if (opt.find("SHAPE") != std::string::npos) { fIsFree = fIsFix = false; fIsShape = true; } else if (opt.find("FREE") != std::string::npos) { fIsFix = fIsShape = false; fIsFree = true; } // DIAG,FULL (or default to full) if (opt.find("DIAG") != std::string::npos) { fIsDiag = true; fIsFull = false; } else if (opt.find("FULL") != std::string::npos) { fIsDiag = false; fIsFull = true; } // CHI2/LL (OTHERS?) if (opt.find("LOG") != std::string::npos) { fIsChi2 = false; ERR(FTL) << "No other LIKELIHOODS properly supported!" << std::endl; ERR(FTL) << "Try to use a chi2!" << std::endl; throw; } else { fIsChi2 = true; } // EXTRAS if (opt.find("RAW") != std::string::npos) fIsRawEvents = true; if (opt.find("DIF") != std::string::npos) fIsDifXSec = true; if (opt.find("ENU1D") != std::string::npos) fIsEnu1D = true; if (opt.find("NORM") != std::string::npos) fAddNormPen = true; if (opt.find("MASK") != std::string::npos) fIsMask = true; return; }; //******************************************************************** void JointMeas1D::SetSmearingMatrix(std::string smearfile, int truedim, int recodim) { //******************************************************************** // The smearing matrix describes the migration from true bins (rows) to reco // bins (columns) // Counter over the true bins! int row = 0; std::string line; std::ifstream smear(smearfile.c_str(), ifstream::in); // Note that the smearing matrix may be rectangular. fSmearMatrix = new TMatrixD(truedim, recodim); if (smear.is_open()) LOG(SAM) << "Reading smearing matrix from file: " << smearfile << std::endl; else ERR(FTL) << "Smearing matrix provided is incorrect: " << smearfile << std::endl; while (std::getline(smear >> std::ws, line, '\n')) { int column = 0; std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { (*fSmearMatrix)(row, column) = (*iter) / 100.; // Convert to fraction from // percentage (this may not be // general enough) column++; } row++; } return; } //******************************************************************** void JointMeas1D::ApplySmearingMatrix() { //******************************************************************** if (!fSmearMatrix) { ERR(WRN) << fName << ": attempted to apply smearing matrix, but none was set" << std::endl; return; } TH1D* unsmeared = (TH1D*)fMCHist->Clone(); TH1D* smeared = (TH1D*)fMCHist->Clone(); smeared->Reset(); // Loop over reconstructed bins // true = row; reco = column for (int rbin = 0; rbin < fSmearMatrix->GetNcols(); ++rbin) { // Sum up the constributions from all true bins double rBinVal = 0; // Loop over true bins for (int tbin = 0; tbin < fSmearMatrix->GetNrows(); ++tbin) { rBinVal += (*fSmearMatrix)(tbin, rbin) * unsmeared->GetBinContent(tbin + 1); } smeared->SetBinContent(rbin + 1, rBinVal); } fMCHist = (TH1D*)smeared->Clone(); return; } /* Reconfigure LOOP */ //******************************************************************** void JointMeas1D::ResetAll() { //******************************************************************** fMCHist->Reset(); fMCFine->Reset(); fMCStat->Reset(); return; }; //******************************************************************** void JointMeas1D::FillHistograms() { //******************************************************************** if (Signal) { fMCHist->Fill(fXVar, Weight); fMCFine->Fill(fXVar, Weight); fMCStat->Fill(fXVar, 1.0); if (fMCHist_Modes) fMCHist_Modes->Fill(Mode, fXVar, Weight); } return; }; //******************************************************************** void JointMeas1D::ScaleEvents() { //******************************************************************** LOG(FIT) << "Scaling JointMeas1D" << std::endl; // Fill MCWeighted; for (int i = 0; i < fMCHist->GetNbinsX(); i++) { fMCWeighted->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1)); fMCWeighted->SetBinError(i + 1, fMCHist->GetBinError(i + 1)); } // Setup Stat ratios for MC and MC Fine double* statratio = new double[fMCHist->GetNbinsX()]; for (int i = 0; i < fMCHist->GetNbinsX(); i++) { if (fMCHist->GetBinContent(i + 1) != 0) { statratio[i] = fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1); } else { statratio[i] = 0.0; } } double* statratiofine = new double[fMCFine->GetNbinsX()]; for (int i = 0; i < fMCFine->GetNbinsX(); i++) { if (fMCFine->GetBinContent(i + 1) != 0) { statratiofine[i] = fMCFine->GetBinError(i + 1) / fMCFine->GetBinContent(i + 1); } else { statratiofine[i] = 0.0; } } // Scaling for raw event rates if (fIsRawEvents) { double datamcratio = fDataHist->Integral() / fMCHist->Integral(); fMCHist->Scale(datamcratio); fMCFine->Scale(datamcratio); if (fMCHist_Modes) fMCHist_Modes->Scale(datamcratio); // Scaling for XSec as function of Enu } else if (fIsEnu1D) { PlotUtils::FluxUnfoldedScaling(fMCHist, GetFluxHistogram(), GetEventHistogram(), fScaleFactor, fNEvents); PlotUtils::FluxUnfoldedScaling(fMCFine, GetFluxHistogram(), GetEventHistogram(), fScaleFactor, fNEvents); // if (fMCHist_Modes) { // PlotUtils::FluxUnfoldedScaling(fMCHist_Modes, GetFluxHistogram(), // GetEventHistogram(), fScaleFactor, // fNEvents); // } // Any other differential scaling } else { fMCHist->Scale(fScaleFactor, "width"); fMCFine->Scale(fScaleFactor, "width"); if (fMCHist_Modes) fMCHist_Modes->Scale(fScaleFactor, "width"); } // Proper error scaling - ROOT Freaks out with xsec weights sometimes for (int i = 0; i < fMCStat->GetNbinsX(); i++) { fMCHist->SetBinError(i + 1, fMCHist->GetBinContent(i + 1) * statratio[i]); } for (int i = 0; i < fMCFine->GetNbinsX(); i++) { fMCFine->SetBinError(i + 1, fMCFine->GetBinContent(i + 1) * statratiofine[i]); } // Clean up delete statratio; delete statratiofine; return; }; //******************************************************************** void JointMeas1D::ApplyNormScale(double norm) { //******************************************************************** fCurrentNorm = norm; fMCHist->Scale(1.0 / norm); fMCFine->Scale(1.0 / norm); return; }; /* Statistic Functions - Outsources to StatUtils */ //******************************************************************** int JointMeas1D::GetNDOF() { //******************************************************************** int ndof = fDataHist->GetNbinsX(); if (fMaskHist) ndof -= fMaskHist->Integral(); return ndof; } //******************************************************************** double JointMeas1D::GetLikelihood() { //******************************************************************** // If this is for a ratio, there is no data histogram to compare to! if (fNoData || !fDataHist) return 0.; // Apply Masking to MC if Required. if (fIsMask and fMaskHist) { PlotUtils::MaskBins(fMCHist, fMaskHist); } // Sort Shape Scaling double scaleF = 0.0; if (fIsShape) { if (fMCHist->Integral(1, fMCHist->GetNbinsX(), "width")) { scaleF = fDataHist->Integral(1, fDataHist->GetNbinsX(), "width") / fMCHist->Integral(1, fMCHist->GetNbinsX(), "width"); fMCHist->Scale(scaleF); fMCFine->Scale(scaleF); } } // Likelihood Calculation double stat = 0.; if (fIsChi2) { if (fIsRawEvents) { stat = StatUtils::GetChi2FromEventRate(fDataHist, fMCHist, fMaskHist); } else if (fIsDiag) { stat = StatUtils::GetChi2FromDiag(fDataHist, fMCHist, fMaskHist); } else if (!fIsDiag and !fIsRawEvents) { stat = StatUtils::GetChi2FromCov(fDataHist, fMCHist, covar, fMaskHist); } } // Sort Penalty Terms if (fAddNormPen) { double penalty = (1. - fCurrentNorm) * (1. - fCurrentNorm) / (fNormError * fNormError); stat += penalty; } // Return to normal scaling if (fIsShape and !FitPar::Config().GetParB("saveshapescaling")) { fMCHist->Scale(1. / scaleF); fMCFine->Scale(1. / scaleF); } fLikelihood = stat; return stat; } /* Fake Data Functions */ //******************************************************************** void JointMeas1D::SetFakeDataValues(std::string fakeOption) { //******************************************************************** // Setup original/datatrue TH1D* tempdata = (TH1D*) fDataHist->Clone(); if (!fIsFakeData) { fIsFakeData = true; // Make a copy of the original data histogram. if (!fDataOrig) fDataOrig = (TH1D*)fDataHist->Clone((fName + "_data_original").c_str()); } else { ResetFakeData(); } // Setup Inputs fFakeDataInput = fakeOption; LOG(SAM) << "Setting fake data from : " << fFakeDataInput << std::endl; // From MC if (fFakeDataInput.compare("MC") == 0) { fDataHist = (TH1D*)fMCHist->Clone((fName + "_MC").c_str()); // Fake File } else { if (!fFakeDataFile) fFakeDataFile = new TFile(fFakeDataInput.c_str(), "READ"); fDataHist = (TH1D*)fFakeDataFile->Get((fName + "_MC").c_str()); } // Setup Data Hist fDataHist->SetNameTitle((fName + "_FAKE").c_str(), (fName + fPlotTitles).c_str()); // Replace Data True if (fDataTrue) delete fDataTrue; fDataTrue = (TH1D*)fDataHist->Clone(); fDataTrue->SetNameTitle((fName + "_FAKE_TRUE").c_str(), (fName + fPlotTitles).c_str()); // Make a new covariance for fake data hist. int nbins = fDataHist->GetNbinsX(); double alpha_i = 0.0; double alpha_j = 0.0; for (int i = 0; i < nbins; i++) { for (int j = 0; j < nbins; j++) { alpha_i = fDataHist->GetBinContent(i + 1) / tempdata->GetBinContent(i + 1); alpha_j = fDataHist->GetBinContent(j + 1) / tempdata->GetBinContent(j + 1); (*fFullCovar)(i, j) = alpha_i * alpha_j * (*fFullCovar)(i, j); } } // Setup Covariances if (covar) delete covar; covar = StatUtils::GetInvert(fFullCovar); if (fDecomp) delete fDecomp; fDecomp = StatUtils::GetInvert(fFullCovar); delete tempdata; return; }; //******************************************************************** void JointMeas1D::ResetFakeData() { //******************************************************************** if (fIsFakeData) { if (fDataHist) delete fDataHist; fDataHist = (TH1D*)fDataTrue->Clone((fSettings.GetName() + "_FKDAT").c_str()); } } //******************************************************************** void JointMeas1D::ResetData() { //******************************************************************** if (fIsFakeData) { if (fDataHist) delete fDataHist; fDataHist = (TH1D*)fDataOrig->Clone((fSettings.GetName() + "_data").c_str()); } fIsFakeData = false; } //******************************************************************** void JointMeas1D::ThrowCovariance() { //******************************************************************** // Take a fDecomposition and use it to throw the current dataset. // Requires fDataTrue also be set incase used repeatedly. if (fDataHist) delete fDataHist; fDataHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar); return; }; //******************************************************************** void JointMeas1D::ThrowDataToy(){ //******************************************************************** if (!fDataTrue) fDataTrue = (TH1D*) fDataHist->Clone(); if (fMCHist) delete fMCHist; fMCHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar); } /* Access Functions */ //******************************************************************** TH1D* JointMeas1D::GetMCHistogram() { //******************************************************************** if (!fMCHist) return fMCHist; std::ostringstream chi2; chi2 << std::setprecision(5) << this->GetLikelihood(); int linecolor = kRed; int linestyle = 1; int linewidth = 1; int fillcolor = 0; int fillstyle = 1001; if (fSettings.Has("linecolor")) linecolor = fSettings.GetI("linecolor"); if (fSettings.Has("linestyle")) linestyle = fSettings.GetI("linestyle"); if (fSettings.Has("linewidth")) linewidth = fSettings.GetI("linewidth"); if (fSettings.Has("fillcolor")) fillcolor = fSettings.GetI("fillcolor"); if (fSettings.Has("fillstyle")) fillstyle = fSettings.GetI("fillstyle"); fMCHist->SetTitle(chi2.str().c_str()); fMCHist->SetLineColor(linecolor); fMCHist->SetLineStyle(linestyle); fMCHist->SetLineWidth(linewidth); fMCHist->SetFillColor(fillcolor); fMCHist->SetFillStyle(fillstyle); return fMCHist; }; //******************************************************************** TH1D* JointMeas1D::GetDataHistogram() { //******************************************************************** if (!fDataHist) return fDataHist; int datacolor = kBlack; int datastyle = 1; int datawidth = 1; if (fSettings.Has("datacolor")) datacolor = fSettings.GetI("datacolor"); if (fSettings.Has("datastyle")) datastyle = fSettings.GetI("datastyle"); if (fSettings.Has("datawidth")) datawidth = fSettings.GetI("datawidth"); fDataHist->SetLineColor(datacolor); fDataHist->SetLineWidth(datawidth); fDataHist->SetMarkerStyle(datastyle); return fDataHist; }; /* Write Functions */ // Save all the histograms at once //******************************************************************** void JointMeas1D::Write(std::string drawOpt) { //******************************************************************** // Get Draw Options drawOpt = FitPar::Config().GetParS("drawopts"); // Write Settigns if (drawOpt.find("SETTINGS") != std::string::npos){ fSettings.Set("#chi^{2}",fLikelihood); fSettings.Set("NDOF", this->GetNDOF() ); fSettings.Set("#chi^{2}/NDOF", fLikelihood / this->GetNDOF() ); fSettings.Write(); } // Write Data/MC GetDataHistogram()->Write(); GetMCHistogram()->Write(); // Write Fine Histogram if (drawOpt.find("FINE") != std::string::npos) GetFineList().at(0)->Write(); // Write Weighted Histogram if (drawOpt.find("WEIGHTS") != std::string::npos && fMCWeighted) fMCWeighted->Write(); // Save Flux/Evt if no event manager if (!FitPar::Config().GetParB("EventManager")) { if (drawOpt.find("FLUX") != std::string::npos && GetFluxHistogram()) GetFluxHistogram()->Write(); if (drawOpt.find("EVT") != std::string::npos && GetEventHistogram()) GetEventHistogram()->Write(); if (drawOpt.find("XSEC") != std::string::npos && GetEventHistogram()) GetEventHistogram()->Write(); } // Write Mask if (fIsMask && (drawOpt.find("MASK") != std::string::npos)) { fMaskHist->Write(); } // Write Covariances if (drawOpt.find("COV") != std::string::npos && fFullCovar) { PlotUtils::GetFullCovarPlot(fFullCovar, fSettings.GetName()); } if (drawOpt.find("INVCOV") != std::string::npos && covar) { PlotUtils::GetInvCovarPlot(covar, fSettings.GetName()); } if (drawOpt.find("DECOMP") != std::string::npos && fDecomp) { PlotUtils::GetDecompCovarPlot(fDecomp, fSettings.GetName()); } // // Likelihood residual plots // if (drawOpt.find("RESIDUAL") != std::string::npos) { // WriteResidualPlots(); // } // Ratio and Shape Plots if (drawOpt.find("RATIO") != std::string::npos) { WriteRatioPlot(); } if (drawOpt.find("SHAPE") != std::string::npos) { WriteShapePlot(); if (drawOpt.find("RATIO") != std::string::npos) WriteShapeRatioPlot(); } // // RATIO // if (drawOpt.find("CANVMC") != std::string::npos) { // TCanvas* c1 = WriteMCCanvas(fDataHist, fMCHist); // c1->Write(); // delete c1; // } // // PDG // if (drawOpt.find("CANVPDG") != std::string::npos && fMCHist_Modes) { // TCanvas* c2 = WritePDGCanvas(fDataHist, fMCHist, fMCHist_Modes); // c2->Write(); // delete c2; // } // Write Extra Histograms AutoWriteExtraTH1(); WriteExtraHistograms(); if (fSaveSubMeas) { for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; exp->Write(drawOpt); } } // Returning LOG(SAM) << "Written Histograms: " << fName << std::endl; return; } //******************************************************************** void JointMeas1D::WriteRatioPlot() { //******************************************************************** // Setup mc data ratios TH1D* dataRatio = (TH1D*)fDataHist->Clone((fName + "_data_RATIO").c_str()); TH1D* mcRatio = (TH1D*)fMCHist->Clone((fName + "_MC_RATIO").c_str()); // Extra MC Data Ratios for (int i = 0; i < mcRatio->GetNbinsX(); i++) { dataRatio->SetBinContent(i + 1, fDataHist->GetBinContent(i + 1) / fMCHist->GetBinContent(i + 1)); dataRatio->SetBinError(i + 1, fDataHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1)); mcRatio->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1) / fMCHist->GetBinContent(i + 1)); mcRatio->SetBinError(i + 1, fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1)); } // Write ratios mcRatio->Write(); dataRatio->Write(); delete mcRatio; delete dataRatio; } //******************************************************************** void JointMeas1D::WriteShapePlot() { //******************************************************************** TH1D* mcShape = (TH1D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str()); double shapeScale = 1.0; if (fIsRawEvents) { shapeScale = fDataHist->Integral() / fMCHist->Integral(); } else { shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width"); } mcShape->Scale(shapeScale); std::stringstream ss; ss << shapeScale; mcShape->SetTitle(ss.str().c_str()); mcShape->SetLineWidth(3); mcShape->SetLineStyle(7); mcShape->Write(); delete mcShape; } //******************************************************************** void JointMeas1D::WriteShapeRatioPlot() { //******************************************************************** // Get a mcshape histogram TH1D* mcShape = (TH1D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str()); double shapeScale = 1.0; if (fIsRawEvents) { shapeScale = fDataHist->Integral() / fMCHist->Integral(); } else { shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width"); } mcShape->Scale(shapeScale); // Create shape ratio histograms TH1D* mcShapeRatio = (TH1D*)mcShape->Clone((fName + "_MC_SHAPE_RATIO").c_str()); TH1D* dataShapeRatio = (TH1D*)fDataHist->Clone((fName + "_data_SHAPE_RATIO").c_str()); // Divide the histograms mcShapeRatio->Divide(mcShape); dataShapeRatio->Divide(mcShape); // Colour the shape ratio plots mcShapeRatio->SetLineWidth(3); mcShapeRatio->SetLineStyle(7); mcShapeRatio->Write(); dataShapeRatio->Write(); delete mcShapeRatio; delete dataShapeRatio; } // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "JointMeas1D.h" /* Constructor/Deconstuctor */ /* Setup Functions */ //******************************************************************** void JointMeas1D::SetupMeasurement(std::string input, std::string type, FitWeight* rw, std::string fkdt) { //******************************************************************** // For joint samples, input files are given as a semi-colon seperated list. // Parse this list and save it for later, and set up the types etc. if (FitPar::Config().GetParB("EventManager")) { ERR(FTL) << "Event Manager does not yet work with JointMeas1D Samples" << std::endl; ERR(FTL) << "If you want good predictions for " << fName << " then run with it turned off! (-q EventManager=0)" << std::endl; } fSubInFiles.clear(); std::vector entries = GeneralUtils::ParseToStr(input, ";"); if (entries.size() < 2) { ERR(FTL) << "Joint measurement expected to recieve at least two semi-colon " "separated input files, but recieved: \"" << input << "\"" << std::endl; throw; } std::vector first_file_descriptor = GeneralUtils::ParseToStr(entries.front(), ":"); if (first_file_descriptor.size() != 2) { ERR(FTL) << "Found Joint measurement where the input file had no type: \"" << input << "\", expected \"INPUTTYPE:File.root;File2.root\"." << std::endl; throw; } std::string inpType = first_file_descriptor[0]; for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { if (GeneralUtils::ParseToStr(*iter, ":").size() != 2) { std::stringstream ss(""); ss << inpType << ":" << (*iter); fSubInFiles.push_back(ss.str()); } else { fSubInFiles.push_back(*iter); } } // Set Engine and Fake Data fRW = rw; fFakeDataInput = fkdt; // Set Fit Options SetFitOptions(type); return; } /* XSec Functions */ //******************************************************************** double JointMeas1D::TotalIntegratedFlux(std::string intOpt, double low, double high) { //******************************************************************** double totalflux = 0.0; // Destroy the job for sub samples for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; double expflux = exp->TotalIntegratedFlux(intOpt, low, high); // Fill flux options if (fIsRatio) { totalflux = expflux; break; } if (fIsSummed) { totalflux += expflux; } } return totalflux; } /* Reconfigure Functions */ //******************************************************************** void JointMeas1D::Reconfigure() { //******************************************************************** for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; exp->Reconfigure(); } ConvertEventRates(); return; } //******************************************************************** void JointMeas1D::ConvertEventRates() { //******************************************************************** // Apply Event Scaling for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = static_cast(*expIter); exp->ScaleEvents(); } // Joint function called by top level class MakePlots(); // Do Final Normalisation ApplyNormScale(fRW->GetSampleNorm(this->fName)); } //******************************************************************** void JointMeas1D::MakePlots() { //******************************************************************** // Reset the 1D histograms but not the subClasses ResetAll(); // If Summed if (fIsSummed) { for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = static_cast(*expIter); this->fMCHist->Add(exp->GetMCList().at(0)); this->fMCFine->Add(exp->GetFineList().at(0)); } return; } // If Ratio if (fIsRatio) { int sample = 0; for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; if (sample == 0) { this->fMCHist->Add(exp->GetMCList().at(0)); this->fMCFine->Add(exp->GetFineList().at(0)); } else if (sample == 1) { this->fMCHist->Divide(exp->GetMCList().at(0)); this->fMCFine->Divide(exp->GetFineList().at(0)); } else { break; } sample++; } return; } return; } /* Access Functions */ //******************************************************************** std::vector JointMeas1D::GetMCList() { //******************************************************************** // Make Default Vector std::vector tempVect; tempVect.push_back(this->fMCHist); // Return vector from all sub samples for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; std::vector subTempVect = exp->GetMCList(); for (UInt_t i = 0; i < subTempVect.size(); i++) { tempVect.push_back(subTempVect.at(i)); } } return tempVect; } //******************************************************************** std::vector JointMeas1D::GetDataList() { //******************************************************************** // Make Default Vector std::vector tempVect; tempVect.push_back(this->fDataHist); // Return vector from all sub samples for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; std::vector subTempVect = exp->GetDataList(); for (UInt_t i = 0; i < subTempVect.size(); i++) { tempVect.push_back(subTempVect.at(i)); } } return tempVect; } //******************************************************************** std::vector JointMeas1D::GetFineList() { //******************************************************************** // Make Default Vector std::vector tempVect; tempVect.push_back(this->fMCFine); // Return vector from all sub samples for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; std::vector subTempVect = exp->GetFineList(); for (UInt_t i = 0; i < subTempVect.size(); i++) { tempVect.push_back(subTempVect.at(i)); } } return tempVect; } //******************************************************************** std::vector JointMeas1D::GetMaskList() { //******************************************************************** // Make Default Vector std::vector tempVect; tempVect.push_back(this->fMaskHist); // Return vector from all sub samples for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; std::vector subTempVect = exp->GetMaskList(); for (UInt_t i = 0; i < subTempVect.size(); i++) { tempVect.push_back(subTempVect.at(i)); } } return tempVect; } //******************************************************************** std::vector JointMeas1D::GetFluxList() { //******************************************************************** // Make Default Vector std::vector tempVect; tempVect.push_back(MeasurementBase::GetFluxHistogram()); // Return vector from all sub samples for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; std::vector subTempVect = exp->GetFluxList(); for (UInt_t i = 0; i < subTempVect.size(); i++) { tempVect.push_back(subTempVect.at(i)); } } return tempVect; } //******************************************************************** std::vector JointMeas1D::GetEventRateList() { //******************************************************************** // Make Default Vector std::vector tempVect; tempVect.push_back(MeasurementBase::GetEventHistogram()); // Return vector from all sub samples for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; std::vector subTempVect = exp->GetEventRateList(); for (UInt_t i = 0; i < subTempVect.size(); i++) { tempVect.push_back(subTempVect.at(i)); } } return tempVect; } //******************************************************************** std::vector JointMeas1D::GetXSecList() { //******************************************************************** // Make Default Vector std::vector tempVect; tempVect.push_back(MeasurementBase::GetXSecHistogram()); // Return vector from all sub samples for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; std::vector subTempVect = exp->GetXSecList(); for (UInt_t i = 0; i < subTempVect.size(); i++) { tempVect.push_back(subTempVect.at(i)); } } return tempVect; } //******************************************************************** TH1D* JointMeas1D::GetCombinedFlux() { //******************************************************************** TH1D* newflux = NULL; int sample = 0; for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; // Get flux from experiment std::vector fluxVect = exp->GetFluxList(); // Setup newflux if (sample == 0) { newflux = (TH1D*)fluxVect.at(0); newflux->Reset(); } // Add all fluxes for (UInt_t i = 0; i < fluxVect.size(); i++) { newflux->Add((TH1D*)fluxVect.at(i)); sample++; } } if (!newflux){ ERR(FTL) << "No combined flux setup in JointMeas1D" << std::endl; } return newflux; } //******************************************************************** TH1D* JointMeas1D::GetCombinedEventRate() { //******************************************************************** TH1D* newflux = NULL; int sample = 0; for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { MeasurementBase* exp = *expIter; // Get flux from experiment std::vector fluxVect = exp->GetFluxList(); // Setup newflux if (sample == 0) { newflux = (TH1D*)fluxVect.at(0); newflux->Reset(); } // Add all fluxes for (UInt_t i = 0; i < fluxVect.size(); i++) { newflux->Add(fluxVect.at(i)); sample++; } } if (!newflux){ ERR(FTL) << "No combined event rate setup in JointMeas1D" << std::endl; } return newflux; } //******************************************************************** std::vector JointMeas1D::GetSubSamples() { //******************************************************************** std::vector exps; for (std::vector::const_iterator expIter = fSubChain.begin(); expIter != fSubChain.end(); expIter++) { exps.push_back(*expIter); } return exps; } //// CRAP TO BE REMOVED //******************************************************************** void JointMeas1D::SetDataValues(std::string dataFile) { //******************************************************************** // Override this function if the input file isn't in a suitable format LOG(SAM) << "Reading data from: " << dataFile.c_str() << std::endl; fDataHist = PlotUtils::GetTH1DFromFile(dataFile, (fName + "_data"), fPlotTitles); fDataTrue = (TH1D*)fDataHist->Clone(); // Number of data points is number of bins fNDataPointsX = fDataHist->GetXaxis()->GetNbins(); return; }; //******************************************************************** void JointMeas1D::SetDataFromDatabase(std::string inhistfile, std::string histname) { //******************************************************************** LOG(SAM) << "Filling histogram from " << inhistfile << "->" << histname << std::endl; fDataHist = PlotUtils::GetTH1DFromRootFile( (GeneralUtils::GetTopLevelDir() + "/data/" + inhistfile), histname); fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_data").c_str()); return; }; //******************************************************************** void JointMeas1D::SetDataFromFile(std::string inhistfile, std::string histname) { //******************************************************************** LOG(SAM) << "Filling histogram from " << inhistfile << "->" << histname << std::endl; fDataHist = PlotUtils::GetTH1DFromRootFile((inhistfile), histname); fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_data").c_str()); return; }; //******************************************************************** void JointMeas1D::SetCovarMatrix(std::string covarFile) { //******************************************************************** // Covariance function, only really used when reading in the MB Covariances. TFile* tempFile = new TFile(covarFile.c_str(), "READ"); TH2D* covarPlot = new TH2D(); // TH2D* decmpPlot = new TH2D(); TH2D* covarInvPlot = new TH2D(); TH2D* fFullCovarPlot = new TH2D(); std::string covName = ""; std::string covOption = FitPar::Config().GetParS("thrown_covariance"); if (fIsShape || fIsFree) covName = "shp_"; if (fIsDiag) covName += "diag"; else covName += "full"; covarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str()); covarInvPlot = (TH2D*)tempFile->Get((covName + "covinv").c_str()); if (!covOption.compare("SUB")) fFullCovarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str()); else if (!covOption.compare("FULL")) fFullCovarPlot = (TH2D*)tempFile->Get("fullcov"); else ERR(WRN) << "Incorrect thrown_covariance option in parameters." << std::endl; int dim = int(fDataHist->GetNbinsX()); //-this->masked->Integral()); int covdim = int(fDataHist->GetNbinsX()); this->covar = new TMatrixDSym(dim); fFullCovar = new TMatrixDSym(dim); fDecomp = new TMatrixDSym(dim); int row, column = 0; row = 0; column = 0; for (Int_t i = 0; i < covdim; i++) { // if (this->masked->GetBinContent(i+1) > 0) continue; for (Int_t j = 0; j < covdim; j++) { // if (this->masked->GetBinContent(j+1) > 0) continue; (*this->covar)(row, column) = covarPlot->GetBinContent(i + 1, j + 1); (*fFullCovar)(row, column) = fFullCovarPlot->GetBinContent(i + 1, j + 1); column++; } column = 0; row++; } // Set bin errors on data if (!fIsDiag) { StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar); } // Get Deteriminant and inverse matrix // fCovDet = this->covar->Determinant(); TDecompSVD LU = TDecompSVD(*this->covar); this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); return; }; //******************************************************************** // Sets the covariance matrix from a provided file in a text format // scale is a multiplicative pre-factor to apply in the case where the // covariance is given in some unit (e.g. 1E-38) void JointMeas1D::SetCovarMatrixFromText(std::string covarFile, int dim, double scale) { //******************************************************************** // Make a counter to track the line number int row = 0; std::string line; std::ifstream covarread(covarFile.c_str(), ifstream::in); this->covar = new TMatrixDSym(dim); fFullCovar = new TMatrixDSym(dim); if (covarread.is_open()) LOG(SAM) << "Reading covariance matrix from file: " << covarFile << std::endl; else ERR(FTL) << "Covariance matrix provided is incorrect: " << covarFile << std::endl; // Loop over the lines in the file while (std::getline(covarread >> std::ws, line, '\n')) { int column = 0; // Loop over entries and insert them into matrix std::vector entries = GeneralUtils::ParseToDbl(line, " "); if (entries.size() <= 1) { ERR(WRN) << "SetCovarMatrixFromText -> Covariance matrix only has <= 1 " "entries on this line: " << row << std::endl; } for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { (*covar)(row, column) = *iter; (*fFullCovar)(row, column) = *iter; column++; } row++; } covarread.close(); // Scale the actualy covariance matrix by some multiplicative factor (*fFullCovar) *= scale; // Robust matrix inversion method TDecompSVD LU = TDecompSVD(*this->covar); // THIS IS ACTUALLY THE INVERSE COVARIANCE MATRIXA AAAAARGH delete this->covar; this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); // Now need to multiply by the scaling factor // If the covariance (*this->covar) *= 1. / (scale); return; }; //******************************************************************** void JointMeas1D::SetCovarMatrixFromCorrText(std::string corrFile, int dim) { //******************************************************************** // Make a counter to track the line number int row = 0; std::string line; std::ifstream corr(corrFile.c_str(), ifstream::in); this->covar = new TMatrixDSym(dim); this->fFullCovar = new TMatrixDSym(dim); if (corr.is_open()) LOG(SAM) << "Reading and converting correlation matrix from file: " << corrFile << std::endl; else { ERR(FTL) << "Correlation matrix provided is incorrect: " << corrFile << std::endl; exit(-1); } while (std::getline(corr >> std::ws, line, '\n')) { int column = 0; // Loop over entries and insert them into matrix // Multiply by the errors to get the covariance, rather than the correlation // matrix std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { double val = (*iter) * this->fDataHist->GetBinError(row + 1) * 1E38 * this->fDataHist->GetBinError(column + 1) * 1E38; if (val == 0) { ERR(FTL) << "Found a zero value in the covariance matrix, assuming " "this is an error!" << std::endl; exit(-1); } (*this->covar)(row, column) = val; (*this->fFullCovar)(row, column) = val; column++; } row++; } // Robust matrix inversion method TDecompSVD LU = TDecompSVD(*this->covar); delete this->covar; this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); return; }; //******************************************************************** // FullUnits refers to if we have "real" unscaled units in the covariance matrix, e.g. 1E-76. // If this is the case we need to scale it so that the chi2 contribution is correct // NUISANCE internally assumes the covariance matrix has units of 1E76 void JointMeas1D::SetCovarFromDataFile(std::string covarFile, std::string covName, bool FullUnits) { //******************************************************************** LOG(SAM) << "Getting covariance from " << covarFile << "->" << covName << std::endl; TFile* tempFile = new TFile(covarFile.c_str(), "READ"); TH2D* covPlot = (TH2D*)tempFile->Get(covName.c_str()); covPlot->SetDirectory(0); // Scale the covariance matrix if it comes in normal units if (FullUnits) { covPlot->Scale(1.E76); } int dim = covPlot->GetNbinsX(); fFullCovar = new TMatrixDSym(dim); for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { (*fFullCovar)(i, j) = covPlot->GetBinContent(i + 1, j + 1); } } this->covar = (TMatrixDSym*)fFullCovar->Clone(); fDecomp = (TMatrixDSym*)fFullCovar->Clone(); TDecompSVD LU = TDecompSVD(*this->covar); this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); TDecompChol LUChol = TDecompChol(*fDecomp); LUChol.Decompose(); fDecomp = new TMatrixDSym(dim, LU.GetU().GetMatrixArray(), ""); return; }; // std::vector JointMeas1D::GetMCList(void){ // std::vector temp; // return temp; // } // std::vector JointMeas1D::GetDataList(void){ // std::vector temp; // return temp; // } // std::vector JointMeas1D::GetMaskList(void){ // std::vector temp; // return temp; // } // std::vector JointMeas1D::GetFineList(void){ // std::vector temp; // return temp; // } diff --git a/src/FitBase/JointMeas1D.h b/src/FitBase/JointMeas1D.h index a82dab3..cada32a 100644 --- a/src/FitBase/JointMeas1D.h +++ b/src/FitBase/JointMeas1D.h @@ -1,685 +1,688 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #ifndef JOINTMEASUREMENT_1D_H_SEEN #define JOINTMEASUREMENT_1D_H_SEEN /*! * \addtogroup FitBase * @{ */ #include #include #include #include #include #include #include #include #include // ROOT includes #include #include #include #include #include #include #include #include #include #include #include #include #include "Measurement1D.h" // External data fit includes #include "FitEvent.h" #include "FitParameters.h" #include "FitUtils.h" #include "MeasurementBase.h" #include "PlotUtils.h" #include "StatUtils.h" //******************************************************************** /// 1D Measurement base class. Histogram handling is done in this base layer. class JointMeas1D : public MeasurementBase { //******************************************************************** public: /* Constructor/Deconstuctor */ JointMeas1D(void); virtual ~JointMeas1D(void); /* Setup Functions */ SampleSettings LoadSampleSettings(nuiskey samplekey); /// \brief Setup all configs once initialised /// /// Should be called after all configs have been setup inside fSettings container. /// Handles the processing of inputs and setting up of types. /// Replaces the old 'SetupMeasurement' function. void FinaliseSampleSettings(); /// \brief Read 1D data inputs from a text file. /// /// Inputfile should have the format: \n /// low_binedge_1 bin_content_1 bin_error_1 \n /// low_binedge_2 bin_content_2 bin_error_2 \n /// .... .... .... \n /// high_bin_edge_N 0.0 0.0 virtual void SetDataFromTextFile(std::string datafile); /// \brief Read 1D data inputs from a root file. /// /// inhistfile specifies the path to the root file /// histname specifies the name of the histogram. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ';' so that: \n /// 'myhistfile.root;myhistname' \n /// will also work. virtual void SetDataFromRootFile(std::string inhistfile, std::string histname = ""); /// \brief Set data bin errors to sqrt(entries) /// /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST /// /// Sets the data errors as the sqrt of the bin contents /// Should be use for counting experiments virtual void SetPoissonErrors(); /// \brief Make diagonal covariance from data /// /// \warning If no histogram passed, data must be setup first! /// Setup the covariance inputs by taking the data histogram /// errors and setting up a diagonal covariance matrix. /// /// If no data is supplied, fDataHist is used if already set. virtual void SetCovarFromDiagonal(TH1D* data = NULL); /// \brief Read the data covariance from a text file. /// /// Inputfile should have the format: \n /// covariance_11 covariance_12 covariance_13 ... \n /// covariance_21 covariance_22 covariance_23 ... \n /// ... ... ... ... \n /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCovarFromTextFile(std::string covfile, int dim = -1); virtual void SetCovarFromMultipleTextFiles(std::string covfiles, int dim = -1); /// \brief Read the data covariance from a ROOT file. /// /// - covfile specifies the full path to the file /// - histname specifies the name of the covariance object. Both TMatrixDSym and TH2D are supported. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCovarFromRootFile(std::string covfile, std::string histname); /// \brief Read the inverted data covariance from a text file. /// /// Inputfile should have similar format to that shown /// in SetCovarFromTextFile. /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCovarInvertFromTextFile(std::string covfile, int dim = -1); /// \brief Read the inverted data covariance from a ROOT file. /// /// Inputfile should have similar format to that shown /// in SetCovarFromRootFile. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCovarInvertFromRootFile(std::string covfile, std::string histname); /// \brief Read the data correlations from a text file. /// /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST /// /// Inputfile should have similar format to that shown /// in SetCovarFromTextFile. /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCorrelationFromTextFile(std::string covfile, int dim = -1); /// \brief Read the data correlations from multiple text files. /// /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST /// /// Inputfile should have similar format to that shown /// in SetCovarFromTextFile. /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of first covfile. virtual void SetCorrelationFromMultipleTextFiles(std::string corrfiles, int dim = -1); /// \brief Read the data correlations from a ROOT file. /// /// \warning REQUIRES DATA TO BE SET FIRST /// /// Inputfile should have similar format to that shown /// in SetCovarFromRootFile. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCorrelationFromRootFile(std::string covfile, std::string histname); + /// \brief Try to extract a shape-only matrix from the existing covariance + virtual void SetShapeCovar(); /// \brief Read the cholesky decomposed covariance from a text file and turn it into a covariance /// /// Inputfile should have similar format to that shown /// in SetCovarFromTextFile. /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCholDecompFromTextFile(std::string covfile, int dim = -1); /// \brief Read the cholesky decomposed covariance from a ROOT file and turn it into a covariance /// /// Inputfile should have similar format to that shown /// in SetCovarFromRootFile. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCholDecompFromRootFile(std::string covfile, std::string histname); /// \brief Scale the data by some scale factor virtual void ScaleData(double scale); /// \brief Scale the covariaince and its invert/decomp by some scale factor. virtual void ScaleCovar(double scale); /// \brief Setup a bin masking histogram and apply masking to data /// /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST /// /// Reads in a list of bins in a text file to be masked. Format is: \n /// bin_index_1 1 \n /// bin_index_2 1 \n /// bin_index_3 1 \n /// /// If 0 is given then a bin entry will NOT be masked. So for example: \n\n /// 1 1 \n /// 2 1 \n /// 3 0 \n /// 4 1 \n\n /// Will mask only the 1st, 2nd, and 4th bins. /// /// Masking can be turned on by specifiying the MASK option when creating a sample. /// When this is passed NUISANCE will look in the following locations for the mask file: /// - FitPar::Config().GetParS(fName + ".mask") /// - "data/masks/" + fName + ".mask"; virtual void SetBinMask(std::string maskfile); /// \brief Final constructor setup /// \warning Should be called right at the end of the constructor. /// /// Contains a series of checks to ensure the data and inputs have been setup. /// Also creates the MC histograms needed for fitting. virtual void FinaliseMeasurement(); /// \brief Set the current fit options from a string. /// /// This is called twice for each sample, once to set the default /// and once to set the current setting (if anything other than default given) /// /// For this to work properly it requires the default and allowed types to be /// set correctly. These should be specified as a string listing options. /// /// To split up options so that NUISANCE can automatically detect ones that /// are conflicting. Any options seperated with the '/' symbol are non conflicting /// and can be given together, whereas any seperated with the ',' symbol cannot /// be specified by the end user at the same time. /// /// Default Type Examples: /// - DIAG/FIX = Default option will be a diagonal covariance, with FIXED norm. /// - MASK/SHAPE = Default option will be a masked hist, with SHAPE always on. /// /// Allowed Type examples: /// - 'FULL/DIAG/NORM/MASK' = Any of these options can be specified. /// - 'FULL,FREE,SHAPE/MASK/NORM' = User can give either FULL, FREE, or SHAPE as on option. /// MASK and NORM can also be included as options. virtual void SetFitOptions(std::string opt); /* Smearing */ /// \brief Read in smearing matrix from file /// /// Set the smearing matrix from a text file given the size of the matrix virtual void SetSmearingMatrix(std::string smearfile, int truedim, int recodim); /// \brief Apply smearing to MC true to get MC reco /// /// Apply smearing matrix to fMCHist using fSmearingMatrix virtual void ApplySmearingMatrix(void); /* Reconfigure Functions */ /// \brief Create a Measurement1D box /// /// Creates a new 1D variable box containing just fXVar. /// /// This box is the bare minimum required by the JointFCN when /// running fast reconfigures during a routine. /// If for some reason a sample needs extra variables to be saved then /// it should override this function creating its own MeasurementVariableBox /// that contains the extra variables. virtual MeasurementVariableBox* CreateBox() {return new MeasurementVariableBox1D();}; /// \brief Reset all MC histograms /// /// Resets all standard histograms and those registered to auto /// process to zero. /// /// If extra histograms are not included in auto processing, then they must be reset /// by overriding this function and doing it manually if required. virtual void ResetAll(void); /// \brief Fill MC Histograms from XVar /// /// Fill standard histograms using fXVar, Weight read from the variable box. /// /// WARNING : Any extra MC histograms need to be filled by overriding this function, /// even if they have been set to auto process. virtual void FillHistograms(void); // \brief Convert event rates to final histogram /// /// Apply standard scaling procedure to standard mc histograms to convert from /// raw events to xsec prediction. /// /// If any distributions have been set to auto process /// that is done during this function call, and a differential xsec is assumed. /// If that is not the case this function must be overriden. virtual void ScaleEvents(void); /// \brief Scale MC by a factor=1/norm /// /// Apply a simple normalisation scaling if the option FREE or a norm_parameter /// has been specified in the NUISANCE routine. virtual void ApplyNormScale(double norm); /* Statistical Functions */ /// \brief Get Number of degrees of freedom /// /// Returns the number bins inside the data histogram accounting for /// any bin masking applied. virtual int GetNDOF(void); /// \brief Return Data/MC Likelihood at current state /// /// Returns the likelihood of the data given the current MC prediction. /// Diferent likelihoods definitions are used depending on the FitOptions. virtual double GetLikelihood(void); /* Fake Data */ /// \brief Set the fake data values from either a file, or MC /// /// - Setting from a file "path": \n /// When reading from a file the full path must be given to a standard /// nuisance output. The standard MC histogram should have a name that matches /// this sample for it to be read in. /// \n\n /// - Setting from "MC": \n /// If the MC option is given the current MC prediction is used as fake data. virtual void SetFakeDataValues(std::string fakeOption); /// \brief Reset fake data back to starting fake data /// /// Reset the fake data back to original fake data (Reset back to before /// ThrowCovariance was first called) virtual void ResetFakeData(void); /// \brief Reset fake data back to original data /// /// Reset the data histogram back to the true original dataset for this sample /// before any fake data was defined. virtual void ResetData(void); /// \brief Generate fake data by throwing the covariance. /// /// Can be used on fake MC data or just the original dataset. /// Call ResetFakeData or ResetData to return to values before the throw. virtual void ThrowCovariance(void); /// \brief Throw the data by its assigned errors and assign this to MC /// /// Used when creating data toys by assign the MC to this thrown data /// so that the likelihood is calculated between data and thrown data virtual void ThrowDataToy(void); /* Access Functions */ /// \brief Returns nicely formatted MC Histogram /// /// Format options can also be given in the samplesettings: /// - linecolor /// - linestyle /// - linewidth /// - fillcolor /// - fillstyle /// /// So to have a sample line colored differently in the xml cardfile put: \n /// virtual TH1D* GetMCHistogram(void); /// \brief Returns nicely formatted data Histogram /// /// Format options can also be given in the samplesettings: /// - datacolor /// - datastyle /// - datawidth /// /// So to have a sample data colored differently in the xml cardfile put: \n /// virtual TH1D* GetDataHistogram(void); /// \brief Returns a list of all MC histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. virtual std::vector GetMCList(void); /// \brief Returns a list of all Data histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. virtual std::vector GetDataList(void); /// \brief Returns a list of all Mask histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. virtual std::vector GetMaskList(void); /// \brief Returns a list of all Fine histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. virtual std::vector GetFineList(void); /* Write Functions */ /// \brief Save the current state to the current TFile directory \n /// /// Data/MC are both saved by default. /// A range of other histograms can be saved by setting the /// config option 'drawopts'. /// /// Possible options: \n /// - FINE = Write Fine Histogram \n /// - WEIGHTS = Write Weighted MC Histogram (before scaling) \n /// - FLUX = Write Flux Histogram from MC Input \n /// - EVT = Write Event Histogram from MC Input \n /// - XSEC = Write XSec Histogram from MC Input \n /// - MASK = Write Mask Histogram \n /// - COV = Write Covariance Histogram \n /// - INVCOV = Write Inverted Covariance Histogram \n /// - DECMOP = Write Decomp. Covariance Histogram \n /// - RESIDUAL= Write Resudial Histograms \n /// - RATIO = Write Data/MC Ratio Histograms \n /// - SHAPE = Write MC Shape Histograms norm. to Data \n /// - CANVMC = Build MC Canvas Showing Data, MC, Shape \n /// - MODES = Write PDG Stack \n /// - CANVPDG = Build MC Canvas Showing Data, PDGStack \n /// /// So to save a range of these in parameters/config.xml set: \n /// virtual void Write(std::string drawOpt); virtual void WriteRatioPlot(); virtual void WriteShapePlot(); virtual void WriteShapeRatioPlot(); double TotalIntegratedFlux(std::string intOpt, double low, double high); //* // OLD DEFUNCTIONS // /// OLD FUNCTION virtual void SetupMeasurement(std::string input, std::string type, FitWeight* rw, std::string fkdt); /// OLD FUNCTION virtual void SetupDefaultHist(void); /// OLD FUNCTION virtual void SetDataValues(std::string dataFile); /// OLD FUNCTION virtual void SetDataFromFile(std::string inhistfile, std::string histname); /// OLD FUNCTION virtual void SetDataFromDatabase(std::string inhistfile, std::string histname); /// OLD FUNCTION virtual void SetCovarMatrix(std::string covarFile); /// OLD FUNCTION virtual void SetCovarMatrixFromText(std::string covarFile, int dim, double scale = 1.0); /// OLD FUNCTION virtual void SetCovarMatrixFromCorrText(std::string covarFile, int dim); /// OLD FUNCTION virtual void SetCovarFromDataFile(std::string covarFile, std::string covName, bool FullUnits = false); ////// JOINT MEAS1D Functions ////// /* Reconfigure Functions */ /// Call reconfigure on every sub sample virtual void Reconfigure(); /// Stitch the sub sample plots together to make a final fMCHist after /// reconfigure has been called virtual void MakePlots(); virtual std::vector GetSubSamples(); virtual void ConvertEventRates(); /* Access Functions */ virtual std::vector GetFluxList(); virtual std::vector GetEventRateList(); virtual std::vector GetXSecList(); //! Return a flux integrated across all sub samples virtual TH1D* GetCombinedFlux(); //! Return an event rate integrated across all sub samples virtual TH1D* GetCombinedEventRate(); virtual TH1D* GetEventHistogram() { return GetCombinedEventRate(); }; virtual TH1D* GetXSecHistogram() { ERR(WRN) << "XSec histogram not properly implemented for joint measurements."; return MeasurementBase::GetXSecHistogram(); }; virtual TH1D* GetFluxHistogram() { return GetCombinedFlux(); }; protected: // Data TH1D* fDataHist; ///< default data histogram TH1D* fDataOrig; ///< histogram to store original data before throws. TH1D* fDataTrue; ///< histogram to store true dataset std::string fPlotTitles; ///< Plot title x and y for the histograms // MC TH1D* fMCHist; ///< default MC Histogram used in the chi2 fits TH1D* fMCFine; ///< finely binned MC histogram TH1D* fMCStat; ///< histogram with unweighted events to properly calculate TH1D* fMCWeighted; ///< Weighted histogram before xsec scaling TH1I* fMaskHist; ///< Mask histogram for neglecting specific bins TMatrixD* fSmearMatrix; ///< Smearing matrix (note, this is not symmetric) TrueModeStack* fMCHist_Modes; ///< Optional True Mode Stack // Statistical TMatrixDSym* covar; ///< Inverted Covariance TMatrixDSym* fFullCovar; ///< Full Covariance TMatrixDSym* fDecomp; ///< Decomposed Covariance TMatrixDSym* fCorrel; ///< Correlation Matrix + TMatrixDSym* fShapeCovar; ///< Shape-only covariance TMatrixDSym* fCovar; ///< New FullCovar TMatrixDSym* fInvert; ///< New covar double fNormError; ///< Sample norm error // Fake Data bool fIsFakeData; ///< Flag: is the current data fake from MC std::string fFakeDataInput; ///< Input fake data file path TFile* fFakeDataFile; ///< Input fake data file // Fit specific flags std::string fFitType; ///< Current fit type std::string fAllowedTypes; ///< Fit Types Possible std::string fDefaultTypes; ///< Starting Default Fit Types bool fIsShape; ///< Flag : Perform Shape-only fit bool fIsFree; ///< Flag : Perform normalisation free fit bool fIsDiag; ///< Flag : only include uncorrelated diagonal errors bool fIsMask; ///< Flag : Apply bin masking bool fIsRawEvents; ///< Flag : Are bin contents just event rates bool fIsEnu1D; ///< Flag : Perform Flux Unfolded Scaling bool fIsChi2SVD; ///< Flag : Use alternative Chi2 SVD Method (Do not use) bool fAddNormPen; ///< Flag : Add a normalisation penalty term to the chi2. bool fIsFix; ///< Flag : keeping norm fixed bool fIsFull; ///< Flag : using full covariaince bool fIsDifXSec; ///< Flag : creating a dif xsec bool fIsChi2; ///< Flag : using Chi2 over LL methods bool fIsSmeared; ///< Flag : Apply smearing? /// OLD STUFF TO REMOVE TH1D* fMCHist_PDG[61]; ///< REMOVE OLD MC PDG Plot // Arrays for data entries Double_t* fXBins; ///< REMOVE xBin edges Double_t* fDataValues; ///< REMOVE data bin contents Double_t* fDataErrors; ///< REMOVE data bin errors Int_t fNDataPointsX; ///< REMOVE number of data points //// JOINT MEAS1D OBJECTS //// std::vector fSubChain; //!< Vector of experimental classes //! that are the sub measurements std::vector fSubInFiles; //!< vector of input files for each of the sub measurements. bool fIsRatio; //!< Flag: is this sample a hist1/hist2 ratio sample bool fIsSummed; //!< Flag: is this sample a combination hist1 + hist2 bool fSaveSubMeas; //!< Flag: Save each of the histograms from the sub //! samples as well as this joint samples plots double fLikelihood; }; /*! @} */ #endif diff --git a/src/FitBase/Measurement1D.cxx b/src/FitBase/Measurement1D.cxx index 2b0a123..70a03a5 100644 --- a/src/FitBase/Measurement1D.cxx +++ b/src/FitBase/Measurement1D.cxx @@ -1,1870 +1,1896 @@ // Copyright 2016 L. Pickering, P. Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This ile is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "Measurement1D.h" //******************************************************************** Measurement1D::Measurement1D(void) { //******************************************************************** // XSec Scalings fScaleFactor = -1.0; fCurrentNorm = 1.0; // Histograms fDataHist = NULL; fDataTrue = NULL; fMCHist = NULL; fMCFine = NULL; fMCWeighted = NULL; fMaskHist = NULL; // Covar covar = NULL; fFullCovar = NULL; - + fShapeCovar = NULL; + fCovar = NULL; fInvert = NULL; fDecomp = NULL; - + // Fake Data fFakeDataInput = ""; fFakeDataFile = NULL; // Options fDefaultTypes = "FIX/FULL/CHI2"; fAllowedTypes = "FIX,FREE,SHAPE/FULL,DIAG/CHI2/NORM/ENUCORR/Q2CORR/ENU1D/MASK/NOWIDTH"; fIsFix = false; fIsShape = false; fIsFree = false; fIsDiag = false; fIsFull = false; fAddNormPen = false; fIsMask = false; fIsChi2SVD = false; fIsRawEvents = false; fIsNoWidth = false; fIsDifXSec = false; fIsEnu1D = false; // Inputs fInput = NULL; fRW = NULL; // Extra Histograms fMCHist_Modes = NULL; } //******************************************************************** Measurement1D::~Measurement1D(void) { //******************************************************************** if (fDataHist) delete fDataHist; if (fDataTrue) delete fDataTrue; if (fMCHist) delete fMCHist; if (fMCFine) delete fMCFine; if (fMCWeighted) delete fMCWeighted; if (fMaskHist) delete fMaskHist; if (covar) delete covar; if (fFullCovar) delete fFullCovar; + if (fShapeCovar) delete fShapeCovar; if (fCovar) delete fCovar; if (fInvert) delete fInvert; if (fDecomp) delete fDecomp; } //******************************************************************** void Measurement1D::FinaliseSampleSettings() { //******************************************************************** MeasurementBase::FinaliseSampleSettings(); // Setup naming + renaming fName = fSettings.GetName(); fSettings.SetS("originalname", fName); if (fSettings.Has("rename")) { fName = fSettings.GetS("rename"); fSettings.SetS("name", fName); } // Setup all other options LOG(SAM) << "Finalising Sample Settings: " << fName << std::endl; if ((fSettings.GetS("originalname").find("Evt") != std::string::npos)) { fIsRawEvents = true; LOG(SAM) << "Found event rate measurement but using poisson likelihoods." << std::endl; } if (fSettings.GetS("originalname").find("XSec_1DEnu") != std::string::npos) { fIsEnu1D = true; LOG(SAM) << "::" << fName << "::" << std::endl; LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, " << "not flux averaged!" << std::endl; } if (fIsEnu1D && fIsRawEvents) { LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this " "really correct?!" << std::endl; LOG(SAM) << "Check experiment constructor for " << fName << " and correct this!" << std::endl; LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl; exit(-1); } if (!fRW) fRW = FitBase::GetRW(); if (!fInput and !fIsJoint) SetupInputs(fSettings.GetS("input")); // Setup options SetFitOptions(fDefaultTypes); // defaults SetFitOptions(fSettings.GetS("type")); // user specified EnuMin = GeneralUtils::StrToDbl(fSettings.GetS("enu_min")); EnuMax = GeneralUtils::StrToDbl(fSettings.GetS("enu_max")); if (fAddNormPen) { if (fNormError <= 0.0) { ERR(WRN) << "Norm error for class " << fName << " is 0.0!" << std::endl; ERR(WRN) << "If you want to use it please add fNormError=VAL" << std::endl; throw; } } } //******************************************************************** void Measurement1D::CreateDataHistogram(int dimx, double* binx) { //******************************************************************** if (fDataHist) delete fDataHist; fDataHist = new TH1D( (fSettings.GetName() + "_data").c_str(), (fSettings.GetFullTitles()).c_str(), dimx, binx) ; } //******************************************************************** void Measurement1D::SetDataFromTextFile(std::string datafile) { //******************************************************************** LOG(SAM) << "Reading data from text file: " << datafile << std::endl; fDataHist = PlotUtils::GetTH1DFromFile(datafile, fSettings.GetName() + "_data", fSettings.GetFullTitles()); } //******************************************************************** void Measurement1D::SetDataFromRootFile(std::string datafile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading data from root file: " << datafile << ";" << histname << std::endl; fDataHist = PlotUtils::GetTH1DFromRootFile(datafile, histname); fDataHist->SetNameTitle((fSettings.GetName() + "_data").c_str(), (fSettings.GetFullTitles()).c_str()); return; }; //******************************************************************** void Measurement1D::SetEmptyData(){ //******************************************************************** fDataHist = new TH1D("EMPTY_DATA","EMPTY_DATA",1,0.0,1.0); } //******************************************************************** void Measurement1D::SetPoissonErrors() { //******************************************************************** if (!fDataHist) { ERR(FTL) << "Need a data hist to setup possion errors! " << std::endl; ERR(FTL) << "Setup Data First!" << std::endl; throw; } for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) { fDataHist->SetBinError(i + 1, sqrt(fDataHist->GetBinContent(i + 1))); } } //******************************************************************** void Measurement1D::SetCovarFromDiagonal(TH1D* data) { //******************************************************************** if (!data and fDataHist) { data = fDataHist; } if (data) { LOG(SAM) << "Setting diagonal covariance for: " << data->GetName() << std::endl; fFullCovar = StatUtils::MakeDiagonalCovarMatrix(data); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } else { ERR(FTL) << "No data input provided to set diagonal covar from!" << std::endl; } // if (!fIsDiag) { // ERR(FTL) << "SetCovarMatrixFromDiag called for measurement " // << "that is not set as diagonal." << std::endl; // throw; // } } //******************************************************************** void Measurement1D::SetCovarFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) { dim = fDataHist->GetNbinsX(); } LOG(SAM) << "Reading covariance from text file: " << covfile << std::endl; fFullCovar = StatUtils::GetCovarFromTextFile(covfile, dim); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement1D::SetCovarFromMultipleTextFiles(std::string covfiles, int dim) { //******************************************************************** if (dim == -1) { dim = fDataHist->GetNbinsX(); } std::vector covList = GeneralUtils::ParseToStr(covfiles, ";"); fFullCovar = new TMatrixDSym(dim); for (uint i = 0; i < covList.size(); ++i){ LOG(SAM) << "Reading covariance from text file: " << covList[i] << std::endl; TMatrixDSym* temp_cov = StatUtils::GetCovarFromTextFile(covList[i], dim); (*fFullCovar) += (*temp_cov); delete temp_cov; } covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement1D::SetCovarFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading covariance from text file: " << covfile << ";" << histname << std::endl; fFullCovar = StatUtils::GetCovarFromRootFile(covfile, histname); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement1D::SetCovarInvertFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) { dim = fDataHist->GetNbinsX(); } LOG(SAM) << "Reading inverted covariance from text file: " << covfile << std::endl; covar = StatUtils::GetCovarFromTextFile(covfile, dim); fFullCovar = StatUtils::GetInvert(covar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement1D::SetCovarInvertFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading inverted covariance from text file: " << covfile << ";" << histname << std::endl; covar = StatUtils::GetCovarFromRootFile(covfile, histname); fFullCovar = StatUtils::GetInvert(covar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement1D::SetCorrelationFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) dim = fDataHist->GetNbinsX(); LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << dim << std::endl; TMatrixDSym* correlation = StatUtils::GetCovarFromTextFile(covfile, dim); if (!fDataHist) { ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n" << "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl; throw; } // Fill covar from data errors and correlations fFullCovar = new TMatrixDSym(dim); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { (*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76; } } // Fill other covars. covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete correlation; } //******************************************************************** void Measurement1D::SetCorrelationFromMultipleTextFiles(std::string corrfiles, int dim) { //******************************************************************** if (dim == -1) { dim = fDataHist->GetNbinsX(); } std::vector corrList = GeneralUtils::ParseToStr(corrfiles, ";"); fFullCovar = new TMatrixDSym(dim); for (uint i = 0; i < corrList.size(); ++i){ LOG(SAM) << "Reading covariance from text file: " << corrList[i] << std::endl; TMatrixDSym* temp_cov = StatUtils::GetCovarFromTextFile(corrList[i], dim); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { (*temp_cov)(i, j) = (*temp_cov)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76; } } (*fFullCovar) += (*temp_cov); delete temp_cov; } covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement1D::SetCorrelationFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << histname << std::endl; TMatrixDSym* correlation = StatUtils::GetCovarFromRootFile(covfile, histname); if (!fDataHist) { ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n" << "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl; throw; } // Fill covar from data errors and correlations fFullCovar = new TMatrixDSym(fDataHist->GetNbinsX()); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { (*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76; } } // Fill other covars. covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete correlation; } //******************************************************************** void Measurement1D::SetCholDecompFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) { dim = fDataHist->GetNbinsX(); } LOG(SAM) << "Reading cholesky from text file: " << covfile << std::endl; TMatrixD* temp = StatUtils::GetMatrixFromTextFile(covfile, dim, dim); TMatrixD* trans = (TMatrixD*)temp->Clone(); trans->T(); (*trans) *= (*temp); fFullCovar = new TMatrixDSym(dim, trans->GetMatrixArray(), ""); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete temp; delete trans; } //******************************************************************** void Measurement1D::SetCholDecompFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading cholesky decomp from root file: " << covfile << ";" << histname << std::endl; TMatrixD* temp = StatUtils::GetMatrixFromRootFile(covfile, histname); TMatrixD* trans = (TMatrixD*)temp->Clone(); trans->T(); (*trans) *= (*temp); fFullCovar = new TMatrixDSym(temp->GetNrows(), trans->GetMatrixArray(), ""); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete temp; delete trans; } +void Measurement1D::SetShapeCovar(){ + + // Return if this is missing any pre-requisites + if (!fFullCovar) return; + if (!fDataHist) return; + + // Also return if it's bloody stupid under the circumstances + if (fIsDiag) return; + + fShapeCovar = StatUtils::ExtractShapeOnlyCovar(fFullCovar, fDataHist); + return; +} //******************************************************************** void Measurement1D::ScaleData(double scale) { //******************************************************************** fDataHist->Scale(scale); } //******************************************************************** void Measurement1D::ScaleDataErrors(double scale) { //******************************************************************** for (int i = 0; i < fDataHist->GetNbinsX(); i++) { fDataHist->SetBinError(i + 1, fDataHist->GetBinError(i + 1) * scale); } } //******************************************************************** void Measurement1D::ScaleCovar(double scale) { //******************************************************************** (*fFullCovar) *= scale; (*covar) *= 1.0 / scale; (*fDecomp) *= sqrt(scale); } //******************************************************************** void Measurement1D::SetBinMask(std::string maskfile) { //******************************************************************** if (!fIsMask) return; LOG(SAM) << "Reading bin mask from file: " << maskfile << std::endl; // Create a mask histogram with dim of data int nbins = fDataHist->GetNbinsX(); fMaskHist = new TH1I((fSettings.GetName() + "_BINMASK").c_str(), (fSettings.GetName() + "_BINMASK; Bin; Mask?").c_str(), nbins, 0, nbins); std::string line; std::ifstream mask(maskfile.c_str(), ifstream::in); if (!mask.is_open()) { LOG(FTL) << " Cannot find mask file." << std::endl; throw; } while (std::getline(mask >> std::ws, line, '\n')) { std::vector entries = GeneralUtils::ParseToInt(line, " "); // Skip lines with poorly formatted lines if (entries.size() < 2) { LOG(WRN) << "Measurement1D::SetBinMask(), couldn't parse line: " << line << std::endl; continue; } // The first index should be the bin number, the second should be the mask // value. int val = 0; if (entries[1] > 0) val = 1; fMaskHist->SetBinContent(entries[0], val); } // Apply masking by setting masked data bins to zero PlotUtils::MaskBins(fDataHist, fMaskHist); return; } //******************************************************************** void Measurement1D::FinaliseMeasurement() { //******************************************************************** LOG(SAM) << "Finalising Measurement: " << fName << std::endl; if (fSettings.GetB("onlymc")){ if (fDataHist) delete fDataHist; fDataHist = new TH1D("empty_data","empty_data",1,0.0,1.0); } // Make sure data is setup if (!fDataHist) { ERR(FTL) << "No data has been setup inside " << fName << " constructor!" << std::endl; throw; } // Make sure covariances are setup if (!fFullCovar) { fIsDiag = true; SetCovarFromDiagonal(fDataHist); } if (!covar) { covar = StatUtils::GetInvert(fFullCovar); } if (!fDecomp) { fDecomp = StatUtils::GetDecomp(fFullCovar); } // Push the diagonals of fFullCovar onto the data histogram // Comment this out until the covariance/data scaling is consistent! - // StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar); + StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, 1E-38); + + // If shape only, set covar and fDecomp using the shape-only matrix (if set) + if (fIsShape && fShapeCovar){ + if (covar) delete covar; + covar = StatUtils::GetInvert(fShapeCovar); + if (fDecomp) delete fDecomp; + fDecomp = StatUtils::GetDecomp(fFullCovar); + } // Setup fMCHist from data fMCHist = (TH1D*)fDataHist->Clone(); fMCHist->SetNameTitle((fSettings.GetName() + "_MC").c_str(), (fSettings.GetFullTitles()).c_str()); fMCHist->Reset(); // Setup fMCFine fMCFine = new TH1D("mcfine", "mcfine", fDataHist->GetNbinsX() * 8, fMCHist->GetBinLowEdge(1), fMCHist->GetBinLowEdge(fDataHist->GetNbinsX() + 1)); fMCFine->SetNameTitle((fSettings.GetName() + "_MC_FINE").c_str(), (fSettings.GetFullTitles()).c_str()); fMCFine->Reset(); // Setup MC Stat fMCStat = (TH1D*)fMCHist->Clone(); fMCStat->Reset(); // Search drawopts for possible types to include by default std::string drawopts = FitPar::Config().GetParS("drawopts"); if (drawopts.find("MODES") != std::string::npos) { fMCHist_Modes = new TrueModeStack( (fSettings.GetName() + "_MODES").c_str(), ("True Channels"), fMCHist); SetAutoProcessTH1(fMCHist_Modes, kCMD_Reset, kCMD_Norm, kCMD_Write); } // Setup bin masks using sample name if (fIsMask) { std::string curname = fName; std::string origname = fSettings.GetS("originalname"); // Check rename.mask std::string maskloc = FitPar::Config().GetParDIR(curname + ".mask"); // Check origname.mask if (maskloc.empty()) maskloc = FitPar::Config().GetParDIR(origname + ".mask"); // Check database if (maskloc.empty()) { maskloc = FitPar::GetDataBase() + "/masks/" + origname + ".mask"; } // Setup Bin Mask SetBinMask(maskloc); } if (fScaleFactor < 0) { ERR(FTL) << "I found a negative fScaleFactor in " << __FILE__ << ":" << __LINE__ << std::endl; ERR(FTL) << "fScaleFactor = " << fScaleFactor << std::endl; ERR(FTL) << "EXITING" << std::endl; throw; } // Create and fill Weighted Histogram if (!fMCWeighted) { fMCWeighted = (TH1D*)fMCHist->Clone(); fMCWeighted->SetNameTitle((fName + "_MCWGHTS").c_str(), (fName + "_MCWGHTS" + fPlotTitles).c_str()); fMCWeighted->GetYaxis()->SetTitle("Weighted Events"); } } //******************************************************************** void Measurement1D::SetFitOptions(std::string opt) { //******************************************************************** // Do nothing if default given if (opt == "DEFAULT") return; // CHECK Conflicting Fit Options std::vector fit_option_allow = GeneralUtils::ParseToStr(fAllowedTypes, "/"); for (UInt_t i = 0; i < fit_option_allow.size(); i++) { std::vector fit_option_section = GeneralUtils::ParseToStr(fit_option_allow.at(i), ","); bool found_option = false; for (UInt_t j = 0; j < fit_option_section.size(); j++) { std::string av_opt = fit_option_section.at(j); if (!found_option and opt.find(av_opt) != std::string::npos) { found_option = true; } else if (found_option and opt.find(av_opt) != std::string::npos) { ERR(FTL) << "ERROR: Conflicting fit options provided: " << opt << std::endl << "Conflicting group = " << fit_option_section.at(i) << std::endl << "You should only supply one of these options in card file." << std::endl; throw; } } } // Check all options are allowed std::vector fit_options_input = GeneralUtils::ParseToStr(opt, "/"); for (UInt_t i = 0; i < fit_options_input.size(); i++) { if (fAllowedTypes.find(fit_options_input.at(i)) == std::string::npos) { ERR(FTL) << "ERROR: Fit Option '" << fit_options_input.at(i) << "' Provided is not allowed for this measurement." << std::endl; ERR(FTL) << "Fit Options should be provided as a '/' seperated list " "(e.g. FREE/DIAG/NORM)" << std::endl; ERR(FTL) << "Available options for " << fName << " are '" << fAllowedTypes << "'" << std::endl; throw; } } // Set TYPE fFitType = opt; // FIX,SHAPE,FREE if (opt.find("FIX") != std::string::npos) { fIsFree = fIsShape = false; fIsFix = true; } else if (opt.find("SHAPE") != std::string::npos) { fIsFree = fIsFix = false; fIsShape = true; } else if (opt.find("FREE") != std::string::npos) { fIsFix = fIsShape = false; fIsFree = true; } // DIAG,FULL (or default to full) if (opt.find("DIAG") != std::string::npos) { fIsDiag = true; fIsFull = false; } else if (opt.find("FULL") != std::string::npos) { fIsDiag = false; fIsFull = true; } // CHI2/LL (OTHERS?) if (opt.find("LOG") != std::string::npos) { fIsChi2 = false; ERR(FTL) << "No other LIKELIHOODS properly supported!" << std::endl; ERR(FTL) << "Try to use a chi2!" << std::endl; throw; } else { fIsChi2 = true; } // EXTRAS if (opt.find("RAW") != std::string::npos) fIsRawEvents = true; if (opt.find("NOWIDTH") != std::string::npos) fIsNoWidth = true; if (opt.find("DIF") != std::string::npos) fIsDifXSec = true; if (opt.find("ENU1D") != std::string::npos) fIsEnu1D = true; if (opt.find("NORM") != std::string::npos) fAddNormPen = true; if (opt.find("MASK") != std::string::npos) fIsMask = true; return; }; //******************************************************************** void Measurement1D::SetSmearingMatrix(std::string smearfile, int truedim, int recodim) { //******************************************************************** // The smearing matrix describes the migration from true bins (rows) to reco // bins (columns) // Counter over the true bins! int row = 0; std::string line; std::ifstream smear(smearfile.c_str(), ifstream::in); // Note that the smearing matrix may be rectangular. fSmearMatrix = new TMatrixD(truedim, recodim); if (smear.is_open()) LOG(SAM) << "Reading smearing matrix from file: " << smearfile << std::endl; else ERR(FTL) << "Smearing matrix provided is incorrect: " << smearfile << std::endl; while (std::getline(smear >> std::ws, line, '\n')) { int column = 0; std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { (*fSmearMatrix)(row, column) = (*iter) / 100.; // Convert to fraction from // percentage (this may not be // general enough) column++; } row++; } return; } //******************************************************************** void Measurement1D::ApplySmearingMatrix() { //******************************************************************** if (!fSmearMatrix) { ERR(WRN) << fName << ": attempted to apply smearing matrix, but none was set" << std::endl; return; } TH1D* unsmeared = (TH1D*)fMCHist->Clone(); TH1D* smeared = (TH1D*)fMCHist->Clone(); smeared->Reset(); // Loop over reconstructed bins // true = row; reco = column for (int rbin = 0; rbin < fSmearMatrix->GetNcols(); ++rbin) { // Sum up the constributions from all true bins double rBinVal = 0; // Loop over true bins for (int tbin = 0; tbin < fSmearMatrix->GetNrows(); ++tbin) { rBinVal += (*fSmearMatrix)(tbin, rbin) * unsmeared->GetBinContent(tbin + 1); } smeared->SetBinContent(rbin + 1, rBinVal); } fMCHist = (TH1D*)smeared->Clone(); return; } /* Reconfigure LOOP */ //******************************************************************** void Measurement1D::ResetAll() { //******************************************************************** fMCHist->Reset(); fMCFine->Reset(); fMCStat->Reset(); return; }; //******************************************************************** void Measurement1D::FillHistograms() { //******************************************************************** if (Signal) { fMCHist->Fill(fXVar, Weight); fMCFine->Fill(fXVar, Weight); fMCStat->Fill(fXVar, 1.0); if (fMCHist_Modes) fMCHist_Modes->Fill(Mode, fXVar, Weight); } return; }; //******************************************************************** void Measurement1D::ScaleEvents() { //******************************************************************** // Fill MCWeighted; // for (int i = 0; i < fMCHist->GetNbinsX(); i++) { // fMCWeighted->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1)); // fMCWeighted->SetBinError(i + 1, fMCHist->GetBinError(i + 1)); // } // Setup Stat ratios for MC and MC Fine double* statratio = new double[fMCHist->GetNbinsX()]; for (int i = 0; i < fMCHist->GetNbinsX(); i++) { if (fMCHist->GetBinContent(i + 1) != 0) { statratio[i] = fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1); } else { statratio[i] = 0.0; } } double* statratiofine = new double[fMCFine->GetNbinsX()]; for (int i = 0; i < fMCFine->GetNbinsX(); i++) { if (fMCFine->GetBinContent(i + 1) != 0) { statratiofine[i] = fMCFine->GetBinError(i + 1) / fMCFine->GetBinContent(i + 1); } else { statratiofine[i] = 0.0; } } // Scaling for raw event rates if (fIsRawEvents) { double datamcratio = fDataHist->Integral() / fMCHist->Integral(); fMCHist->Scale(datamcratio); fMCFine->Scale(datamcratio); if (fMCHist_Modes) fMCHist_Modes->Scale(datamcratio); // Scaling for XSec as function of Enu } else if (fIsEnu1D) { PlotUtils::FluxUnfoldedScaling(fMCHist, GetFluxHistogram(), GetEventHistogram(), fScaleFactor, fNEvents); PlotUtils::FluxUnfoldedScaling(fMCFine, GetFluxHistogram(), GetEventHistogram(), fScaleFactor, fNEvents); // if (fMCHist_Modes) { // PlotUtils::FluxUnfoldedScaling(fMCHist_Modes, GetFluxHistogram(), // GetEventHistogram(), fScaleFactor, // fNEvents); // } } else if (fIsNoWidth) { fMCHist->Scale(fScaleFactor); fMCFine->Scale(fScaleFactor); if (fMCHist_Modes) fMCHist_Modes->Scale(fScaleFactor); // Any other differential scaling } else { fMCHist->Scale(fScaleFactor, "width"); fMCFine->Scale(fScaleFactor, "width"); if (fMCHist_Modes) fMCHist_Modes->Scale(fScaleFactor, "width"); } // Proper error scaling - ROOT Freaks out with xsec weights sometimes for (int i = 0; i < fMCStat->GetNbinsX(); i++) { fMCHist->SetBinError(i + 1, fMCHist->GetBinContent(i + 1) * statratio[i]); } for (int i = 0; i < fMCFine->GetNbinsX(); i++) { fMCFine->SetBinError(i + 1, fMCFine->GetBinContent(i + 1) * statratiofine[i]); } // Clean up delete statratio; delete statratiofine; return; }; //******************************************************************** void Measurement1D::ApplyNormScale(double norm) { //******************************************************************** fCurrentNorm = norm; fMCHist->Scale(1.0 / norm); fMCFine->Scale(1.0 / norm); return; }; /* Statistic Functions - Outsources to StatUtils */ //******************************************************************** int Measurement1D::GetNDOF() { //******************************************************************** int ndof = fDataHist->GetNbinsX(); if (fMaskHist and fIsMask) ndof -= fMaskHist->Integral(); return ndof; } //******************************************************************** double Measurement1D::GetLikelihood() { //******************************************************************** // If this is for a ratio, there is no data histogram to compare to! if (fNoData || !fDataHist) return 0.; // Apply Masking to MC if Required. if (fIsMask and fMaskHist) { PlotUtils::MaskBins(fMCHist, fMaskHist); } // Sort Shape Scaling double scaleF = 0.0; // TODO Include !fIsRawEvents if (fIsShape) { if (fMCHist->Integral(1, fMCHist->GetNbinsX(), "width")) { scaleF = fDataHist->Integral(1, fDataHist->GetNbinsX(), "width") / fMCHist->Integral(1, fMCHist->GetNbinsX(), "width"); fMCHist->Scale(scaleF); fMCFine->Scale(scaleF); } } // Likelihood Calculation double stat = 0.; if (fIsChi2) { if (fIsRawEvents) { stat = StatUtils::GetChi2FromEventRate(fDataHist, fMCHist, fMaskHist); } else if (fIsDiag) { stat = StatUtils::GetChi2FromDiag(fDataHist, fMCHist, fMaskHist); } else if (!fIsDiag and !fIsRawEvents) { stat = StatUtils::GetChi2FromCov(fDataHist, fMCHist, covar, fMaskHist); } } // Sort Penalty Terms if (fAddNormPen) { double penalty = (1. - fCurrentNorm) * (1. - fCurrentNorm) / (fNormError * fNormError); stat += penalty; } // Return to normal scaling if (fIsShape) { // and !FitPar::Config().GetParB("saveshapescaling")) { fMCHist->Scale(1. / scaleF); fMCFine->Scale(1. / scaleF); } fLikelihood = stat; return stat; } /* Fake Data Functions */ //******************************************************************** void Measurement1D::SetFakeDataValues(std::string fakeOption) { //******************************************************************** // Setup original/datatrue TH1D* tempdata = (TH1D*) fDataHist->Clone(); if (!fIsFakeData) { fIsFakeData = true; // Make a copy of the original data histogram. if (!fDataOrig) fDataOrig = (TH1D*)fDataHist->Clone((fName + "_data_original").c_str()); } else { ResetFakeData(); } // Setup Inputs fFakeDataInput = fakeOption; LOG(SAM) << "Setting fake data from : " << fFakeDataInput << std::endl; // From MC if (fFakeDataInput.compare("MC") == 0) { fDataHist = (TH1D*)fMCHist->Clone((fName + "_MC").c_str()); // Fake File } else { if (!fFakeDataFile) fFakeDataFile = new TFile(fFakeDataInput.c_str(), "READ"); fDataHist = (TH1D*)fFakeDataFile->Get((fName + "_MC").c_str()); } // Setup Data Hist fDataHist->SetNameTitle((fName + "_FAKE").c_str(), (fName + fPlotTitles).c_str()); // Replace Data True if (fDataTrue) delete fDataTrue; fDataTrue = (TH1D*)fDataHist->Clone(); fDataTrue->SetNameTitle((fName + "_FAKE_TRUE").c_str(), (fName + fPlotTitles).c_str()); // Make a new covariance for fake data hist. int nbins = fDataHist->GetNbinsX(); double alpha_i = 0.0; double alpha_j = 0.0; for (int i = 0; i < nbins; i++) { for (int j = 0; j < nbins; j++) { alpha_i = fDataHist->GetBinContent(i + 1) / tempdata->GetBinContent(i + 1); alpha_j = fDataHist->GetBinContent(j + 1) / tempdata->GetBinContent(j + 1); (*fFullCovar)(i, j) = alpha_i * alpha_j * (*fFullCovar)(i, j); } } // Setup Covariances if (covar) delete covar; covar = StatUtils::GetInvert(fFullCovar); if (fDecomp) delete fDecomp; fDecomp = StatUtils::GetInvert(fFullCovar); delete tempdata; return; }; //******************************************************************** void Measurement1D::ResetFakeData() { //******************************************************************** if (fIsFakeData) { if (fDataHist) delete fDataHist; fDataHist = (TH1D*)fDataTrue->Clone((fSettings.GetName() + "_FKDAT").c_str()); } } //******************************************************************** void Measurement1D::ResetData() { //******************************************************************** if (fIsFakeData) { if (fDataHist) delete fDataHist; fDataHist = (TH1D*)fDataOrig->Clone((fSettings.GetName() + "_data").c_str()); } fIsFakeData = false; } //******************************************************************** void Measurement1D::ThrowCovariance() { //******************************************************************** // Take a fDecomposition and use it to throw the current dataset. // Requires fDataTrue also be set incase used repeatedly. if (!fDataTrue) fDataTrue = (TH1D*) fDataHist->Clone(); if (fDataHist) delete fDataHist; fDataHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar); return; }; //******************************************************************** void Measurement1D::ThrowDataToy(){ //******************************************************************** if (!fDataTrue) fDataTrue = (TH1D*) fDataHist->Clone(); if (fMCHist) delete fMCHist; fMCHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar); } /* Access Functions */ //******************************************************************** TH1D* Measurement1D::GetMCHistogram() { //******************************************************************** if (!fMCHist) return fMCHist; std::ostringstream chi2; chi2 << std::setprecision(5) << this->GetLikelihood(); int linecolor = kRed; int linestyle = 1; int linewidth = 1; int fillcolor = 0; int fillstyle = 1001; // if (fSettings.Has("linecolor")) linecolor = fSettings.GetI("linecolor"); // if (fSettings.Has("linestyle")) linestyle = fSettings.GetI("linestyle"); // if (fSettings.Has("linewidth")) linewidth = fSettings.GetI("linewidth"); // if (fSettings.Has("fillcolor")) fillcolor = fSettings.GetI("fillcolor"); // if (fSettings.Has("fillstyle")) fillstyle = fSettings.GetI("fillstyle"); fMCHist->SetTitle(chi2.str().c_str()); fMCHist->SetLineColor(linecolor); fMCHist->SetLineStyle(linestyle); fMCHist->SetLineWidth(linewidth); fMCHist->SetFillColor(fillcolor); fMCHist->SetFillStyle(fillstyle); return fMCHist; }; //******************************************************************** TH1D* Measurement1D::GetDataHistogram() { //******************************************************************** if (!fDataHist) return fDataHist; int datacolor = kBlack; int datastyle = 1; int datawidth = 1; // if (fSettings.Has("datacolor")) datacolor = fSettings.GetI("datacolor"); // if (fSettings.Has("datastyle")) datastyle = fSettings.GetI("datastyle"); // if (fSettings.Has("datawidth")) datawidth = fSettings.GetI("datawidth"); fDataHist->SetLineColor(datacolor); fDataHist->SetLineWidth(datawidth); fDataHist->SetMarkerStyle(datastyle); return fDataHist; }; /* Write Functions */ // Save all the histograms at once //******************************************************************** void Measurement1D::Write(std::string drawOpt) { //******************************************************************** // Get Draw Options drawOpt = FitPar::Config().GetParS("drawopts"); // Write Settigns if (drawOpt.find("SETTINGS") != std::string::npos){ fSettings.Set("#chi^{2}",fLikelihood); fSettings.Set("NDOF", this->GetNDOF() ); fSettings.Set("#chi^{2}/NDOF", fLikelihood / this->GetNDOF() ); fSettings.Write(); } // Write Data/MC GetDataList().at(0)->Write(); GetMCList().at(0)->Write(); // Write Fine Histogram if (drawOpt.find("FINE") != std::string::npos) GetFineList().at(0)->Write(); // Write Weighted Histogram if (drawOpt.find("WEIGHTS") != std::string::npos && fMCWeighted) fMCWeighted->Write(); // Save Flux/Evt if no event manager if (!FitPar::Config().GetParB("EventManager")) { if (drawOpt.find("FLUX") != std::string::npos && GetFluxHistogram()) GetFluxHistogram()->Write(); if (drawOpt.find("EVT") != std::string::npos && GetEventHistogram()) GetEventHistogram()->Write(); if (drawOpt.find("XSEC") != std::string::npos && GetEventHistogram()) GetXSecHistogram()->Write(); } // Write Mask if (fIsMask && (drawOpt.find("MASK") != std::string::npos)) { fMaskHist->Write(); } // Write Covariances if (drawOpt.find("COV") != std::string::npos && fFullCovar) { PlotUtils::GetFullCovarPlot(fFullCovar, fSettings.GetName()); } if (drawOpt.find("INVCOV") != std::string::npos && covar) { PlotUtils::GetInvCovarPlot(covar, fSettings.GetName()); } if (drawOpt.find("DECOMP") != std::string::npos && fDecomp) { PlotUtils::GetDecompCovarPlot(fDecomp, fSettings.GetName()); } // // Likelihood residual plots // if (drawOpt.find("RESIDUAL") != std::string::npos) { // WriteResidualPlots(); // } // Ratio and Shape Plots if (drawOpt.find("RATIO") != std::string::npos) { WriteRatioPlot(); } if (drawOpt.find("SHAPE") != std::string::npos) { WriteShapePlot(); if (drawOpt.find("RATIO") != std::string::npos) WriteShapeRatioPlot(); } // // RATIO // if (drawOpt.find("CANVMC") != std::string::npos) { // TCanvas* c1 = WriteMCCanvas(fDataHist, fMCHist); // c1->Write(); // delete c1; // } // // PDG // if (drawOpt.find("CANVPDG") != std::string::npos && fMCHist_Modes) { // TCanvas* c2 = WritePDGCanvas(fDataHist, fMCHist, fMCHist_Modes); // c2->Write(); // delete c2; // } // Write Extra Histograms AutoWriteExtraTH1(); WriteExtraHistograms(); // Returning LOG(SAM) << "Written Histograms: " << fName << std::endl; return; } //******************************************************************** void Measurement1D::WriteRatioPlot() { //******************************************************************** // Setup mc data ratios TH1D* dataRatio = (TH1D*)fDataHist->Clone((fName + "_data_RATIO").c_str()); TH1D* mcRatio = (TH1D*)fMCHist->Clone((fName + "_MC_RATIO").c_str()); // Extra MC Data Ratios for (int i = 0; i < mcRatio->GetNbinsX(); i++) { dataRatio->SetBinContent(i + 1, fDataHist->GetBinContent(i + 1) / fMCHist->GetBinContent(i + 1)); dataRatio->SetBinError(i + 1, fDataHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1)); mcRatio->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1) / fMCHist->GetBinContent(i + 1)); mcRatio->SetBinError(i + 1, fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1)); } // Write ratios mcRatio->Write(); dataRatio->Write(); delete mcRatio; delete dataRatio; } //******************************************************************** void Measurement1D::WriteShapePlot() { //******************************************************************** TH1D* mcShape = (TH1D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str()); + TH1D* dataShape = (TH1D*)fDataHist->Clone((fName + "_data_SHAPE").c_str()); + if (fShapeCovar) StatUtils::SetDataErrorFromCov(dataShape, fShapeCovar, 1E-38); + double shapeScale = 1.0; if (fIsRawEvents) { shapeScale = fDataHist->Integral() / fMCHist->Integral(); } else { shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width"); } mcShape->Scale(shapeScale); std::stringstream ss; ss << shapeScale; mcShape->SetTitle(ss.str().c_str()); mcShape->SetLineWidth(3); mcShape->SetLineStyle(7); mcShape->Write(); + dataShape->Write(); delete mcShape; } //******************************************************************** void Measurement1D::WriteShapeRatioPlot() { //******************************************************************** // Get a mcshape histogram TH1D* mcShape = (TH1D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str()); double shapeScale = 1.0; if (fIsRawEvents) { shapeScale = fDataHist->Integral() / fMCHist->Integral(); } else { shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width"); } mcShape->Scale(shapeScale); // Create shape ratio histograms TH1D* mcShapeRatio = (TH1D*)mcShape->Clone((fName + "_MC_SHAPE_RATIO").c_str()); TH1D* dataShapeRatio = (TH1D*)fDataHist->Clone((fName + "_data_SHAPE_RATIO").c_str()); // Divide the histograms mcShapeRatio->Divide(mcShape); dataShapeRatio->Divide(mcShape); // Colour the shape ratio plots mcShapeRatio->SetLineWidth(3); mcShapeRatio->SetLineStyle(7); mcShapeRatio->Write(); dataShapeRatio->Write(); delete mcShapeRatio; delete dataShapeRatio; } //// CRAP TO BE REMOVED //******************************************************************** void Measurement1D::SetupMeasurement(std::string inputfile, std::string type, FitWeight * rw, std::string fkdt) { //******************************************************************** - //nuiskey samplekey = Config::CreateKey("sample"); -// samplekey.AddS("name", fName); -// samplekey.AddS("type",type); -// samplekey.AddS("input",inputfile); -// fSettings = LoadSampleSettings(samplekey); - + nuiskey samplekey = Config::CreateKey("sample"); + samplekey.AddS("name", fName); + samplekey.AddS("type",type); + samplekey.AddS("input",inputfile); + fSettings = LoadSampleSettings(samplekey); + // Reset everything to NULL // Init(); // Check if name contains Evt, indicating that it is a raw number of events // measurements and should thus be treated as once fIsRawEvents = false; if ((fName.find("Evt") != std::string::npos) && fIsRawEvents == false) { fIsRawEvents = true; LOG(SAM) << "Found event rate measurement but fIsRawEvents == false!" << std::endl; LOG(SAM) << "Overriding this and setting fIsRawEvents == true!" << std::endl; } fIsEnu1D = false; if (fName.find("XSec_1DEnu") != std::string::npos) { fIsEnu1D = true; LOG(SAM) << "::" << fName << "::" << std::endl; LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, " "not flux averaged!" << std::endl; } if (fIsEnu1D && fIsRawEvents) { LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this " "really correct?!" << std::endl; LOG(SAM) << "Check experiment constructor for " << fName << " and correct this!" << std::endl; LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl; exit(-1); } fRW = rw; if (!fInput and !fIsJoint) SetupInputs(inputfile); // Set Default Options SetFitOptions(fDefaultTypes); // Set Passed Options SetFitOptions(type); // Still adding support for flat flux inputs // // Set Enu Flux Scaling // if (isFlatFluxFolding) this->Input()->ApplyFluxFolding( // this->defaultFluxHist ); // FinaliseMeasurement(); } //******************************************************************** void Measurement1D::SetupDefaultHist() { //******************************************************************** // Setup fMCHist fMCHist = (TH1D*)fDataHist->Clone(); fMCHist->SetNameTitle((fName + "_MC").c_str(), (fName + "_MC" + fPlotTitles).c_str()); // Setup fMCFine Int_t nBins = fMCHist->GetNbinsX(); fMCFine = new TH1D( (fName + "_MC_FINE").c_str(), (fName + "_MC_FINE" + fPlotTitles).c_str(), nBins * 6, fMCHist->GetBinLowEdge(1), fMCHist->GetBinLowEdge(nBins + 1)); fMCStat = (TH1D*)fMCHist->Clone(); fMCStat->Reset(); fMCHist->Reset(); fMCFine->Reset(); // Setup the NEUT Mode Array PlotUtils::CreateNeutModeArray((TH1D*)fMCHist, (TH1**)fMCHist_PDG); PlotUtils::ResetNeutModeArray((TH1**)fMCHist_PDG); // Setup bin masks using sample name if (fIsMask) { std::string maskloc = FitPar::Config().GetParDIR(fName + ".mask"); if (maskloc.empty()) { maskloc = FitPar::GetDataBase() + "/masks/" + fName + ".mask"; } SetBinMask(maskloc); } fMCHist_Modes = new TrueModeStack( (fName + "_MODES").c_str(), ("True Channels"), fMCHist); SetAutoProcessTH1(fMCHist_Modes, kCMD_Reset, kCMD_Norm, kCMD_Write); return; } //******************************************************************** void Measurement1D::SetDataValues(std::string dataFile) { //******************************************************************** // Override this function if the input file isn't in a suitable format LOG(SAM) << "Reading data from: " << dataFile.c_str() << std::endl; fDataHist = PlotUtils::GetTH1DFromFile(dataFile, (fName + "_data"), fPlotTitles); fDataTrue = (TH1D*)fDataHist->Clone(); // Number of data points is number of bins fNDataPointsX = fDataHist->GetXaxis()->GetNbins(); return; }; //******************************************************************** void Measurement1D::SetDataFromDatabase(std::string inhistfile, std::string histname) { //******************************************************************** LOG(SAM) << "Filling histogram from " << inhistfile << "->" << histname << std::endl; fDataHist = PlotUtils::GetTH1DFromRootFile( (GeneralUtils::GetTopLevelDir() + "/data/" + inhistfile), histname); fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_data").c_str()); return; }; //******************************************************************** void Measurement1D::SetDataFromFile(std::string inhistfile, std::string histname) { //******************************************************************** LOG(SAM) << "Filling histogram from " << inhistfile << "->" << histname << std::endl; fDataHist = PlotUtils::GetTH1DFromRootFile((inhistfile), histname); fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_data").c_str()); return; }; //******************************************************************** void Measurement1D::SetCovarMatrix(std::string covarFile) { //******************************************************************** // Covariance function, only really used when reading in the MB Covariances. TFile* tempFile = new TFile(covarFile.c_str(), "READ"); TH2D* covarPlot = new TH2D(); // TH2D* decmpPlot = new TH2D(); TH2D* covarInvPlot = new TH2D(); TH2D* fFullCovarPlot = new TH2D(); std::string covName = ""; std::string covOption = FitPar::Config().GetParS("thrown_covariance"); if (fIsShape || fIsFree) covName = "shp_"; if (fIsDiag) covName += "diag"; else covName += "full"; covarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str()); covarInvPlot = (TH2D*)tempFile->Get((covName + "covinv").c_str()); if (!covOption.compare("SUB")) fFullCovarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str()); else if (!covOption.compare("FULL")) fFullCovarPlot = (TH2D*)tempFile->Get("fullcov"); else ERR(WRN) << "Incorrect thrown_covariance option in parameters." << std::endl; int dim = int(fDataHist->GetNbinsX()); //-this->masked->Integral()); int covdim = int(fDataHist->GetNbinsX()); this->covar = new TMatrixDSym(dim); fFullCovar = new TMatrixDSym(dim); fDecomp = new TMatrixDSym(dim); int row, column = 0; row = 0; column = 0; for (Int_t i = 0; i < covdim; i++) { // if (this->masked->GetBinContent(i+1) > 0) continue; for (Int_t j = 0; j < covdim; j++) { // if (this->masked->GetBinContent(j+1) > 0) continue; (*this->covar)(row, column) = covarPlot->GetBinContent(i + 1, j + 1); (*fFullCovar)(row, column) = fFullCovarPlot->GetBinContent(i + 1, j + 1); column++; } column = 0; row++; } // Set bin errors on data if (!fIsDiag) { StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar); } // Get Deteriminant and inverse matrix // fCovDet = this->covar->Determinant(); TDecompSVD LU = TDecompSVD(*this->covar); this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); return; }; //******************************************************************** // Sets the covariance matrix from a provided file in a text format // scale is a multiplicative pre-factor to apply in the case where the // covariance is given in some unit (e.g. 1E-38) void Measurement1D::SetCovarMatrixFromText(std::string covarFile, int dim, double scale) { //******************************************************************** // Make a counter to track the line number int row = 0; std::string line; std::ifstream covarread(covarFile.c_str(), ifstream::in); this->covar = new TMatrixDSym(dim); fFullCovar = new TMatrixDSym(dim); if (covarread.is_open()) LOG(SAM) << "Reading covariance matrix from file: " << covarFile << std::endl; else ERR(FTL) << "Covariance matrix provided is incorrect: " << covarFile << std::endl; // Loop over the lines in the file while (std::getline(covarread >> std::ws, line, '\n')) { int column = 0; // Loop over entries and insert them into matrix std::vector entries = GeneralUtils::ParseToDbl(line, " "); if (entries.size() <= 1) { ERR(WRN) << "SetCovarMatrixFromText -> Covariance matrix only has <= 1 " "entries on this line: " << row << std::endl; } for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { (*covar)(row, column) = *iter; (*fFullCovar)(row, column) = *iter; column++; } row++; } covarread.close(); // Scale the actualy covariance matrix by some multiplicative factor (*fFullCovar) *= scale; // Robust matrix inversion method TDecompSVD LU = TDecompSVD(*this->covar); // THIS IS ACTUALLY THE INVERSE COVARIANCE MATRIXA AAAAARGH delete this->covar; this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); // Now need to multiply by the scaling factor // If the covariance (*this->covar) *= 1. / (scale); return; }; //******************************************************************** void Measurement1D::SetCovarMatrixFromCorrText(std::string corrFile, int dim) { //******************************************************************** // Make a counter to track the line number int row = 0; std::string line; std::ifstream corr(corrFile.c_str(), ifstream::in); this->covar = new TMatrixDSym(dim); this->fFullCovar = new TMatrixDSym(dim); if (corr.is_open()) LOG(SAM) << "Reading and converting correlation matrix from file: " << corrFile << std::endl; else { ERR(FTL) << "Correlation matrix provided is incorrect: " << corrFile << std::endl; exit(-1); } while (std::getline(corr >> std::ws, line, '\n')) { int column = 0; // Loop over entries and insert them into matrix // Multiply by the errors to get the covariance, rather than the correlation // matrix std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { double val = (*iter) * this->fDataHist->GetBinError(row + 1) * 1E38 * this->fDataHist->GetBinError(column + 1) * 1E38; if (val == 0) { ERR(FTL) << "Found a zero value in the covariance matrix, assuming " "this is an error!" << std::endl; exit(-1); } (*this->covar)(row, column) = val; (*this->fFullCovar)(row, column) = val; column++; } row++; } // Robust matrix inversion method TDecompSVD LU = TDecompSVD(*this->covar); delete this->covar; this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); return; }; //******************************************************************** // FullUnits refers to if we have "real" unscaled units in the covariance matrix, e.g. 1E-76. // If this is the case we need to scale it so that the chi2 contribution is correct // NUISANCE internally assumes the covariance matrix has units of 1E76 void Measurement1D::SetCovarFromDataFile(std::string covarFile, std::string covName, bool FullUnits) { //******************************************************************** LOG(SAM) << "Getting covariance from " << covarFile << "->" << covName << std::endl; TFile* tempFile = new TFile(covarFile.c_str(), "READ"); TH2D* covPlot = (TH2D*)tempFile->Get(covName.c_str()); covPlot->SetDirectory(0); // Scale the covariance matrix if it comes in normal units if (FullUnits) { covPlot->Scale(1.E76); } int dim = covPlot->GetNbinsX(); fFullCovar = new TMatrixDSym(dim); for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { (*fFullCovar)(i, j) = covPlot->GetBinContent(i + 1, j + 1); } } this->covar = (TMatrixDSym*)fFullCovar->Clone(); fDecomp = (TMatrixDSym*)fFullCovar->Clone(); TDecompSVD LU = TDecompSVD(*this->covar); this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); TDecompChol LUChol = TDecompChol(*fDecomp); LUChol.Decompose(); fDecomp = new TMatrixDSym(dim, LU.GetU().GetMatrixArray(), ""); return; }; // //******************************************************************** // void Measurement1D::SetBinMask(std::string maskFile) { // //******************************************************************** // // Create a mask histogram. // int nbins = fDataHist->GetNbinsX(); // fMaskHist = // new TH1I((fName + "_fMaskHist").c_str(), // (fName + "_fMaskHist; Bin; Mask?").c_str(), nbins, 0, nbins); // std::string line; // std::ifstream mask(maskFile.c_str(), ifstream::in); // if (mask.is_open()) // LOG(SAM) << "Reading bin mask from file: " << maskFile << std::endl; // else // LOG(FTL) << " Cannot find mask file." << std::endl; // while (std::getline(mask >> std::ws, line, '\n')) { // std::vector entries = GeneralUtils::ParseToInt(line, " "); // // Skip lines with poorly formatted lines // if (entries.size() < 2) { // LOG(WRN) << "Measurement1D::SetBinMask(), couldn't parse line: " << line // << std::endl; // continue; // } // // The first index should be the bin number, the second should be the mask // // value. // fMaskHist->SetBinContent(entries[0], entries[1]); // } // // Set masked data bins to zero // PlotUtils::MaskBins(fDataHist, fMaskHist); // return; // } // //******************************************************************** // void Measurement1D::GetBinContents(std::vector& cont, // std::vector& err) { // //******************************************************************** // // Return a vector of the main bin contents // for (int i = 0; i < fMCHist->GetNbinsX(); i++) { // cont.push_back(fMCHist->GetBinContent(i + 1)); // err.push_back(fMCHist->GetBinError(i + 1)); // } // return; // }; /* XSec Functions */ // //******************************************************************** // void Measurement1D::SetFluxHistogram(std::string fluxFile, int minE, int // maxE, // double fluxNorm) { // //******************************************************************** // // Note this expects the flux bins to be given in terms of MeV // LOG(SAM) << "Reading flux from file: " << fluxFile << std::endl; // TGraph f(fluxFile.c_str(), "%lg %lg"); // fFluxHist = // new TH1D((fName + "_flux").c_str(), (fName + "; E_{#nu} (GeV)").c_str(), // f.GetN() - 1, minE, maxE); // Double_t* yVal = f.GetY(); // for (int i = 0; i < fFluxHist->GetNbinsX(); ++i) // fFluxHist->SetBinContent(i + 1, yVal[i] * fluxNorm); // }; // //******************************************************************** // double Measurement1D::TotalIntegratedFlux(std::string intOpt, double low, // double high) { // //******************************************************************** // if (fInput->GetType() == kGiBUU) { // return 1.0; // } // // The default case of low = -9999.9 and high = -9999.9 // if (low == -9999.9) low = this->EnuMin; // if (high == -9999.9) high = this->EnuMax; // int minBin = fFluxHist->GetXaxis()->FindBin(low); // int maxBin = fFluxHist->GetXaxis()->FindBin(high); // // Get integral over custom range // double integral = fFluxHist->Integral(minBin, maxBin + 1, intOpt.c_str()); // return integral; // }; diff --git a/src/FitBase/Measurement1D.h b/src/FitBase/Measurement1D.h index b3c14a9..e373dfe 100644 --- a/src/FitBase/Measurement1D.h +++ b/src/FitBase/Measurement1D.h @@ -1,650 +1,655 @@ // Copyright 2016 L. Pickering, P towell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #ifndef MEASUREMENT_1D_H_SEEN #define MEASUREMENT_1D_H_SEEN /*! * \addtogroup FitBase * @{ */ #include #include #include #include #include #include #include #include // ROOT includes #include #include #include #include #include #include #include #include #include #include #include #include // External data fit includes #include "FitEvent.h" #include "FitParameters.h" #include "FitUtils.h" #include "MeasurementBase.h" #include "PlotUtils.h" #include "StatUtils.h" #include "SignalDef.h" #include "MeasurementVariableBox.h" #include "MeasurementVariableBox1D.h" namespace NUISANCE { namespace FitBase { } } //******************************************************************** /// 1D Measurement base class. Histogram handling is done in this base layer. class Measurement1D : public MeasurementBase { //******************************************************************** public: /* Constructor/Deconstuctor */ Measurement1D(void); virtual ~Measurement1D(void); /* Setup Functions */ /// \brief Setup all configs once initialised /// /// Should be called after all configs have been setup inside fSettings container. /// Handles the processing of inputs and setting up of types. /// Replaces the old 'SetupMeasurement' function. void FinaliseSampleSettings(); /// \brief Creates the 1D data distribution given the binning provided. virtual void CreateDataHistogram(int dimx, double* binx); /// \brief Read 1D data inputs from a text file. /// /// Inputfile should have the format: \n /// low_binedge_1 bin_content_1 bin_error_1 \n /// low_binedge_2 bin_content_2 bin_error_2 \n /// .... .... .... \n /// high_bin_edge_N 0.0 0.0 virtual void SetDataFromTextFile(std::string datafile); /// \brief Read 1D data inputs from a root file. /// /// inhistfile specifies the path to the root file /// histname specifies the name of the histogram. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ';' so that: \n /// 'myhistfile.root;myhistname' \n /// will also work. virtual void SetDataFromRootFile(std::string inhistfile, std::string histname = ""); /// \brief Setup a default empty data histogram /// /// Only used for flattree creators. virtual void SetEmptyData(); /// \brief Set data bin errors to sqrt(entries) /// /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST /// /// Sets the data errors as the sqrt of the bin contents /// Should be use for counting experiments virtual void SetPoissonErrors(); /// \brief Make diagonal covariance from data /// /// \warning If no histogram passed, data must be setup first! /// Setup the covariance inputs by taking the data histogram /// errors and setting up a diagonal covariance matrix. /// /// If no data is supplied, fDataHist is used if already set. virtual void SetCovarFromDiagonal(TH1D* data = NULL); /// \brief Read the data covariance from a text file. /// /// Inputfile should have the format: \n /// covariance_11 covariance_12 covariance_13 ... \n /// covariance_21 covariance_22 covariance_23 ... \n /// ... ... ... ... \n /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCovarFromTextFile(std::string covfile, int dim = -1); virtual void SetCovarFromMultipleTextFiles(std::string covfiles, int dim = -1); /// \brief Read the data covariance from a ROOT file. /// /// - covfile specifies the full path to the file /// - histname specifies the name of the covariance object. Both TMatrixDSym and TH2D are supported. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCovarFromRootFile(std::string covfile, std::string histname=""); /// \brief Read the inverted data covariance from a text file. /// /// Inputfile should have similar format to that shown /// in SetCovarFromTextFile. /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCovarInvertFromTextFile(std::string covfile, int dim = -1); /// \brief Read the inverted data covariance from a ROOT file. /// /// Inputfile should have similar format to that shown /// in SetCovarFromRootFile. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCovarInvertFromRootFile(std::string covfile, std::string histname=""); /// \brief Read the data correlations from a text file. /// /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST /// /// Inputfile should have similar format to that shown /// in SetCovarFromTextFile. /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCorrelationFromTextFile(std::string covfile, int dim = -1); /// \brief Read the data correlations from multiple text files. /// /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST /// /// Inputfile should have similar format to that shown /// in SetCovarFromTextFile. /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of the first corrfile. virtual void SetCorrelationFromMultipleTextFiles(std::string corrfiles, int dim = -1); /// \brief Read the data correlations from a ROOT file. /// /// \warning REQUIRES DATA TO BE SET FIRST /// /// Inputfile should have similar format to that shown /// in SetCovarFromRootFile. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCorrelationFromRootFile(std::string covfile, std::string histname=""); /// \brief Read the cholesky decomposed covariance from a text file and turn it into a covariance /// /// Inputfile should have similar format to that shown /// in SetCovarFromTextFile. /// /// If no dimensions are given, it is assumed from the number /// entries in the first line of covfile. virtual void SetCholDecompFromTextFile(std::string covfile, int dim = -1); /// \brief Read the cholesky decomposed covariance from a ROOT file and turn it into a covariance /// /// Inputfile should have similar format to that shown /// in SetCovarFromRootFile. /// /// If no histogram name is given the inhistfile value /// is automatically parsed with ; so that: \n /// mycovfile.root;myhistname \n /// will also work. virtual void SetCholDecompFromRootFile(std::string covfile, std::string histname=""); + /// \brief Try to extract a shape-only matrix from the existing covariance + virtual void SetShapeCovar(); /// \brief Scale the data by some scale factor virtual void ScaleData(double scale); /// \brief Scale the data error bars by some scale factor virtual void ScaleDataErrors(double scale); /// \brief Scale the covariaince and its invert/decomp by some scale factor. virtual void ScaleCovar(double scale); /// \brief Setup a bin masking histogram and apply masking to data /// /// \warning REQUIRES DATA HISTOGRAM TO BE SET FIRST /// /// Reads in a list of bins in a text file to be masked. Format is: \n /// bin_index_1 1 \n /// bin_index_2 1 \n /// bin_index_3 1 \n /// /// If 0 is given then a bin entry will NOT be masked. So for example: \n\n /// 1 1 \n /// 2 1 \n /// 3 0 \n /// 4 1 \n\n /// Will mask only the 1st, 2nd, and 4th bins. /// /// Masking can be turned on by specifiying the MASK option when creating a sample. /// When this is passed NUISANCE will look in the following locations for the mask file: /// - FitPar::Config().GetParS(fName + ".mask") /// - "data/masks/" + fName + ".mask"; virtual void SetBinMask(std::string maskfile); /// \brief Set the current fit options from a string. /// /// This is called twice for each sample, once to set the default /// and once to set the current setting (if anything other than default given) /// /// For this to work properly it requires the default and allowed types to be /// set correctly. These should be specified as a string listing options. /// /// To split up options so that NUISANCE can automatically detect ones that /// are conflicting. Any options seperated with the '/' symbol are non conflicting /// and can be given together, whereas any seperated with the ',' symbol cannot /// be specified by the end user at the same time. /// /// Default Type Examples: /// - DIAG/FIX = Default option will be a diagonal covariance, with FIXED norm. /// - MASK/SHAPE = Default option will be a masked hist, with SHAPE always on. /// /// Allowed Type examples: /// - 'FULL/DIAG/NORM/MASK' = Any of these options can be specified. /// - 'FULL,FREE,SHAPE/MASK/NORM' = User can give either FULL, FREE, or SHAPE as on option. /// MASK and NORM can also be included as options. virtual void SetFitOptions(std::string opt); /// \brief Final constructor setup /// \warning Should be called right at the end of the constructor. /// /// Contains a series of checks to ensure the data and inputs have been setup. /// Also creates the MC histograms needed for fitting. void FinaliseMeasurement(); /* Smearing */ /// \brief Read in smearing matrix from file /// /// Set the smearing matrix from a text file given the size of the matrix virtual void SetSmearingMatrix(std::string smearfile, int truedim, int recodim); /// \brief Apply smearing to MC true to get MC reco /// /// Apply smearing matrix to fMCHist using fSmearingMatrix virtual void ApplySmearingMatrix(void); /* Reconfigure Functions */ /// \brief Create a Measurement1D box /// /// Creates a new 1D variable box containing just fXVar. /// /// This box is the bare minimum required by the JointFCN when /// running fast reconfigures during a routine. /// If for some reason a sample needs extra variables to be saved then /// it should override this function creating its own MeasurementVariableBox /// that contains the extra variables. virtual MeasurementVariableBox* CreateBox() {return new MeasurementVariableBox1D();}; /// \brief Reset all MC histograms /// /// Resets all standard histograms and those registered to auto /// process to zero. /// /// If extra histograms are not included in auto processing, then they must be reset /// by overriding this function and doing it manually if required. virtual void ResetAll(void); /// \brief Fill MC Histograms from XVar /// /// Fill standard histograms using fXVar, Weight read from the variable box. /// /// WARNING : Any extra MC histograms need to be filled by overriding this function, /// even if they have been set to auto process. virtual void FillHistograms(void); // \brief Convert event rates to final histogram /// /// Apply standard scaling procedure to standard mc histograms to convert from /// raw events to xsec prediction. /// /// If any distributions have been set to auto process /// that is done during this function call, and a differential xsec is assumed. /// If that is not the case this function must be overriden. virtual void ScaleEvents(void); /// \brief Scale MC by a factor=1/norm /// /// Apply a simple normalisation scaling if the option FREE or a norm_parameter /// has been specified in the NUISANCE routine. virtual void ApplyNormScale(double norm); /* Statistical Functions */ /// \brief Get Number of degrees of freedom /// /// Returns the number bins inside the data histogram accounting for /// any bin masking applied. virtual int GetNDOF(void); /// \brief Return Data/MC Likelihood at current state /// /// Returns the likelihood of the data given the current MC prediction. /// Diferent likelihoods definitions are used depending on the FitOptions. virtual double GetLikelihood(void); /* Fake Data */ /// \brief Set the fake data values from either a file, or MC /// /// - Setting from a file "path": \n /// When reading from a file the full path must be given to a standard /// nuisance output. The standard MC histogram should have a name that matches /// this sample for it to be read in. /// \n\n /// - Setting from "MC": \n /// If the MC option is given the current MC prediction is used as fake data. virtual void SetFakeDataValues(std::string fakeOption); /// \brief Reset fake data back to starting fake data /// /// Reset the fake data back to original fake data (Reset back to before /// ThrowCovariance was first called) virtual void ResetFakeData(void); /// \brief Reset fake data back to original data /// /// Reset the data histogram back to the true original dataset for this sample /// before any fake data was defined. virtual void ResetData(void); /// \brief Generate fake data by throwing the covariance. /// /// Can be used on fake MC data or just the original dataset. /// Call ResetFakeData or ResetData to return to values before the throw. virtual void ThrowCovariance(void); /// \brief Throw the data by its assigned errors and assign this to MC /// /// Used when creating data toys by assign the MC to this thrown data /// so that the likelihood is calculated between data and thrown data virtual void ThrowDataToy(void); /* Access Functions */ /// \brief Returns nicely formatted MC Histogram /// /// Format options can also be given in the samplesettings: /// - linecolor /// - linestyle /// - linewidth /// - fillcolor /// - fillstyle /// /// So to have a sample line colored differently in the xml cardfile put: \n /// virtual TH1D* GetMCHistogram(void); /// \brief Returns nicely formatted data Histogram /// /// Format options can also be given in the samplesettings: /// - datacolor /// - datastyle /// - datawidth /// /// So to have a sample data colored differently in the xml cardfile put: \n /// virtual TH1D* GetDataHistogram(void); /// \brief Returns a list of all MC histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. inline virtual std::vector GetMCList(void) { return std::vector(1, GetMCHistogram()); } /// \brief Returns a list of all Data histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. inline virtual std::vector GetDataList(void) { return std::vector(1, GetDataHistogram()); } /// \brief Returns a list of all Mask histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. inline virtual std::vector GetMaskList(void) { return std::vector(1, fMaskHist); }; /// \brief Returns a list of all Fine histograms. /// /// Override this if you have extra histograms that need to be /// accessed outside of the Measurement1D class. inline virtual std::vector GetFineList(void) { return std::vector(1, fMCFine); }; /* Write Functions */ /// \brief Save the current state to the current TFile directory \n /// /// Data/MC are both saved by default. /// A range of other histograms can be saved by setting the /// config option 'drawopts'. /// /// Possible options: \n /// - FINE = Write Fine Histogram \n /// - WEIGHTS = Write Weighted MC Histogram (before scaling) \n /// - FLUX = Write Flux Histogram from MC Input \n /// - EVT = Write Event Histogram from MC Input \n /// - XSEC = Write XSec Histogram from MC Input \n /// - MASK = Write Mask Histogram \n /// - COV = Write Covariance Histogram \n /// - INVCOV = Write Inverted Covariance Histogram \n /// - DECMOP = Write Decomp. Covariance Histogram \n /// - RESIDUAL= Write Resudial Histograms \n /// - RATIO = Write Data/MC Ratio Histograms \n /// - SHAPE = Write MC Shape Histograms norm. to Data \n /// - CANVMC = Build MC Canvas Showing Data, MC, Shape \n /// - MODES = Write PDG Stack \n /// - CANVPDG = Build MC Canvas Showing Data, PDGStack \n /// /// So to save a range of these in parameters/config.xml set: \n /// virtual void Write(std::string drawOpt); virtual void WriteRatioPlot(); virtual void WriteShapePlot(); virtual void WriteShapeRatioPlot(); //* // OLD DEFUNCTIONS // /// OLD FUNCTION virtual void SetupMeasurement(std::string input, std::string type, FitWeight* rw, std::string fkdt); /// OLD FUNCTION virtual void SetupDefaultHist(void); /// OLD FUNCTION virtual void SetDataValues(std::string dataFile); /// OLD FUNCTION virtual void SetDataFromFile(std::string inhistfile, std::string histname); /// OLD FUNCTION virtual void SetDataFromDatabase(std::string inhistfile, std::string histname); /// OLD FUNCTION virtual void SetCovarMatrix(std::string covarFile); /// OLD FUNCTION virtual void SetCovarMatrixFromText(std::string covarFile, int dim, double scale = 1.0); /// OLD FUNCTION virtual void SetCovarMatrixFromCorrText(std::string covarFile, int dim); /// OLD FUNCTION virtual void SetCovarFromDataFile(std::string covarFile, std::string covName, bool FullUnits = false); /// OLD FUNCTION // virtual THStack GetModeStack(void); protected: // Data TH1D* fDataHist; ///< default data histogram TH1D* fDataOrig; ///< histogram to store original data before throws. TH1D* fDataTrue; ///< histogram to store true dataset std::string fPlotTitles; ///< Plot title x and y for the histograms // MC TH1D* fMCHist; ///< default MC Histogram used in the chi2 fits TH1D* fMCFine; ///< finely binned MC histogram TH1D* fMCStat; ///< histogram with unweighted events to properly calculate TH1D* fMCWeighted; ///< Weighted histogram before xsec scaling TH1I* fMaskHist; ///< Mask histogram for neglecting specific bins TMatrixD* fSmearMatrix; ///< Smearing matrix (note, this is not symmetric) TrueModeStack* fMCHist_Modes; ///< Optional True Mode Stack // Statistical TMatrixDSym* covar; ///< Inverted Covariance TMatrixDSym* fFullCovar; ///< Full Covariance TMatrixDSym* fDecomp; ///< Decomposed Covariance TMatrixDSym* fCorrel; ///< Correlation Matrix + TMatrixDSym* fShapeCovar; ///< Shape-only covariance + TMatrixDSym* fShapeDecomp; ///< Decomposed shape-only covariance + TMatrixDSym* fCovar; ///< New FullCovar TMatrixDSym* fInvert; ///< New covar double fNormError; ///< Sample norm error double fLikelihood; ///< Likelihood value // Fake Data bool fIsFakeData; ///< Flag: is the current data fake from MC std::string fFakeDataInput; ///< Input fake data file path TFile* fFakeDataFile; ///< Input fake data file // Fit specific flags std::string fFitType; ///< Current fit type std::string fAllowedTypes; ///< Fit Types Possible std::string fDefaultTypes; ///< Starting Default Fit Types bool fIsShape; ///< Flag : Perform Shape-only fit bool fIsFree; ///< Flag : Perform normalisation free fit bool fIsDiag; ///< Flag : only include uncorrelated diagonal errors bool fIsMask; ///< Flag : Apply bin masking bool fIsRawEvents; ///< Flag : Are bin contents just event rates bool fIsEnu1D; ///< Flag : Perform Flux Unfolded Scaling bool fIsChi2SVD; ///< Flag : Use alternative Chi2 SVD Method (Do not use) bool fAddNormPen; ///< Flag : Add a normalisation penalty term to the chi2. bool fIsFix; ///< Flag : keeping norm fixed bool fIsFull; ///< Flag : using full covariaince bool fIsDifXSec; ///< Flag : creating a dif xsec bool fIsChi2; ///< Flag : using Chi2 over LL methods bool fIsSmeared; ///< Flag : Apply smearing? /// OLD STUFF TO REMOVE TH1D* fMCHist_PDG[61]; ///< REMOVE OLD MC PDG Plot // Arrays for data entries Double_t* fXBins; ///< REMOVE xBin edges Double_t* fDataValues; ///< REMOVE data bin contents Double_t* fDataErrors; ///< REMOVE data bin errors Int_t fNDataPointsX; ///< REMOVE number of data points }; /*! @} */ #endif diff --git a/src/FitBase/Measurement2D.cxx b/src/FitBase/Measurement2D.cxx index 4c3a6df..33fdd0f 100644 --- a/src/FitBase/Measurement2D.cxx +++ b/src/FitBase/Measurement2D.cxx @@ -1,1961 +1,1961 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "Measurement2D.h" #include "TDecompChol.h" //******************************************************************** Measurement2D::Measurement2D(void) { //******************************************************************** covar = NULL; fDecomp = NULL; fFullCovar = NULL; fMCHist = NULL; fMCFine = NULL; fDataHist = NULL; fMCHist_X = NULL; fMCHist_Y = NULL; fDataHist_X = NULL; fDataHist_Y = NULL; fMaskHist = NULL; fMapHist = NULL; fDataOrig = NULL; fDataTrue = NULL; fMCWeighted = NULL; fDefaultTypes = "FIX/FULL/CHI2"; fAllowedTypes = "FIX,FREE,SHAPE/FULL,DIAG/CHI2/NORM/ENUCORR/Q2CORR/ENU1D/FITPROJX/" "FITPROJY"; fIsFix = false; fIsShape = false; fIsFree = false; fIsDiag = false; fIsFull = false; fAddNormPen = false; fIsMask = false; fIsChi2SVD = false; fIsRawEvents = false; fIsDifXSec = false; fIsEnu = false; // XSec Scalings fScaleFactor = -1.0; fCurrentNorm = 1.0; // Histograms fDataHist = NULL; fDataTrue = NULL; fMCHist = NULL; fMCFine = NULL; fMCWeighted = NULL; fMaskHist = NULL; // Covar covar = NULL; fFullCovar = NULL; fCovar = NULL; fInvert = NULL; fDecomp = NULL; // Fake Data fFakeDataInput = ""; fFakeDataFile = NULL; // Options fDefaultTypes = "FIX/FULL/CHI2"; fAllowedTypes = "FIX,FREE,SHAPE/FULL,DIAG/CHI2/NORM/ENUCORR/Q2CORR/ENU1D/MASK"; fIsFix = false; fIsShape = false; fIsFree = false; fIsDiag = false; fIsFull = false; fAddNormPen = false; fIsMask = false; fIsChi2SVD = false; fIsRawEvents = false; fIsDifXSec = false; fIsEnu1D = false; // Inputs fInput = NULL; fRW = NULL; // Extra Histograms fMCHist_Modes = NULL; } //******************************************************************** Measurement2D::~Measurement2D(void) { //******************************************************************** if (fDataHist) delete fDataHist; if (fDataTrue) delete fDataTrue; if (fMCHist) delete fMCHist; if (fMCFine) delete fMCFine; if (fMCWeighted) delete fMCWeighted; if (fMaskHist) delete fMaskHist; if (covar) delete covar; if (fFullCovar) delete fFullCovar; if (fCovar) delete fCovar; if (fInvert) delete fInvert; if (fDecomp) delete fDecomp; } //******************************************************************** void Measurement2D::FinaliseSampleSettings() { //******************************************************************** MeasurementBase::FinaliseSampleSettings(); // Setup naming + renaming fName = fSettings.GetName(); fSettings.SetS("originalname", fName); if (fSettings.Has("rename")) { fName = fSettings.GetS("rename"); fSettings.SetS("name", fName); } // Setup all other options LOG(SAM) << "Finalising Sample Settings: " << fName << std::endl; if ((fSettings.GetS("originalname").find("Evt") != std::string::npos)) { fIsRawEvents = true; LOG(SAM) << "Found event rate measurement but using poisson likelihoods." << std::endl; } if (fSettings.GetS("originalname").find("XSec_1DEnu") != std::string::npos) { fIsEnu1D = true; LOG(SAM) << "::" << fName << "::" << std::endl; LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, " << "not flux averaged!" << std::endl; } if (fIsEnu1D && fIsRawEvents) { LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this " "really correct?!" << std::endl; LOG(SAM) << "Check experiment constructor for " << fName << " and correct this!" << std::endl; LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl; exit(-1); } if (!fRW) fRW = FitBase::GetRW(); if (!fInput) SetupInputs(fSettings.GetS("input")); // Setup options SetFitOptions(fDefaultTypes); // defaults SetFitOptions(fSettings.GetS("type")); // user specified EnuMin = GeneralUtils::StrToDbl(fSettings.GetS("enu_min")); EnuMax = GeneralUtils::StrToDbl(fSettings.GetS("enu_max")); if (fAddNormPen) { fNormError = fSettings.GetNormError(); if (fNormError <= 0.0) { ERR(WRN) << "Norm error for class " << fName << " is 0.0!" << std::endl; ERR(WRN) << "If you want to use it please add fNormError=VAL" << std::endl; throw; } } } void Measurement2D::CreateDataHistogram(int dimx, double* binx, int dimy, double* biny) { if (fDataHist) delete fDataHist; LOG(SAM) << "Creating Data Histogram dim : " << dimx << " " << dimy << std::endl; fDataHist = new TH2D( (fSettings.GetName() + "_data").c_str(), (fSettings.GetFullTitles()).c_str(), dimx - 1, binx, dimy - 1, biny ); } void Measurement2D::SetDataFromTextFile(std::string datfile) { // fDataHist = PlotUtils::GetTH2DFromTextFile(datfile,""); } void Measurement2D::SetDataFromRootFile(std::string datfile, std::string histname) { fDataHist = PlotUtils::GetTH2DFromRootFile(datfile, histname); } void Measurement2D::SetDataValuesFromTextFile(std::string datfile, TH2D* hist) { LOG(SAM) << "Setting data values from text file" << std::endl; if (!hist) hist = fDataHist; // Read TH2D From textfile TH2D* valhist = (TH2D*) hist->Clone(); valhist->Reset(); PlotUtils::Set2DHistFromText(datfile, valhist, 1.0, true); LOG(SAM) << " -> Filling values from read hist." << std::endl; for (int i = 0; i < valhist->GetNbinsX(); i++) { for (int j = 0; j < valhist->GetNbinsY(); j++) { hist->SetBinContent(i + 1, j + 1, valhist->GetBinContent(i + 1, j + 1)); } } LOG(SAM) << " --> Done" << std::endl; } void Measurement2D::SetDataErrorsFromTextFile(std::string datfile, TH2D* hist) { LOG(SAM) << "Setting data errors from text file" << std::endl; if (!hist) hist = fDataHist; // Read TH2D From textfile TH2D* valhist = (TH2D*) hist->Clone(); valhist->Reset(); PlotUtils::Set2DHistFromText(datfile, valhist, 1.0); // Fill Errors LOG(SAM) << " -> Filling errors from read hist." << std::endl; for (int i = 0; i < valhist->GetNbinsX(); i++) { for (int j = 0; j < valhist->GetNbinsY(); j++) { hist->SetBinError(i + 1, j + 1, valhist->GetBinContent(i + 1, j + 1)); } } LOG(SAM) << " --> Done" << std::endl; } void Measurement2D::SetMapValuesFromText(std::string dataFile) { TH2D* hist = fDataHist; std::vector edgex; std::vector edgey; for (int i = 0; i <= hist->GetNbinsX(); i++) edgex.push_back(hist->GetXaxis()->GetBinLowEdge(i + 1)); for (int i = 0; i <= hist->GetNbinsY(); i++) edgey.push_back(hist->GetYaxis()->GetBinLowEdge(i + 1)); fMapHist = new TH2I((fName + "_map").c_str(), (fName + fPlotTitles).c_str(), edgex.size() - 1, &edgex[0], edgey.size() - 1, &edgey[0]); LOG(SAM) << "Reading map from: " << dataFile << std::endl; PlotUtils::Set2DHistFromText(dataFile, fMapHist, 1.0); } //******************************************************************** void Measurement2D::SetPoissonErrors() { //******************************************************************** if (!fDataHist) { ERR(FTL) << "Need a data hist to setup possion errors! " << std::endl; ERR(FTL) << "Setup Data First!" << std::endl; throw; } for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) { fDataHist->SetBinError(i + 1, sqrt(fDataHist->GetBinContent(i + 1))); } } //******************************************************************** void Measurement2D::SetCovarFromDiagonal(TH2D* data) { //******************************************************************** if (!data and fDataHist) { data = fDataHist; } if (data) { LOG(SAM) << "Setting diagonal covariance for: " << data->GetName() << std::endl; fFullCovar = StatUtils::MakeDiagonalCovarMatrix(data); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } else { ERR(FTL) << "No data input provided to set diagonal covar from!" << std::endl; } // if (!fIsDiag) { // ERR(FTL) << "SetCovarMatrixFromDiag called for measurement " // << "that is not set as diagonal." << std::endl; // throw; // } } //******************************************************************** void Measurement2D::SetCovarFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) { dim = this->GetNDOF(); } LOG(SAM) << "Reading covariance from text file: " << covfile << std::endl; fFullCovar = StatUtils::GetCovarFromTextFile(covfile, dim); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement2D::SetCovarFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading covariance from text file: " << covfile << ";" << histname << std::endl; fFullCovar = StatUtils::GetCovarFromRootFile(covfile, histname); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement2D::SetCovarInvertFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) { dim = this->GetNDOF(); } LOG(SAM) << "Reading inverted covariance from text file: " << covfile << std::endl; covar = StatUtils::GetCovarFromTextFile(covfile, dim); fFullCovar = StatUtils::GetInvert(covar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement2D::SetCovarInvertFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading inverted covariance from text file: " << covfile << ";" << histname << std::endl; covar = StatUtils::GetCovarFromRootFile(covfile, histname); fFullCovar = StatUtils::GetInvert(covar); fDecomp = StatUtils::GetDecomp(fFullCovar); } //******************************************************************** void Measurement2D::SetCorrelationFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) dim = this->GetNDOF(); LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << dim << std::endl; TMatrixDSym* correlation = StatUtils::GetCovarFromTextFile(covfile, dim); if (!fDataHist) { ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n" << "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl; throw; } // Fill covar from data errors and correlations fFullCovar = new TMatrixDSym(dim); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { (*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76; } } // Fill other covars. covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete correlation; } //******************************************************************** void Measurement2D::SetCorrelationFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading data correlations from text file: " << covfile << ";" << histname << std::endl; TMatrixDSym* correlation = StatUtils::GetCovarFromRootFile(covfile, histname); if (!fDataHist) { ERR(FTL) << "Trying to set correlations from text file but there is no data to build it from. \n" << "In constructor make sure data is set before SetCorrelationFromTextFile is called. \n" << std::endl; throw; } // Fill covar from data errors and correlations fFullCovar = new TMatrixDSym(fDataHist->GetNbinsX()); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsX(); j++) { (*fFullCovar)(i, j) = (*correlation)(i, j) * fDataHist->GetBinError(i + 1) * fDataHist->GetBinError(j + 1) * 1.E76; } } // Fill other covars. covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete correlation; } //******************************************************************** void Measurement2D::SetCholDecompFromTextFile(std::string covfile, int dim) { //******************************************************************** if (dim == -1) { dim = this->GetNDOF(); } LOG(SAM) << "Reading cholesky from text file: " << covfile << " " << dim << std::endl; TMatrixD* temp = StatUtils::GetMatrixFromTextFile(covfile, dim, dim); TMatrixD* trans = (TMatrixD*)temp->Clone(); trans->T(); (*trans) *= (*temp); fFullCovar = new TMatrixDSym(dim, trans->GetMatrixArray(), ""); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete temp; delete trans; } //******************************************************************** void Measurement2D::SetCholDecompFromRootFile(std::string covfile, std::string histname) { //******************************************************************** LOG(SAM) << "Reading cholesky decomp from root file: " << covfile << ";" << histname << std::endl; TMatrixD* temp = StatUtils::GetMatrixFromRootFile(covfile, histname); TMatrixD* trans = (TMatrixD*)temp->Clone(); trans->T(); (*trans) *= (*temp); fFullCovar = new TMatrixDSym(temp->GetNrows(), trans->GetMatrixArray(), ""); covar = StatUtils::GetInvert(fFullCovar); fDecomp = StatUtils::GetDecomp(fFullCovar); delete temp; delete trans; } //******************************************************************** void Measurement2D::ScaleData(double scale) { //******************************************************************** fDataHist->Scale(scale); } //******************************************************************** void Measurement2D::ScaleDataErrors(double scale) { //******************************************************************** for (int i = 0; i < fDataHist->GetNbinsX(); i++) { for (int j = 0; j < fDataHist->GetNbinsY(); j++) { fDataHist->SetBinError(i + 1, j + 1, fDataHist->GetBinError(i + 1, j + 1) * scale); } } } //******************************************************************** void Measurement2D::ScaleCovar(double scale) { //******************************************************************** (*fFullCovar) *= scale; (*covar) *= 1.0 / scale; (*fDecomp) *= sqrt(scale); } //******************************************************************** void Measurement2D::SetBinMask(std::string maskfile) { //******************************************************************** if (!fIsMask) return; LOG(SAM) << "Reading bin mask from file: " << maskfile << std::endl; // Create a mask histogram with dim of data int nbinsx = fDataHist->GetNbinsX(); int nbinxy = fDataHist->GetNbinsY(); fMaskHist = new TH2I((fSettings.GetName() + "_BINMASK").c_str(), (fSettings.GetName() + "_BINMASK; Bin; Mask?").c_str(), nbinsx, 0, nbinsx, nbinxy, 0, nbinxy); std::string line; std::ifstream mask(maskfile.c_str(), ifstream::in); if (!mask.is_open()) { LOG(FTL) << " Cannot find mask file." << std::endl; throw; } while (std::getline(mask >> std::ws, line, '\n')) { std::vector entries = GeneralUtils::ParseToInt(line, " "); // Skip lines with poorly formatted lines if (entries.size() < 2) { LOG(WRN) << "Measurement2D::SetBinMask(), couldn't parse line: " << line << std::endl; continue; } // The first index should be the bin number, the second should be the mask // value. int val = 0; if (entries[2] > 0) val = 1; fMaskHist->SetBinContent(entries[0], entries[1], val); } // Apply masking by setting masked data bins to zero PlotUtils::MaskBins(fDataHist, fMaskHist); return; } //******************************************************************** void Measurement2D::FinaliseMeasurement() { //******************************************************************** LOG(SAM) << "Finalising Measurement: " << fName << std::endl; if (fSettings.GetB("onlymc")) { if (fDataHist) delete fDataHist; fDataHist = new TH2D("empty_data", "empty_data", 1, 0.0, 1.0,1,0.0,1.0); } // Make sure data is setup if (!fDataHist) { ERR(FTL) << "No data has been setup inside " << fName << " constructor!" << std::endl; throw; } // Make sure covariances are setup if (!fFullCovar) { fIsDiag = true; SetCovarFromDiagonal(fDataHist); } if (!covar) { covar = StatUtils::GetInvert(fFullCovar); } if (!fDecomp) { fDecomp = StatUtils::GetDecomp(fFullCovar); } // Setup fMCHist from data fMCHist = (TH2D*)fDataHist->Clone(); fMCHist->SetNameTitle((fSettings.GetName() + "_MC").c_str(), (fSettings.GetFullTitles()).c_str()); fMCHist->Reset(); // Setup fMCFine fMCFine = new TH2D("mcfine", "mcfine", fDataHist->GetNbinsX() * 6, fMCHist->GetXaxis()->GetBinLowEdge(1), fMCHist->GetXaxis()->GetBinLowEdge(fDataHist->GetNbinsX() + 1), fDataHist->GetNbinsY() * 6, fMCHist->GetYaxis()->GetBinLowEdge(1), fMCHist->GetYaxis()->GetBinLowEdge(fDataHist->GetNbinsY() + 1)); fMCFine->SetNameTitle((fSettings.GetName() + "_MC_FINE").c_str(), (fSettings.GetFullTitles()).c_str()); fMCFine->Reset(); // Setup MC Stat fMCStat = (TH2D*)fMCHist->Clone(); fMCStat->Reset(); // Search drawopts for possible types to include by default std::string drawopts = FitPar::Config().GetParS("drawopts"); if (drawopts.find("MODES") != std::string::npos) { fMCHist_Modes = new TrueModeStack( (fSettings.GetName() + "_MODES").c_str(), ("True Channels"), fMCHist); SetAutoProcessTH1(fMCHist_Modes); } // Setup bin masks using sample name if (fIsMask) { std::string curname = fName; std::string origname = fSettings.GetS("originalname"); // Check rename.mask std::string maskloc = FitPar::Config().GetParDIR(curname + ".mask"); // Check origname.mask if (maskloc.empty()) maskloc = FitPar::Config().GetParDIR(origname + ".mask"); // Check database if (maskloc.empty()) { maskloc = FitPar::GetDataBase() + "/masks/" + origname + ".mask"; } // Setup Bin Mask SetBinMask(maskloc); } if (fScaleFactor < 0) { ERR(FTL) << "I found a negative fScaleFactor in " << __FILE__ << ":" << __LINE__ << std::endl; ERR(FTL) << "fScaleFactor = " << fScaleFactor << std::endl; ERR(FTL) << "EXITING" << std::endl; throw; } // Create and fill Weighted Histogram if (!fMCWeighted) { fMCWeighted = (TH2D*)fMCHist->Clone(); fMCWeighted->SetNameTitle((fName + "_MCWGHTS").c_str(), (fName + "_MCWGHTS" + fPlotTitles).c_str()); fMCWeighted->GetYaxis()->SetTitle("Weighted Events"); } } //******************************************************************** void Measurement2D::SetFitOptions(std::string opt) { //******************************************************************** // Do nothing if default given if (opt == "DEFAULT") return; // CHECK Conflicting Fit Options std::vector fit_option_allow = GeneralUtils::ParseToStr(fAllowedTypes, "/"); for (UInt_t i = 0; i < fit_option_allow.size(); i++) { std::vector fit_option_section = GeneralUtils::ParseToStr(fit_option_allow.at(i), ","); bool found_option = false; for (UInt_t j = 0; j < fit_option_section.size(); j++) { std::string av_opt = fit_option_section.at(j); if (!found_option and opt.find(av_opt) != std::string::npos) { found_option = true; } else if (found_option and opt.find(av_opt) != std::string::npos) { ERR(FTL) << "ERROR: Conflicting fit options provided: " << opt << std::endl << "Conflicting group = " << fit_option_section.at(i) << std::endl << "You should only supply one of these options in card file." << std::endl; throw; } } } // Check all options are allowed std::vector fit_options_input = GeneralUtils::ParseToStr(opt, "/"); for (UInt_t i = 0; i < fit_options_input.size(); i++) { if (fAllowedTypes.find(fit_options_input.at(i)) == std::string::npos) { ERR(FTL) << "ERROR: Fit Option '" << fit_options_input.at(i) << "' Provided is not allowed for this measurement." << std::endl; ERR(FTL) << "Fit Options should be provided as a '/' seperated list " "(e.g. FREE/DIAG/NORM)" << std::endl; ERR(FTL) << "Available options for " << fName << " are '" << fAllowedTypes << "'" << std::endl; throw; } } // Set TYPE fFitType = opt; // FIX,SHAPE,FREE if (opt.find("FIX") != std::string::npos) { fIsFree = fIsShape = false; fIsFix = true; } else if (opt.find("SHAPE") != std::string::npos) { fIsFree = fIsFix = false; fIsShape = true; } else if (opt.find("FREE") != std::string::npos) { fIsFix = fIsShape = false; fIsFree = true; } // DIAG,FULL (or default to full) if (opt.find("DIAG") != std::string::npos) { fIsDiag = true; fIsFull = false; } else if (opt.find("FULL") != std::string::npos) { fIsDiag = false; fIsFull = true; } // CHI2/LL (OTHERS?) if (opt.find("LOG") != std::string::npos) { fIsChi2 = false; ERR(FTL) << "No other LIKELIHOODS properly supported!" << std::endl; ERR(FTL) << "Try to use a chi2!" << std::endl; throw; } else { fIsChi2 = true; } // EXTRAS if (opt.find("RAW") != std::string::npos) fIsRawEvents = true; if (opt.find("DIF") != std::string::npos) fIsDifXSec = true; if (opt.find("ENU1D") != std::string::npos) fIsEnu1D = true; if (opt.find("NORM") != std::string::npos) fAddNormPen = true; if (opt.find("MASK") != std::string::npos) fIsMask = true; // Set TYPE fFitType = opt; // FIX,SHAPE,FREE if (opt.find("FIX") != std::string::npos) { fIsFree = fIsShape = false; fIsFix = true; } else if (opt.find("SHAPE") != std::string::npos) { fIsFree = fIsFix = false; fIsShape = true; } else if (opt.find("FREE") != std::string::npos) { fIsFix = fIsShape = false; fIsFree = true; } // DIAG,FULL (or default to full) if (opt.find("DIAG") != std::string::npos) { fIsDiag = true; fIsFull = false; } else if (opt.find("FULL") != std::string::npos) { fIsDiag = false; fIsFull = true; } // CHI2/LL (OTHERS?) if (opt.find("LOG") != std::string::npos) fIsChi2 = false; else fIsChi2 = true; // EXTRAS if (opt.find("RAW") != std::string::npos) fIsRawEvents = true; if (opt.find("DIF") != std::string::npos) fIsDifXSec = true; if (opt.find("ENU1D") != std::string::npos) fIsEnu = true; if (opt.find("NORM") != std::string::npos) fAddNormPen = true; if (opt.find("MASK") != std::string::npos) fIsMask = true; fIsProjFitX = (opt.find("FITPROJX") != std::string::npos); fIsProjFitY = (opt.find("FITPROJY") != std::string::npos); return; }; /* Reconfigure LOOP */ //******************************************************************** void Measurement2D::ResetAll() { //******************************************************************** fMCHist->Reset(); fMCFine->Reset(); fMCStat->Reset(); return; }; //******************************************************************** void Measurement2D::FillHistograms() { //******************************************************************** if (Signal) { fMCHist->Fill(fXVar, fYVar, Weight); fMCFine->Fill(fXVar, fYVar, Weight); fMCStat->Fill(fXVar, fYVar, 1.0); if (fMCHist_Modes) fMCHist_Modes->Fill(Mode, fXVar, fYVar, Weight); } return; }; //******************************************************************** void Measurement2D::ScaleEvents() { //******************************************************************** // Fill MCWeighted; // for (int i = 0; i < fMCHist->GetNbinsX(); i++) { // fMCWeighted->SetBinContent(i + 1, fMCHist->GetBinContent(i + 1)); // fMCWeighted->SetBinError(i + 1, fMCHist->GetBinError(i + 1)); // } // Setup Stat ratios for MC and MC Fine double* statratio = new double[fMCHist->GetNbinsX()]; for (int i = 0; i < fMCHist->GetNbinsX(); i++) { if (fMCHist->GetBinContent(i + 1) != 0) { statratio[i] = fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1); } else { statratio[i] = 0.0; } } double* statratiofine = new double[fMCFine->GetNbinsX()]; for (int i = 0; i < fMCFine->GetNbinsX(); i++) { if (fMCFine->GetBinContent(i + 1) != 0) { statratiofine[i] = fMCFine->GetBinError(i + 1) / fMCFine->GetBinContent(i + 1); } else { statratiofine[i] = 0.0; } } // Scaling for raw event rates if (fIsRawEvents) { double datamcratio = fDataHist->Integral() / fMCHist->Integral(); fMCHist->Scale(datamcratio); fMCFine->Scale(datamcratio); if (fMCHist_Modes) fMCHist_Modes->Scale(datamcratio); // Scaling for XSec as function of Enu } else if (fIsEnu1D) { PlotUtils::FluxUnfoldedScaling(fMCHist, GetFluxHistogram(), GetEventHistogram(), fScaleFactor); PlotUtils::FluxUnfoldedScaling(fMCFine, GetFluxHistogram(), GetEventHistogram(), fScaleFactor); // if (fMCHist_Modes) { // PlotUtils::FluxUnfoldedScaling(fMCHist_Modes, GetFluxHistogram(), // GetEventHistogram(), fScaleFactor, // fNEvents); // } // Any other differential scaling } else { fMCHist->Scale(fScaleFactor, "width"); fMCFine->Scale(fScaleFactor, "width"); // if (fMCHist_Modes) fMCHist_Modes->Scale(fScaleFactor, "width"); } // Proper error scaling - ROOT Freaks out with xsec weights sometimes for (int i = 0; i < fMCStat->GetNbinsX(); i++) { fMCHist->SetBinError(i + 1, fMCHist->GetBinContent(i + 1) * statratio[i]); } for (int i = 0; i < fMCFine->GetNbinsX(); i++) { fMCFine->SetBinError(i + 1, fMCFine->GetBinContent(i + 1) * statratiofine[i]); } // Clean up delete statratio; delete statratiofine; return; }; //******************************************************************** void Measurement2D::ApplyNormScale(double norm) { //******************************************************************** fCurrentNorm = norm; fMCHist->Scale(1.0 / norm); fMCFine->Scale(1.0 / norm); return; }; /* Statistic Functions - Outsources to StatUtils */ //******************************************************************** int Measurement2D::GetNDOF() { //******************************************************************** // Just incase it has gone... if (!fDataHist) return -1; int nDOF = 0; // If datahist has no errors make sure we don't include those bins as they are // not data points for (int xBin = 0; xBin < fDataHist->GetNbinsX() + 1; ++xBin) { for (int yBin = 0; yBin < fDataHist->GetNbinsY() + 1; ++yBin) { if (fDataHist->GetBinError(xBin, yBin) != 0) ++nDOF; } } // Account for possible bin masking int nMasked = 0; if (fMaskHist and fIsMask) if (fMaskHist->Integral() > 0) for (int xBin = 0; xBin < fMaskHist->GetNbinsX() + 1; ++xBin) for (int yBin = 0; yBin < fMaskHist->GetNbinsY() + 1; ++yBin) if (fMaskHist->GetBinContent(xBin, yBin) > 0.5) ++nMasked; // Take away those masked DOF if (fIsMask) { nDOF -= nMasked; } return nDOF; } //******************************************************************** double Measurement2D::GetLikelihood() { //******************************************************************** // If this is for a ratio, there is no data histogram to compare to! if (fNoData || !fDataHist) return 0.; // Fix weird masking bug if (!fIsMask) { if (fMaskHist) { fMaskHist = NULL; } } else { if (fMaskHist) { PlotUtils::MaskBins(fMCHist, fMaskHist); } } // if (fIsProjFitX or fIsProjFitY) return GetProjectedChi2(); // Scale up the results to match each other (Not using width might be // inconsistent with Meas1D) double scaleF = fDataHist->Integral() / fMCHist->Integral(); if (fIsShape) { fMCHist->Scale(scaleF); fMCFine->Scale(scaleF); - PlotUtils::ScaleNeutModeArray((TH1**)fMCHist_PDG, scaleF); + //PlotUtils::ScaleNeutModeArray((TH1**)fMCHist_PDG, scaleF); } if (!fMapHist) { fMapHist = StatUtils::GenerateMap(fDataHist); } // Get the chi2 from either covar or diagonals double chi2 = 0.0; if (fIsChi2) { if (fIsDiag) { chi2 = StatUtils::GetChi2FromDiag(fDataHist, fMCHist, fMapHist, fMaskHist); } else { chi2 = StatUtils::GetChi2FromCov(fDataHist, fMCHist, covar, fMapHist, fMaskHist); } } // Add a normal penalty term if (fAddNormPen) { chi2 += (1 - (fCurrentNorm)) * (1 - (fCurrentNorm)) / (fNormError * fNormError); LOG(REC) << "Norm penalty = " << (1 - (fCurrentNorm)) * (1 - (fCurrentNorm)) / (fNormError * fNormError) << std::endl; } // Adjust the shape back to where it was. if (fIsShape and !FitPar::Config().GetParB("saveshapescaling")) { fMCHist->Scale(1. / scaleF); fMCFine->Scale(1. / scaleF); } fLikelihood = chi2; return chi2; } /* Fake Data Functions */ //******************************************************************** void Measurement2D::SetFakeDataValues(std::string fakeOption) { //******************************************************************** // Setup original/datatrue TH2D* tempdata = (TH2D*) fDataHist->Clone(); if (!fIsFakeData) { fIsFakeData = true; // Make a copy of the original data histogram. if (!fDataOrig) fDataOrig = (TH2D*)fDataHist->Clone((fName + "_data_original").c_str()); } else { ResetFakeData(); } // Setup Inputs fFakeDataInput = fakeOption; LOG(SAM) << "Setting fake data from : " << fFakeDataInput << std::endl; // From MC if (fFakeDataInput.compare("MC") == 0) { fDataHist = (TH2D*)fMCHist->Clone((fName + "_MC").c_str()); // Fake File } else { if (!fFakeDataFile) fFakeDataFile = new TFile(fFakeDataInput.c_str(), "READ"); fDataHist = (TH2D*)fFakeDataFile->Get((fName + "_MC").c_str()); } // Setup Data Hist fDataHist->SetNameTitle((fName + "_FAKE").c_str(), (fName + fPlotTitles).c_str()); // Replace Data True if (fDataTrue) delete fDataTrue; fDataTrue = (TH2D*)fDataHist->Clone(); fDataTrue->SetNameTitle((fName + "_FAKE_TRUE").c_str(), (fName + fPlotTitles).c_str()); // Make a new covariance for fake data hist. int nbins = fDataHist->GetNbinsX() * fDataHist->GetNbinsY(); double alpha_i = 0.0; double alpha_j = 0.0; for (int i = 0; i < nbins; i++) { for (int j = 0; j < nbins; j++) { if (tempdata->GetBinContent(i + 1) && tempdata->GetBinContent(j + 1)) { alpha_i = fDataHist->GetBinContent(i + 1) / tempdata->GetBinContent(i + 1); alpha_j = fDataHist->GetBinContent(j + 1) / tempdata->GetBinContent(j + 1); } else { alpha_i = 0.0; alpha_j = 0.0; } (*fFullCovar)(i, j) = alpha_i * alpha_j * (*fFullCovar)(i, j); } } // Setup Covariances if (covar) delete covar; covar = StatUtils::GetInvert(fFullCovar); if (fDecomp) delete fDecomp; fDecomp = StatUtils::GetInvert(fFullCovar); delete tempdata; return; }; //******************************************************************** void Measurement2D::ResetFakeData() { //******************************************************************** if (fIsFakeData) { if (fDataHist) delete fDataHist; fDataHist = (TH2D*)fDataTrue->Clone((fSettings.GetName() + "_FKDAT").c_str()); } } //******************************************************************** void Measurement2D::ResetData() { //******************************************************************** if (fIsFakeData) { if (fDataHist) delete fDataHist; fDataHist = (TH2D*)fDataOrig->Clone((fSettings.GetName() + "_data").c_str()); } fIsFakeData = false; } //******************************************************************** void Measurement2D::ThrowCovariance() { //******************************************************************** // Take a fDecomposition and use it to throw the current dataset. // Requires fDataTrue also be set incase used repeatedly. if (fDataHist) delete fDataHist; fDataHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar); return; }; //******************************************************************** void Measurement2D::ThrowDataToy() { //******************************************************************** if (!fDataTrue) fDataTrue = (TH2D*) fDataHist->Clone(); if (fMCHist) delete fMCHist; fMCHist = StatUtils::ThrowHistogram(fDataTrue, fFullCovar); } /* Access Functions */ //******************************************************************** TH2D* Measurement2D::GetMCHistogram() { //******************************************************************** if (!fMCHist) return fMCHist; std::ostringstream chi2; chi2 << std::setprecision(5) << this->GetLikelihood(); int linecolor = kRed; int linestyle = 1; int linewidth = 1; int fillcolor = 0; int fillstyle = 1001; if (fSettings.Has("linecolor")) linecolor = fSettings.GetI("linecolor"); if (fSettings.Has("linestyle")) linestyle = fSettings.GetI("linestyle"); if (fSettings.Has("linewidth")) linewidth = fSettings.GetI("linewidth"); if (fSettings.Has("fillcolor")) fillcolor = fSettings.GetI("fillcolor"); if (fSettings.Has("fillstyle")) fillstyle = fSettings.GetI("fillstyle"); fMCHist->SetTitle(chi2.str().c_str()); fMCHist->SetLineColor(linecolor); fMCHist->SetLineStyle(linestyle); fMCHist->SetLineWidth(linewidth); fMCHist->SetFillColor(fillcolor); fMCHist->SetFillStyle(fillstyle); return fMCHist; }; //******************************************************************** TH2D* Measurement2D::GetDataHistogram() { //******************************************************************** if (!fDataHist) return fDataHist; int datacolor = kBlack; int datastyle = 1; int datawidth = 1; if (fSettings.Has("datacolor")) datacolor = fSettings.GetI("datacolor"); if (fSettings.Has("datastyle")) datastyle = fSettings.GetI("datastyle"); if (fSettings.Has("datawidth")) datawidth = fSettings.GetI("datawidth"); fDataHist->SetLineColor(datacolor); fDataHist->SetLineWidth(datawidth); fDataHist->SetMarkerStyle(datastyle); return fDataHist; }; /* Write Functions */ // Save all the histograms at once //******************************************************************** void Measurement2D::Write(std::string drawOpt) { //******************************************************************** // Get Draw Options drawOpt = FitPar::Config().GetParS("drawopts"); // Write Settigns if (drawOpt.find("SETTINGS") != std::string::npos) { fSettings.Set("#chi^{2}", fLikelihood); fSettings.Set("NDOF", this->GetNDOF() ); fSettings.Set("#chi^{2}/NDOF", fLikelihood / this->GetNDOF() ); fSettings.Write(); } // Write Data/MC GetDataList().at(0)->Write(); GetMCList().at(0)->Write(); // Write Fine Histogram if (drawOpt.find("FINE") != std::string::npos) GetFineList().at(0)->Write(); // Write Weighted Histogram if (drawOpt.find("WEIGHTS") != std::string::npos && fMCWeighted) fMCWeighted->Write(); // Save Flux/Evt if no event manager if (!FitPar::Config().GetParB("EventManager")) { if (drawOpt.find("FLUX") != std::string::npos && GetFluxHistogram()) GetFluxHistogram()->Write(); if (drawOpt.find("EVT") != std::string::npos && GetEventHistogram()) GetEventHistogram()->Write(); if (drawOpt.find("XSEC") != std::string::npos && GetEventHistogram()) GetEventHistogram()->Write(); } // Write Mask if (fIsMask && (drawOpt.find("MASK") != std::string::npos)) { fMaskHist->Write(); } // Write Covariances if (drawOpt.find("COV") != std::string::npos && fFullCovar) { PlotUtils::GetFullCovarPlot(fFullCovar, fSettings.GetName()); } if (drawOpt.find("INVCOV") != std::string::npos && covar) { PlotUtils::GetInvCovarPlot(covar, fSettings.GetName()); } if (drawOpt.find("DECOMP") != std::string::npos && fDecomp) { PlotUtils::GetDecompCovarPlot(fDecomp, fSettings.GetName()); } // // Likelihood residual plots // if (drawOpt.find("RESIDUAL") != std::string::npos) { // WriteResidualPlots(); // } // // RATIO // if (drawOpt.find("CANVMC") != std::string::npos) { // TCanvas* c1 = WriteMCCanvas(fDataHist, fMCHist); // c1->Write(); // delete c1; // } // // PDG // if (drawOpt.find("CANVPDG") != std::string::npos && fMCHist_Modes) { // TCanvas* c2 = WritePDGCanvas(fDataHist, fMCHist, fMCHist_Modes); // c2->Write(); // delete c2; // } // Write Extra Histograms AutoWriteExtraTH1(); WriteExtraHistograms(); /// 2D VERSION // If null pointer return if (!fMCHist and !fDataHist) { LOG(SAM) << fName << "Incomplete histogram set!" << std::endl; return; } // FitPar::Config().out->cd(); // Get Draw Options drawOpt = FitPar::Config().GetParS("drawopts"); bool drawData = (drawOpt.find("DATA") != std::string::npos); bool drawNormal = (drawOpt.find("MC") != std::string::npos); bool drawEvents = (drawOpt.find("EVT") != std::string::npos); bool drawXSec = (drawOpt.find("XSEC") != std::string::npos); bool drawFine = (drawOpt.find("FINE") != std::string::npos); bool drawRatio = (drawOpt.find("RATIO") != std::string::npos); // bool drawModes = (drawOpt.find("MODES") != std::string::npos); bool drawShape = (drawOpt.find("SHAPE") != std::string::npos); bool residual = (drawOpt.find("RESIDUAL") != std::string::npos); bool drawMatrix = (drawOpt.find("MATRIX") != std::string::npos); bool drawFlux = (drawOpt.find("FLUX") != std::string::npos); bool drawMask = (drawOpt.find("MASK") != std::string::npos); bool drawMap = (drawOpt.find("MAP") != std::string::npos); bool drawProj = (drawOpt.find("PROJ") != std::string::npos); // bool drawCanvPDG = (drawOpt.find("CANVPDG") != std::string::npos); bool drawCov = (drawOpt.find("COV") != std::string::npos); bool drawSliceCanvYMC = (drawOpt.find("CANVYMC") != std::string::npos); bool drawWeighted = (drawOpt.find("WGHT") != std::string::npos); if (FitPar::Config().GetParB("EventManager")) { drawFlux = false; drawXSec = false; drawEvents = false; } if (fMaskHist) fMaskHist->Write(); // Save standard plots if (drawData) this->GetDataList().at(0)->Write(); if (drawNormal) this->GetMCList().at(0)->Write(); if (drawCov) { TH2D(*fFullCovar).Write((fName + "_COV").c_str()); } if (drawOpt.find("INVCOV") != std::string::npos) { TH2D(*covar).Write((fName + "_INVCOV").c_str()); } // Generate a simple map if (!fMapHist) fMapHist = StatUtils::GenerateMap(fDataHist); // Convert to 1D Lists TH1D* data_1D = StatUtils::MapToTH1D(fDataHist, fMapHist); TH1D* mc_1D = StatUtils::MapToTH1D(fMCHist, fMapHist); TH1I* mask_1D = StatUtils::MapToMask(fMaskHist, fMapHist); data_1D->Write(); mc_1D->Write(); if (mask_1D) { mask_1D->Write(); TMatrixDSym* calc_cov = StatUtils::ApplyInvertedMatrixMasking(covar, mask_1D); TH1D* calc_data = StatUtils::ApplyHistogramMasking(data_1D, mask_1D); TH1D* calc_mc = StatUtils::ApplyHistogramMasking(mc_1D, mask_1D); TH2D* bin_cov = new TH2D(*calc_cov); bin_cov->Write(); calc_data->Write(); calc_mc->Write(); delete mask_1D; delete calc_cov; delete calc_data; delete calc_mc; delete bin_cov; } delete data_1D; delete mc_1D; // Save only mc and data if splines if (fEventType == 4 or fEventType == 3) { return; } // Draw Extra plots if (drawFine) this->GetFineList().at(0)->Write(); if (drawFlux and GetFluxHistogram()) { GetFluxHistogram()->Write(); } if (drawEvents and GetEventHistogram()) { GetEventHistogram()->Write(); } if (fIsMask and drawMask) { fMaskHist->Write((fName + "_MSK").c_str()); //< save mask } if (drawMap) fMapHist->Write((fName + "_MAP").c_str()); //< save map // // Save neut stack // if (drawModes) { // THStack combo_fMCHist_PDG = PlotUtils::GetNeutModeStack( // (fName + "_MC_PDG").c_str(), (TH1**)fMCHist_PDG, 0); // combo_fMCHist_PDG.Write(); // } // Save Matrix plots if (drawMatrix and fFullCovar and covar and fDecomp) { TH2D cov = TH2D((*fFullCovar)); cov.SetNameTitle((fName + "_cov").c_str(), (fName + "_cov;Bins; Bins;").c_str()); cov.Write(); TH2D covinv = TH2D((*this->covar)); covinv.SetNameTitle((fName + "_covinv").c_str(), (fName + "_cov;Bins; Bins;").c_str()); covinv.Write(); TH2D covdec = TH2D((*fDecomp)); covdec.SetNameTitle((fName + "_covdec").c_str(), (fName + "_cov;Bins; Bins;").c_str()); covdec.Write(); } // Save ratio plots if required if (drawRatio) { // Needed for error bars for (int i = 0; i < fMCHist->GetNbinsX() * fMCHist->GetNbinsY(); i++) fMCHist->SetBinError(i + 1, 0.0); fDataHist->GetSumw2(); fMCHist->GetSumw2(); // Create Ratio Histograms TH2D* dataRatio = (TH2D*)fDataHist->Clone((fName + "_data_RATIO").c_str()); TH2D* mcRatio = (TH2D*)fMCHist->Clone((fName + "_MC_RATIO").c_str()); mcRatio->Divide(fMCHist); dataRatio->Divide(fMCHist); // Cancel bin errors on MC for (int i = 0; i < mcRatio->GetNbinsX() * mcRatio->GetNbinsY(); i++) { mcRatio->SetBinError( i + 1, fMCHist->GetBinError(i + 1) / fMCHist->GetBinContent(i + 1)); } mcRatio->SetMinimum(0); mcRatio->SetMaximum(2); dataRatio->SetMinimum(0); dataRatio->SetMaximum(2); mcRatio->Write(); dataRatio->Write(); delete mcRatio; delete dataRatio; } // Save Shape Plots if required if (drawShape) { // Create Shape Histogram TH2D* mcShape = (TH2D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str()); double shapeScale = 1.0; if (fIsRawEvents) { shapeScale = fDataHist->Integral() / fMCHist->Integral(); } else { shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width"); } mcShape->Scale(shapeScale); mcShape->SetLineWidth(3); mcShape->SetLineStyle(7); // dashes mcShape->Write(); // Save shape ratios if (drawRatio) { // Needed for error bars mcShape->GetSumw2(); // Create shape ratio histograms TH2D* mcShapeRatio = (TH2D*)mcShape->Clone((fName + "_MC_SHAPE_RATIO").c_str()); TH2D* dataShapeRatio = (TH2D*)fDataHist->Clone((fName + "_data_SHAPE_RATIO").c_str()); // Divide the histograms mcShapeRatio->Divide(mcShape); dataShapeRatio->Divide(mcShape); // Colour the shape ratio plots mcShapeRatio->SetLineWidth(3); mcShapeRatio->SetLineStyle(7); // dashes mcShapeRatio->Write(); dataShapeRatio->Write(); delete mcShapeRatio; delete dataShapeRatio; } delete mcShape; } // Save residual calculations of what contributed to the chi2 values. if (residual) { } if (fIsProjFitX or fIsProjFitY or drawProj) { // If not already made, make the projections if (!fMCHist_X) { PlotUtils::MatchEmptyBins(fDataHist, fMCHist); fMCHist_X = PlotUtils::GetProjectionX(fMCHist, fMaskHist); fMCHist_Y = PlotUtils::GetProjectionY(fMCHist, fMaskHist); fDataHist_X = PlotUtils::GetProjectionX(fDataHist, fMaskHist); fDataHist_Y = PlotUtils::GetProjectionY(fDataHist, fMaskHist); double chi2X = StatUtils::GetChi2FromDiag(fDataHist_X, fMCHist_X); double chi2Y = StatUtils::GetChi2FromDiag(fDataHist_Y, fMCHist_Y); fMCHist_X->SetTitle(Form("%f", chi2X)); fMCHist_Y->SetTitle(Form("%f", chi2Y)); } // Save the histograms fDataHist_X->Write(); fMCHist_X->Write(); fDataHist_Y->Write(); fMCHist_Y->Write(); } if (drawSliceCanvYMC or true) { TCanvas* c1 = new TCanvas((fName + "_MC_CANV_Y").c_str(), (fName + "_MC_CANV_Y").c_str(), 800, 600); c1->Divide(int(sqrt(fDataHist->GetNbinsY() + 1)), int(sqrt(fDataHist->GetNbinsY() + 1))); TH2D* mcShape = (TH2D*)fMCHist->Clone((fName + "_MC_SHAPE").c_str()); double shapeScale = fDataHist->Integral("width") / fMCHist->Integral("width"); mcShape->Scale(shapeScale); mcShape->SetLineStyle(7); c1->cd(1); TLegend* leg = new TLegend(0.6, 0.6, 0.9, 0.9); leg->AddEntry(fDataHist, (fName + " Data").c_str(), "ep"); leg->AddEntry(fMCHist, (fName + " MC").c_str(), "l"); leg->AddEntry(mcShape, (fName + " Shape").c_str(), "l"); leg->Draw("SAME"); /* // Make Y slices for (int i = 0; i < fDataHist->GetNbinY(); i++){ c1->cd(i+2); TH1D* fDataHist_SliceY = PlotUtils::GetSliceY(fDataHist, i); fDataHist_SliceY->Draw("E1"); TH1D* fMCHist_SliceY = PlotUtils::GetSliceY(fMCHist, i); fMCHist_SliceY->Draw("SAME HIST C"); TH1D* mcShape_SliceY = PlotUtils::GetSliceY(mcShape, i); mcShape_SliceY->Draw("SAME HIST C"); } */ c1->Write(); } if (drawWeighted) { fMCWeighted->Write(); } // Returning LOG(SAM) << "Written Histograms: " << fName << std::endl; return; // Returning LOG(SAM) << "Written Histograms: " << fName << std::endl; return; } /* Setup Functions */ //******************************************************************** void Measurement2D::SetupMeasurement(std::string inputfile, std::string type, FitWeight* rw, std::string fkdt) { //******************************************************************** // Check if name contains Evt, indicating that it is a raw number of events // measurements and should thus be treated as once fIsRawEvents = false; if ((fName.find("Evt") != std::string::npos) && fIsRawEvents == false) { fIsRawEvents = true; LOG(SAM) << "Found event rate measurement but fIsRawEvents == false!" << std::endl; LOG(SAM) << "Overriding this and setting fIsRawEvents == true!" << std::endl; } fIsEnu = false; if ((fName.find("XSec") != std::string::npos) && (fName.find("Enu") != std::string::npos)) { fIsEnu = true; LOG(SAM) << "::" << fName << "::" << std::endl; LOG(SAM) << "Found XSec Enu measurement, applying flux integrated scaling, " "not flux averaged!" << std::endl; if (FitPar::Config().GetParB("EventManager")) { ERR(FTL) << "Enu Measurements do not yet work with the Event Manager!" << std::endl; ERR(FTL) << "If you want decent flux unfolded results please run in " "series mode (-q EventManager=0)" << std::endl; sleep(2); } } if (fIsEnu && fIsRawEvents) { LOG(SAM) << "Found 1D Enu XSec distribution AND fIsRawEvents, is this " "really correct?!" << std::endl; LOG(SAM) << "Check experiment constructor for " << fName << " and correct this!" << std::endl; LOG(SAM) << "I live in " << __FILE__ << ":" << __LINE__ << std::endl; exit(-1); } // Reset everything to NULL fRW = rw; // Setting up 2D Inputs this->SetupInputs(inputfile); // Set Default Options SetFitOptions(fDefaultTypes); // Set Passed Options SetFitOptions(type); } //******************************************************************** void Measurement2D::SetupDefaultHist() { //******************************************************************** // Setup fMCHist fMCHist = (TH2D*)fDataHist->Clone(); fMCHist->SetNameTitle((fName + "_MC").c_str(), (fName + "_MC" + fPlotTitles).c_str()); // Setup fMCFine Int_t nBinsX = fMCHist->GetNbinsX(); Int_t nBinsY = fMCHist->GetNbinsY(); fMCFine = new TH2D((fName + "_MC_FINE").c_str(), (fName + "_MC_FINE" + fPlotTitles).c_str(), nBinsX * 3, fMCHist->GetXaxis()->GetBinLowEdge(1), fMCHist->GetXaxis()->GetBinLowEdge(nBinsX + 1), nBinsY * 3, fMCHist->GetYaxis()->GetBinLowEdge(1), fMCHist->GetYaxis()->GetBinLowEdge(nBinsY + 1)); // Setup MC Stat fMCStat = (TH2D*)fMCHist->Clone(); fMCStat->Reset(); // Setup the NEUT Mode Array - PlotUtils::CreateNeutModeArray(fMCHist, (TH1**)fMCHist_PDG); + //PlotUtils::CreateNeutModeArray(fMCHist, (TH1**)fMCHist_PDG); // Setup bin masks using sample name if (fIsMask) { std::string maskloc = FitPar::Config().GetParDIR(fName + ".mask"); if (maskloc.empty()) { maskloc = FitPar::GetDataBase() + "/masks/" + fName + ".mask"; } SetBinMask(maskloc); } return; } //******************************************************************** void Measurement2D::SetDataValues(std::string dataFile, std::string TH2Dname) { //******************************************************************** if (dataFile.find(".root") == std::string::npos) { ERR(FTL) << "Error! " << dataFile << " is not a .root file" << std::endl; ERR(FTL) << "Currently only .root file reading is supported (MiniBooNE " "CC1pi+ 2D), but implementing .txt should be dirt easy" << std::endl; ERR(FTL) << "See me at " << __FILE__ << ":" << __LINE__ << std::endl; exit(-1); } else { TFile* inFile = new TFile(dataFile.c_str(), "READ"); fDataHist = (TH2D*)(inFile->Get(TH2Dname.c_str())->Clone()); fDataHist->SetDirectory(0); fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_MC" + fPlotTitles).c_str()); delete inFile; } return; } //******************************************************************** void Measurement2D::SetDataValues(std::string dataFile, double dataNorm, std::string errorFile, double errorNorm) { //******************************************************************** // Make a counter to track the line number int yBin = 0; std::string line; std::ifstream data(dataFile.c_str(), ifstream::in); fDataHist = new TH2D((fName + "_data").c_str(), (fName + fPlotTitles).c_str(), fNDataPointsX - 1, fXBins, fNDataPointsY - 1, fYBins); if (data.is_open()) LOG(SAM) << "Reading data from: " << dataFile.c_str() << std::endl; while (std::getline(data >> std::ws, line, '\n')) { int xBin = 0; // Loop over entries and insert them into the histogram std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { fDataHist->SetBinContent(xBin + 1, yBin + 1, (*iter) * dataNorm); xBin++; } yBin++; } yBin = 0; std::ifstream error(errorFile.c_str(), ifstream::in); if (error.is_open()) LOG(SAM) << "Reading errors from: " << errorFile.c_str() << std::endl; while (std::getline(error >> std::ws, line, '\n')) { int xBin = 0; // Loop over entries and insert them into the histogram std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { fDataHist->SetBinError(xBin + 1, yBin + 1, (*iter) * errorNorm); xBin++; } yBin++; } return; }; //******************************************************************** void Measurement2D::SetDataValuesFromText(std::string dataFile, double dataNorm) { //******************************************************************** fDataHist = new TH2D((fName + "_data").c_str(), (fName + fPlotTitles).c_str(), fNDataPointsX - 1, fXBins, fNDataPointsY - 1, fYBins); LOG(SAM) << "Reading data from: " << dataFile << std::endl; PlotUtils::Set2DHistFromText(dataFile, fDataHist, dataNorm, true); return; }; //******************************************************************** void Measurement2D::SetCovarMatrix(std::string covarFile) { //******************************************************************** // Used to read a covariance matrix from a root file TFile* tempFile = new TFile(covarFile.c_str(), "READ"); // Make plots that we want TH2D* covarPlot = new TH2D(); // TH2D* decmpPlot = new TH2D(); TH2D* covarInvPlot = new TH2D(); TH2D* fFullCovarPlot = new TH2D(); // Get covariance options for fake data studies std::string covName = ""; std::string covOption = FitPar::Config().GetParS("throw_covariance"); // Which matrix to get? if (fIsShape || fIsFree) covName = "shp_"; if (fIsDiag) covName += "diag"; else covName += "full"; covarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str()); covarInvPlot = (TH2D*)tempFile->Get((covName + "covinv").c_str()); // Throw either the sub matrix or the full matrix if (!covOption.compare("SUB")) fFullCovarPlot = (TH2D*)tempFile->Get((covName + "cov").c_str()); else if (!covOption.compare("FULL")) fFullCovarPlot = (TH2D*)tempFile->Get("fullcov"); else ERR(WRN) << " Incorrect thrown_covariance option in parameters." << std::endl; // Bin masking? int dim = int(fDataHist->GetNbinsX()); //-this->masked->Integral()); int covdim = int(fDataHist->GetNbinsX()); // Make new covars this->covar = new TMatrixDSym(dim); fFullCovar = new TMatrixDSym(dim); fDecomp = new TMatrixDSym(dim); // Full covariance values int row, column = 0; row = 0; column = 0; for (Int_t i = 0; i < covdim; i++) { // masking can be dodgy // if (this->masked->GetBinContent(i+1) > 0) continue; for (Int_t j = 0; j < covdim; j++) { // if (this->masked->GetBinContent(j+1) > 0) continue; (*this->covar)(row, column) = covarPlot->GetBinContent(i + 1, j + 1); (*fFullCovar)(row, column) = fFullCovarPlot->GetBinContent(i + 1, j + 1); column++; } column = 0; row++; } // Set bin errors on data if (!fIsDiag) { for (Int_t i = 0; i < fDataHist->GetNbinsX(); i++) { fDataHist->SetBinError( i + 1, sqrt((covarPlot->GetBinContent(i + 1, i + 1))) * 1E-38); } } TDecompSVD LU = TDecompSVD(*this->covar); this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); tempFile->Close(); delete tempFile; return; }; //******************************************************************** void Measurement2D::SetCovarMatrixFromText(std::string covarFile, int dim) { //******************************************************************** // Make a counter to track the line number int row = 0; std::string line; std::ifstream covar(covarFile.c_str(), ifstream::in); this->covar = new TMatrixDSym(dim); fFullCovar = new TMatrixDSym(dim); if (covar.is_open()) LOG(SAM) << "Reading covariance matrix from file: " << covarFile << std::endl; while (std::getline(covar >> std::ws, line, '\n')) { int column = 0; // Loop over entries and insert them into matrix // Multiply by the errors to get the covariance, rather than the correlation // matrix std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { double val = (*iter) * fDataHist->GetBinError(row + 1) * 1E38 * fDataHist->GetBinError(column + 1) * 1E38; (*this->covar)(row, column) = val; (*fFullCovar)(row, column) = val; column++; } row++; } // Robust matrix inversion method TDecompSVD LU = TDecompSVD(*this->covar); this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); return; }; //******************************************************************** void Measurement2D::SetCovarMatrixFromChol(std::string covarFile, int dim) { //******************************************************************** // Make a counter to track the line number int row = 0; std::string line; std::ifstream covarread(covarFile.c_str(), ifstream::in); TMatrixD* newcov = new TMatrixD(dim, dim); if (covarread.is_open()) LOG(SAM) << "Reading covariance matrix from file: " << covarFile << std::endl; while (std::getline(covarread >> std::ws, line, '\n')) { int column = 0; // Loop over entries and insert them into matrix // Multiply by the errors to get the covariance, rather than the correlation // matrix std::vector entries = GeneralUtils::ParseToDbl(line, " "); for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { (*newcov)(row, column) = *iter; column++; } row++; } covarread.close(); // Form full covariance TMatrixD* trans = (TMatrixD*)(newcov)->Clone(); trans->T(); (*trans) *= (*newcov); fFullCovar = new TMatrixDSym(dim, trans->GetMatrixArray(), ""); delete newcov; delete trans; // Robust matrix inversion method TDecompChol LU = TDecompChol(*this->fFullCovar); this->covar = new TMatrixDSym(dim, LU.Invert().GetMatrixArray(), ""); return; }; // //******************************************************************** // void Measurement2D::SetMapValuesFromText(std::string dataFile) { // //******************************************************************** // fMapHist = new TH2I((fName + "_map").c_str(), (fName + fPlotTitles).c_str(), // fNDataPointsX - 1, fXBins, fNDataPointsY - 1, fYBins); // LOG(SAM) << "Reading map from: " << dataFile << std::endl; // PlotUtils::Set2DHistFromText(dataFile, fMapHist, 1.0); // return; // }; diff --git a/src/FitBase/MeasurementBase.cxx b/src/FitBase/MeasurementBase.cxx index a77597e..235b470 100644 --- a/src/FitBase/MeasurementBase.cxx +++ b/src/FitBase/MeasurementBase.cxx @@ -1,561 +1,562 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MeasurementBase.h" /* Constructor/Destructors */ //******************************************************************** // 2nd Level Constructor (Inherits From MeasurementBase.h) MeasurementBase::MeasurementBase(void) { //******************************************************************** fScaleFactor = 1.0; fMCFilled = false; fNoData = false; fInput = NULL; // Set the default values // After-wards this gets set in SetupMeasurement EnuMin = 0.; EnuMax = 1.E5; fMeasurementSpeciesType = kSingleSpeciesMeasurement; fEventVariables = NULL; fIsJoint = false; }; void MeasurementBase::FinaliseMeasurement() { // Used to setup default data hists, covars, etc. } //******************************************************************** // 2nd Level Destructor (Inherits From MeasurementBase.h) MeasurementBase::~MeasurementBase() { //******************************************************************** }; //******************************************************************** double MeasurementBase::TotalIntegratedFlux(std::string intOpt, double low, double high) { //******************************************************************** // Set Energy Limits if (low == -9999.9) low = this->EnuMin; if (high == -9999.9) high = this->EnuMax; return GetInput()->TotalIntegratedFlux(low, high, intOpt); }; //******************************************************************** double MeasurementBase::PredictedEventRate(std::string intOpt, double low, double high) { //******************************************************************** // Set Energy Limits if (low == -9999.9) low = this->EnuMin; if (high == -9999.9) high = this->EnuMax; return GetInput()->PredictedEventRate(low, high, intOpt) * 1E-38; }; //******************************************************************** void MeasurementBase::SetupInputs(std::string inputfile) { //******************************************************************** // Add this infile to the global manager if (FitPar::Config().GetParB("EventManager")) { fInput = FitBase::AddInput(fName, inputfile); } else { std::vector file_descriptor = GeneralUtils::ParseToStr(inputfile, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfile << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inpType = InputUtils::ParseInputType(file_descriptor[0]); fInput = InputUtils::CreateInputHandler(fName, inpType, file_descriptor[1]); } fNEvents = fInput->GetNEvents(); // Expect INPUTTYPE:FileLocation(s) std::vector file_descriptor = GeneralUtils::ParseToStr(inputfile, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfile << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } fInputType = InputUtils::ParseInputType(file_descriptor[0]); fInputFileName = file_descriptor[1]; if (EnuMin == 0 && EnuMax == 1.E5) { EnuMin = fInput->GetFluxHistogram()->GetBinLowEdge(1); EnuMax = fInput->GetFluxHistogram()->GetBinLowEdge( fInput->GetFluxHistogram()->GetNbinsX() + 1); } fFluxHist = fInput->GetFluxHistogram(); fEventHist = fInput->GetEventHistogram(); } //*********************************************** int MeasurementBase::GetInputID() { //*********************************************** return FitBase::GetInputID(fInputFileName); } //*********************************************** SampleSettings MeasurementBase::LoadSampleSettings(nuiskey samplekey) { //*********************************************** SampleSettings setting = SampleSettings(samplekey); fName = setting.GetS("name"); // Used as an initial setup function incase we need to do anything here. LOG(SAM) << "Loading Sample : " << setting.GetName() << std::endl; if (!fIsJoint) SetupInputs( setting.GetS("input") ); return setting; } //*********************************************** SampleSettings MeasurementBase::LoadSampleSettings(std::string name, std::string input, std::string type) { //*********************************************** nuiskey samplekey = Config::CreateKey("sample"); samplekey.SetS("name",name); samplekey.SetS("input",input); samplekey.SetS("type",type); return LoadSampleSettings(samplekey); } void MeasurementBase::FinaliseSampleSettings() { EnuMin = fSettings.GetD("enu_min"); EnuMax = fSettings.GetD("enu_max"); } //*********************************************** void MeasurementBase::Reconfigure() { //*********************************************** LOG(REC) << " Reconfiguring sample " << fName << std::endl; // Reset Histograms ResetExtraHistograms(); AutoResetExtraTH1(); this->ResetAll(); // FitEvent* cust_event = fInput->GetEventPointer(); int fNEvents = fInput->GetNEvents(); int countwidth = (fNEvents / 5); // MAIN EVENT LOOP FitEvent* cust_event = fInput->FirstNuisanceEvent(); int i = 0; int npassed = 0; while(cust_event){ cust_event->RWWeight = fRW->CalcWeight(cust_event); cust_event->Weight = cust_event->RWWeight * cust_event->InputWeight; Weight = cust_event->Weight; // Initialize fXVar = -999.9; fYVar = -999.9; fZVar = -999.9; Signal = false; Mode = cust_event->Mode; // Extract Measurement Variables this->FillEventVariables(cust_event); Signal = this->isSignal(cust_event); if (Signal) npassed++; GetBox()->SetX(fXVar); GetBox()->SetY(fYVar); GetBox()->SetZ(fZVar); GetBox()->SetMode(Mode); // GetBox()->fSignal = Signal; // Fill Histogram Values GetBox()->FillBoxFromEvent(cust_event); // this->FillExtraHistograms(GetBox(), Weight); this->FillHistogramsFromBox(GetBox(), Weight); // Print Out if (LOG_LEVEL(REC) && countwidth > 0 && !(i % countwidth)) { std::stringstream ss(""); ss.unsetf(std::ios_base::fixed); ss << std::setw(7) << std::right << i << "/" << fNEvents << " events (" << std::setw(2) << double(i) / double(fNEvents) * 100. << std::left << std::setw(5) << "%) " << "[S,X,Y,Z,M,W] = [" << std::fixed << std::setprecision(2) << std::right << Signal << ", " << std::setw(5) << fXVar << ", " << std::setw(5) << fYVar << ", " << std::setw(5) << fYVar << ", " << std::setw(3) << (int)Mode << ", " << std::setw(5) << Weight << "] " << std::endl; LOG(SAM) << ss.str(); } // iterate cust_event = fInput->NextNuisanceEvent(); i++; } LOG(SAM) << npassed << "/" << fNEvents << " passed selection " << std::endl; if (npassed == 0) { LOG(SAM) << "WARNING: NO EVENTS PASSED SELECTION!" << std::endl; } LOG(REC) << std::setw(10) << std::right << NSignal << "/" << fNEvents << " events passed selection + binning after reweight" << std::endl; // Finalise Histograms fMCFilled = true; this->ConvertEventRates(); } void MeasurementBase::FillHistogramsFromBox(MeasurementVariableBox* var, double weight) { fXVar = var->GetX(); fYVar = var->GetY(); fZVar = var->GetZ(); // Signal = var->fSignal; // Mode = var->fMode; Weight = weight; + fEventVariables = var; FillHistograms(); FillExtraHistograms(var, weight); } void MeasurementBase::FillHistograms(double weight){ Weight = weight * GetBox()->GetSampleWeight(); FillHistograms(); FillExtraHistograms(GetBox(), Weight); } MeasurementVariableBox* MeasurementBase::FillVariableBox(FitEvent* event) { GetBox()->Reset(); Mode = event->Mode; Weight = 1.0; //event->Weight; this->FillEventVariables(event); Signal = this->isSignal(event); GetBox()->FillBoxFromEvent(event); GetBox()->SetX(fXVar); GetBox()->SetY(fYVar); GetBox()->SetZ(fZVar); GetBox()->SetMode(event->Mode); GetBox()->SetSampleWeight(Weight); // GetBox()->fSignal = Signal; return GetBox(); } MeasurementVariableBox* MeasurementBase::GetBox() { if (!fEventVariables) fEventVariables = CreateBox(); return fEventVariables; } //*********************************************** void MeasurementBase::ReconfigureFast() { //*********************************************** this->Reconfigure(); } //*********************************************** void MeasurementBase::ConvertEventRates() { //*********************************************** AutoScaleExtraTH1(); ScaleExtraHistograms(GetBox()); this->ScaleEvents(); double normval = fRW->GetSampleNorm(this->fName); if (normval < 0.01 or normval > 10.0){ ERR(WRN) << "Norm Value inside MeasurementBase::ConvertEventRates() looks off!" << std::endl; ERR(WRN) << "It could have become out of sync with the minimizer norm list." << std::endl; ERR(WRN) << "Setting it to 1.0" << std::endl; normval = 1.0; } AutoNormExtraTH1(normval); NormExtraHistograms(GetBox(), normval); this->ApplyNormScale(normval); } //*********************************************** InputHandlerBase* MeasurementBase::GetInput() { //*********************************************** if (!fInput) { ERR(FTL) << "MeasurementBase::fInput not set. Please submit your command " "line options and input cardfile with a bug report to: " "nuisance@projects.hepforge.org" << std::endl; throw; } return fInput; }; //*********************************************** void MeasurementBase::Renormalise() { //*********************************************** // Called when the fitter has changed a measurements normalisation but not any // reweight dials // Means we don't have to call the time consuming reconfigure when this // happens. double norm = fRW->GetDialValue(this->fName + "_norm"); if ((this->fCurrentNorm == 0.0 and norm != 0.0) or not fMCFilled) { this->ReconfigureFast(); return; } if (this->fCurrentNorm == norm) return; this->ApplyNormScale(1.0 / this->fCurrentNorm); this->ApplyNormScale(norm); return; }; //*********************************************** void MeasurementBase::SetSignal(bool sig) { //*********************************************** Signal = sig; } //*********************************************** void MeasurementBase::SetSignal(FitEvent* evt) { //*********************************************** Signal = this->isSignal(evt); } //*********************************************** void MeasurementBase::SetWeight(double wght) { //*********************************************** Weight = wght; } //*********************************************** void MeasurementBase::SetMode(int md) { //*********************************************** Mode = md; } //*********************************************** std::vector MeasurementBase::GetFluxList() { //*********************************************** return GetInput()->GetFluxList(); } //*********************************************** std::vector MeasurementBase::GetEventRateList() { //*********************************************** return GetInput()->GetEventList(); } //*********************************************** std::vector MeasurementBase::GetXSecList() { //*********************************************** return GetInput()->GetXSecList(); } void MeasurementBase::ProcessExtraHistograms(int cmd, MeasurementVariableBox* vars, double weight) { // This should be overriden if we have extra histograms!!! // Add a flag to tell user this... return; } void MeasurementBase::FillExtraHistograms(MeasurementVariableBox* vars, double weight) { ProcessExtraHistograms(kCMD_Fill, vars, weight); } void MeasurementBase::ScaleExtraHistograms(MeasurementVariableBox* vars) { ProcessExtraHistograms(kCMD_Scale, vars, 1.0); } void MeasurementBase::ResetExtraHistograms() { ProcessExtraHistograms(kCMD_Reset, NULL, 1.0); } void MeasurementBase::NormExtraHistograms(MeasurementVariableBox* vars, double norm) { ProcessExtraHistograms(kCMD_Norm, vars, norm); } void MeasurementBase::WriteExtraHistograms() { ProcessExtraHistograms(kCMD_Write, NULL, 1.00); } void MeasurementBase::SetAutoProcessTH1(TH1* hist, int c1, int c2, int c3, int c4, int c5) { FakeStack* fake = new FakeStack(hist); SetAutoProcessTH1(fake, c1, c2, c3, c4, c5); // Need to add a destroy command! } void MeasurementBase::SetAutoProcess(TH1* hist, int c1, int c2, int c3, int c4, int c5) { FakeStack* fake = new FakeStack(hist); SetAutoProcessTH1(fake, c1, c2, c3, c4, c5); // Need to add a destroy command! } void MeasurementBase::SetAutoProcess(TGraph* g, int c1, int c2, int c3, int c4, int c5) { FakeStack* fake = new FakeStack(g); SetAutoProcessTH1(fake, c1, c2, c3, c4, c5); // Need to add a destroy command! } void MeasurementBase::SetAutoProcess(TF1* f, int c1, int c2, int c3, int c4, int c5) { FakeStack* fake = new FakeStack(f); SetAutoProcessTH1(fake, c1, c2, c3, c4, c5); // Need to add a destroy command! } void MeasurementBase::SetAutoProcess(StackBase* hist, int c1, int c2, int c3, int c4, int c5){ SetAutoProcessTH1(hist, c1, c2, c3, c4, c5); } void MeasurementBase::SetAutoProcessTH1(StackBase* hist, int c1, int c2, int c3, int c4, int c5) { // Set Defaults // int ncommands = kCMD_extraplotflags; bool autoflags[5]; autoflags[0] = false; autoflags[1] = false; autoflags[2] = false; autoflags[3] = false; autoflags[4] = false; int givenflags[5]; givenflags[0] = c1; givenflags[1] = c2; givenflags[2] = c3; givenflags[3] = c4; givenflags[4] = c5; fExtraTH1s[hist] = std::vector(5,0); // Setup a default one. if (c1 == -1 && c2 == -1 && c3 == -1 && c4 == -1 && c5 == -1){ fExtraTH1s[hist][kCMD_Reset] = 1; fExtraTH1s[hist][kCMD_Scale] = 1; fExtraTH1s[hist][kCMD_Norm] = 1; fExtraTH1s[hist][kCMD_Write] = 1; } for (int i = 0; i < 5; i++) { switch (givenflags[i]) { // Skip over... case -1: break; case kCMD_Reset: case kCMD_Scale: case kCMD_Norm: case kCMD_Write: fExtraTH1s[hist][givenflags[i]] = 1; break; case kCMD_Fill: ERR(FTL) << "Can't auto fill yet!" << std::endl; autoflags[givenflags[i]] = 1; break; default: break; } } // LOG(SAM) << "AutoProcessing " << hist->GetName() << std::endl; }; void MeasurementBase::AutoFillExtraTH1() { ERR(FTL) << "Can't auto fill yet! it's too inefficent!" << std::endl; return; } void MeasurementBase::AutoResetExtraTH1() { for (std::map >::iterator iter = fExtraTH1s.begin(); iter != fExtraTH1s.end(); iter++) { if (!((*iter).second)[kCMD_Reset]) continue; (*iter).first->Reset(); } }; void MeasurementBase::AutoScaleExtraTH1() { for (std::map >::iterator iter = fExtraTH1s.begin(); iter != fExtraTH1s.end(); iter++) { if (!((*iter).second)[kCMD_Scale]) continue; if (fIsNoWidth){ (*iter).first->Scale(fScaleFactor); } else { (*iter).first->Scale(fScaleFactor, "width"); } } }; void MeasurementBase::AutoNormExtraTH1(double norm) { double sfactor = 0.0; if (norm != 0.0) sfactor = 1.0 / norm; for (std::map >::iterator iter = fExtraTH1s.begin(); iter != fExtraTH1s.end(); iter++) { if (!((*iter).second)[kCMD_Norm]) continue; (*iter).first->Scale(sfactor); } }; void MeasurementBase::AutoWriteExtraTH1() { for (std::map >::iterator iter = fExtraTH1s.begin(); iter != fExtraTH1s.end(); iter++) { if (!(((*iter).second)[kCMD_Write])) continue; (*iter).first->Write(); } }; diff --git a/src/K2K/K2K_NC1pi0_Evt_1Dppi0_nu.cxx b/src/K2K/K2K_NC1pi0_Evt_1Dppi0_nu.cxx index e93aee9..523a194 100644 --- a/src/K2K/K2K_NC1pi0_Evt_1Dppi0_nu.cxx +++ b/src/K2K/K2K_NC1pi0_Evt_1Dppi0_nu.cxx @@ -1,73 +1,72 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "K2K_NC1pi0_Evt_1Dppi0_nu.h" // The constructor K2K_NC1pi0_Evt_1Dppi0_nu::K2K_NC1pi0_Evt_1Dppi0_nu(nuiskey samplekey){ // Sample overview --------------------------------------------------- std::string descrip = "K2K_NC1pi0_Evt_1Dppi0_nu sample. \n" \ "Target: D2 \n" \ "Flux: \n" \ "Signal: \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("p_{#pi^{0}} (MeV/c)"); fSettings.SetYTitle("Number of events"); fSettings.SetAllowedTypes("EVT/SHAPE/DIAG", "EVT/SHAPE/DIAG/Q2CORR/MASK"); fSettings.SetEnuRange(0.0, 5.0); fSettings.DefineAllowedTargets("H,O"); // plot information fSettings.SetTitle("K2K_NC1pi0_Evt_1Dppi0_nu"); fSettings.DefineAllowedSpecies("numu"); fSettings.SetDataInput( FitPar::GetDataBase() + "K2K/nc1pi0/ppi0.csv"); FinaliseSampleSettings(); - // Scaling Setup --------------------------------------------------- - // ScaleFactor for shape - fScaleFactor = (fDataHist->Integral() / (fNEvents + 0.)); - // Plot Setup ------------------------------------------------------- SetDataFromTextFile( fSettings.GetDataInput() ); SetCovarFromDiagonal(); + // Scale for shape + fScaleFactor = fDataHist->Integral()/double(fNEvents); + // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void K2K_NC1pi0_Evt_1Dppi0_nu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(111) == 0) return; TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP; double ppi0 = FitUtils::p(Ppi0)*1000.; fXVar = ppi0; return; }; bool K2K_NC1pi0_Evt_1Dppi0_nu::isSignal(FitEvent *event) { return SignalDef::isNC1pi(event, 14, 111, EnuMin, EnuMax); // Check this signal definition } diff --git a/src/MINERvA/MINERvAVariableBoxes.h b/src/MINERvA/MINERvAVariableBoxes.h index 56288f8..06ed9ed 100644 --- a/src/MINERvA/MINERvAVariableBoxes.h +++ b/src/MINERvA/MINERvAVariableBoxes.h @@ -1,30 +1,57 @@ #ifndef MINERvA_VARIABLES_BOX_H #define MINERvA_VARIABLES_BOX_H #include "MeasurementVariableBox.h" #include "MeasurementVariableBox1D.h" #include "MeasurementVariableBox2D.h" /*! * \addtogroup FitBase * @{ */ /// Custom box used to also save All Pion Tpi for each event. class NTpiVariableBox1D : public MeasurementVariableBox1D { public: - inline NTpiVariableBox1D() { Reset(); }; + inline NTpiVariableBox1D() { }; inline void Reset() { fTpiVect.clear(); } + + inline MeasurementVariableBox* CloneSignalBox(){ + NTpiVariableBox1D* box = new NTpiVariableBox1D(); + box->fX = this->fX; + box->fSampleWeight = this->fSampleWeight; + + box->fTpiVect.clear(); + for (int i = 0; i < this->fTpiVect.size(); i++){ + box->fTpiVect.push_back( this->fTpiVect[i] ); + } + return box; + } + inline void Print(){ + std::cout << "Box Print Size : " << this->fTpiVect.size() << std::endl; + } + std::vector fTpiVect; }; /// Custom box used to also save All Pion Tpi for each event. class NthpiVariableBox1D : public MeasurementVariableBox1D { public: - inline NthpiVariableBox1D() { Reset(); }; + inline NthpiVariableBox1D() { }; inline void Reset() { fthpiVect.clear(); } + inline MeasurementVariableBox* CloneSignalBox(){ + NthpiVariableBox1D* box = new NthpiVariableBox1D(); + box->fX = this->fX; + box->fSampleWeight = this->fSampleWeight; + + box->fthpiVect.clear(); + for (int i = 0; i < this->fthpiVect.size(); i++){ + box->fthpiVect.push_back( this->fthpiVect[i] ); + } + return box; + } std::vector fthpiVect; }; #endif diff --git a/src/MINERvA/MINERvA_CC1pi0_XSec_1DEnu_antinu.cxx b/src/MINERvA/MINERvA_CC1pi0_XSec_1DEnu_antinu.cxx index cbee9ae..f5a2fa7 100644 --- a/src/MINERvA/MINERvA_CC1pi0_XSec_1DEnu_antinu.cxx +++ b/src/MINERvA/MINERvA_CC1pi0_XSec_1DEnu_antinu.cxx @@ -1,108 +1,109 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MINERvA_SignalDef.h" #include "MINERvA_CC1pi0_XSec_1DEnu_antinu.h" //******************************************************************** MINERvA_CC1pi0_XSec_1DEnu_antinu::MINERvA_CC1pi0_XSec_1DEnu_antinu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MINERvA_CC1pi0_XSec_1DEnu_antinu sample. \n" \ "Target: CH \n" \ "Flux: MINERvA Forward Horn Current numubar \n" \ "Signal: Any event with 1 muon, 1 pion, no other tracks \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("E_{#nu} (GeV)"); fSettings.SetYTitle("#sigma(E_{#nu} (cm^{2}/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG/NORM/MASK", "FIX/DIAG"); fSettings.SetEnuRange(1.5, 10.0); fSettings.DefineAllowedTargets("C,H"); // CCQELike plot information fSettings.SetTitle("MINERvA_CC1pi0_XSec_1DEnu_antinu"); fSettings.DefineAllowedSpecies("numu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = GetEventHistogram()->Integral("width")*double(1E-38)/double(fNEvents); // Plot Setup ------------------------------------------------------- SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CC1pi0/2016/anu-cc1pi0-xsec-enu.csv"); for (int i = 0; i < fDataHist->GetNbinsX()+1; i++) { fDataHist->SetBinError(i+1, fDataHist->GetBinContent(i+1)*fDataHist->GetBinError(i+1)/100.); } SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir()+"/data/MINERvA/CC1pi0/2016/anu-cc1pi0-correlation-enu.csv"); + SetShapeCovar(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void MINERvA_CC1pi0_XSec_1DEnu_antinu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(-13) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Pmu = event->GetHMFSParticle(-13)->fP; double hadMass = FitUtils::Wrec(Pnu, Pmu); double Enu = -999; if (hadMass < 1800) Enu = Pnu.E()/1000.; fXVar = Enu; return; }; // ************************************** // MINERvA CC1pi0 in anti-neutrino mode // Unfortunately there's no information on the neutrino component which is // subtracted off // // 2014 analysis: // Exactly one positive muon // Exactly one observed pi0 // No pi+/pi allowed // No information on what is done with mesons, oops? // No information on what is done with nucleons, oops? // // 2016 analysis: // Exactly one positive muon // Exactly one observed pi0 // No other mesons // No other charged tracks (means no protons) // //******************************************************************** bool MINERvA_CC1pi0_XSec_1DEnu_antinu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCC1pi0_MINERvA_2016(event, EnuMin, EnuMax); } diff --git a/src/MINERvA/MINERvA_CC1pi0_XSec_1DQ2_antinu.cxx b/src/MINERvA/MINERvA_CC1pi0_XSec_1DQ2_antinu.cxx index 8b3eb7b..f5fc03a 100644 --- a/src/MINERvA/MINERvA_CC1pi0_XSec_1DQ2_antinu.cxx +++ b/src/MINERvA/MINERvA_CC1pi0_XSec_1DQ2_antinu.cxx @@ -1,91 +1,92 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MINERvA_SignalDef.h" #include "MINERvA_CC1pi0_XSec_1DQ2_antinu.h" //******************************************************************** MINERvA_CC1pi0_XSec_1DQ2_antinu::MINERvA_CC1pi0_XSec_1DQ2_antinu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MINERvA_CC1pi0_XSec_1DQ2_antinu sample. \n" \ "Target: CH \n" \ "Flux: MINERvA Forward Horn Current numubar \n" \ "Signal: Any event with 1 muon, 1 pion, no other tracks \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("Q^{2} (GeV^{2})"); fSettings.SetYTitle("d#sigma/dQ^{2} (cm^{2}/(GeV^{2})/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG/NORM/MASK", "FIX/DIAG"); fSettings.SetEnuRange(1.5, 10.0); fSettings.DefineAllowedTargets("C,H"); // CCQELike plot information fSettings.SetTitle("MINERvA_CC1pi0_XSec_1DQ2_antinu"); fSettings.DefineAllowedSpecies("numu"); // fFluxCorrected = fSettings.Found("name", "fluxcorr"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = GetEventHistogram()->Integral("width")*double(1E-38)/double(fNEvents)/TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CC1pi0/2016/anu-cc1pi0-xsec-q2.csv"); for (int i = 0; i < fDataHist->GetNbinsX()+1; i++) { fDataHist->SetBinError(i+1, fDataHist->GetBinContent(i+1)*fDataHist->GetBinError(i+1)/100.); } SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir()+"/data/MINERvA/CC1pi0/2016/anu-cc1pi0-correlation-q2.csv"); + SetShapeCovar(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void MINERvA_CC1pi0_XSec_1DQ2_antinu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(-13) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Pmu = event->GetHMFSParticle(-13)->fP; double hadMass = FitUtils::Wrec(Pnu, Pmu); double Q2 = -999; if (hadMass < 1800) { Q2 = -1*(Pnu-Pmu).Mag2()/1.E6; } fXVar = Q2; return; }; //******************************************************************** bool MINERvA_CC1pi0_XSec_1DQ2_antinu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCC1pi0_MINERvA_2016(event, EnuMin, EnuMax); } diff --git a/src/MINERvA/MINERvA_CC1pi0_XSec_1DTpi0_antinu.cxx b/src/MINERvA/MINERvA_CC1pi0_XSec_1DTpi0_antinu.cxx index 67d9729..cfab2c3 100644 --- a/src/MINERvA/MINERvA_CC1pi0_XSec_1DTpi0_antinu.cxx +++ b/src/MINERvA/MINERvA_CC1pi0_XSec_1DTpi0_antinu.cxx @@ -1,97 +1,98 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MINERvA_SignalDef.h" #include "MINERvA_CC1pi0_XSec_1DTpi0_antinu.h" // The 2016 MINERvA measurement is in Tpi // The 2016 MINERvA measurement is in ppi //******************************************************************** MINERvA_CC1pi0_XSec_1DTpi0_antinu::MINERvA_CC1pi0_XSec_1DTpi0_antinu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MINERvA_CC1pi0_XSec_1DTpi0_antinu sample. \n" \ "Target: CH \n" \ "Flux: MINERvA Forward Horn Current numubar \n" \ "Signal: Any event with 1 muon, 1 pion, no other tracks \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("T_{#pi} (GeV)"); fSettings.SetYTitle("d#sigma/dT_{#pi} (cm^{2}/GeV/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/FULL"); fSettings.SetEnuRange(1.5, 10.0); fSettings.DefineAllowedTargets("C,H"); // CCQELike plot information fSettings.SetTitle("MINERvA_CC1pi0_XSec_1DTpi0_antinu"); fSettings.DefineAllowedSpecies("numu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents) / TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CC1pi0/2016/anu-cc1pi0-xsec-pion-kinetic-energy.csv"); for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) { fDataHist->SetBinError(i + 1, fDataHist->GetBinContent(i + 1)*fDataHist->GetBinError(i + 1) / 100.); } SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CC1pi0/2016/anu-cc1pi0-correlation-pion-kinetic-energy.csv"); + SetShapeCovar(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void MINERvA_CC1pi0_XSec_1DTpi0_antinu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(111) == 0 || event->NumFSParticle(-13) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP; TLorentzVector Pmu = event->GetHMFSParticle(-13)->fP; double hadMass = FitUtils::Wrec(Pnu, Pmu); double Tpi0 = -999; if (hadMass < 1800) Tpi0 = FitUtils::T(Ppi0); fXVar = Tpi0; }; //******************************************************************** bool MINERvA_CC1pi0_XSec_1DTpi0_antinu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCC1pi0_MINERvA_2016(event, EnuMin, EnuMax); } diff --git a/src/MINERvA/MINERvA_CC1pi0_XSec_1Dpmu_antinu.cxx b/src/MINERvA/MINERvA_CC1pi0_XSec_1Dpmu_antinu.cxx index 71ac265..19dfe99 100644 --- a/src/MINERvA/MINERvA_CC1pi0_XSec_1Dpmu_antinu.cxx +++ b/src/MINERvA/MINERvA_CC1pi0_XSec_1Dpmu_antinu.cxx @@ -1,89 +1,90 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MINERvA_SignalDef.h" #include "MINERvA_CC1pi0_XSec_1Dpmu_antinu.h" //******************************************************************** MINERvA_CC1pi0_XSec_1Dpmu_antinu::MINERvA_CC1pi0_XSec_1Dpmu_antinu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MINERvA_CC1pi0_XSec_1Dpmu_antinu sample. \n" \ "Target: CH \n" \ "Flux: MINERvA Forward Horn Current numubarr \n" \ "Signal: Any event with 1 muon, 1 pion, no other tracks \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("p_{#mu} (GeV)"); fSettings.SetYTitle("d#sigma/dp_{#mu} (cm^{2}/GeV/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG/NORM/MASK", "FIX/DIAG"); fSettings.SetEnuRange(1.5, 10.0); fSettings.DefineAllowedTargets("C,H"); // CCQELike plot information fSettings.SetTitle("MINERvA_CC1pi0_XSec_1Dpmu_antinu"); fSettings.DefineAllowedSpecies("numu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = GetEventHistogram()->Integral("width")*double(1E-38)/double(fNEvents)/TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CC1pi0/2016/anu-cc1pi0-xsec-muon-momentum.csv"); for (int i = 0; i < fDataHist->GetNbinsX()+1; i++) { fDataHist->SetBinError(i+1, fDataHist->GetBinContent(i+1)*fDataHist->GetBinError(i+1)/100.); } SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir()+"/data/MINERvA/CC1pi0/2016/anu-cc1pi0-correlation-muon-momentum.csv"); + SetShapeCovar(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void MINERvA_CC1pi0_XSec_1Dpmu_antinu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(-13) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Pmu = event->GetHMFSParticle(-13)->fP; double hadMass = FitUtils::Wrec(Pnu, Pmu); double pmu = -999; if (hadMass < 1800) pmu = FitUtils::p(Pmu); fXVar = pmu; return; }; //******************************************************************** bool MINERvA_CC1pi0_XSec_1Dpmu_antinu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCC1pi0_MINERvA_2016(event, EnuMin, EnuMax); } diff --git a/src/MINERvA/MINERvA_CC1pi0_XSec_1Dth_antinu.cxx b/src/MINERvA/MINERvA_CC1pi0_XSec_1Dth_antinu.cxx index d8a8313..5d56b9d 100644 --- a/src/MINERvA/MINERvA_CC1pi0_XSec_1Dth_antinu.cxx +++ b/src/MINERvA/MINERvA_CC1pi0_XSec_1Dth_antinu.cxx @@ -1,131 +1,132 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MINERvA_SignalDef.h" #include "MINERvA_CC1pi0_XSec_1Dth_antinu.h" //******************************************************************** MINERvA_CC1pi0_XSec_1Dth_antinu::MINERvA_CC1pi0_XSec_1Dth_antinu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MINERvA_CC1pi0_XSec_1Dth_antinu sample. \n" \ "Target: CH \n" \ "Flux: MINERvA Forward Horn Current numubar \n" \ "Signal: Any event with 1 muon, 1 pion, no other tracks \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("#theta_{#pi} (degrees)"); fSettings.SetYTitle("d#sigma/d#theta_{#pi}) (cm^{2}/nucleon/degree)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/FULL"); fSettings.SetEnuRange(1.5, 10.0); fSettings.DefineAllowedTargets("C,H"); fUpdatedData = !fSettings.Found("name", "2015"); fFluxCorrection = fSettings.Found("name","fluxcorr"); // CCQELike plot information fSettings.SetTitle("MINERvA_CC1pi0_XSec_1Dth_antinu"); fSettings.DefineAllowedSpecies("numu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents) / TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- if (fUpdatedData) { hadMassCut = 1800; fIsDiag = false; SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CC1pi0/2016/anu-cc1pi0-xsec-pion-angle.csv"); // Error is given as percentage of cross-section // Need to scale the bin error properly before we do correlation -> covariance conversion for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) { fDataHist->SetBinError(i + 1, fDataHist->GetBinContent(i + 1)*fDataHist->GetBinError(i + 1) / 100.); } SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CC1pi0/2016/anu-cc1pi0-correlation-pion-angle.csv"); + SetShapeCovar(); } else { // Although the covariance is given for MINERvA CC1pi0 nubar from 2015, it doesn't Cholesky decompose, hinting at something bad // I've tried adding small numbers to the diagonal but it still didn't work and the chi2s are crazy fIsDiag = true; fNormError = 0.15; // No hadronic mass cut on old publication hadMassCut = 99999; SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CC1pi0/2015/ccpi0_th.csv"); SetCovarFromDiagonal(); } // end special treatment depending on release year if (fFluxCorrection) { for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) { fDataHist->SetBinContent(i + 1, fDataHist->GetBinContent(i + 1) * 1.11); } } // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void MINERvA_CC1pi0_XSec_1Dth_antinu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(111) == 0 || event->NumFSParticle(-13) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP; TLorentzVector Pmu = event->GetHMFSParticle(-13)->fP; double hadMass = FitUtils::Wrec(Pnu, Pmu); double th = -999; if (hadMass < hadMassCut) th = (180. / M_PI) * FitUtils::th(Pnu, Ppi0); fXVar = th; return; }; //******************************************************************** bool MINERvA_CC1pi0_XSec_1Dth_antinu::isSignal(FitEvent *event) { //******************************************************************** if (fUpdatedData) { return SignalDef::isCC1pi0_MINERvA_2016(event, EnuMin, EnuMax); } else { return SignalDef::isCC1pi0_MINERvA_2015(event, EnuMin, EnuMax); } } diff --git a/src/MINERvA/MINERvA_CC1pi0_XSec_1Dthmu_antinu.cxx b/src/MINERvA/MINERvA_CC1pi0_XSec_1Dthmu_antinu.cxx index cfde6e4..e5d212d 100644 --- a/src/MINERvA/MINERvA_CC1pi0_XSec_1Dthmu_antinu.cxx +++ b/src/MINERvA/MINERvA_CC1pi0_XSec_1Dthmu_antinu.cxx @@ -1,90 +1,91 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MINERvA_SignalDef.h" #include "MINERvA_CC1pi0_XSec_1Dthmu_antinu.h" //******************************************************************** MINERvA_CC1pi0_XSec_1Dthmu_antinu::MINERvA_CC1pi0_XSec_1Dthmu_antinu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MINERvA_CC1pi0_XSec_1Dthmu_antinu sample. \n" \ "Target: CH \n" \ "Flux: MINERvA Forward Horn Current numubar \n" \ "Signal: Any event with 1 muon, 1 pion, no other tracks \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("#theta_{#mu}"); fSettings.SetYTitle("d#sigma/d#theta_{#mu} (cm^{2}/degrees/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG/NORM/MASK", "FIX/DIAG"); fSettings.SetEnuRange(1.5, 10.0); fSettings.DefineAllowedTargets("C,H"); // CCQELike plot information fSettings.SetTitle("MINERvA_CC1pi0_XSec_1Dthmu_antinu"); fSettings.DefineAllowedSpecies("numu"); fFluxCorrected = fSettings.Found("name", "fluxcorr"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = GetEventHistogram()->Integral("width")*double(1E-38)/double(fNEvents)/TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CC1pi0/2016/anu-cc1pi0-xsec-muon-angle.csv"); for (int i = 0; i < fDataHist->GetNbinsX()+1; i++) { fDataHist->SetBinError(i+1, fDataHist->GetBinContent(i+1)*fDataHist->GetBinError(i+1)/100.); } SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir()+"/data/MINERvA/CC1pi0/2016/anu-cc1pi0-correlation-muon-angle.csv"); + SetShapeCovar(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void MINERvA_CC1pi0_XSec_1Dthmu_antinu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(-13) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Pmu = event->GetHMFSParticle(-13)->fP; double hadMass = FitUtils::Wrec(Pnu, Pmu); double thmu = -999; if (hadMass < 1800) thmu = (180./M_PI)*FitUtils::th(Pnu, Pmu); fXVar = thmu; return; }; //******************************************************************** bool MINERvA_CC1pi0_XSec_1Dthmu_antinu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCC1pi0_MINERvA_2016(event, EnuMin, EnuMax); } diff --git a/src/MINERvA/MINERvA_CC1pip_XSec_1D_2017Update.cxx b/src/MINERvA/MINERvA_CC1pip_XSec_1D_2017Update.cxx index ed7ca53..aad2bd9 100644 --- a/src/MINERvA/MINERvA_CC1pip_XSec_1D_2017Update.cxx +++ b/src/MINERvA/MINERvA_CC1pip_XSec_1D_2017Update.cxx @@ -1,169 +1,170 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MINERvA_SignalDef.h" #include "MINERvA_CC1pip_XSec_1D_2017Update.h" //******************************************************************** void MINERvA_CC1pip_XSec_1D_2017Update::SetupDataSettings(){ //******************************************************************** // Set Distribution std::string name = fSettings.GetS("name"); if (!name.compare("MINERvA_CC1pip_XSec_1DTpi_nu_2017")) fDist = kTpi; else if (!name.compare("MINERvA_CC1pip_XSec_1Dth_nu_2017")) fDist= kth; else if (!name.compare("MINERvA_CC1pip_XSec_1Dpmu_nu_2017")) fDist= kpmu; else if (!name.compare("MINERvA_CC1pip_XSec_1Dthmu_nu_2017")) fDist= kthmu; else if (!name.compare("MINERvA_CC1pip_XSec_1DQ2_nu_2017")) fDist= kQ2; else if (!name.compare("MINERvA_CC1pip_XSec_1DEnu_nu_2017")) fDist= kEnu; // Define what files to use from the dist std::string datafile = ""; std::string covarfile = ""; std::string titles = ""; std::string distdescript = ""; switch(fDist){ case (kTpi): datafile = "cc1pip_updated_1DTpi"; covarfile = "cc1pip_updated_1DTpi"; titles = "CC1#pi Updated;T_{#pi} (MeV);d#sigma/dT_{#pi} (cm^{2}/nucleon/MeV)"; break; case (kth): datafile = "cc1pip_updated_1Dth"; covarfile = "cc1pip_updated_1Dth"; titles = "CC1#pi Updated;#theta_{#pi};d#sigma/d#theta_{#pi} (cm^{2}/nucleon)"; break; case (kpmu): datafile = "cc1pip_updated_1Dpmu"; covarfile = "cc1pip_updated_1Dpmu"; titles = "CC1#pi Updated;p_{#mu} (GeV);d#sigma/dp_{#mu} (cm^{2}/nucleon/GeV)"; break; case (kthmu): datafile = "cc1pip_updated_1Dthmu"; covarfile = "cc1pip_updated_1Dthmu"; titles ="CC1#pi Updated;#theta_{#mu};d#sigma/d#theta_{#mu} (cm^{2}/nucleon)"; break; case (kQ2): datafile = "cc1pip_updated_1DQ2"; covarfile = "cc1pip_updated_1DQ2"; titles ="CC1#pi Updated;Q^{2} (GeV^{2});d#sigma/dQ^{2} (cm^{2}/nucleon/GeV^{2})"; break; case (kEnu): datafile = "cc1pip_updated_1DEnu"; covarfile = "cc1pip_updated_1DEnu"; titles ="CC1#pi Updated;E_{#nu} (GeV);#sigma(E_#nu) (cm^{2}/nucleon)"; break; default: THROW("Unknown Analysis Distribution : " << fDist); } // Choose shape or rate covariance fIsShape = fSettings.Found("type","SHAPE"); std::string covid = fIsShape ? "_shapecov.txt" : "_ratecov.txt"; // Now setup each data distribution and description. std::string descrip = distdescript + \ "Target: CH \n" \ "Flux: MINERvA Forward Horn Current numu ONLY \n" \ "Signal: Any event with 1 muon, and 1pi+ or 1pi- in FS. W < 1.4"; fSettings.SetDescription(descrip); fSettings.SetDataInput( GeneralUtils::GetTopLevelDir()+"/data/MINERvA/CC1pip/070717/" + datafile + "_data.txt" ); fSettings.SetCovarInput( GeneralUtils::GetTopLevelDir()+"/data/MINERvA/CC1pip/070717/" + covarfile + covid ); fSettings.SetTitle( GeneralUtils::ParseToStr(titles,";")[0] ); fSettings.SetXTitle( GeneralUtils::ParseToStr(titles,";")[1] ); fSettings.SetYTitle( GeneralUtils::ParseToStr(titles,";")[2] ); return; } //******************************************************************** MINERvA_CC1pip_XSec_1D_2017Update::MINERvA_CC1pip_XSec_1D_2017Update(nuiskey samplekey) { //******************************************************************** // Define Sample Settings common to all data distributions fSettings = LoadSampleSettings(samplekey); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/FULL"); fSettings.SetEnuRange(1.5, 10.0); fSettings.DefineAllowedTargets("C,H"); fSettings.DefineAllowedSpecies("numu"); SetupDataSettings(); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // If Enu setup scale factor for Enu Unfolded, otherwise use differential if (fDist == kEnu) fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents); else fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents) / TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- SetDataFromTextFile( fSettings.GetDataInput() ); SetCorrelationFromTextFile( fSettings.GetCovarInput() ); + SetShapeCovar(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; //******************************************************************** void MINERvA_CC1pip_XSec_1D_2017Update::FillEventVariables(FitEvent *event) { //******************************************************************** fXVar = -999.9; if (event->NumFSParticle(PhysConst::pdg_charged_pions) == 0 || event->NumFSParticle(13) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Ppip = event->GetHMFSParticle(PhysConst::pdg_charged_pions)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; double Tpi = Ppip.E() - Ppip.Mag(); double th = (180./M_PI)*FitUtils::th(Pnu, Ppip); double pmu = Pmu.Vect().Mag()/1.E3; // GeV double thmu = (180.0/M_PI)*FitUtils::th(Pnu, Pmu); double Q2 = fabs((Pmu - Pnu).Mag2()) / 1.E6; // Using true here? double Enu = Pnu.E() / 1.E3; switch(fDist){ case kTpi: fXVar = Tpi; break; case kth: fXVar = th; break; case kpmu: fXVar = pmu; break; case kthmu: fXVar = thmu; break; case kQ2: fXVar = Q2; break; case kEnu: fXVar = Enu; break; default: THROW("DIST NOT FOUND : " << fDist); } return; }; //******************************************************************** bool MINERvA_CC1pip_XSec_1D_2017Update::isSignal(FitEvent *event) { //******************************************************************** // Only seem to release full phase space return SignalDef::isCC1pip_MINERvA_2017(event, EnuMin, EnuMax); } diff --git a/src/MINERvA/MINERvA_CCNpip_XSec_1DTpi_nu.cxx b/src/MINERvA/MINERvA_CCNpip_XSec_1DTpi_nu.cxx index 51fa133..74f9d9a 100644 --- a/src/MINERvA/MINERvA_CCNpip_XSec_1DTpi_nu.cxx +++ b/src/MINERvA/MINERvA_CCNpip_XSec_1DTpi_nu.cxx @@ -1,267 +1,267 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MINERvA_SignalDef.h" #include "MINERvA_CCNpip_XSec_1DTpi_nu.h" //******************************************************************** MINERvA_CCNpip_XSec_1DTpi_nu::MINERvA_CCNpip_XSec_1DTpi_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MINERvA_CCNpip_XSec_1DTpi_nu sample. \n" \ "Target: CH \n" \ "Flux: MINERvA Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 electron, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("T_{#pi} (MeV)"); fSettings.SetYTitle("(1/T#Phi) dN_{#pi}/dT_{#pi} (cm^{2}/MeV/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/FULL"); fSettings.SetEnuRange(1.5, 10.0); fSettings.DefineAllowedTargets("C,H"); fSettings.DefineAllowedSpecies("numu"); fFullPhaseSpace = !fSettings.Found("name", "_20deg"); fFluxCorrection = fSettings.Found("name", "fluxcorr"); fUpdatedData = !fSettings.Found("name", "2015"); fSettings.SetTitle("MINERvA_CCNpip_XSec_1DTpi_nu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents) / TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- // Full Phase Space if (fFullPhaseSpace) { // 2016 release if (fUpdatedData) { SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2016/nu-ccNpi+-xsec-pion-kinetic-energy.csv"); // MINERvA has the error quoted as a percentage of the cross-section // Need to make this into an absolute error before we go from correlation // matrix -> covariance matrix since it depends on the error in the ith // bin for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) { fDataHist->SetBinError(i + 1, fDataHist->GetBinContent(i + 1) * (fDataHist->GetBinError(i + 1) / 100.)); } // This is a correlation matrix, not covariance matrix, so needs to be // converted SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2016/nu-ccNpi+-correlation-pion-kinetic-energy.csv"); // 2015 release } else { // If we're doing shape only if (fIsShape) { SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_Tpi_shape.txt"); SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_Tpi_shape_cov.txt"); // If we're doing full cross-section } else { SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_Tpi.txt"); SetCorrelationFromTextFile( GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_Tpi_cov.txt"); } } // Restricted Phase Space } else { // Only 2015 data released restricted muon phase space cross-section // unfortunately if (fUpdatedData) { ERR(FTL) << fName << " has no updated 2016 data for restricted phase space! Using 2015 data." << std::endl; throw; } // If we're using the shape only data if (fIsShape) { SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_Tpi_20deg_shape.txt"); SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_Tpi_20deg_shape_cov.txt"); // Or total cross-section } else { SetDataFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_Tpi_20deg.txt"); SetCorrelationFromTextFile(GeneralUtils::GetTopLevelDir() + "/data/MINERvA/CCNpip/2015/MINERvA_CCNpi_Tpi_20deg_cov.txt"); } } // Scale the MINERvA data to account for the flux difference // Adjust MINERvA data to flux correction; roughly a 11% normalisation increase in data // Please change when MINERvA releases new data! if (fFluxCorrection) { for (int i = 0; i < fDataHist->GetNbinsX() + 1; i++) { fDataHist->SetBinContent(i + 1, fDataHist->GetBinContent(i + 1) * 1.11); } } // Make some auxillary helper plots onePions = (TH1D*)(fDataHist->Clone()); onePions->SetNameTitle((fName + "_1pions").c_str(), (fName + "_1pions" + fPlotTitles).c_str()); SetAutoProcessTH1(onePions, kCMD_Reset, kCMD_Scale, kCMD_Norm); twoPions = (TH1D*)(fDataHist->Clone()); twoPions->SetNameTitle((fName + "_2pions").c_str(), (fName + "_2pions;" + fPlotTitles).c_str()); SetAutoProcessTH1(twoPions, kCMD_Reset, kCMD_Scale, kCMD_Norm); threePions = (TH1D*)(fDataHist->Clone()); threePions->SetNameTitle((fName + "_3pions").c_str(), (fName + "_3pions" + fPlotTitles).c_str()); SetAutoProcessTH1(threePions, kCMD_Reset, kCMD_Scale, kCMD_Norm); morePions = (TH1D*)(fDataHist->Clone()); morePions->SetNameTitle((fName + "_4pions").c_str(), (fName + "_4pions" + fPlotTitles).c_str()); SetAutoProcessTH1(morePions, kCMD_Reset, kCMD_Scale, kCMD_Norm); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; //******************************************************************** // Here we have to fill for every pion we find in the event void MINERvA_CCNpip_XSec_1DTpi_nu::FillEventVariables(FitEvent *event) { //******************************************************************** if (event->NumFSParticle(211) == 0 && event->NumFSParticle(-211) == 0) return; if (event->NumFSParticle(13) == 0) return; // Need to make this use event boxes // Clear out the vectors GetPionBox()->Reset(); TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; // Loop over the particle stack for (unsigned int j = 2; j < event->Npart(); ++j) { // Only include alive particles if (event->GetParticleState(j) != kFinalState) continue; int PID = (event->PartInfo(j))->fPID; // Pick up the charged pions in the event if (abs(PID) == 211) { double ppi = FitUtils::T(event->PartInfo(j)->fP) * 1000.; GetPionBox()->fTpiVect.push_back(ppi); } } fXVar = 0; return; }; //******************************************************************** // The last bool refers to if we're using restricted phase space or not bool MINERvA_CCNpip_XSec_1DTpi_nu::isSignal(FitEvent *event) { //******************************************************************** // Last false refers to that this is NOT the restricted MINERvA phase space, // in which only forward-going muons are accepted return SignalDef::isCCNpip_MINERvA(event, EnuMin, EnuMax, !fFullPhaseSpace, !fUpdatedData); } //******************************************************************** // Need to override FillHistograms() here because we fill the histogram N_pion // times void MINERvA_CCNpip_XSec_1DTpi_nu::FillHistograms() { //******************************************************************** if (Signal) { - unsigned int nPions = GetPionBox()->fTpiVect.size(); + unsigned int nPions = GetPionBox()->fTpiVect.size(); // Need to loop over all the pions in the sample for (size_t k = 0; k < nPions; ++k) { double tpi = GetPionBox()->fTpiVect[k]; this->fMCHist->Fill(tpi, Weight); this->fMCFine->Fill(tpi, Weight); this->fMCStat->Fill(tpi, 1.0); if (nPions == 1) { onePions->Fill(tpi, Weight); } else if (nPions == 2) { twoPions->Fill(tpi, Weight); } else if (nPions == 3) { threePions->Fill(tpi, Weight); } else if (nPions > 3) { morePions->Fill(tpi, Weight); } if (fMCHist_Modes) fMCHist_Modes->Fill(Mode, tpi, Weight); } } } //******************************************************************** void MINERvA_CCNpip_XSec_1DTpi_nu::ScaleEvents() { //******************************************************************** Measurement1D::ScaleEvents(); onePions->Scale(this->fScaleFactor, "width"); twoPions->Scale(this->fScaleFactor, "width"); threePions->Scale(this->fScaleFactor, "width"); morePions->Scale(this->fScaleFactor, "width"); return; } //******************************************************************** void MINERvA_CCNpip_XSec_1DTpi_nu::Write(std::string drawOpts) { //******************************************************************** Measurement1D::Write(drawOpts); // Make an auto processed pion stack // Draw the npions stack onePions->SetTitle("1#pi"); onePions->SetLineColor(kBlack); // onePions->SetFillStyle(0); onePions->SetFillColor(onePions->GetLineColor()); twoPions->SetTitle("2#pi"); twoPions->SetLineColor(kRed); // twoPions->SetFillStyle(0); twoPions->SetFillColor(twoPions->GetLineColor()); threePions->SetTitle("3#pi"); threePions->SetLineColor(kGreen); // threePions->SetFillStyle(0); threePions->SetFillColor(threePions->GetLineColor()); morePions->SetTitle(">3#pi"); morePions->SetLineColor(kBlue); // morePions->SetFillStyle(0); morePions->SetFillColor(morePions->GetLineColor()); THStack pionStack = THStack((fName + "_pionStack").c_str(), (fName + "_pionStack").c_str()); pionStack.Add(onePions); pionStack.Add(twoPions); pionStack.Add(threePions); pionStack.Add(morePions); pionStack.Write(); return; } diff --git a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DEnu_nu.cxx b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DEnu_nu.cxx index dfdd241..5c61d66 100644 --- a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DEnu_nu.cxx +++ b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DEnu_nu.cxx @@ -1,94 +1,95 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MiniBooNE_CC1pi0_XSec_1DEnu_nu.h" //******************************************************************** MiniBooNE_CC1pi0_XSec_1DEnu_nu::MiniBooNE_CC1pi0_XSec_1DEnu_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MiniBooNE_CC1pi0_XSec_1DEnu_nu sample. \n" \ "Target: CH \n" \ "Flux: MiniBooNE Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 muon, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("E_{#nu} (GeV)"); fSettings.SetYTitle("#sigma(E_{#nu}) (cm^{2}/CH_{2})"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/NORM/MASK", "FIX/FULL"); fSettings.SetEnuRange(0.5, 2.0); fSettings.DefineAllowedTargets("C,H"); // CCQELike plot information fSettings.SetTitle("MiniBooNE_CC1pi0_XSec_1DEnu_nu"); fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/totalxsec_edit.txt" ); fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/totalxsec_covar.txt" ); fSettings.DefineAllowedSpecies("numu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = GetEventHistogram()->Integral("width")*double(1E-38)/double(fNEvents)*(14.08); // Plot Setup ------------------------------------------------------- SetDataFromTextFile( fSettings.GetDataInput() ); SetCorrelationFromTextFile( fSettings.GetCovarInput() ); + SetShapeCovar(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void MiniBooNE_CC1pi0_XSec_1DEnu_nu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(111) == 0 || event->NumFSParticle(13) == 0) return; TLorentzVector Pnu =event->GetNeutrinoIn()->fP; TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; double Enu = FitUtils::EnuCC1pi0rec(Pnu, Pmu, Ppi0); fXVar = Enu; return; }; // ************************************************** // MiniBooNE CC1pi0 signal definition // // The signal definition is: // Exactly one negative muon // Exactly one pi0 // No additional mesons // Any number of nucleons // // Does a few clever cuts on the likelihood to reduce CCQE contamination by // looking at "fuzziness" of the ring; CCQE events are sharp, CC1pi0 are fuzzy // (because of the pi0->2 gamma collinearity) bool MiniBooNE_CC1pi0_XSec_1DEnu_nu::isSignal(FitEvent *event) { return SignalDef::isCC1pi(event, 14, 111, EnuMin, EnuMax); } diff --git a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DQ2_nu.cxx b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DQ2_nu.cxx index 3c15ca2..4316e32 100644 --- a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DQ2_nu.cxx +++ b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DQ2_nu.cxx @@ -1,81 +1,82 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MiniBooNE_CC1pi0_XSec_1DQ2_nu.h" //******************************************************************** MiniBooNE_CC1pi0_XSec_1DQ2_nu::MiniBooNE_CC1pi0_XSec_1DQ2_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MiniBooNE_CC1pi0_XSec_1DQ2_nu sample. \n" \ "Target: CH \n" \ "Flux: MiniBooNE Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 muon, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("Q^{2}_{CC#pi} (GeV^{2})"); fSettings.SetYTitle("d#sigma/dQ_{CC#pi}^{2} (cm^{2}/GeV^{2})"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/NORM/MASK", "FIX/FULL"); fSettings.SetEnuRange(0.5, 2.0); fSettings.DefineAllowedTargets("C,H"); // CCQELike plot information fSettings.SetTitle("MiniBooNE_CC1pi0_XSec_1DQ2_nu"); fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/dxsecdq2_edit.txt" ); fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/dxsecdq2_covar.txt" ); fSettings.DefineAllowedSpecies("numu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = GetEventHistogram()->Integral("width")*double(1E-38)/double(fNEvents)*(14.08)/TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- SetDataFromTextFile( fSettings.GetDataInput() ); SetCorrelationFromTextFile( fSettings.GetCovarInput() ); + SetShapeCovar(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void MiniBooNE_CC1pi0_XSec_1DQ2_nu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(13) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; double q2 = -1*(Pnu-Pmu).Mag2()/(1.E6); fXVar = q2; return; }; //******************************************************************** bool MiniBooNE_CC1pi0_XSec_1DQ2_nu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCC1pi(event, 14, 111, EnuMin, EnuMax); } diff --git a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DTu_nu.cxx b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DTu_nu.cxx index 3245928..07df183 100644 --- a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DTu_nu.cxx +++ b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1DTu_nu.cxx @@ -1,83 +1,84 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MiniBooNE_CC1pi0_XSec_1DTu_nu.h" //******************************************************************** MiniBooNE_CC1pi0_XSec_1DTu_nu::MiniBooNE_CC1pi0_XSec_1DTu_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MiniBooNE_CC1pi0_XSec_1DTu_nu sample. \n" \ "Target: CH \n" \ "Flux: MiniBooNE Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 muon, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("T_{#mu} (GeV)"); fSettings.SetYTitle("d#sigma/dE_{#mu} (cm^{2}/GeV^{2}/CH_{2})"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/NORM/MASK", "FIX/FULL"); fSettings.SetEnuRange(0.5, 2.0); fSettings.DefineAllowedTargets("C,H"); // CCQELike plot information fSettings.SetTitle("MiniBooNE_CC1pi0_XSec_1DTu_nu"); fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/dxsecdemu_edit.txt" ); fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/dxsecdemu_covar.txt" ); fSettings.DefineAllowedSpecies("numu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = GetEventHistogram()->Integral("width")*double(1E-38)/double(fNEvents)*(14.08)/TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- SetDataFromTextFile( fSettings.GetDataInput() ); SetCorrelationFromTextFile( fSettings.GetCovarInput() ); + SetShapeCovar(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void MiniBooNE_CC1pi0_XSec_1DTu_nu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(111) == 0 || event->NumFSParticle(13) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; double TuCCpi0 = FitUtils::T(Pmu); fXVar = TuCCpi0; return; }; //******************************************************************** bool MiniBooNE_CC1pi0_XSec_1DTu_nu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCC1pi(event, 14, 111, EnuMin, EnuMax); } diff --git a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dcosmu_nu.cxx b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dcosmu_nu.cxx index 7ed184e..757046a 100644 --- a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dcosmu_nu.cxx +++ b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dcosmu_nu.cxx @@ -1,85 +1,86 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MiniBooNE_CC1pi0_XSec_1Dcosmu_nu.h" //******************************************************************** MiniBooNE_CC1pi0_XSec_1Dcosmu_nu::MiniBooNE_CC1pi0_XSec_1Dcosmu_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MiniBooNE_CC1pi0_XSec_1Dcosmu_nu sample. \n" \ "Target: CH \n" \ "Flux: MiniBooNE Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 muon, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("cos#theta_{#mu}"); fSettings.SetYTitle("d#sigma/dcos#theta_{#mu} (cm^{2}/CH_{2})"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/NORM/MASK", "FIX/FULL"); fSettings.SetEnuRange(0.5, 2.0); fSettings.DefineAllowedTargets("C,H"); // CCQELike plot information fSettings.SetTitle("MiniBooNE_CC1pi0_XSec_1Dcosmu_nu"); fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/dxsecdcosmu_edit.txt" ); fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/dxsecdcosmu_covar.txt" ); fSettings.DefineAllowedSpecies("numu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = GetEventHistogram()->Integral("width")*double(1E-38)/double(fNEvents)*(14.08)/TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- SetDataFromTextFile( fSettings.GetDataInput() ); SetCorrelationFromTextFile( fSettings.GetCovarInput() ); + SetShapeCovar(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void MiniBooNE_CC1pi0_XSec_1Dcosmu_nu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(111) == 0 || event->NumFSParticle(13) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; // No W cut on MiniBooNE CC1pi+ double CosMu = cos(FitUtils::th(Pnu, Pmu)); fXVar = CosMu; return; }; //******************************************************************** bool MiniBooNE_CC1pi0_XSec_1Dcosmu_nu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCC1pi(event, 14, 111, EnuMin, EnuMax); } diff --git a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dcospi0_nu.cxx b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dcospi0_nu.cxx index 0758791..a0ad302 100644 --- a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dcospi0_nu.cxx +++ b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dcospi0_nu.cxx @@ -1,84 +1,85 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MiniBooNE_CC1pi0_XSec_1Dcospi0_nu.h" //******************************************************************** MiniBooNE_CC1pi0_XSec_1Dcospi0_nu::MiniBooNE_CC1pi0_XSec_1Dcospi0_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MiniBooNE_CC1pi0_XSec_1Dcospi0_nu sample. \n" \ "Target: CH \n" \ "Flux: MiniBooNE Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 muon, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("cos#theta_{#pi^{0}}"); fSettings.SetYTitle("d#sigma/dcos#theta_{#pi^{0}} (cm^{2}/CH_{2})"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/NORM/MASK", "FIX/FULL"); fSettings.SetEnuRange(0.5, 2.0); fSettings.DefineAllowedTargets("C,H"); // CCQELike plot information fSettings.SetTitle("MiniBooNE_CC1pi0_XSec_1Dcospi0_nu"); fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/dxsecdcospi_edit.txt" ); fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/CC1pi0/dxsecdcospi_covar.txt" ); fSettings.DefineAllowedSpecies("numu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = GetEventHistogram()->Integral("width")*double(1E-38)/double(fNEvents)*(14.08)/TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- SetDataFromTextFile( fSettings.GetDataInput() ); SetCorrelationFromTextFile( fSettings.GetCovarInput() ); + SetShapeCovar(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void MiniBooNE_CC1pi0_XSec_1Dcospi0_nu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(111) == 0 || event->NumFSParticle(13) == 0) return; TLorentzVector Pnu =event->GetNeutrinoIn()->fP; TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; double CosPi0 = cos(FitUtils::th(Pnu, Ppi0)); fXVar = CosPi0; return; }; //******************************************************************** bool MiniBooNE_CC1pi0_XSec_1Dcospi0_nu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCC1pi(event, 14, 111, EnuMin, EnuMax); } diff --git a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dppi0_nu.cxx b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dppi0_nu.cxx index 0b258df..09919a9 100644 --- a/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dppi0_nu.cxx +++ b/src/MiniBooNE/MiniBooNE_CC1pi0_XSec_1Dppi0_nu.cxx @@ -1,90 +1,91 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MiniBooNE_CC1pi0_XSec_1Dppi0_nu.h" MiniBooNE_CC1pi0_XSec_1Dppi0_nu::MiniBooNE_CC1pi0_XSec_1Dppi0_nu(nuiskey confkey) { // 1. Initalise sample Settings (all overrideable in cardfile) -------------- fSettings = LoadSampleSettings(confkey); // Must go first fSettings.SetDescription(""); fSettings.SetXTitle("p_{#pi^{0}} (GeV/c)"); fSettings.SetYTitle("d#sigma/dp_{#pi^{0}} (cm^{2}/GeV/CH_{2})"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/FULL"); fSettings.SetEnuRange(0.5, 2.0); fSettings.SetSuggestedFlux( FitPar::GetDataBase() + "/MiniBooNE/ccqe/mb_fhc_flux.root"); fSettings.SetTitle("MiniBooNE #nu_#mu CC1#pi^{0} on CH"); fSettings.SetDataInput( FitPar::GetDataBase() + "/MiniBooNE/CC1pi0/dxsecdppi_edit.txt" ); fSettings.SetCovarInput( FitPar::GetDataBase() + "/MiniBooNE/CC1pi0/dxsecdppi_covar.txt" ); fSettings.DefineAllowedSpecies("numu"); fSettings.DefineAllowedTargets("C,H"); FinaliseSampleSettings(); // Must go after all settings // 2. Set Scale Factor ------------------------------------------------------- fScaleFactor = GetEventHistogram()->Integral("width") * double(1E-38) / double(fNEvents) * (14.08) / TotalIntegratedFlux("width"); // 3. Plot Setup ------------------------------------------------------- SetDataValues( fSettings.GetDataInput() ); SetCovarMatrixFromCorrText( fSettings.GetCovarInput(), fDataHist->GetNbinsX() ); + SetShapeCovar(); // Create a Target Species Stack copying data fTargetStack = new TargetTypeStack( fSettings.Name() + "_TGT", "Target Contributions" + fSettings.PlotTitles(), fDataHist); SetAutoProcessTH1(fTargetStack); // Final MC Setup // Must go last FinaliseMeasurement(); }; void MiniBooNE_CC1pi0_XSec_1Dppi0_nu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(111) == 0 || event->NumFSParticle(13) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; double p_pi0 = FitUtils::p(Ppi0); fXVar = p_pi0; fTargetPDG = event->fTargetPDG; return; }; //******************************************************************** bool MiniBooNE_CC1pi0_XSec_1Dppi0_nu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCC1pi(event, 14, 111, EnuMin, EnuMax); } //******************************************************************** void MiniBooNE_CC1pi0_XSec_1Dppi0_nu::FillExtraHistograms(MeasurementVariableBox* box, double weight){ //******************************************************************** if (!Signal) return; fTargetStack->Fill( fTargetPDG, fXVar, weight ); } diff --git a/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu.cxx b/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu.cxx index 5013411..48a3f35 100644 --- a/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu.cxx +++ b/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu.cxx @@ -1,102 +1,103 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu.h" //******************************************************************** MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu::MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu sample. \n" \ "Target: CH \n" \ "Flux: MiniBooNE Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 muon, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("cos#theta_{#pi^{0}}"); fSettings.SetYTitle("d#sigma/dcos#theta_{#pi^{0}} (cm^{2}/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/NORM/MASK", "FIX/FULL"); fSettings.SetEnuRange(0.0, 5.0); fSettings.DefineAllowedTargets("C,H"); fSettings.SetTitle("MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu"); nunubar_mode = fSettings.Found("name", "combined"); if (!nunubar_mode) { fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/nubarcosthetapi0xsec_edit.txt" ); fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/nubarcosthetapi0xsecerrormatrix.txt" ); fSettings.DefineAllowedSpecies("numub"); } else { fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/combinedsignnumodecosthetapi0xsec_edit.txt"); fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/combinedsignnumodecosthetapi0xsecerrormatrix.txt"); fSettings.DefineAllowedSpecies("numu,numub"); } - + FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38) / double(fNEvents) / TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- SetDataFromTextFile( fSettings.GetDataInput() ); SetCovarFromTextFile( fSettings.GetCovarInput() ); ScaleCovar(1.E-5); StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, 1E-38); + SetShapeCovar(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu::FillEventVariables(FitEvent *event) { // (CP) require pi0 in final state (this makes some assumptions about how the // generator treats the pi0 after it is produced in the nucleus. // MB required 2 photons to make a pion signal, so check for those later if (event->NumFSParticle(111) == 0 ) { return; } if (abs(event->NumFSParticle(13)) == 1 || abs(event->NumFSParticle(11)) == 1 || abs(event->NumFSParticle(15)) == 1 || abs(event->NumFSParticle(17)) == 1) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP; double CosPi0 = cos(FitUtils::th(Pnu, Ppi0)); fXVar = CosPi0; return; }; //******************************************************************** bool MiniBooNE_NC1pi0_XSec_1Dcospi0_antinu::isSignal(FitEvent *event) { //******************************************************************** if (nunubar_mode) { return (SignalDef::isNC1pi(event, 14, 111, EnuMin, EnuMax) || SignalDef::isNC1pi(event, -14, 111, EnuMin, EnuMax)); } else { return SignalDef::isNC1pi(event, -14, 111, EnuMin, EnuMax); } } diff --git a/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dcospi0_nu.cxx b/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dcospi0_nu.cxx index e413b2c..fcc28a0 100644 --- a/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dcospi0_nu.cxx +++ b/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dcospi0_nu.cxx @@ -1,104 +1,105 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MiniBooNE_NC1pi0_XSec_1Dcospi0_nu.h" //******************************************************************** MiniBooNE_NC1pi0_XSec_1Dcospi0_nu::MiniBooNE_NC1pi0_XSec_1Dcospi0_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MiniBooNE_NC1pi0_XSec_1Dcospi0_nu sample. \n" \ "Target: CH \n" \ "Flux: MiniBooNE Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 muon, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("cos#theta_{#pi^{0}}"); fSettings.SetYTitle("d#sigma/dcos#theta_{#pi^{0}} (cm^{2}/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/NORM/MASK", "FIX/FULL"); fSettings.SetEnuRange(0.0, 5.0); fSettings.DefineAllowedTargets("C,H"); fSettings.SetTitle("MiniBooNE_NC1pi0_XSec_1Dcospi0_nu"); nunubarmode = fSettings.Found("name", "combined"); if (!nunubarmode) { fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/nucosthetapi0xsec_edit.txt" ); fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/nucosthetapi0xsecerrormatrix.txt" ); fSettings.DefineAllowedSpecies("numu"); } else { fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/combinedsignnubarmodecosthetapi0xsec_edit.txt"); fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/combinedsignnubarmodecosthetapi0xsecerrormatrix.txt"); fSettings.DefineAllowedSpecies("numu,numub"); } FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38) / double(fNEvents) / TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- SetDataFromTextFile( fSettings.GetDataInput() ); SetCovarFromTextFile( fSettings.GetCovarInput() ); ScaleCovar(1.E-5); StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, 1E-38); + SetShapeCovar(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void MiniBooNE_NC1pi0_XSec_1Dcospi0_nu::FillEventVariables(FitEvent *event) { // (CP) require pi0 in final state (this makes some assumptions about how the // generator treats the pi0 after it is produced in the nucleus. // MB required 2 photons to make a pion signal, so check for those later if (event->NumFSParticle(111) == 0 ) { return; } if (abs(event->NumFSParticle(13)) == 1 || abs(event->NumFSParticle(11)) == 1 || abs(event->NumFSParticle(15)) == 1 || abs(event->NumFSParticle(17)) == 1) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP; double CosPi0 = cos(FitUtils::th(Pnu, Ppi0)); fXVar = CosPi0; return; }; //******************************************************************** bool MiniBooNE_NC1pi0_XSec_1Dcospi0_nu::isSignal(FitEvent *event) { //******************************************************************** if (nunubarmode){ return (SignalDef::isNC1pi(event, 14, 111, EnuMin, EnuMax) || SignalDef::isNC1pi(event, -14, 111, EnuMin, EnuMax)); } else { return SignalDef::isNC1pi(event, 14, 111, EnuMin, EnuMax); } } diff --git a/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dppi0_antinu.cxx b/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dppi0_antinu.cxx index de94f25..3f13396 100644 --- a/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dppi0_antinu.cxx +++ b/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dppi0_antinu.cxx @@ -1,103 +1,104 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MiniBooNE_NC1pi0_XSec_1Dppi0_antinu.h" //******************************************************************** MiniBooNE_NC1pi0_XSec_1Dppi0_antinu::MiniBooNE_NC1pi0_XSec_1Dppi0_antinu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MiniBooNE_NC1pi0_XSec_1Dppi0_antinu sample. \n" \ "Target: CH \n" \ "Flux: MiniBooNE Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 muon, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("p_{#pi^{0}} (GeV/c)"); fSettings.SetYTitle("d#sigma/dp_{#pi^{0}} (cm^{2}/(GeV/c)/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/NORM/MASK", "FIX/FULL"); fSettings.SetEnuRange(0.0, 5.0); fSettings.DefineAllowedTargets("C,H"); fSettings.SetTitle("MiniBooNE_NC1pi0_XSec_1Dppi0_antinu"); nunubarmode = fSettings.Found("name", "combined"); if (!nunubarmode) { fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/nubarppi0xsec_edit.txt" ); fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/nubarppi0xsecerrormatrix.txt" ); fSettings.DefineAllowedSpecies("numu"); } else { fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/combinedsignnumodeppi0xsec_edit.txt"); fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/combinedsignnumodeppi0xsecerrormatrix.txt"); fSettings.DefineAllowedSpecies("numu,numub"); } FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38) / double(fNEvents) / TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- SetDataFromTextFile( fSettings.GetDataInput() ); SetCovarFromTextFile( fSettings.GetCovarInput() ); ScaleCovar(1.E-5); StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, 1E-38); + SetShapeCovar(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void MiniBooNE_NC1pi0_XSec_1Dppi0_antinu::FillEventVariables(FitEvent *event) { // (CP) require pi0 in final state (this makes some assumptions about how the // generator treats the pi0 after it is produced in the nucleus. // MB required 2 photons to make a pion signal, so check for those later if (event->NumFSParticle(111) == 0) { return; } if (abs(event->NumFSParticle(13)) == 1 || abs(event->NumFSParticle(11)) == 1 || abs(event->NumFSParticle(15)) == 1 || abs(event->NumFSParticle(17)) == 1) return; TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP; double p_pi0 = FitUtils::p(Ppi0); fXVar = p_pi0; return; }; //******************************************************************** bool MiniBooNE_NC1pi0_XSec_1Dppi0_antinu::isSignal(FitEvent *event) { //******************************************************************** if (nunubarmode){ return (SignalDef::isNC1pi(event, -14, 111, EnuMin, EnuMax) || SignalDef::isNC1pi(event, 14, 111, EnuMin, EnuMax) ); } else { return SignalDef::isNC1pi(event, -14, 111, EnuMin, EnuMax); } } diff --git a/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dppi0_nu.cxx b/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dppi0_nu.cxx index 1dc1119..ea0fea1 100644 --- a/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dppi0_nu.cxx +++ b/src/MiniBooNE/MiniBooNE_NC1pi0_XSec_1Dppi0_nu.cxx @@ -1,103 +1,104 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "MiniBooNE_NC1pi0_XSec_1Dppi0_nu.h" //******************************************************************** MiniBooNE_NC1pi0_XSec_1Dppi0_nu::MiniBooNE_NC1pi0_XSec_1Dppi0_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "MiniBooNE_NC1pi0_XSec_1Dppi0_nu sample. \n" \ "Target: CH \n" \ "Flux: MiniBooNE Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 muon, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("p_{#pi^{0}} (GeV/c)"); fSettings.SetYTitle("d#sigma/dp_{#pi^{0}} (cm^{2}/(GeV/c)/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/FULL,DIAG/NORM/MASK", "FIX/FULL"); fSettings.SetEnuRange(0.0, 5.0); fSettings.DefineAllowedTargets("C,H"); fSettings.SetTitle("MiniBooNE_NC1pi0_XSec_1Dppi0_nu"); nunubar_mode_nu = fSettings.Found("name", "combined"); if (!nunubar_mode_nu) { fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/nuppi0xsec_edit.txt" ); fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/nuppi0xsecerrormatrix.txt" ); fSettings.DefineAllowedSpecies("numu"); } else { fSettings.SetDataInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/combinedsignnubarmodeppi0xsec_edit.txt"); fSettings.SetCovarInput( FitPar::GetDataBase() + "MiniBooNE/NC1pi0/combinedsignnubarmodeppi0xsecerrormatrix.txt"); fSettings.DefineAllowedSpecies("numu,numub"); } FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38) / double(fNEvents) / TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- SetDataFromTextFile( fSettings.GetDataInput() ); SetCovarFromTextFile( fSettings.GetCovarInput() ); ScaleCovar(1.E-5); StatUtils::SetDataErrorFromCov(fDataHist, fFullCovar, 1E-38); + SetShapeCovar(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; void MiniBooNE_NC1pi0_XSec_1Dppi0_nu::FillEventVariables(FitEvent *event) { // (CP) require pi0 in final state (this makes some assumptions about how the // generator treats the pi0 after it is produced in the nucleus. // MB required 2 photons to make a pion signal, so check for those later if (event->NumFSParticle(111) == 0) { return; } if (abs(event->NumFSParticle(13)) == 1 || abs(event->NumFSParticle(11)) == 1 || abs(event->NumFSParticle(15)) == 1 || abs(event->NumFSParticle(17)) == 1) return; TLorentzVector Ppi0 = event->GetHMFSParticle(111)->fP; double p_pi0 = FitUtils::p(Ppi0); fXVar = p_pi0; return; }; //******************************************************************** bool MiniBooNE_NC1pi0_XSec_1Dppi0_nu::isSignal(FitEvent *event) { //******************************************************************** if (nunubar_mode_nu){ return (SignalDef::isNC1pi(event, 14, 111, EnuMin, EnuMax) || SignalDef::isNC1pi(event, -14, 111, EnuMin, EnuMax)); } else { return SignalDef::isNC1pi(event, 14, 111, EnuMin, EnuMax); } } diff --git a/src/T2K/T2K_CC1pip_CH_XSec_1DQ2_nu.cxx b/src/T2K/T2K_CC1pip_CH_XSec_1DQ2_nu.cxx index 2764225..ee52182 100644 --- a/src/T2K/T2K_CC1pip_CH_XSec_1DQ2_nu.cxx +++ b/src/T2K/T2K_CC1pip_CH_XSec_1DQ2_nu.cxx @@ -1,204 +1,201 @@ #include #include "T2K_SignalDef.h" #include "T2K_CC1pip_CH_XSec_1DQ2_nu.h" // The constructor T2K_CC1pip_CH_XSec_1DQ2_nu::T2K_CC1pip_CH_XSec_1DQ2_nu(std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile){ EnuMin = 0.; EnuMax = 100.; fIsDiag = false; // Here we can give either MB (kMB), extended MB (keMB) or Delta (kDelta) if (type.find("eMB") != std::string::npos) { fT2KSampleType = keMB; fName = "T2K_CC1pip_CH_XSec_1DQ2eMB_nu"; fPlotTitles = "; Q^{2}_{eMB} (GeV^{2}); d#sigma/dQ^{2}_{eMB} (cm^{2}/GeV^{2}/nucleon)"; } else if (type.find("MB") != std::string::npos) { fT2KSampleType = kMB; fName = "T2K_CC1pip_CH_XSec_1DQ2MB_nu"; fPlotTitles = "; Q^{2}_{MB} (GeV^{2}); d#sigma/dQ^{2}_{MB} (cm^{2}/GeV^{2}/nucleon)"; } else if (type.find("Delta") != std::string::npos) { fT2KSampleType = kDelta; fName = "T2K_CC1pip_CH_XSec_1DQ2delta_nu"; fPlotTitles = "; Q^{2}_{#Delta} (GeV^{2}); d#sigma/dQ^{2}_{#Delta} (cm^{2}/GeV^{2}/nucleon)"; } else { LOG(SAM) << "Found no specified type, using MiniBooNE E_nu/Q2 definition" << std::endl; fT2KSampleType = kMB; fName = "T2K_CC1pip_CH_XSec_1DQ2MB_nu"; fPlotTitles = "; Q^{2}_{MB} (GeV^{2}); d#sigma/dQ^{2}_{MB} (cm^{2}/GeV^{2}/nucleon)"; } Measurement1D::SetupMeasurement(inputfile, type, rw, fakeDataFile); //type = keMB; //type = kDelta; if (fT2KSampleType == kMB) { this->SetDataValues(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Q2_MB.root"); this->SetCovarMatrix(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Q2_MB.root"); } else if (fT2KSampleType == keMB) { this->SetDataValues(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Q2_extendedMB.root"); this->SetCovarMatrix(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Q2_extendedMB.root"); } else if (fT2KSampleType == kDelta) { this->SetDataValues(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Q2_Delta.root"); this->SetCovarMatrix(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Q2_Delta.root"); } else { ERR(FTL) << "No data type set for " << fName << std::endl; ERR(FTL) << __FILE__ << ":" << __LINE__ << std::endl; exit(-1); } + SetShapeCovar(); this->SetupDefaultHist(); - + this->fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width"); }; // Override this for now // Should really have Measurement1D do this properly though void T2K_CC1pip_CH_XSec_1DQ2_nu::SetDataValues(std::string fileLocation) { LOG(DEB) << "Reading: " << this->fName << "\nData: " << fileLocation.c_str() << std::endl; TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file! // Don't want the last bin of dataCopy TH1D *dataCopy = (TH1D*)(dataFile->Get("hResult_sliced_0_1"))->Clone(); const int nPoints = dataCopy->GetNbinsX()-6; LOG(DEB) << nPoints << std::endl; double *binEdges = new double[nPoints+1]; for (int i = 0; i < nPoints+1; i++) { binEdges[i] = dataCopy->GetBinLowEdge(i+1); } for (int i = 0; i < nPoints+1; i++) { LOG(DEB) << "binEdges[" << i << "] = " << binEdges[i] << std::endl; } fDataHist = new TH1D((fName+"_data").c_str(), (fName+"_data"+fPlotTitles).c_str(), nPoints, binEdges); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { fDataHist->SetBinContent(i+1, dataCopy->GetBinContent(i+1)*1E-38); fDataHist->SetBinError(i+1, dataCopy->GetBinError(i+1)*1E-38); LOG(DEB) << fDataHist->GetBinLowEdge(i+1) << " " << fDataHist->GetBinContent(i+1) << " " << fDataHist->GetBinError(i+1) << std::endl; } fDataHist->SetDirectory(0); //should disassociate fDataHist with dataFile fDataHist->SetNameTitle((fName+"_data").c_str(), (fName+"_MC"+fPlotTitles).c_str()); dataFile->Close(); }; // Override this for now // Should really have Measurement1D do this properly though void T2K_CC1pip_CH_XSec_1DQ2_nu::SetCovarMatrix(std::string fileLocation) { LOG(DEB) << "Covariance: " << fileLocation.c_str() << std::endl; TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file! TH2D *covarMatrix = (TH2D*)(dataFile->Get("TMatrixDBase;1"))->Clone(); int nBinsX = covarMatrix->GetXaxis()->GetNbins(); int nBinsY = covarMatrix->GetYaxis()->GetNbins(); LOG(DEB) << nBinsX << std::endl; LOG(DEB) << fDataHist->GetNbinsX() << std::endl; if ((nBinsX != nBinsY)) ERR(WRN) << "covariance matrix not square!" << std::endl; - this->covar = new TMatrixDSym(nBinsX-7); this->fFullCovar = new TMatrixDSym(nBinsX-7); // First two entries are BS // Last entry is BS for (int i = 0; i < nBinsX-7; i++) { for (int j = 0; j < nBinsY-7; j++) { - (*this->covar)(i, j) = covarMatrix->GetBinContent(i+3, j+3); //adds syst+stat covariances (*this->fFullCovar)(i, j) = covarMatrix->GetBinContent(i+3, j+3); //adds syst+stat covariances - LOG(DEB) << "covar(" << i << ", " << j << ") = " << (*this->covar)(i,j) << std::endl; + LOG(DEB) << "fFullCovar(" << i << ", " << j << ") = " << (*this->fFullCovar)(i,j) << std::endl; } } //should now have set covariance, I hope - TDecompChol tempMat = TDecompChol(*this->covar); - this->covar = new TMatrixDSym(nBinsX, tempMat.Invert().GetMatrixArray(), ""); - // *this->covar *= 1E-38*1E-38; - + this->fDecomp = StatUtils::GetDecomp(this->fFullCovar); + this->covar = StatUtils::GetInvert(this->fFullCovar); return; }; void T2K_CC1pip_CH_XSec_1DQ2_nu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(13) == 0 || event->NumFSParticle(211) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Ppip = event->GetHMFSParticle(211)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; double q2 = -999; switch(fT2KSampleType) { // First int refers to how we reconstruct Enu // 0 uses true neutrino energy (not used here but common for other analyses when they unfold to true Enu from reconstructed Enu) // 1 uses "extended MiniBooNE" method // 2 uses "MiniBooNE reconstructed" method // 3 uses Delta resonance mass for reconstruction // // The last bool refers to if pion directional information was used // // Use MiniBooNE reconstructed Enu; uses Michel tag so no pion direction information case kMB: q2 = FitUtils::Q2CC1piprec(Pnu, Pmu, Ppip, 2, false); break; // Use Extended MiniBooNE reconstructed Enu // Needs pion information to reconstruct so bool is true (did not include Michel e tag) case keMB: q2 = FitUtils::Q2CC1piprec(Pnu, Pmu, Ppip, 1, true); break; // Use Delta resonance reconstructed Enu // Uses Michel electron so don't have pion directional information case kDelta: q2 = FitUtils::Q2CC1piprec(Pnu, Pmu, Ppip, 3, false); break; } fXVar = q2; return; }; //******************************************************************** bool T2K_CC1pip_CH_XSec_1DQ2_nu::isSignal(FitEvent *event) { //******************************************************************** // Warning: The CH analysis has different signal definition to the H2O analysis! // Often to do with the Michel tag switch(fT2KSampleType) { // Using MiniBooNE formula for Enu reconstruction on the Q2 variable // Does have Michel e tag, set bool to true! case kMB: return SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, true); break; // Using extended MiniBooNE formula for Enu reconstruction on the Q2 variable // Does not have Michel e tag because we need directional information to reconstruct Q2 case keMB: return SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, false); break; // Using Delta resonance for Enu reconstruction on the Q2 variable // Does have Michel e tag, bool to true case kDelta: return SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, true); break; } // Default to return false return false; } diff --git a/src/T2K/T2K_CC1pip_CH_XSec_1DWrec_nu.cxx b/src/T2K/T2K_CC1pip_CH_XSec_1DWrec_nu.cxx index 0961a84..c31b6aa 100644 --- a/src/T2K/T2K_CC1pip_CH_XSec_1DWrec_nu.cxx +++ b/src/T2K/T2K_CC1pip_CH_XSec_1DWrec_nu.cxx @@ -1,118 +1,116 @@ #include #include "T2K_SignalDef.h" #include "T2K_CC1pip_CH_XSec_1DWrec_nu.h" // The constructor T2K_CC1pip_CH_XSec_1DWrec_nu::T2K_CC1pip_CH_XSec_1DWrec_nu(std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile){ fName = "T2K_CC1pip_CH_XSec_1DWrec_nu"; fPlotTitles = "; W_{rec} (GeV/c); d#sigma/dW_{rec} (cm^{2}/(GeV/c^{2})/nucleon)"; EnuMin = 0.; EnuMax = 100.; fIsDiag = false; Measurement1D::SetupMeasurement(inputfile, type, rw, fakeDataFile); this->SetDataValues(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/W.root"); this->SetCovarMatrix(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/W.root"); - + SetShapeCovar(); this->SetupDefaultHist(); this->fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width"); }; // Override this for now // Should really have Measurement1D do this properly though void T2K_CC1pip_CH_XSec_1DWrec_nu::SetDataValues(std::string fileLocation) { LOG(DEB) << "Reading: " << this->fName << "\nData: " << fileLocation.c_str() << std::endl; TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file! // Don't want the first and last bin of dataCopy TH1D *dataCopy = (TH1D*)(dataFile->Get("hResult_sliced_0_1"))->Clone(); LOG(DEB) << dataCopy->GetNbinsX() << std::endl; const int dataPoints = dataCopy->GetNbinsX()-2; double *binEdges = new double[dataPoints+1]; // Want to skip the first bin here for (int i = 0; i < dataPoints+1; i++) { binEdges[i] = dataCopy->GetBinLowEdge(i+2); } for (int i = 0; i < dataPoints+1; i++) { LOG(DEB) << "binEdges[" << i << "] = " << binEdges[i] << std::endl; } fDataHist = new TH1D((fName+"_data").c_str(), (fName+"_data"+fPlotTitles).c_str(), dataPoints, binEdges); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { fDataHist->SetBinContent(i+1, dataCopy->GetBinContent(i+2)*1E-38); fDataHist->SetBinError(i+1, dataCopy->GetBinError(i+2)*1E-38); LOG(DEB) << fDataHist->GetBinLowEdge(i+1) << " " << fDataHist->GetBinContent(i+1) << " " << fDataHist->GetBinError(i+1) << std::endl; } fDataHist->SetDirectory(0); //should disassociate fDataHist with dataFile //fDataHist->SetNameTitle((fName+"_data").c_str(), (fName+"_MC"+fPlotTitles).c_str()); dataFile->Close(); }; // Override this for now // Should really have Measurement1D do this properly though void T2K_CC1pip_CH_XSec_1DWrec_nu::SetCovarMatrix(std::string fileLocation) { LOG(DEB) << "Covariance: " << fileLocation.c_str() << std::endl; TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file! TH2D *covarMatrix = (TH2D*)(dataFile->Get("TMatrixDBase;1"))->Clone(); const int nBinsX = covarMatrix->GetXaxis()->GetNbins(); const int nBinsY = covarMatrix->GetYaxis()->GetNbins(); if ((nBinsX != nBinsY)) ERR(WRN) << "covariance matrix not square!" << std::endl; LOG(DEB) << nBinsX << std::endl; LOG(DEB) << fDataHist->GetNbinsX() << std::endl; - this->covar = new TMatrixDSym(nBinsX-3); this->fFullCovar = new TMatrixDSym(nBinsX-3); for (int i = 0; i < nBinsX-3; i++) { for (int j = 0; j < nBinsY-3; j++) { - (*this->covar)(i, j) = covarMatrix->GetBinContent(i+4, j+4); //adds syst+stat covariances - LOG(DEB) << "covar(" << i << ", " << j << ") = " << (*this->covar)(i,j) << std::endl; + (*this->fFullCovar)(i, j) = covarMatrix->GetBinContent(i+4, j+4); //adds syst+stat covariances + LOG(DEB) << "fFullCovar(" << i << ", " << j << ") = " << (*this->fFullCovar)(i,j) << std::endl; } } //should now have set covariance, I hope - TDecompChol tempMat = TDecompChol(*this->covar); - this->covar = new TMatrixDSym(nBinsX, tempMat.Invert().GetMatrixArray(), ""); - // *this->covar *= 1E-38*1E-38; + this->fDecomp = StatUtils::GetDecomp(this->fFullCovar); + this->covar = StatUtils::GetInvert(this->fFullCovar); return; }; void T2K_CC1pip_CH_XSec_1DWrec_nu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(13) == 0 || event->NumFSParticle(211) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Ppip = event->GetHMFSParticle(211)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; double Wrec = FitUtils::WrecCC1pip_T2K_MB(Pnu, Pmu, Ppip); fXVar = Wrec; return; }; //******************************************************************** bool T2K_CC1pip_CH_XSec_1DWrec_nu::isSignal(FitEvent *event) { //******************************************************************** // This sample includes the Michel e tag so do not have to cut into the pion phase space return SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, true); } diff --git a/src/T2K/T2K_CC1pip_CH_XSec_1Dpmu_nu.cxx b/src/T2K/T2K_CC1pip_CH_XSec_1Dpmu_nu.cxx index b56e2b7..702a16d 100644 --- a/src/T2K/T2K_CC1pip_CH_XSec_1Dpmu_nu.cxx +++ b/src/T2K/T2K_CC1pip_CH_XSec_1Dpmu_nu.cxx @@ -1,156 +1,154 @@ #include "T2K_CC1pip_CH_XSec_1Dpmu_nu.h" #include //******************************************************************** T2K_CC1pip_CH_XSec_1Dpmu_nu::T2K_CC1pip_CH_XSec_1Dpmu_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "T2K_CC1pip_CH_XSec_1Dpmu_nu sample. \n" \ "Target: CH \n" \ "Flux: T2k Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 electron, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetDescription(descrip); fSettings.SetXTitle("p_{#mu} (GeV/c)"); fSettings.SetYTitle("d#sigma/dp_{#mu} (cm^{2}/(GeV/c)/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/DIAG"); fSettings.SetEnuRange(0.0, 100.0); fSettings.DefineAllowedTargets("C,H"); // CCQELike plot information fSettings.SetTitle("T2K_CC1pip_CH_XSec_1Dpmu_nu"); fSettings.SetDataInput( GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Pmu.root" ); fSettings.SetCovarInput( GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Pmu.root" ); fSettings.DefineAllowedSpecies("numu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- SetDataValues( fSettings.GetDataInput() ); SetCovarMatrix( fSettings.GetCovarInput() ); + SetShapeCovar(); + // Final setup --------------------------------------------------- FinaliseMeasurement(); }; // Override this for now // Should really have Measurement1D do this properly though void T2K_CC1pip_CH_XSec_1Dpmu_nu::SetDataValues(std::string fileLocation) { LOG(DEB) << "Reading: " << this->fName << "\nData: " << fileLocation.c_str() << std::endl; TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file! // Don't want the last bin of dataCopy TH1D *dataCopy = (TH1D*)(dataFile->Get("hResult_sliced_0_1"))->Clone(); LOG(DEB) << "nbins = " << dataCopy->GetNbinsX() << std::endl; double *binEdges = new double[dataCopy->GetNbinsX()-1]; for (int i = 0; i < dataCopy->GetNbinsX()-1; i++) { binEdges[i] = dataCopy->GetBinLowEdge(i+1); } binEdges[dataCopy->GetNbinsX()-1] = dataCopy->GetBinLowEdge(dataCopy->GetNbinsX()); for (int i = 0; i < dataCopy->GetNbinsX()+5; i++) { LOG(DEB) << "binEdges[" << i << "] = " << binEdges[i] << std::endl; } fDataHist = new TH1D((fName+"_data").c_str(), (fName+"_data"+fPlotTitles).c_str(), dataCopy->GetNbinsX()-1, binEdges); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { fDataHist->SetBinContent(i+1, dataCopy->GetBinContent(i+1)*1E-38); fDataHist->SetBinError(i+1, dataCopy->GetBinError(i+1)*1E-38); LOG(DEB) << fDataHist->GetBinLowEdge(i+1) << " " << fDataHist->GetBinContent(i+1) << std::endl; } fDataHist->SetDirectory(0); //should disassociate fDataHist with dataFile fDataHist->SetNameTitle((fName+"_data").c_str(), (fName+"_MC"+fPlotTitles).c_str()); dataFile->Close(); }; // Override this for now // Should really have Measurement1D do this properly though void T2K_CC1pip_CH_XSec_1Dpmu_nu::SetCovarMatrix(std::string fileLocation) { LOG(DEB) << "Covariance: " << fileLocation.c_str() << std::endl; TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file! TH2D *covarMatrix = (TH2D*)(dataFile->Get("TMatrixDBase;1"))->Clone(); int nBinsX = covarMatrix->GetXaxis()->GetNbins(); int nBinsY = covarMatrix->GetYaxis()->GetNbins(); if ((nBinsX != nBinsY)) ERR(WRN) << "covariance matrix not square!" << std::endl; - this->covar = new TMatrixDSym(nBinsX-2); this->fFullCovar = new TMatrixDSym(nBinsX-2); // First two entries are BS // Last entry is BS for (int i = 1; i < nBinsX-1; i++) { for (int j = 1; j < nBinsY-1; j++) { - (*this->covar)(i-1, j-1) = covarMatrix->GetBinContent(i+1, j+1); //adds syst+stat covariances (*this->fFullCovar)(i-1, j-1) = covarMatrix->GetBinContent(i+1, j+1); //adds syst+stat covariances - LOG(DEB) << "covar(" << i-1 << ", " << j-1 << ") = " << (*this->covar)(i-1,j-1) << std::endl; + LOG(DEB) << "fFullCovar(" << i-1 << ", " << j-1 << ") = " << (*this->fFullCovar)(i-1,j-1) << std::endl; } } //should now have set covariance, I hope - TDecompChol tempMat = TDecompChol(*this->covar); - this->covar = new TMatrixDSym(nBinsX, tempMat.Invert().GetMatrixArray(), ""); - // *this->covar *= 1E-38*1E-38; - + this->fDecomp = StatUtils::GetDecomp(this->fFullCovar); + this->covar = StatUtils::GetInvert(this->fFullCovar); return; }; void T2K_CC1pip_CH_XSec_1Dpmu_nu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(13) == 0 || event->NumFSParticle(211) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Ppip = event->GetHMFSParticle(211)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; double pmu = FitUtils::p(Pmu); fXVar = pmu; return; }; //******************************************************************** bool T2K_CC1pip_CH_XSec_1Dpmu_nu::isSignal(FitEvent *event) { //******************************************************************** // Warning: The CH analysis has different signal definition to the H2O analysis! // // If Michel e- is used for pion PID we don't have directional info on pion; set the bool to true // The bool is if we use Michel e- or not // Also, for events binned in muon momentum/angle there's no cut on the pion kinematics // // Additionally, the 2D distribution uses 0.8 > cos th mu > 0 and no pion phase space reduction applied // Also no muon momentum reduction applied // // This uses a slightly custom signal definition where a cut is only placed on the muon angle, not the momentum if (!SignalDef::isCC1pi(event, 14, 211, EnuMin, EnuMax)) return false; TLorentzVector Pnu = event->GetHMISParticle(14)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; double cos_th_mu = cos(FitUtils::th(Pnu,Pmu)); if (cos_th_mu >= 0.2) return true; return false; }; diff --git a/src/T2K/T2K_CC1pip_CH_XSec_1Dppi_nu.cxx b/src/T2K/T2K_CC1pip_CH_XSec_1Dppi_nu.cxx index 423d9c1..f787b76 100644 --- a/src/T2K/T2K_CC1pip_CH_XSec_1Dppi_nu.cxx +++ b/src/T2K/T2K_CC1pip_CH_XSec_1Dppi_nu.cxx @@ -1,179 +1,177 @@ #include #include "T2K_SignalDef.h" #include "T2K_CC1pip_CH_XSec_1Dppi_nu.h" //******************************************************************** T2K_CC1pip_CH_XSec_1Dppi_nu::T2K_CC1pip_CH_XSec_1Dppi_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "T2K_CC1pip_CH_XSec_1Dppi_nu sample. \n" \ "Target: CH \n" \ "Flux: T2k Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 electron, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetTitle("T2K_CC1pip_CH_XSec_1Dppi_nu"); fSettings.SetDescription(descrip); fSettings.SetXTitle("p_{#pi} (GeV/c)"); fSettings.SetYTitle("d#sigma/dW_{rec} (cm^{2}/(GeV/c)/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/DIAG"); fSettings.SetEnuRange(0.0, 100.0); fSettings.DefineAllowedTargets("C,H"); fSettings.DefineAllowedSpecies("numu"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38) / double(fNEvents) / TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- if (fSettings.GetS("type").find("Michel") != std::string::npos) { useMichel = true; fName += "_Michel"; SetDataValues(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/CH/Ppi.root"); SetCovarMatrix(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/CH/Ppi.root"); } else { useMichel = false; - fName += "_kin"; + // fName += "_kin"; SetDataValues(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/CH/Ppi_noME.root"); SetCovarMatrix(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/CH/Ppi_noME.root"); } + + SetShapeCovar(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; // Override this for now // Should really have Measurement1D do this properly though void T2K_CC1pip_CH_XSec_1Dppi_nu::SetDataValues(std::string fileLocation) { LOG(DEB) << "Reading: " << this->fName << "\nData: " << fileLocation.c_str() << std::endl; TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file! // Don't want the last bin of dataCopy TH1D *dataCopy = (TH1D*)(dataFile->Get("hResult_sliced_0_1"))->Clone(); LOG(DEB) << dataCopy->GetNbinsX() << std::endl; double *binEdges = new double[dataCopy->GetNbinsX() - 1]; for (int i = 0; i < dataCopy->GetNbinsX() - 1; i++) { binEdges[i] = dataCopy->GetBinLowEdge(i + 1); } binEdges[dataCopy->GetNbinsX() - 1] = dataCopy->GetBinLowEdge(dataCopy->GetNbinsX()); fDataHist = new TH1D((fName + "_data").c_str(), (fName + "_data" + fPlotTitles).c_str(), dataCopy->GetNbinsX() - 2, binEdges); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { fDataHist->SetBinContent(i + 1, dataCopy->GetBinContent(i + 1) * 1E-38); fDataHist->SetBinError(i + 1, dataCopy->GetBinError(i + 1) * 1E-38); LOG(DEB) << fDataHist->GetBinLowEdge(i + 1) << " " << fDataHist->GetBinContent(i + 1) << std::endl; } fDataHist->SetDirectory(0); //should disassociate fDataHist with dataFile fDataHist->SetNameTitle((fName + "_data").c_str(), (fName + "_MC" + fPlotTitles).c_str()); dataFile->Close(); }; // Override this for now // Should really have Measurement1D do this properly though void T2K_CC1pip_CH_XSec_1Dppi_nu::SetCovarMatrix(std::string fileLocation) { LOG(DEB) << "Covariance: " << fileLocation.c_str() << std::endl; TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file! TH2D *covarMatrix = (TH2D*)(dataFile->Get("TMatrixDBase;1"))->Clone(); int nBinsX = covarMatrix->GetXaxis()->GetNbins(); int nBinsY = covarMatrix->GetYaxis()->GetNbins(); if ((nBinsX != nBinsY)) ERR(WRN) << "covariance matrix not square!" << std::endl; - this->covar = new TMatrixDSym(nBinsX - 2); - this->fFullCovar = new TMatrixDSym(nBinsX - 2); + this->fFullCovar = new TMatrixDSym(nBinsX - 3); // First two entries are BS // Last entry is BS - for (int i = 1; i < nBinsX - 1; i++) { - for (int j = 1; j < nBinsY - 1; j++) { + for (int i = 2; i < nBinsX-1; i++) { + for (int j = 2; j < nBinsY-1; j++) { LOG(DEB) << "(" << i << ", " << j << ") = " << covarMatrix->GetBinContent(i + 1, j + 1) << std::endl; - (*this->covar)(i - 1, j - 1) = covarMatrix->GetBinContent(i, j); //adds syst+stat covariances - (*this->fFullCovar)(i - 1, j - 1) = covarMatrix->GetBinContent(i, j); //adds syst+stat covariances + (*this->fFullCovar)(i - 2, j - 2) = covarMatrix->GetBinContent(i, j); //adds syst+stat covariances } } //should now have set covariance, I hope - TDecompChol tempMat = TDecompChol(*this->covar); - this->covar = new TMatrixDSym(nBinsX, tempMat.Invert().GetMatrixArray(), ""); - // *this->covar *= 1E-38*1E-38; - + this->fDecomp = StatUtils::GetDecomp(this->fFullCovar); + this->covar = StatUtils::GetInvert(this->fFullCovar); return; }; void T2K_CC1pip_CH_XSec_1Dppi_nu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(13) == 0 || event->NumFSParticle(211) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Ppip = event->GetHMFSParticle(211)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; double ppip = FitUtils::p(Ppip); fXVar = ppip; return; }; //******************************************************************** bool T2K_CC1pip_CH_XSec_1Dppi_nu::isSignal(FitEvent *event) { //******************************************************************** // This distribution uses a somewhat different signal definition so might as well implement it separately here // If we use Michel tag sample we don't cut into the pion phase space, only the muon phase space // The last bool refers to if we have Michel e or not if (useMichel) { return SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, true); } else { // Custom signal definition if we aren't using Michel tag; cut on muon and cut only on pion angle // does the event pass the muon cut? bool muonPass = SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, true); // If the event doesn't pass the muon cut return false if (!muonPass) { return false; } // does the event pass the pion angle cut? // we already know there's just one muon in the event if it passes muonPass so don't need to make an event loop rejection // Need the neutrino four-vector to get the angle between pion and neutrino TLorentzVector Pnu = event->PartInfo(0)->fP; TLorentzVector Ppip; for (unsigned int j = 2; j < event->Npart(); j++) { if (!((event->PartInfo(j))->fIsAlive) && (event->PartInfo(j))->fNEUTStatusCode != 0) continue; //move on if NOT ALIVE and NOT NORMAL int PID = (event->PartInfo(j))->fPID; if (PID == 211) { Ppip = event->PartInfo(j)->fP; // Once the pion is found we can break break; } } double cos_th_pi = cos(FitUtils::th(Pnu, Ppip)); // Now check the angle of the pion if (cos_th_pi <= 0.2) { return false; } else { return true; } } // Unnecessary default to false return false; } diff --git a/src/T2K/T2K_CC1pip_CH_XSec_1Dq3_nu.cxx b/src/T2K/T2K_CC1pip_CH_XSec_1Dq3_nu.cxx index 28f6e7b..6a34455 100644 --- a/src/T2K/T2K_CC1pip_CH_XSec_1Dq3_nu.cxx +++ b/src/T2K/T2K_CC1pip_CH_XSec_1Dq3_nu.cxx @@ -1,113 +1,109 @@ #include #include "T2K_SignalDef.h" #include "T2K_CC1pip_CH_XSec_1Dq3_nu.h" // The constructor T2K_CC1pip_CH_XSec_1Dq3_nu::T2K_CC1pip_CH_XSec_1Dq3_nu(std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile){ fName = "T2K_CC1pip_CH_XSec_1Dq3_nu"; fPlotTitles = "; q_{3} (GeV/c); d#sigma/dq_{3} (cm^{2}/(GeV/c)/nucleon)"; EnuMin = 0.; EnuMax = 100.; fIsDiag = false; Measurement1D::SetupMeasurement(inputfile, type, rw, fakeDataFile); this->SetDataValues(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Q3.root"); this->SetCovarMatrix(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Q3.root"); - + SetShapeCovar(); this->SetupDefaultHist(); this->fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width"); }; // Override this for now // Should really have Measurement1D do this properly though void T2K_CC1pip_CH_XSec_1Dq3_nu::SetDataValues(std::string fileLocation) { LOG(DEB) << "Reading: " << this->fName << "\nData: " << fileLocation.c_str() << std::endl; TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file! // Don't want the last bin of dataCopy TH1D *dataCopy = (TH1D*)(dataFile->Get("hResult_sliced_0_1"))->Clone(); - double *binEdges = new double[dataCopy->GetNbinsX()-1]; + double *binEdges = new double[dataCopy->GetNbinsX()-2]; LOG(DEB) << dataCopy->GetNbinsX() << std::endl; - for (int i = 1; i < dataCopy->GetNbinsX(); i++) { + for (int i = 1; i < dataCopy->GetNbinsX()-1; i++) { binEdges[i-1] = dataCopy->GetBinLowEdge(i+1); LOG(DEB) << i-1 << " " << binEdges[i-1] << " from binLowEdge " << i+1 << std::endl; } fDataHist = new TH1D((fName+"_data").c_str(), (fName+"_data"+fPlotTitles).c_str(), dataCopy->GetNbinsX()-2, binEdges); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { fDataHist->SetBinContent(i+1, dataCopy->GetBinContent(i+2)*1E-38); fDataHist->SetBinError(i+1, dataCopy->GetBinError(i+2)*1E-38); LOG(DEB) << fDataHist->GetBinLowEdge(i+1) << " " << fDataHist->GetBinContent(i+1) << " " << fDataHist->GetBinError(i+1) << std::endl; } fDataHist->SetDirectory(0); //should disassociate fDataHist with dataFile fDataHist->SetNameTitle((fName+"_data").c_str(), (fName+"_MC"+fPlotTitles).c_str()); dataFile->Close(); }; // Override this for now // Should really have Measurement1D do this properly though void T2K_CC1pip_CH_XSec_1Dq3_nu::SetCovarMatrix(std::string fileLocation) { LOG(DEB) << "Covariance: " << fileLocation.c_str() << std::endl; TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file! TH2D *covarMatrix = (TH2D*)(dataFile->Get("TMatrixDBase;1"))->Clone(); int nBinsX = covarMatrix->GetXaxis()->GetNbins(); int nBinsY = covarMatrix->GetYaxis()->GetNbins(); if ((nBinsX != nBinsY)) ERR(WRN) << "covariance matrix not square!" << std::endl; - this->covar = new TMatrixDSym(nBinsX-2); - this->fFullCovar = new TMatrixDSym(nBinsX-2); + this->fFullCovar = new TMatrixDSym(nBinsX-3); // First two entries are BS // Last entry is BS for (int i = 2; i < nBinsX-1; i++) { for (int j = 2; j < nBinsY-1; j++) { - (*this->covar)(i-2, j-2) = covarMatrix->GetBinContent(i+1, j+1); //adds syst+stat covariances (*this->fFullCovar)(i-2, j-2) = covarMatrix->GetBinContent(i+1, j+1); //adds syst+stat covariances - LOG(DEB) << "covar(" << i-2 << ", " << j-2 << ") = " << (*this->covar)(i-2,j-2) << std::endl; + LOG(DEB) << "fFullCovar(" << i-2 << ", " << j-2 << ") = " << (*this->fFullCovar)(i-2,j-2) << std::endl; } } //should now have set covariance, I hope - TDecompChol tempMat = TDecompChol(*this->covar); - this->covar = new TMatrixDSym(nBinsX, tempMat.Invert().GetMatrixArray(), ""); - // *this->covar *= 1E-38*1E-38; - + this->fDecomp = StatUtils::GetDecomp(this->fFullCovar); + this->covar = StatUtils::GetInvert(this->fFullCovar); return; }; void T2K_CC1pip_CH_XSec_1Dq3_nu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(13) == 0 || event->NumFSParticle(211) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Ppip = event->GetHMFSParticle(211)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; double q3 = FitUtils::q3_CC1pip_T2K(Pnu, Pmu, Ppip); fXVar = q3; return; }; //******************************************************************** bool T2K_CC1pip_CH_XSec_1Dq3_nu::isSignal(FitEvent *event) { //******************************************************************** // Has a Michel e sample in so no phase space cut on pion required return SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, true); } diff --git a/src/T2K/T2K_CC1pip_CH_XSec_1Dthmupi_nu.cxx b/src/T2K/T2K_CC1pip_CH_XSec_1Dthmupi_nu.cxx index b191482..da6cc55 100644 --- a/src/T2K/T2K_CC1pip_CH_XSec_1Dthmupi_nu.cxx +++ b/src/T2K/T2K_CC1pip_CH_XSec_1Dthmupi_nu.cxx @@ -1,113 +1,109 @@ #include #include "T2K_SignalDef.h" #include "T2K_CC1pip_CH_XSec_1Dthmupi_nu.h" // The constructor T2K_CC1pip_CH_XSec_1Dthmupi_nu::T2K_CC1pip_CH_XSec_1Dthmupi_nu(std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile){ fName = "T2K_CC1pip_CH_XSec_1Dthmupi_nu"; fPlotTitles = "; #theta_{#pi,#mu} (radians); d#sigma/d#theta_{#pi} (cm^{2}/nucleon)"; EnuMin = 0.; EnuMax = 100.; fIsDiag = false; Measurement1D::SetupMeasurement(inputfile, type, rw, fakeDataFile); this->SetDataValues(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Thetapimu.root"); this->SetCovarMatrix(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Thetapimu.root"); - + SetShapeCovar(); this->SetupDefaultHist(); this->fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width"); }; // Override this for now // Should really have Measurement1D do this properly though void T2K_CC1pip_CH_XSec_1Dthmupi_nu::SetDataValues(std::string fileLocation) { LOG(DEB) << "Reading: " << this->fName << "\nData: " << fileLocation.c_str() << std::endl; TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file! // Don't want the first and last bin of dataCopy TH1D *dataCopy = (TH1D*)(dataFile->Get("hResult_sliced_0_1"))->Clone(); LOG(DEB) << "dataCopy->GetNbinsX() = " << dataCopy->GetNbinsX() << std::endl; double *binEdges = new double[dataCopy->GetNbinsX()]; for (int i = 0; i < dataCopy->GetNbinsX(); i++) { binEdges[i] = dataCopy->GetBinLowEdge(i+1); } binEdges[dataCopy->GetNbinsX()] = dataCopy->GetBinLowEdge(dataCopy->GetNbinsX()+1); for (int i = 0; i < dataCopy->GetNbinsX()+5; i++) { LOG(DEB) << "binEdges[" << i << "] = " << binEdges[i] << std::endl; } fDataHist = new TH1D((fName+"_data").c_str(), (fName+"_data"+fPlotTitles).c_str(), dataCopy->GetNbinsX(), binEdges); for (int i = 0; i < fDataHist->GetNbinsX()+1; i++) { fDataHist->SetBinContent(i+1, dataCopy->GetBinContent(i+1)*1E-38); fDataHist->SetBinError(i+1, dataCopy->GetBinError(i+1)*1E-38); LOG(DEB) << fDataHist->GetBinLowEdge(i+1) << " " << fDataHist->GetBinContent(i+1) << " " << fDataHist->GetBinError(i+1) << std::endl; } fDataHist->SetDirectory(0); //should disassociate fDataHist with dataFile dataFile->Close(); }; // Override this for now // Should really have Measurement1D do this properly though void T2K_CC1pip_CH_XSec_1Dthmupi_nu::SetCovarMatrix(std::string fileLocation) { LOG(DEB) << "Covariance: " << fileLocation.c_str() << std::endl; TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file! TH2D *covarMatrix = (TH2D*)(dataFile->Get("TMatrixDBase;1"))->Clone(); int nBinsX = covarMatrix->GetXaxis()->GetNbins(); int nBinsY = covarMatrix->GetYaxis()->GetNbins(); if ((nBinsX != nBinsY)) ERR(WRN) << "covariance matrix not square!" << std::endl; - this->covar = new TMatrixDSym(nBinsX-1); this->fFullCovar = new TMatrixDSym(nBinsX-1); for (int i = 1; i < nBinsX; i++) { for (int j = 1; j < nBinsY; j++) { - (*this->covar)(i-1, j-1) = covarMatrix->GetBinContent(i, j); //adds syst+stat covariances (*this->fFullCovar)(i-1, j-1) = covarMatrix->GetBinContent(i, j); //adds syst+stat covariances - LOG(DEB) << "covar(" << i-1 << ", " << j-1 << ") = " << (*this->covar)(i-1,j-1) << std::endl; + LOG(DEB) << "fFullCovar(" << i-1 << ", " << j-1 << ") = " << (*this->fFullCovar)(i-1,j-1) << std::endl; } } //should now have set covariance, I hope - TDecompChol tempMat = TDecompChol(*this->covar); - this->covar = new TMatrixDSym(nBinsX, tempMat.Invert().GetMatrixArray(), ""); - // *this->covar *= 1E-38*1E-38; - + this->fDecomp = StatUtils::GetDecomp(this->fFullCovar); + this->covar = StatUtils::GetInvert(this->fFullCovar); dataFile->Close(); }; void T2K_CC1pip_CH_XSec_1Dthmupi_nu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(13) == 0 || event->NumFSParticle(211) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Ppip = event->GetHMFSParticle(211)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; double thmupi = FitUtils::th(Pmu, Ppip); fXVar = thmupi; return; }; //******************************************************************** bool T2K_CC1pip_CH_XSec_1Dthmupi_nu::isSignal(FitEvent *event) { //******************************************************************** // This sample requires directional information on the pion so can't use Michel tag sample return SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, false); } diff --git a/src/T2K/T2K_CC1pip_CH_XSec_1Dthpi_nu.cxx b/src/T2K/T2K_CC1pip_CH_XSec_1Dthpi_nu.cxx index 4324fe6..b8be6c5 100644 --- a/src/T2K/T2K_CC1pip_CH_XSec_1Dthpi_nu.cxx +++ b/src/T2K/T2K_CC1pip_CH_XSec_1Dthpi_nu.cxx @@ -1,114 +1,110 @@ #include #include "T2K_SignalDef.h" #include "T2K_CC1pip_CH_XSec_1Dthpi_nu.h" // The constructor T2K_CC1pip_CH_XSec_1Dthpi_nu::T2K_CC1pip_CH_XSec_1Dthpi_nu(std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile){ fName = "T2K_CC1pip_CH_XSec_1Dthpi_nu"; fPlotTitles = "; #theta_{#pi} (radians); d#sigma/d#theta_{#pi} (cm^{2}/nucleon)"; EnuMin = 0.; EnuMax = 100.; fIsDiag = false; Measurement1D::SetupMeasurement(inputfile, type, rw, fakeDataFile); this->SetDataValues(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Thetapi.root"); this->SetCovarMatrix(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/Thetapi.root"); - + SetShapeCovar(); this->SetupDefaultHist(); this->fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width"); }; // Override this for now // Should really have Measurement1D do this properly though void T2K_CC1pip_CH_XSec_1Dthpi_nu::SetDataValues(std::string fileLocation) { LOG(DEB) << "Reading: " << this->fName << "\nData: " << fileLocation.c_str() << std::endl; TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file! // Don't want the first and last bin of dataCopy TH1D *dataCopy = (TH1D*)(dataFile->Get("hResult_sliced_0_1"))->Clone(); LOG(DEB) << "dataCopy->GetNbinsX() = " << dataCopy->GetNbinsX() << std::endl; double *binEdges = new double[dataCopy->GetNbinsX()-4]; for (int i = 0; i < dataCopy->GetNbinsX()-4; i++) { binEdges[i] = dataCopy->GetBinLowEdge(i+1); } binEdges[dataCopy->GetNbinsX()-4] = dataCopy->GetBinLowEdge(dataCopy->GetNbinsX()-3); for (int i = 0; i < dataCopy->GetNbinsX(); i++) { LOG(DEB) << "binEdges[" << i << "] = " << binEdges[i] << std::endl; } fDataHist = new TH1D((fName+"_data").c_str(), (fName+"_data"+fPlotTitles).c_str(), dataCopy->GetNbinsX()-4, binEdges); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { fDataHist->SetBinContent(i+1, dataCopy->GetBinContent(i+1)*1E-38); fDataHist->SetBinError(i+1, dataCopy->GetBinError(i+1)*1E-38); LOG(DEB) << fDataHist->GetBinLowEdge(i+1) << " " << fDataHist->GetBinContent(i+1) << " " << fDataHist->GetBinError(i+1) << std::endl; } fDataHist->SetDirectory(0); //should disassociate fDataHist with dataFile dataFile->Close(); }; // Override this for now // Should really have Measurement1D do this properly though void T2K_CC1pip_CH_XSec_1Dthpi_nu::SetCovarMatrix(std::string fileLocation) { LOG(DEB) << "Covariance: " << fileLocation.c_str() << std::endl; TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file! TH2D *covarMatrix = (TH2D*)(dataFile->Get("TMatrixDBase;1"))->Clone(); int nBinsX = covarMatrix->GetXaxis()->GetNbins(); int nBinsY = covarMatrix->GetYaxis()->GetNbins(); if ((nBinsX != nBinsY)) ERR(WRN) << "covariance matrix not square!" << std::endl; - this->covar = new TMatrixDSym(nBinsX-5); this->fFullCovar = new TMatrixDSym(nBinsX-5); for (int i = 2; i < nBinsX-3; i++) { for (int j = 2; j < nBinsY-3; j++) { - (*this->covar)(i-2, j-2) = covarMatrix->GetBinContent(i, j); //adds syst+stat covariances (*this->fFullCovar)(i-2, j-2) = covarMatrix->GetBinContent(i, j); //adds syst+stat covariances - LOG(DEB) << "covar(" << i-2 << ", " << j-2 << ") = " << (*this->covar)(i-2,j-2) << std::endl; + LOG(DEB) << "fFullCovar(" << i-2 << ", " << j-2 << ") = " << (*this->fFullCovar)(i-2,j-2) << std::endl; } } //should now have set covariance, I hope - TDecompChol tempMat = TDecompChol(*this->covar); - this->covar = new TMatrixDSym(nBinsX, tempMat.Invert().GetMatrixArray(), ""); - // *this->covar *= 1E-38*1E-38; - + this->fDecomp = StatUtils::GetDecomp(this->fFullCovar); + this->covar = StatUtils::GetInvert(this->fFullCovar); dataFile->Close(); }; void T2K_CC1pip_CH_XSec_1Dthpi_nu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(13) == 0 || event->NumFSParticle(211) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Ppip = event->GetHMFSParticle(211)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; double thpi = FitUtils::th(Pnu, Ppip); fXVar = thpi; return; }; //******************************************************************** bool T2K_CC1pip_CH_XSec_1Dthpi_nu::isSignal(FitEvent *event) { //******************************************************************** // This sample uses directional info on the pion so Michel e tag sample can not be included // i.e. we need reduce the pion variable phase space return SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, false); } diff --git a/src/T2K/T2K_CC1pip_CH_XSec_1Dthq3pi_nu.cxx b/src/T2K/T2K_CC1pip_CH_XSec_1Dthq3pi_nu.cxx index e3a1cbb..1426e80 100644 --- a/src/T2K/T2K_CC1pip_CH_XSec_1Dthq3pi_nu.cxx +++ b/src/T2K/T2K_CC1pip_CH_XSec_1Dthq3pi_nu.cxx @@ -1,119 +1,115 @@ #include #include "T2K_SignalDef.h" #include "T2K_CC1pip_CH_XSec_1Dthq3pi_nu.h" // The constructor T2K_CC1pip_CH_XSec_1Dthq3pi_nu::T2K_CC1pip_CH_XSec_1Dthq3pi_nu(std::string inputfile, FitWeight *rw, std::string type, std::string fakeDataFile){ fName = "T2K_CC1pip_CH_XSec_1Dthq3pi_nu"; fPlotTitles = "; #theta_{q_{3},#pi} (radians); d#sigma/d#theta_{q_{3},#pi} (cm^{2}/(radian)/nucleon)"; EnuMin = 0.; EnuMax = 100.; fIsDiag = false; Measurement1D::SetupMeasurement(inputfile, type, rw, fakeDataFile); this->SetDataValues(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/ThetaQ3Pi.root"); this->SetCovarMatrix(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/CH/ThetaQ3Pi.root"); - + SetShapeCovar(); this->SetupDefaultHist(); this->fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width"); }; // Override this for now // Should really have Measurement1D do this properly though void T2K_CC1pip_CH_XSec_1Dthq3pi_nu::SetDataValues(std::string fileLocation) { LOG(DEB) << "Reading: " << this->fName << "\nData: " << fileLocation.c_str() << std::endl; TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file! // Don't want the last bin of dataCopy TH1D *dataCopy = (TH1D*)(dataFile->Get("hResult_sliced_0_1"))->Clone(); double *binEdges = new double[dataCopy->GetNbinsX()-1]; LOG(DEB) << dataCopy->GetNbinsX() << std::endl; for (int i = 1; i < dataCopy->GetNbinsX()+1; i++) { binEdges[i-1] = dataCopy->GetBinLowEdge(i); LOG(DEB) << i-1 << " " << binEdges[i-1] << std::endl; } for (int i = 0; i < dataCopy->GetNbinsX()+5; i++) { LOG(DEB) << "binEdges[" << i << "] = " << binEdges[i] << std::endl; } fDataHist = new TH1D((fName+"_data").c_str(), (fName+"_data"+fPlotTitles).c_str(), dataCopy->GetNbinsX()-1, binEdges); for (int i = 0; i < fDataHist->GetNbinsX(); i++) { fDataHist->SetBinContent(i+1, dataCopy->GetBinContent(i+1)*1E-38); fDataHist->SetBinError(i+1, dataCopy->GetBinError(i+1)*1E-38); LOG(DEB) << fDataHist->GetBinLowEdge(i+1) << " " << fDataHist->GetBinContent(i+1) << " " << fDataHist->GetBinError(i+1) << std::endl; } fDataHist->SetDirectory(0); //should disassociate fDataHist with dataFile fDataHist->SetNameTitle((fName+"_data").c_str(), (fName+"_MC"+fPlotTitles).c_str()); dataFile->Close(); }; // Override this for now // Should really have Measurement1D do this properly though void T2K_CC1pip_CH_XSec_1Dthq3pi_nu::SetCovarMatrix(std::string fileLocation) { LOG(DEB) << "Covariance: " << fileLocation.c_str() << std::endl; TFile *dataFile = new TFile(fileLocation.c_str()); //truly great .root file! TH2D *covarMatrix = (TH2D*)(dataFile->Get("TMatrixDBase;1"))->Clone(); int nBinsX = covarMatrix->GetXaxis()->GetNbins(); int nBinsY = covarMatrix->GetYaxis()->GetNbins(); if ((nBinsX != nBinsY)) ERR(WRN) << "covariance matrix not square!" << std::endl; // First bin is underflow, last bin is overflow - this->covar = new TMatrixDSym(nBinsX-2); this->fFullCovar = new TMatrixDSym(nBinsX-2); // First two entries are BS // Last entry is BS for (int i = 1; i < nBinsX-1; i++) { for (int j = 1; j < nBinsY-1; j++) { - (*this->covar)(i-1, j-1) = covarMatrix->GetBinContent(i+1, j+1); //adds syst+stat covariances (*this->fFullCovar)(i-1, j-1) = covarMatrix->GetBinContent(i+1, j+1); //adds syst+stat covariances - LOG(DEB) << "covar(" << i-1 << ", " << j-1 << ") = " << (*this->covar)(i-1,j-1) << std::endl; + LOG(DEB) << "fFullCovar(" << i-1 << ", " << j-1 << ") = " << (*this->fFullCovar)(i-1,j-1) << std::endl; } } //should now have set covariance, I hope - TDecompChol tempMat = TDecompChol(*this->covar); - this->covar = new TMatrixDSym(nBinsX, tempMat.Invert().GetMatrixArray(), ""); - // *this->covar *= 1E-38*1E-38; - + this->fDecomp = StatUtils::GetDecomp(this->fFullCovar); + this->covar = StatUtils::GetInvert(this->fFullCovar); return; }; void T2K_CC1pip_CH_XSec_1Dthq3pi_nu::FillEventVariables(FitEvent *event) { if (event->NumFSParticle(13) == 0 || event->NumFSParticle(211) == 0) return; TLorentzVector Pnu = event->GetNeutrinoIn()->fP; TLorentzVector Ppip = event->GetHMFSParticle(211)->fP; TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; double th_q3_pi = FitUtils::thq3pi_CC1pip_T2K(Pnu, Pmu, Ppip); fXVar = th_q3_pi; return; }; //******************************************************************** bool T2K_CC1pip_CH_XSec_1Dthq3pi_nu::isSignal(FitEvent *event) { //******************************************************************** // This sample requires pion directional information so can not include Michel tag sample // i.e. will need to cut the pion phase space return SignalDef::isCC1pip_T2K_CH(event, EnuMin, EnuMax, false); } diff --git a/src/T2K/T2K_CC1pip_H2O_XSec_1DEnuDelta_nu.cxx b/src/T2K/T2K_CC1pip_H2O_XSec_1DEnuDelta_nu.cxx index 6e04801..45c4bf1 100644 --- a/src/T2K/T2K_CC1pip_H2O_XSec_1DEnuDelta_nu.cxx +++ b/src/T2K/T2K_CC1pip_H2O_XSec_1DEnuDelta_nu.cxx @@ -1,74 +1,75 @@ #include "T2K_CC1pip_H2O_XSec_1DEnuDelta_nu.h" // The derived neutrino energy assuming a Delta resonance and a nucleon at rest; so only requires the outgoing muon to derive (and information on the angle between the muon and the neutrino) // Please beware that this is NOT THE "TRUE" NEUTRINO ENERGY; IT'S A PROXY FOR THE TRUE NEUTRINO ENERGY // Also, this is flux-integrated cross-section, not flux averaged //******************************************************************** T2K_CC1pip_H2O_XSec_1DEnuDelta_nu::T2K_CC1pip_H2O_XSec_1DEnuDelta_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "T2K_CC1pip_H2O_XSec_1DEnuDelta_nu sample. \n" \ "Target: CH \n" \ "Flux: T2k Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 electron, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetTitle("T2K_CC1pip_H2O_XSec_1DEnuDelta_nu"); fSettings.SetDescription(descrip); fSettings.SetXTitle("E_{#nu} (GeV)"); fSettings.SetYTitle("#sigma(E_{#nu}) (cm^{2}/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/DIAG"); fSettings.SetEnuRange(0.0, 100.0); fSettings.DefineAllowedTargets("C,H"); fSettings.DefineAllowedSpecies("numu"); fSettings.SetDataInput(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;EnuRec_Delta/hResultTot"); fSettings.SetCovarInput(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;EnuRec_Delta/TotalCovariance"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38) / double(fNEvents); // Plot Setup ------------------------------------------------------- SetDataFromRootFile( fSettings.GetDataInput() ); SetCovarFromRootFile( fSettings.GetCovarInput() ); ScaleCovar(1E76); + SetShapeCovar(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; //******************************************************************** // Find the muon whows kinematics we use to derive the "neutrino energy" void T2K_CC1pip_H2O_XSec_1DEnuDelta_nu::FillEventVariables(FitEvent *event) { //******************************************************************** // Need to make sure there's a muon if (event->NumFSParticle(13) == 0) return; // Get the incoming neutrino TLorentzVector Pnu = event->GetNeutrinoIn()->fP; // Get the muon TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; double Enu = FitUtils::EnuCC1piprecDelta(Pnu, Pmu); fXVar = Enu; return; }; //******************************************************************** // Beware: The H2O analysis has different signal definition to the CH analysis! bool T2K_CC1pip_H2O_XSec_1DEnuDelta_nu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCC1pip_T2K_H2O(event, EnuMin, EnuMax); } diff --git a/src/T2K/T2K_CC1pip_H2O_XSec_1DEnuMB_nu.cxx b/src/T2K/T2K_CC1pip_H2O_XSec_1DEnuMB_nu.cxx index 6779ad4..1f1e902 100644 --- a/src/T2K/T2K_CC1pip_H2O_XSec_1DEnuMB_nu.cxx +++ b/src/T2K/T2K_CC1pip_H2O_XSec_1DEnuMB_nu.cxx @@ -1,80 +1,80 @@ #include "T2K_CC1pip_H2O_XSec_1DEnuMB_nu.h" // The derived neutrino energy using the "MiniBooNE formula" (see paper) // Essentially this is a proxy for the neutrino energy, using the outgoing pion and muon to get the reconstructed neutrino energy, assuming the struck nucleon was at rest // Again, THIS IS NOT A "TRUE" NEUTRINO ENERGY! //******************************************************************** T2K_CC1pip_H2O_XSec_1DEnuMB_nu::T2K_CC1pip_H2O_XSec_1DEnuMB_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "T2K_CC1pip_H2O_XSec_1DEnuMB_nu sample. \n" \ "Target: CH \n" \ "Flux: T2k Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 electron, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetTitle("T2K_CC1pip_H2O_XSec_1DEnuMB_nu"); fSettings.SetDescription(descrip); fSettings.SetXTitle("E_{#nu} (GeV)"); fSettings.SetYTitle("#sigma(E_{#nu}) (cm^{2}/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/DIAG"); fSettings.SetEnuRange(0.0, 100.0); fSettings.DefineAllowedTargets("C,H"); fSettings.DefineAllowedSpecies("numu"); fSettings.SetDataInput(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;EnuRec_MB/hResultTot"); fSettings.SetCovarInput(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;EnuRec_MB/TotalCovariance"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = (GetEventHistogram()->Integral("width") * 1E-38) / double(fNEvents); // Plot Setup ------------------------------------------------------- SetDataFromRootFile( fSettings.GetDataInput() ); SetCovarFromRootFile( fSettings.GetCovarInput() ); ScaleCovar(1E76); - + SetShapeCovar(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; //******************************************************************** // Find the derived neutrino energy using the "MiniBooNE formula" (see paper) // Essentially uses the pion and muon kinematics to derive a pseudo-neutrino energy, assuming the struck nucleon is at rest // We also need the incoming neutrino to get the muon/neutrino and pion/neutrino angles void T2K_CC1pip_H2O_XSec_1DEnuMB_nu::FillEventVariables(FitEvent *event) { //******************************************************************** // Need to make sure there's a muon if (event->NumFSParticle(13) == 0) return; // Need to make sure there's a pion if (event->NumFSParticle(211) == 0) return; // Get the incoming neutrino TLorentzVector Pnu = event->GetNeutrinoIn()->fP; // Get the muon TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; // Get the pion TLorentzVector Ppip = event->GetHMFSParticle(211)->fP; double Enu = FitUtils::EnuCC1piprec(Pnu, Pmu, Ppip); fXVar = Enu; return; }; //******************************************************************** // Beware: The H2O analysis has different signal definition to the CH analysis! bool T2K_CC1pip_H2O_XSec_1DEnuMB_nu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCC1pip_T2K_H2O(event, EnuMin, EnuMax); } diff --git a/src/T2K/T2K_CC1pip_H2O_XSec_1Dcosmu_nu.cxx b/src/T2K/T2K_CC1pip_H2O_XSec_1Dcosmu_nu.cxx index a92a430..8abe3e3 100644 --- a/src/T2K/T2K_CC1pip_H2O_XSec_1Dcosmu_nu.cxx +++ b/src/T2K/T2K_CC1pip_H2O_XSec_1Dcosmu_nu.cxx @@ -1,73 +1,74 @@ #include "T2K_CC1pip_H2O_XSec_1Dcosmu_nu.h" // The cos of the angle between the neutrino and the muon //******************************************************************** T2K_CC1pip_H2O_XSec_1Dcosmu_nu::T2K_CC1pip_H2O_XSec_1Dcosmu_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "T2K_CC1pip_H2O_XSec_1Dcosmu_nu sample. \n" \ "Target: CH \n" \ "Flux: T2k Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 electron, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetTitle("T2K_CC1pip_H2O_XSec_1Dcosmu_nu"); fSettings.SetDescription(descrip); fSettings.SetXTitle("cos#theta_{#pi,#mu}"); fSettings.SetYTitle("d#sigma/dcos#theta_{#pi#mu} (cm^{2}/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/DIAG"); fSettings.SetEnuRange(0.0, 100.0); fSettings.DefineAllowedTargets("C,H"); fSettings.DefineAllowedSpecies("numu"); fSettings.SetDataInput(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;MuCos/hResultTot"); fSettings.SetCovarInput(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;MuCos/TotalCovariance"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- SetDataFromRootFile( fSettings.GetDataInput() ); SetCovarFromRootFile( fSettings.GetCovarInput() ); ScaleCovar(1E76); + SetShapeCovar(); // Final setup --------------------------------------------------- FinaliseMeasurement(); }; //******************************************************************** // Find the cos theta of the angle between muon and neutrino void T2K_CC1pip_H2O_XSec_1Dcosmu_nu::FillEventVariables(FitEvent *event) { //******************************************************************** // Need to make sure there's a muon if (event->NumFSParticle(13) == 0) return; // Get the incoming neutrino TLorentzVector Pnu = event->GetNeutrinoIn()->fP; // Get the muon TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; // Do the cos of the angle between the two double cos_th = cos(FitUtils::th(Pnu, Pmu)); fXVar = cos_th; return; }; //******************************************************************** // Beware: The H2O analysis has different signal definition to the CH analysis! bool T2K_CC1pip_H2O_XSec_1Dcosmu_nu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCC1pip_T2K_H2O(event, EnuMin, EnuMax); } diff --git a/src/T2K/T2K_CC1pip_H2O_XSec_1Dcosmupi_nu.cxx b/src/T2K/T2K_CC1pip_H2O_XSec_1Dcosmupi_nu.cxx index a56f805..1a50ac3 100644 --- a/src/T2K/T2K_CC1pip_H2O_XSec_1Dcosmupi_nu.cxx +++ b/src/T2K/T2K_CC1pip_H2O_XSec_1Dcosmupi_nu.cxx @@ -1,71 +1,72 @@ #include "T2K_CC1pip_H2O_XSec_1Dcosmupi_nu.h" //******************************************************************** T2K_CC1pip_H2O_XSec_1Dcosmupi_nu::T2K_CC1pip_H2O_XSec_1Dcosmupi_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "T2K_CC1pip_H2O_XSec_1Dcosmupi_nu sample. \n" \ "Target: CH \n" \ "Flux: T2k Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 electron, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetTitle("T2K_CC1pip_H2O_XSec_1Dcosmupi_nu"); fSettings.SetDescription(descrip); fSettings.SetXTitle("cos#theta_{#pi,#mu}"); fSettings.SetYTitle("d#sigma/dcos#theta_{#pi#mu} (cm^{2}/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/DIAG"); fSettings.SetEnuRange(0.0, 100.0); fSettings.DefineAllowedTargets("C,H"); fSettings.DefineAllowedSpecies("numu"); fSettings.SetDataInput(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;MuPiCos/hResultTot"); fSettings.SetCovarInput(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;MuPiCos/TotalCovariance"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = GetEventHistogram()->Integral("width")*1E-38/double(fNEvents)/TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- SetDataFromRootFile( fSettings.GetDataInput() ); SetCovarFromRootFile( fSettings.GetCovarInput() ); ScaleCovar(1E76); - + SetShapeCovar(); + // Final setup --------------------------------------------------- FinaliseMeasurement(); }; //******************************************************************** // Find the cos theta of the angle between muon and pion void T2K_CC1pip_H2O_XSec_1Dcosmupi_nu::FillEventVariables(FitEvent *event) { //******************************************************************** // Need to make sure there's a muon if (event->NumFSParticle(13) == 0) return; // Need to make sure there's a pion if (event->NumFSParticle(211) == 0) return; // Get the muon TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; // Get the pion TLorentzVector Ppip = event->GetHMFSParticle(211)->fP; double cos_th = cos(FitUtils::th(Pmu, Ppip)); fXVar = cos_th; return; }; //******************************************************************** // Beware: The H2O analysis has different signal definition to the CH analysis! bool T2K_CC1pip_H2O_XSec_1Dcosmupi_nu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCC1pip_T2K_H2O(event, EnuMin, EnuMax); } diff --git a/src/T2K/T2K_CC1pip_H2O_XSec_1Dcospi_nu.cxx b/src/T2K/T2K_CC1pip_H2O_XSec_1Dcospi_nu.cxx index 3ba843d..fd022ff 100644 --- a/src/T2K/T2K_CC1pip_H2O_XSec_1Dcospi_nu.cxx +++ b/src/T2K/T2K_CC1pip_H2O_XSec_1Dcospi_nu.cxx @@ -1,68 +1,69 @@ #include "T2K_CC1pip_H2O_XSec_1Dcospi_nu.h" //******************************************************************** T2K_CC1pip_H2O_XSec_1Dcospi_nu::T2K_CC1pip_H2O_XSec_1Dcospi_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "T2K_CC1pip_H2O_XSec_1Dcospi_nu sample. \n" \ "Target: CH \n" \ "Flux: T2k Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 electron, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetTitle("T2K_CC1pip_H2O_XSec_1Dcospi_nu"); fSettings.SetDescription(descrip); fSettings.SetXTitle("cos#theta_{#pi}"); fSettings.SetYTitle("d#sigma/dcos#theta_{#pi} (cm^{2}/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/DIAG"); fSettings.SetEnuRange(0.0, 100.0); fSettings.DefineAllowedTargets("C,H"); fSettings.DefineAllowedSpecies("numu"); fSettings.SetDataInput(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;PosPionCos/hResultTot"); fSettings.SetCovarInput(GeneralUtils::GetTopLevelDir()+"/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;PosPionCos/TotalCovariance"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- SetDataFromRootFile( fSettings.GetDataInput() ); SetCovarFromRootFile( fSettings.GetCovarInput() ); ScaleCovar(1E76); - + SetShapeCovar(); + // Final setup --------------------------------------------------- FinaliseMeasurement(); }; //******************************************************************** // Find the cos theta of the angle between pion and neutrino void T2K_CC1pip_H2O_XSec_1Dcospi_nu::FillEventVariables(FitEvent *event) { //******************************************************************** // Need to make sure there's a pion if (event->NumFSParticle(211) == 0) return; // Get the incoming neutrino TLorentzVector Pnu = event->GetNeutrinoIn()->fP; // Get the pion TLorentzVector Ppip = event->GetHMFSParticle(211)->fP; double cos_th = cos(FitUtils::th(Pnu, Ppip)); fXVar = cos_th; return; }; //******************************************************************** // Beware: The H2O analysis has different signal definition to the CH analysis! bool T2K_CC1pip_H2O_XSec_1Dcospi_nu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCC1pip_T2K_H2O(event, EnuMin, EnuMax); } diff --git a/src/T2K/T2K_CC1pip_H2O_XSec_1Dpmu_nu.cxx b/src/T2K/T2K_CC1pip_H2O_XSec_1Dpmu_nu.cxx index 5f482f0..9d6d983 100644 --- a/src/T2K/T2K_CC1pip_H2O_XSec_1Dpmu_nu.cxx +++ b/src/T2K/T2K_CC1pip_H2O_XSec_1Dpmu_nu.cxx @@ -1,70 +1,71 @@ #include "T2K_CC1pip_H2O_XSec_1Dpmu_nu.h" // The muon momentum //******************************************************************** T2K_CC1pip_H2O_XSec_1Dpmu_nu::T2K_CC1pip_H2O_XSec_1Dpmu_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "T2K_CC1pip_H2O_XSec_1Dpmu_nu sample. \n" \ "Target: CH \n" \ "Flux: T2k Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 electron, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetTitle("T2K_CC1pip_H2O_XSec_1Dpmu_nu"); fSettings.SetDescription(descrip); fSettings.SetXTitle("E_{#nu} (GeV)"); fSettings.SetYTitle("#sigma(E_{#nu}) (cm^{2}/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/DIAG"); fSettings.SetEnuRange(0.0, 100.0); fSettings.DefineAllowedTargets("C,H"); fSettings.DefineAllowedSpecies("numu"); fSettings.SetDataInput(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;MuMom/hResultTot"); fSettings.SetCovarInput(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;MuMom/TotalCovariance"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- SetDataFromRootFile( fSettings.GetDataInput() ); SetCovarFromRootFile( fSettings.GetCovarInput() ); ScaleCovar(1E76); - + SetShapeCovar(); + // Final setup --------------------------------------------------- FinaliseMeasurement(); }; //******************************************************************** // Find the momentum of the muon void T2K_CC1pip_H2O_XSec_1Dpmu_nu::FillEventVariables(FitEvent *event) { //******************************************************************** // Need to make sure there's a muon if (event->NumFSParticle(13) == 0) return; // Get the muon TLorentzVector Pmu = event->GetHMFSParticle(13)->fP; double p_mu = FitUtils::p(Pmu); fXVar = p_mu; return; }; //******************************************************************** // Beware: The H2O analysis has different signal definition to the CH analysis! bool T2K_CC1pip_H2O_XSec_1Dpmu_nu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCC1pip_T2K_H2O(event, EnuMin, EnuMax); } diff --git a/src/T2K/T2K_CC1pip_H2O_XSec_1Dppi_nu.cxx b/src/T2K/T2K_CC1pip_H2O_XSec_1Dppi_nu.cxx index 594c1be..7b33785 100644 --- a/src/T2K/T2K_CC1pip_H2O_XSec_1Dppi_nu.cxx +++ b/src/T2K/T2K_CC1pip_H2O_XSec_1Dppi_nu.cxx @@ -1,69 +1,70 @@ #include "T2K_CC1pip_H2O_XSec_1Dppi_nu.h" // The momentum of the (positive) pion //******************************************************************** T2K_CC1pip_H2O_XSec_1Dppi_nu::T2K_CC1pip_H2O_XSec_1Dppi_nu(nuiskey samplekey) { //******************************************************************** // Sample overview --------------------------------------------------- std::string descrip = "T2K_CC1pip_H2O_XSec_1Dppi_nu sample. \n" \ "Target: CH \n" \ "Flux: T2k Forward Horn Current nue + nuebar \n" \ "Signal: Any event with 1 electron, any nucleons, and no other FS particles \n"; // Setup common settings fSettings = LoadSampleSettings(samplekey); fSettings.SetTitle("T2K_CC1pip_H2O_XSec_1Dppi_nu"); fSettings.SetDescription(descrip); fSettings.SetXTitle("p_{#pi^{+}} (GeV/c)"); fSettings.SetYTitle("d#sigma/dp_{#pi^{+}} (cm^{2}/(GeV/c)/nucleon)"); fSettings.SetAllowedTypes("FIX,FREE,SHAPE/DIAG,FULL/NORM/MASK", "FIX/FULL"); fSettings.SetEnuRange(0.0, 100.0); fSettings.DefineAllowedTargets("C,H"); fSettings.DefineAllowedSpecies("numu"); fSettings.SetDataInput(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;PosPionMom/hResultTot"); fSettings.SetCovarInput(GeneralUtils::GetTopLevelDir() + "/data/T2K/CC1pip/H2O/nd280data-numu-cc1pi-xs-on-h2o-2015.root;PosPionMom/TotalCovariance"); FinaliseSampleSettings(); // Scaling Setup --------------------------------------------------- // ScaleFactor automatically setup for DiffXSec/cm2/Nucleon fScaleFactor = (GetEventHistogram()->Integral("width")*1E-38)/double(fNEvents)/TotalIntegratedFlux("width"); // Plot Setup ------------------------------------------------------- SetDataFromRootFile( fSettings.GetDataInput() ); SetCovarFromRootFile( fSettings.GetCovarInput() ); ScaleCovar(1E76); - + SetShapeCovar(); + // Final setup --------------------------------------------------- FinaliseMeasurement(); }; //******************************************************************** // Find the momentum of the (positively charged) pion void T2K_CC1pip_H2O_XSec_1Dppi_nu::FillEventVariables(FitEvent *event) { //******************************************************************** // Need to make sure there's a muon if (event->NumFSParticle(211) == 0) return; // Get the pion TLorentzVector Ppip = event->GetHMFSParticle(211)->fP; double p_pi = FitUtils::p(Ppip); fXVar = p_pi; return; }; //******************************************************************** // Beware: The H2O analysis has different signal definition to the CH analysis! bool T2K_CC1pip_H2O_XSec_1Dppi_nu::isSignal(FitEvent *event) { //******************************************************************** return SignalDef::isCC1pip_T2K_H2O(event, EnuMin, EnuMax); } diff --git a/src/Utils/StatUtils.cxx b/src/Utils/StatUtils.cxx index 276054c..24a458a 100644 --- a/src/Utils/StatUtils.cxx +++ b/src/Utils/StatUtils.cxx @@ -1,1239 +1,1300 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #include "TH1D.h" #include "StatUtils.h" //******************************************************************* Double_t StatUtils::GetChi2FromDiag(TH1D* data, TH1D* mc, TH1I* mask) { //******************************************************************* Double_t Chi2 = 0.0; TH1D* calc_data = (TH1D*)data->Clone(); TH1D* calc_mc = (TH1D*)mc->Clone(); // Add MC Error to data if required if (FitPar::Config().GetParB("statutils.addmcerror")) { for (int i = 0; i < calc_data->GetNbinsX(); i++) { double dterr = calc_data->GetBinError(i + 1); double mcerr = calc_mc->GetBinError(i + 1); if (dterr > 0.0) { calc_data->SetBinError(i + 1, sqrt(dterr * dterr + mcerr * mcerr)); } } } // Apply masking if required if (mask) { calc_data = ApplyHistogramMasking(data, mask); calc_mc = ApplyHistogramMasking(mc, mask); } // Iterate over bins in X for (int i = 0; i < calc_data->GetNbinsX(); i++) { // Ignore bins with zero data or zero bin error if (calc_data->GetBinError(i + 1) <= 0.0 || calc_data->GetBinContent(i + 1) == 0.0) continue; // Take mc data difference double diff = calc_data->GetBinContent(i + 1) - calc_mc->GetBinContent(i + 1); double err = calc_data->GetBinError(i + 1); Chi2 += (diff * diff) / (err * err); } // cleanup delete calc_data; delete calc_mc; return Chi2; }; //******************************************************************* Double_t StatUtils::GetChi2FromDiag(TH2D* data, TH2D* mc, TH2I* map, TH2I* mask) { //******************************************************************* // Generate a simple map if (!map) map = GenerateMap(data); // Convert to 1D Histograms TH1D* data_1D = MapToTH1D(data, map); TH1D* mc_1D = MapToTH1D(mc, map); TH1I* mask_1D = MapToMask(mask, map); // Calculate 1D chi2 from 1D Plots Double_t Chi2 = StatUtils:: GetChi2FromDiag(data_1D, mc_1D, mask_1D); // CleanUp delete data_1D; delete mc_1D; delete mask_1D; return Chi2; }; //******************************************************************* Double_t StatUtils::GetChi2FromCov(TH1D* data, TH1D* mc, TMatrixDSym* invcov, TH1I* mask, double data_scale, double covar_scale) { //******************************************************************* Double_t Chi2 = 0.0; TMatrixDSym* calc_cov = (TMatrixDSym*) invcov->Clone(); TH1D* calc_data = (TH1D*) data->Clone(); TH1D* calc_mc = (TH1D*) mc->Clone(); calc_data->Scale(data_scale); calc_mc ->Scale(data_scale); (*calc_cov) *= covar_scale; // If a mask if applied we need to apply it before the matrix is inverted if (mask) { calc_cov = ApplyInvertedMatrixMasking(invcov, mask); calc_data = ApplyHistogramMasking(data, mask); calc_mc = ApplyHistogramMasking(mc, mask); } // Add MC Error to data if required if (FitPar::Config().GetParB("statutils.addmcerror")) { // Make temp cov TMatrixDSym* newcov = StatUtils::GetInvert(calc_cov); // Add MC err to diag for (int i = 0; i < calc_data->GetNbinsX(); i++) { double mcerr = calc_mc->GetBinError(i + 1) * sqrt(covar_scale); double oldval = (*newcov)(i, i); (*newcov)(i, i) = oldval + mcerr * mcerr; } // Reset the calc_cov to new invert delete calc_cov; calc_cov = GetInvert(newcov); // Delete the tempcov delete newcov; } // iterate over bins in X (i,j) for (int i = 0; i < calc_data->GetNbinsX(); i++) { for (int j = 0; j < calc_data->GetNbinsX(); j++) { if (calc_data->GetBinContent(i + 1) != 0 || calc_mc->GetBinContent(i + 1) != 0) { LOG(DEB) << "i j = " << i << " " << j << std::endl; LOG(DEB) << "Calc_data mc i = " << calc_data->GetBinContent(i + 1) << " " << calc_mc->GetBinContent(i + 1) << " Dif = " << ( calc_data->GetBinContent(i + 1) - calc_mc->GetBinContent(i + 1) ) << std::endl; LOG(DEB) << "Calc_data mc i = " << calc_data->GetBinContent(j + 1) << " " << calc_mc->GetBinContent(j + 1) << " Dif = " << ( calc_data->GetBinContent(j + 1) - calc_mc->GetBinContent(j + 1) ) << std::endl; LOG(DEB) << "Covar = " << (*calc_cov)(i, j) << std::endl; LOG(DEB) << "Cont chi2 = " \ << ( ( calc_data->GetBinContent(i + 1) - calc_mc->GetBinContent(i + 1) ) \ * (*calc_cov)(i, j) \ * ( calc_data->GetBinContent(j + 1) - calc_mc->GetBinContent(j + 1))) << " " << Chi2 << std::endl; Chi2 += ( ( calc_data->GetBinContent(i + 1) - calc_mc->GetBinContent(i + 1) ) \ * (*calc_cov)(i, j) \ * ( calc_data->GetBinContent(j + 1) - calc_mc->GetBinContent(j + 1) ) ); } else { LOG(DEB) << "Error on bin (i,j) = (" << i << "," << j << ")" << std::endl; LOG(DEB) << "data->GetBinContent(i+1) = " << calc_data->GetBinContent(i + 1) << std::endl; LOG(DEB) << "mc->GetBinContent(i+1) = " << calc_mc->GetBinContent(i + 1) << std::endl; LOG(DEB) << "Adding zero to chi2 instead of dying horrifically " << std::endl; Chi2 += 0.; } } } // Cleanup delete calc_cov; delete calc_data; delete calc_mc; return Chi2; } //******************************************************************* Double_t StatUtils::GetChi2FromCov( TH2D* data, TH2D* mc, TMatrixDSym* invcov, TH2I* map, TH2I* mask) { //******************************************************************* // Generate a simple map if (!map) { map = StatUtils::GenerateMap(data); } // Convert to 1D Histograms TH1D* data_1D = MapToTH1D(data, map); TH1D* mc_1D = MapToTH1D(mc, map); TH1I* mask_1D = MapToMask(mask, map); // Calculate 1D chi2 from 1D Plots Double_t Chi2 = StatUtils::GetChi2FromCov(data_1D, mc_1D, invcov, mask_1D); // CleanUp delete data_1D; delete mc_1D; delete mask_1D; return Chi2; } //******************************************************************* Double_t StatUtils::GetChi2FromSVD( TH1D* data, TH1D* mc, TMatrixDSym* cov, TH1I* mask) { //******************************************************************* Double_t Chi2 = 0.0; TMatrixDSym* calc_cov = (TMatrixDSym*) cov->Clone(); TH1D* calc_data = (TH1D*) data->Clone(); TH1D* calc_mc = (TH1D*) mc->Clone(); // If a mask if applied we need to apply it before the matrix is inverted if (mask) { calc_cov = StatUtils::ApplyMatrixMasking(cov, mask); calc_data = StatUtils::ApplyHistogramMasking(data, mask); calc_mc = StatUtils::ApplyHistogramMasking(mc, mask); } // Decompose matrix TDecompSVD LU = TDecompSVD((*calc_cov)); LU.Decompose(); TMatrixDSym* cov_U = new TMatrixDSym(calc_data->GetNbinsX(), LU .GetU().GetMatrixArray(), ""); TVectorD* cov_S = new TVectorD( LU.GetSig() ); // Apply basis rotation before adding up chi2 Double_t rotated_difference = 0.0; for (int i = 0; i < calc_data->GetNbinsX(); i++) { rotated_difference = 0.0; // Rotate basis of Data - MC for (int j = 0; j < calc_data->GetNbinsY(); j++) rotated_difference += ( calc_data->GetBinContent(j + 1) - calc_mc ->GetBinContent(j + 1) ) * (*cov_U)(j, i) ; // Divide by rotated error cov_S Chi2 += rotated_difference * rotated_difference * 1E76 / (*cov_S)(i); } // Cleanup delete calc_cov; delete calc_data; delete calc_mc; delete cov_U; delete cov_S; return Chi2; } //******************************************************************* Double_t StatUtils::GetChi2FromSVD( TH2D* data, TH2D* mc, TMatrixDSym* cov, TH2I* map, TH2I* mask) { //******************************************************************* // Generate a simple map if (!map) map = StatUtils::GenerateMap(data); // Convert to 1D Histograms TH1D* data_1D = MapToTH1D(data, map); TH1D* mc_1D = MapToTH1D(mc, map); TH1I* mask_1D = MapToMask(mask, map); // Calculate from 1D Double_t Chi2 = StatUtils::GetChi2FromSVD(data_1D, mc_1D, cov, mask_1D); // CleanUp delete data_1D; delete mc_1D; delete mask_1D; return Chi2; } //******************************************************************* double StatUtils::GetChi2FromEventRate(TH1D* data, TH1D* mc, TH1I* mask) { //******************************************************************* // If just an event rate, for chi2 just use Poission Likelihood to calculate the chi2 component double chi2 = 0.0; TH1D* calc_data = (TH1D*)data->Clone(); TH1D* calc_mc = (TH1D*)mc->Clone(); // Apply masking if required if (mask) { calc_data = ApplyHistogramMasking(data, mask); calc_mc = ApplyHistogramMasking(mc, mask); } // Iterate over bins in X for (int i = 0; i < calc_data->GetNbinsX(); i++) { double dt = calc_data->GetBinContent(i + 1); double mc = calc_mc->GetBinContent(i + 1); if (mc <= 0) continue; if (dt <= 0) { // Only add difference chi2 += 2 * (mc - dt); } else { // Do the chi2 for Poisson distributions chi2 += 2 * (mc - dt + (dt * log(dt / mc))); } /* LOG(REC)<<"Evt Chi2 cont = "<Clone(); // If a mask is provided we need to apply it before getting NDOF if (mask) { calc_hist = StatUtils::ApplyHistogramMasking(hist, mask); } // NDOF is defined as total number of bins with non-zero errors Int_t NDOF = 0; for (int i = 0; i < calc_hist->GetNbinsX(); i++) { if (calc_hist->GetBinError(i + 1) > 0.0) NDOF++; } delete calc_hist; return NDOF; }; //******************************************************************* Int_t StatUtils::GetNDOF(TH2D* hist, TH2I* map, TH2I* mask) { //******************************************************************* Int_t NDOF = 0; if (!map) map = StatUtils::GenerateMap(hist); for (int i = 0; i < hist->GetNbinsX(); i++) { for (int j = 0; j < hist->GetNbinsY(); j++) { if (mask->GetBinContent(i + 1, j + 1)) continue; if (map->GetBinContent(i + 1, j + 1) <= 0) continue; NDOF++; } } return NDOF; }; //******************************************************************* TH1D* StatUtils::ThrowHistogram(TH1D* hist, TMatrixDSym* cov, bool throwdiag, TH1I* mask) { //******************************************************************* TH1D* calc_hist = (TH1D*) hist->Clone( (std::string(hist->GetName()) + "_THROW" ).c_str() ); TMatrixDSym* calc_cov = (TMatrixDSym*) cov->Clone(); Double_t correl_val = 0.0; // If a mask if applied we need to apply it before the matrix is decomposed if (mask) { calc_cov = ApplyMatrixMasking(cov, mask); calc_hist = ApplyHistogramMasking(calc_hist, mask); } // If a covariance is provided we need a preset random vector and a decomp std::vector rand_val; TMatrixDSym* decomp_cov; if (cov) { for (int i = 0; i < hist->GetNbinsX(); i++) { rand_val.push_back(gRandom->Gaus(0.0, 1.0)); } // Decomp the matrix decomp_cov = StatUtils::GetDecomp(calc_cov); } // iterate over bins for (int i = 0; i < hist->GetNbinsX(); i++) { // By Default the errors on the histogram are thrown uncorrelated to the other errors // if (throwdiag) { // calc_hist->SetBinContent(i + 1, (calc_hist->GetBinContent(i + 1) + \ // gRandom->Gaus(0.0, 1.0) * calc_hist->GetBinError(i + 1)) ); // } // If a covariance is provided that is also thrown if (cov) { correl_val = 0.0; for (int j = 0; j < hist->GetNbinsX(); j++) { correl_val += rand_val[j] * (*decomp_cov)(j, i) ; } calc_hist->SetBinContent(i + 1, (calc_hist->GetBinContent(i + 1) + correl_val * 1E-38)); } } delete calc_cov; delete decomp_cov; // return this new thrown data return calc_hist; }; //******************************************************************* TH2D* StatUtils::ThrowHistogram(TH2D* hist, TMatrixDSym* cov, TH2I* map, bool throwdiag, TH2I* mask) { //******************************************************************* // PLACEHOLDER!!!!!!!!! // Currently no support for throwing 2D Histograms from a covariance (void) hist; (void) cov; (void) map; (void) throwdiag; (void) mask; // /todo // Sort maps if required // Throw the covariance for a 1D plot // Unmap back to 2D Histogram return hist; } //******************************************************************* TH1D* StatUtils::ApplyHistogramMasking(TH1D* hist, TH1I* mask) { //******************************************************************* if (!mask) return ( (TH1D*)hist->Clone() ); // This masking is only sufficient for chi2 calculations, and will have dodgy bin edges. // Get New Bin Count Int_t NBins = 0; for (int i = 0; i < hist->GetNbinsX(); i++) { if (mask->GetBinContent(i + 1)) continue; NBins++; } // Make new hist std::string newmaskname = std::string(hist->GetName()) + "_MSKD"; TH1D* calc_hist = new TH1D( newmaskname.c_str(), newmaskname.c_str(), NBins, 0, NBins); // fill new hist int binindex = 0; for (int i = 0; i < hist->GetNbinsX(); i++) { if (mask->GetBinContent(i + 1)) { LOG(REC) << "Applying mask to bin " << i + 1 << " " << hist->GetName() << std::endl; continue; } calc_hist->SetBinContent(binindex + 1, hist->GetBinContent(i + 1)); calc_hist->SetBinError(binindex + 1, hist->GetBinError(i + 1)); binindex++; } return calc_hist; }; //******************************************************************* TH2D* StatUtils::ApplyHistogramMasking(TH2D* hist, TH2I* mask) { //******************************************************************* TH2D* newhist = (TH2D*) hist->Clone(); if (!mask) return newhist; for (int i = 0; i < hist->GetNbinsX(); i++) { for (int j = 0; j < hist->GetNbinsY(); j++) { if (mask->GetBinContent(i + 1, j + 1) > 0) { newhist->SetBinContent(i + 1, j + 1, 0.0); newhist->SetBinContent(i + 1, j + 1, 0.0); } } } return newhist; } //******************************************************************* TMatrixDSym* StatUtils::ApplyMatrixMasking(TMatrixDSym* mat, TH1I* mask) { //******************************************************************* if (!mask) return (TMatrixDSym*)(mat->Clone()); // Get New Bin Count Int_t NBins = 0; for (int i = 0; i < mask->GetNbinsX(); i++) { if (mask->GetBinContent(i + 1)) continue; NBins++; } // make new matrix TMatrixDSym* calc_mat = new TMatrixDSym(NBins); int col, row; // Need to mask out bins in the current matrix row = 0; for (int i = 0; i < mask->GetNbinsX(); i++) { col = 0; // skip if masked if (mask->GetBinContent(i + 1) > 0.5) continue; for (int j = 0; j < mask->GetNbinsX(); j++) { // skip if masked if (mask->GetBinContent(j + 1) > 0.5) continue; (*calc_mat)(row, col) = (*mat)(i, j); col++; } row++; } return calc_mat; }; //******************************************************************* TMatrixDSym* StatUtils::ApplyMatrixMasking(TMatrixDSym* mat, TH2D* data, TH2I* mask, TH2I* map) { //******************************************************************* if (!map) map = StatUtils::GenerateMap(data); TH1I* mask_1D = StatUtils::MapToMask(mask, map); TMatrixDSym* newmat = StatUtils::ApplyMatrixMasking(mat, mask_1D); delete mask_1D; return newmat; } //******************************************************************* TMatrixDSym* StatUtils::ApplyInvertedMatrixMasking(TMatrixDSym* mat, TH1I* mask) { //******************************************************************* TMatrixDSym* new_mat = GetInvert(mat); TMatrixDSym* masked_mat = ApplyMatrixMasking(new_mat, mask); TMatrixDSym* inverted_mat = GetInvert(masked_mat); delete masked_mat; delete new_mat; return inverted_mat; }; //******************************************************************* TMatrixDSym* StatUtils::ApplyInvertedMatrixMasking(TMatrixDSym* mat, TH2D* data, TH2I* mask, TH2I* map) { //******************************************************************* if (!map) map = StatUtils::GenerateMap(data); TH1I* mask_1D = StatUtils::MapToMask(mask, map); TMatrixDSym* newmat = ApplyInvertedMatrixMasking(mat, mask_1D); delete mask_1D; return newmat; } //******************************************************************* TMatrixDSym* StatUtils::GetInvert(TMatrixDSym* mat) { //******************************************************************* TMatrixDSym* new_mat = (TMatrixDSym*)mat->Clone(); // Check for diagonal bool non_diagonal = false; for (int i = 0; i < new_mat->GetNrows(); i++) { for (int j = 0; j < new_mat->GetNrows(); j++) { if (i == j) continue; if ((*new_mat)(i, j) != 0.0) { non_diagonal = true; break; } } } // If diag, just flip the diag if (!non_diagonal or new_mat->GetNrows() == 1) { for (int i = 0; i < new_mat->GetNrows(); i++) { if ((*new_mat)(i, i) != 0.0) (*new_mat)(i, i) = 1.0 / (*new_mat)(i, i); else (*new_mat)(i, i) = 0.0; } return new_mat; } // Invert full matrix TDecompSVD LU = TDecompSVD((*new_mat)); new_mat = new TMatrixDSym(new_mat->GetNrows(), LU.Invert().GetMatrixArray(), ""); return new_mat; } //******************************************************************* TMatrixDSym* StatUtils::GetDecomp(TMatrixDSym* mat) { //******************************************************************* TMatrixDSym* new_mat = (TMatrixDSym*)mat->Clone(); int nrows = new_mat->GetNrows(); // Check for diagonal bool diagonal = true; for (int i = 0; i < nrows; i++) { for (int j = 0; j < nrows; j++) { if (i == j) continue; if ((*new_mat)(i, j) != 0.0) { diagonal = false; break; } } } // If diag, just flip the diag if (diagonal or nrows == 1) { for (int i = 0; i < nrows; i++) { if ((*new_mat)(i, i) > 0.0) (*new_mat)(i, i) = sqrt((*new_mat)(i, i)); else (*new_mat)(i, i) = 0.0; } return new_mat; } TDecompChol LU = TDecompChol(*new_mat); LU.Decompose(); delete new_mat; TMatrixDSym* dec_mat = new TMatrixDSym(nrows, LU.GetU().GetMatrixArray(), ""); return dec_mat; } //******************************************************************* void StatUtils::ForceNormIntoCovar(TMatrixDSym* mat, TH1D* hist, double norm) { //******************************************************************* if (!mat) mat = MakeDiagonalCovarMatrix(hist); int nbins = mat->GetNrows(); TMatrixDSym* new_mat = new TMatrixDSym(nbins); for (int i = 0; i < nbins; i++) { for (int j = 0; j < nbins; j++) { double valx = hist->GetBinContent(i + 1) * 1E38; double valy = hist->GetBinContent(j + 1) * 1E38; (*new_mat)(i, j) = (*mat)(i, j) + norm * norm * valx * valy; } } // Swap the two delete mat; mat = new_mat; return; }; //******************************************************************* void StatUtils::ForceNormIntoCovar(TMatrixDSym* mat, TH2D* data, double norm, TH2I* map ) { //******************************************************************* if (!map) map = StatUtils::GenerateMap(data); TH1D* data_1D = MapToTH1D(data, map); StatUtils::ForceNormIntoCovar(mat, data_1D, norm); delete data_1D; return; } //******************************************************************* TMatrixDSym* StatUtils::MakeDiagonalCovarMatrix(TH1D* data, double scaleF) { //******************************************************************* TMatrixDSym* newmat = new TMatrixDSym(data->GetNbinsX()); for (int i = 0; i < data->GetNbinsX(); i++) { (*newmat)(i, i) = data->GetBinError(i + 1) * data->GetBinError(i + 1) * scaleF * scaleF; } return newmat; } //******************************************************************* TMatrixDSym* StatUtils::MakeDiagonalCovarMatrix(TH2D* data, TH2I* map, double scaleF) { //******************************************************************* if (!map) map = StatUtils::GenerateMap(data); TH1D* data_1D = MapToTH1D(data, map); return StatUtils::MakeDiagonalCovarMatrix(data_1D, scaleF); }; //******************************************************************* void StatUtils::SetDataErrorFromCov(TH1D* data, TMatrixDSym* cov, double scale) { //******************************************************************* // Check if (cov->GetNrows() != data->GetNbinsX()) { ERR(WRN) << "Nrows in cov don't match nbins in data for SetDataErrorFromCov" << std::endl; } // Set bin errors form cov diag for (int i = 0; i < data->GetNbinsX(); i++) { data->SetBinError(i + 1, sqrt((*cov)(i, i)) * scale ); } return; } //******************************************************************* void StatUtils::SetDataErrorFromCov(TH2D* data, TMatrixDSym* cov, TH2I* map, double scale) { //******************************************************************* // Create map if required if (!map) map = StatUtils::GenerateMap(data); - std::cout << data << " " << cov << " " << map << " " << scale << std::endl; // Set Bin Errors from cov diag int count = 0; for (int i = 0; i < data->GetNbinsX(); i++) { for (int j = 0; j < data->GetNbinsY(); j++) { if (data->GetBinContent(i + 1, j + 1) == 0.0) continue; count = map->GetBinContent(i + 1, j + 1) - 1; data->SetBinError(i + 1, j + 1, sqrt((*cov)(count, count)) * scale ); } } return; } + +TMatrixDSym* StatUtils::ExtractShapeOnlyCovar(TMatrixDSym* full_covar, TH1* data_hist, double data_scale){ + + int nbins = full_covar->GetNrows(); + TMatrixDSym* shape_covar = new TMatrixDSym(nbins); + + // Check nobody is being silly + if (data_hist->GetNbinsX() != nbins){ + ERR(WRN) << "Inconsistent matrix and data histogram passed to StatUtils::ExtractShapeOnlyCovar!" << std::endl; + ERR(WRN) << "data_hist has " << data_hist->GetNbinsX() << " matrix has " << nbins << std::endl; + int err_bins = data_hist->GetNbinsX(); + if (nbins > err_bins) err_bins = nbins; + for (int i = 0; i < err_bins; ++i){ + ERR(WRN) << "Matrix diag. = " << (*full_covar)(i, i) << " data = " << data_hist->GetBinContent(i+1) << std::endl; + } + return NULL; + } + + double total_data = 0; + double total_covar = 0; + + // Initial loop to calculate some constants + for (int i = 0; i < nbins; ++i) { + total_data += data_hist->GetBinContent(i+1)*data_scale; + for (int j = 0; j < nbins; ++j) { + total_covar += (*full_covar)(i,j); + } + } + + if (total_data == 0 || total_covar == 0){ + ERR(WRN) << "Stupid matrix or data histogram passed to StatUtils::ExtractShapeOnlyCovar! Ignoring..." << std::endl; + return NULL; + } + + LOG(SAM) << "Norm error = " << sqrt(total_covar)/total_data << std::endl; + + // Now loop over and calculate the shape-only matrix + for (int i = 0; i < nbins; ++i) { + double data_i = data_hist->GetBinContent(i+1)*data_scale; + + for (int j = 0; j < nbins; ++j) { + double data_j = data_hist->GetBinContent(j+1)*data_scale; + + double norm_term = data_i*data_j*total_covar/total_data/total_data; + double mix_sum1 = 0; + double mix_sum2 = 0; + + for (int k = 0; k < nbins; ++k){ + mix_sum1 += (*full_covar)(k,j); + mix_sum2 += (*full_covar)(i,k); + } + + double mix_term1 = data_i*(mix_sum1/total_data - total_covar*data_j/total_data/total_data); + double mix_term2 = data_j*(mix_sum2/total_data - total_covar*data_i/total_data/total_data); + + (*shape_covar)(i, j) = (*full_covar)(i, j) - mix_term1 - mix_term2 - norm_term; + } + } + return shape_covar; +} + + //******************************************************************* TH2I* StatUtils::GenerateMap(TH2D* hist) { //******************************************************************* std::string maptitle = std::string(hist->GetName()) + "_MAP"; TH2I* map = new TH2I( maptitle.c_str(), maptitle.c_str(), hist->GetNbinsX(), 0, hist->GetNbinsX(), hist->GetNbinsY(), 0, hist->GetNbinsY()); Int_t index = 1; for (int i = 0; i < hist->GetNbinsX(); i++) { for (int j = 0; j < hist->GetNbinsY(); j++) { if (hist->GetBinContent(i + 1, j + 1) > 0 && hist->GetBinError(i + 1, j + 1) > 0) { map->SetBinContent(i + 1, j + 1, index); index++; } else { map->SetBinContent(i + 1, j + 1, 0); } } } return map; } //******************************************************************* TH1D* StatUtils::MapToTH1D(TH2D* hist, TH2I* map) { //******************************************************************* if (!hist) return NULL; // Get N bins for 1D plot Int_t Nbins = map->GetMaximum(); std::string name1D = std::string(hist->GetName()) + "_1D"; // Make new 1D Hist TH1D* newhist = new TH1D(name1D.c_str(), name1D.c_str(), Nbins, 0, Nbins); // map bin contents for (int i = 0; i < map->GetNbinsX(); i++) { for (int j = 0; j < map->GetNbinsY(); j++) { if (map->GetBinContent(i + 1, j + 1) == 0) continue; newhist->SetBinContent(map->GetBinContent(i + 1, j + 1), hist->GetBinContent(i + 1, j + 1)); newhist->SetBinError(map->GetBinContent(i + 1, j + 1), hist->GetBinError(i + 1, j + 1)); } } // return return newhist; } //******************************************************************* TH1I* StatUtils::MapToMask(TH2I* hist, TH2I* map) { //******************************************************************* TH1I* newhist = NULL; if (!hist) return newhist; // Get N bins for 1D plot Int_t Nbins = map->GetMaximum(); std::string name1D = std::string(hist->GetName()) + "_1D"; // Make new 1D Hist newhist = new TH1I(name1D.c_str(), name1D.c_str(), Nbins, 0, Nbins); // map bin contents for (int i = 0; i < map->GetNbinsX(); i++) { for (int j = 0; j < map->GetNbinsY(); j++) { if (map->GetBinContent(i + 1, j + 1) == 0) continue; newhist->SetBinContent(map->GetBinContent(i + 1, j + 1), hist->GetBinContent(i + 1, j + 1)); } } // return return newhist; } TMatrixDSym* StatUtils::GetCovarFromCorrel(TMatrixDSym* correl, TH1D* data) { int nbins = correl->GetNrows(); TMatrixDSym* covar = new TMatrixDSym(nbins); for (int i = 0; i < nbins; i++) { for (int j = 0; j < nbins; j++) { (*covar)(i, j) = (*correl)(i, j) * data->GetBinError(i + 1) * data->GetBinError(j + 1); } } return covar; } //******************************************************************* TMatrixD* StatUtils::GetMatrixFromTextFile(std::string covfile, int dimx, int dimy) { //******************************************************************* // Determine dim if (dimx == -1 and dimy == -1) { std::string line; std::ifstream covar(covfile.c_str(), std::ifstream::in); int row = 0; while (std::getline(covar >> std::ws, line, '\n')) { int column = 0; std::vector entries = GeneralUtils::ParseToDbl(line, " "); if (entries.size() <= 1) { ERR(WRN) << "StatUtils::GetMatrixFromTextFile, matrix only has <= 1 " "entries on this line: " << row << std::endl; } for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { column++; if (column > dimx) dimx = column; } row++; if (row > dimy) dimy = row; } } // Or assume symmetric if (dimx != -1 and dimy == -1) { dimy = dimx; } assert(dimy != -1 && " matrix dimy not set."); // Make new matrix TMatrixD* mat = new TMatrixD(dimx, dimy); std::string line; std::ifstream covar(covfile.c_str(), std::ifstream::in); int row = 0; while (std::getline(covar >> std::ws, line, '\n')) { int column = 0; std::vector entries = GeneralUtils::ParseToDbl(line, " "); if (entries.size() <= 1) { ERR(WRN) << "StatUtils::GetMatrixFromTextFile, matrix only has <= 1 " "entries on this line: " << row << std::endl; } for (std::vector::iterator iter = entries.begin(); iter != entries.end(); iter++) { // Check Rows //assert(row > mat->GetNrows() && " covar rows doesn't match matrix rows."); //assert(column > mat->GetNcols() && " covar cols doesn't match matrix cols."); // Fill Matrix (*mat)(row, column) = (*iter); column++; } row++; } return mat; } //******************************************************************* TMatrixD* StatUtils::GetMatrixFromRootFile(std::string covfile, std::string histname) { //******************************************************************* std::string inputfile = covfile + ";" + histname; std::vector splitfile = GeneralUtils::ParseToStr(inputfile, ";"); if (splitfile.size() < 2) { ERR(FTL) << "No object name given!" << std::endl; throw; } // Get file TFile* tempfile = new TFile(splitfile[0].c_str(), "READ"); // Get Object TObject* obj = tempfile->Get(splitfile[1].c_str()); if (!obj) { ERR(FTL) << "Object " << splitfile[1] << " doesn't exist!" << std::endl; throw; } // Try casting TMatrixD* mat = dynamic_cast(obj); if (mat) { TMatrixD* newmat = (TMatrixD*)mat->Clone(); delete mat; tempfile->Close(); return newmat; } TMatrixDSym* matsym = dynamic_cast(obj); if (matsym) { TMatrixD* newmat = new TMatrixD(matsym->GetNrows(), matsym->GetNrows()); for (int i = 0; i < matsym->GetNrows(); i++) { for (int j = 0; j < matsym->GetNrows(); j++) { (*newmat)(i, j) = (*matsym)(i, j); } } delete matsym; tempfile->Close(); return newmat; } TH2D* mathist = dynamic_cast(obj); if (mathist) { TMatrixD* newmat = new TMatrixD(mathist->GetNbinsX(), mathist->GetNbinsX()); for (int i = 0; i < mathist->GetNbinsX(); i++) { for (int j = 0; j < mathist->GetNbinsX(); j++) { (*newmat)(i, j) = mathist->GetBinContent(i + 1, j + 1); } } delete mathist; tempfile->Close(); return newmat; } return NULL; } //******************************************************************* TMatrixDSym* StatUtils::GetCovarFromTextFile(std::string covfile, int dim){ //******************************************************************* // Delete TempMat TMatrixD* tempmat = GetMatrixFromTextFile(covfile, dim, dim); // Make a symmetric covariance TMatrixDSym* newmat = new TMatrixDSym(tempmat->GetNrows()); for (int i = 0; i < tempmat->GetNrows(); i++){ for (int j = 0; j < tempmat->GetNrows(); j++){ (*newmat)(i,j) = (*tempmat)(i,j); } } delete tempmat; return newmat; } //******************************************************************* TMatrixDSym* StatUtils::GetCovarFromRootFile(std::string covfile, std::string histname){ //******************************************************************* TMatrixD* tempmat = GetMatrixFromRootFile(covfile, histname); TMatrixDSym* newmat = new TMatrixDSym(tempmat->GetNrows()); for (int i = 0; i < tempmat->GetNrows(); i++){ for (int j = 0; j < tempmat->GetNrows(); j++){ (*newmat)(i,j) = (*tempmat)(i,j); } } delete tempmat; return newmat; } diff --git a/src/Utils/StatUtils.h b/src/Utils/StatUtils.h index a44c5c2..bf26e90 100644 --- a/src/Utils/StatUtils.h +++ b/src/Utils/StatUtils.h @@ -1,253 +1,255 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see . *******************************************************************************/ #ifndef STATUTILS_H #define STATUTILS_H // C Includes #include #include #include #include #include #include #include #include #include "assert.h" // Root Includes #include "TH1D.h" #include "TH2I.h" #include "TH2D.h" #include "TFile.h" #include "TMatrixDSym.h" #include "TDecompSVD.h" #include "TMath.h" #include "TRandom3.h" #include "TDecompChol.h" #include "TGraphErrors.h" // Fit Includes #include "FitParameters.h" #include "FitLogger.h" /*! * \addtogroup Utils * @{ */ //! Functions for handling statistics calculations namespace StatUtils{ /* Chi2 Functions */ //! Get Chi2 using diagonal bin errors from the histogram. Masking applied before calculation if mask provided. Double_t GetChi2FromDiag(TH1D* data, TH1D* mc, TH1I* mask=NULL); //! Get Chi2 using diagonal bin errors from the histogram. //! Plots converted to 1D histograms before using 1D calculation. Double_t GetChi2FromDiag(TH2D* data, TH2D* mc, TH2I* map=NULL, TH2I* mask=NULL); //! Get Chi2 using an inverted covariance for the data Double_t GetChi2FromCov( TH1D* data, TH1D* mc, TMatrixDSym* invcov, TH1I* mask=NULL, double data_scale=1, double covar_scale=1E76); //! Get Chi2 using an inverted covariance for the data //! Plots converted to 1D histograms before using 1D calculation. Double_t GetChi2FromCov( TH2D* data, TH2D* mc, TMatrixDSym* invcov, TH2I* map=NULL, TH2I* mask=NULL); //! Get Chi2 using an SVD method on the covariance before calculation. //! Method suggested by Rex at MiniBooNE. Shown that it doesn't actually work. Double_t GetChi2FromSVD( TH1D* data, TH1D* mc, TMatrixDSym* cov, TH1I* mask=NULL); //! Get Chi2 using an SVD method on the covariance before calculation. //! Method suggested by Rex at MiniBooNE. Shown that it doesn't actually work. //! Plots converted to 1D histograms before using 1D calculation. Double_t GetChi2FromSVD( TH2D* data, TH2D* mc, TMatrixDSym* cov, TH2I* map=NULL, TH2I* mask=NULL); //! Get Chi2 using only the raw event rates given in each bin using a -2LL method. Double_t GetChi2FromEventRate(TH1D* data, TH1D* mc, TH1I* mask=NULL); //! Get Chi2 using only the raw event rates given in each bin using a -2LL method. //! Plots converted to 1D histograms before using 1D calculation. Double_t GetChi2FromEventRate(TH2D* data, TH2D* mc, TH2I* map=NULL, TH2I* mask=NULL); // Likelihood Functions //! Placeholder for 1D binned likelihood method Double_t GetLikelihoodFromDiag(TH1D* data, TH1D* mc, TH1I* mask=NULL); //! Placeholder for 2D binned likelihood method Double_t GetLikelihoodFromDiag(TH2D* data, TH2D* mc, TH2I* map=NULL, TH2I* mask=NULL); //! Placeholder for 1D binned likelihood method Double_t GetLikelihoodFromCov( TH1D* data, TH1D* mc, TMatrixDSym* invcov, TH1I* mask=NULL); //! Placeholder for 2D binned likelihood method Double_t GetLikelihoodFromCov( TH2D* data, TH2D* mc, TMatrixDSym* invcov, TH2I* map=NULL, TH2I* mask=NULL); //! Placeholder for 1D binned likelihood method Double_t GetLikelihoodFromSVD( TH1D* data, TH1D* mc, TMatrixDSym* cov, TH1I* mask=NULL); //! Placeholder for 2D binned likelihood method Double_t GetLikelihoodFromSVD( TH2D* data, TH2D* mc, TMatrixDSym* cov, TH2I* map=NULL, TH2I* mask=NULL); //! Placeholder for 1D binned likelihood method Double_t GetLikelihoodFromEventRate(TH1D* data, TH1D* mc, TH1I* mask=NULL); //! Placeholder for 2D binned likelihood method Double_t GetLikelihoodFromEventRate(TH2D* data, TH2D* mc, TH2I* map=NULL, TH2I* mask=NULL); /* NDOF Functions */ //! Return 1D Histogram NDOF considering masking and empty bins Int_t GetNDOF(TH1D* hist, TH1I* mask=NULL); //! Return 2D Histogram NDOF considering masking and empty bins Int_t GetNDOF(TH2D* hist, TH2I* map=NULL, TH2I* mask=NULL); /* Fake Data Functions */ //! Given a full covariance for a 1D data set throw the decomposition to generate fake data. //! throwdiag determines whether diagonal statistical errors are thrown. //! If no covariance is provided only statistical errors are thrown. TH1D* ThrowHistogram(TH1D* hist, TMatrixDSym* cov, bool throwdiag=true, TH1I* mask=NULL); //! Given a full covariance for a 2D data set throw the decomposition to generate fake data. //! Plots are converted to 1D histograms and the 1D ThrowHistogram is used, before being converted back to 2D histograms. TH2D* ThrowHistogram(TH2D* hist, TMatrixDSym* cov, TH2I* map=NULL, bool throwdiag=true, TH2I* mask=NULL); /* Masking Functions */ //! Given a mask histogram, mask out any bins in hist with non zero entries in mask. TH1D* ApplyHistogramMasking(TH1D* hist, TH1I* mask); //! Given a mask histogram, mask out any bins in hist with non zero entries in mask. TH2D* ApplyHistogramMasking(TH2D* hist, TH2I* mask); //! Given a mask histogram apply the masking procedure to each of the rows/columns in a covariance, before recalculating its inverse. TMatrixDSym* ApplyInvertedMatrixMasking(TMatrixDSym* mat, TH1I* mask); //! Given a mask histogram apply the masking procedure to each of the rows/columns in a covariance, before recalculating its inverse. //! Converts to 1D data before using the 1D ApplyInvertedMatrixMasking function and converting back to 2D. TMatrixDSym* ApplyInvertedMatrixMasking(TMatrixDSym* mat, TH2D* data, TH2I* mask, TH2I* map=NULL); //! Given a mask histogram apply the masking procedure to each of the rows/columns in a covariance TMatrixDSym* ApplyMatrixMasking(TMatrixDSym* mat, TH1I* mask); //! Given a mask histogram apply the masking procedure to each of the rows/columns in a covariance //! Converts to 1D data before using the 1D ApplyInvertedMatrixMasking function and converting back to 2D. TMatrixDSym* ApplyMatrixMasking(TMatrixDSym* mat, TH2D* data, TH2I* mask, TH2I* map=NULL); /* Covariance Handling Functions */ //! Return inverted matrix of TMatrixDSym TMatrixDSym* GetInvert(TMatrixDSym* mat); //! Return Cholesky Decomposed matrix of TMatrixDSym TMatrixDSym* GetDecomp(TMatrixDSym* mat); //! Return full covariances TMatrixDSym* GetCovarFromCorrel(TMatrixDSym* correl, TH1D* data); //! Given a normalisation factor for a dataset add in a new normalisation term to the covariance. void ForceNormIntoCovar(TMatrixDSym* mat, TH1D* data, double norm); //! Given a normalisation factor for a dataset add in a new normalisation term to the covariance. //! Convertes 2D to 1D, before using 1D ForceNormIntoCovar void ForceNormIntoCovar(TMatrixDSym* mat, TH2D* data, double norm, TH2I* map=NULL); //! Given a dataset generate an uncorrelated covariance matrix using the bin errors. TMatrixDSym* MakeDiagonalCovarMatrix(TH1D* data, double scaleF=1E38); //! Given a dataset generate an uncorrelated covariance matrix using the bin errors. TMatrixDSym* MakeDiagonalCovarMatrix(TH2D* data, TH2I* map=NULL, double scaleF=1E38); //! Given a covariance set the errors in each bin on the data from the covariance diagonals. void SetDataErrorFromCov(TH1D* data, TMatrixDSym* cov, double scale=1.0); //! Given a covariance set the errors in each bin on the data from the covariance diagonals. void SetDataErrorFromCov(TH2D* data, TMatrixDSym* cov, TH2I* map=NULL, double scale=1.0); + //! Given a covariance, extracts the shape-only matrix using the method from the MiniBooNE TN + TMatrixDSym* ExtractShapeOnlyCovar(TMatrixDSym* full_covar, TH1* data_hist, double data_scale=1E38); /* Mapping Functions */ //! If no map is provided for the 2D histogram, generate one by counting up through the bins along x and y. TH2I* GenerateMap(TH2D* hist); //! Apply a map to a 2D histogram converting it into a 1D histogram. TH1D* MapToTH1D(TH2D* hist, TH2I* map); //! Apply a map to a 2D mask convering it into a 1D mask. TH1I* MapToMask(TH2I* hist, TH2I* map); /// \brief Read TMatrixD from a text file /// /// - covfile = full path to text file /// - dimx = x dimensions of matrix /// - dimy = y dimensions of matrix /// /// Format of textfile should be: \n /// cov_11 cov_12 ... cov_1N \n /// cov_21 cov_22 ... cov_2N \n /// ... ... ... ... \n /// cov_N1 ... ... cov_NN \n /// /// If no dimensions are given, dimx and dimy are determined from rows/columns /// inside textfile. /// /// If only dimx is given a symmetric matrix is assumed. TMatrixD* GetMatrixFromTextFile(std::string covfile, int dimx=-1, int dimy=-1); /// \brief Read TMatrixD from a ROOT file /// /// - covfile = full path to root file (+';histogram') /// - histname = histogram name /// /// If no histogram name is given function assumes it has been appended /// covfile path as: \n /// 'covfile.root;histname' /// /// histname can point to a TMatrixD object, a TMatrixDSym object, or /// a TH2D object. TMatrixD* GetMatrixFromRootFile(std::string covfile, std::string histname=""); /// \brief Calls GetMatrixFromTextFile and turns it into a TMatrixDSym TMatrixDSym* GetCovarFromTextFile(std::string covfile, int dim); /// \brief Calls GetMatrixFromRootFile and turns it into a TMatrixDSym TMatrixDSym* GetCovarFromRootFile(std::string covfile, std::string histname); }; /*! @} */ #endif