diff --git a/PlottinRatios.py b/PlottinRatios.py new file mode 100644 index 0000000..ecbd2ef --- /dev/null +++ b/PlottinRatios.py @@ -0,0 +1,58 @@ + +#!/usr/bin/python + +from ROOT import * +from ROOT import PlotUtils +from array import array +try: + import array as np +except: + exit() +gROOT.SetBatch() #Don't render histograms to a window. Also gets filled areas correct. + +TH1.AddDirectory(False) +lowq2MParamFiles = TFile.Open("../opt/etc/MParamFiles/data/Reweight/lowQ2pi_weights.root") +MyLowq2 = TFile.Open("../NewLowQ2/lowQ2pi_weights.root") + +g_lowq2MP = lowq2MParamFiles.Get("MENU1PI_weights") +g_MyLowq2 = MyLowq2.Get("MENU1PI_weights") + +nPMP = g_lowq2MP.GetN() +nPMy = g_MyLowq2.GetN() + +print (nPMP) +print (nPMy) + +rval = array ('d') +xval = array ('d') + +xMp = double(0) +yMp = double(0) +xMy = double(0) +yMy = double(0) + +for p in range(nPMP): + g_lowq2MP.GetPoint(p, xMp, yMp) + g_MyLowq2.GetPoint(p, xMy, yMy) + rval.append( yMp / yMy) + xval.append(xMp) + +for i in range(10): + print (rval[i]) + print (xval[i]) + +c1 = TCanvas("Warping studies for") +ratio = TGraph(nPMP, xval, rval) +c1.cd() +ratio.GetYaxis().SetRangeUser(0.9,1.1) +ratio.GetYaxis().SetTitle("ratio") +ratio.GetXaxis().SetTitle("q^2 GeV") +ratio.Draw() +c1.Update() +c1.Print("RatioLowq2.png") + + + + + + diff --git a/PrintWarping.py b/PrintWarping.py index 50f75a9..dd3e738 100644 --- a/PrintWarping.py +++ b/PrintWarping.py @@ -10,13 +10,18 @@ gROOT.SetBatch() #Don't render histograms to a window. Also gets filled areas correct. TH1.AddDirectory(False) -variables = ["mixtpi", "mtpi", "enu", "pmu", "ptmu", "pzmu", "q2", "thetamu_deg", "thetapi_deg", "tpi", "wexp"] -#variables = ["mixtpi"] -date = "20230523" +#variables = ["pzmu_vs_ptmu", "tpi_vs_thetapi_deg", "pmu_vs_tpi", "tpi_vs_ptmu", "enu_vs_tpi"] +variables = ["tpi_vs_ptmu"] +#variables = ["pzmu_vs_ptmu", "ptmu_vs_pzmu", "tpi_vs_pmu", "pmu_vs_tpi", "tpi_vs_thetapi_deg", "thetapi_deg_vs_tpi", "ptmu_vs_tpi", "tpi_vs_ptmu", "enu_vs_tpi", "tpi_vs_enu"] +date = "20240619" warp = "WARP3" - +plist="ALL" +corrfac="8.8" +scale="4.689984" for var in variables: - mcFile = TFile.Open("WarpingStudies/newbinning/Warping_{WARP}_{VAR}.root".format(WARP=warp,VAR=var)) + mcFile = TFile.Open("/minerva/data/users/granados/WarpingStudies/Warping/2DWarping/Warping_2D_{PLIST}_{DATE}_stat_scale{SCALE}_{WARP}_{VAR}_corfac{CORFAC}_exclude.root".format(PLIST=plist,DATE=date,WARP=warp,VAR=var,SCALE=scale,CORFAC=corrfac)) +# mcFile = TFile.Open("/minerva/data/users/granados/WarpingStudies/Warping/2DWarping/Warping_2D_{PLIST}_{DATE}_stat_scale{SCALE}_{WARP}_{VAR}.root".format(PLIST=plist,DATE=date,WARP=warp,VAR=var,SCALE=scale,CORFAC=corrfac)) +# mcFile = TFile.Open("/minerva/data/users/granados/WarpingStudies/Warping/2DWarping/Warping_2D_{PLIST}_{DATE}_{WARP}_{VAR}.root".format(PLIST=plist,DATE=date,WARP=warp,VAR=var,SCALE=scale,CORFAC=corrfac)) lineWidth = 3 @@ -36,22 +41,27 @@ h_ndf.SetBinContent(i+1, double(ndf)) titleName = "" - if var == "mixtpi": - titleName = "T_{#pi}" - if var == "pzmu": - titleName = "p^{z}_{#mu}" - if var == "ptmu": - titleName = "p^{t}_{#mu}" - if var == "thetapi_deg": - titleName = "#theta_{#pi}" - if var == "pmu": - titleName = "p_{#mu}" - if var == "q2": - titleName = "q^{2}" - if var == "thetamu_deg": - titleName = "#theta_{#mu}" - if var == "wexp": - titleName = "W_{exp}" + if var == "ptmu_vs_tpi": + titleName = "p^{t}_{#mu} vs T_{#pi}" + if var == "pzmu_vs_ptmu": + titleName = "p^{z}_{#mu} vs p^{t}_{#mu}" + if var == "tpi_vs_thetapi_deg": + titleName = "T_{#pi} vs #theta_{#pi}" + if var == "tpi_vs_pmu": + titleName = "T_{#pi} vs p_{#mu}" + if var == "tpi_vs_ptmu": + titleName = "T_{#pi} vs p^{t}_{#mu}" + if var == "ptmu_vs_pzmu": + titleName = "p^{T}_{#mu} vs p^{z}_{#mu}" + if var == "thetapi_deg_vs_tpi": + titleName = "#theta_{#pi} vs T_{#pi}" + if var == "pmu_vs_tpi": + titleName = "p_{#mu} vs T_{#pi}" + if var == "enu_vs_tpi": + titleName = "E_{#nu} vs T_{#pi}" + if var == "tpi_vs_enu": + titleName = "T_{#pi} vs E_{#nu}" + c1 = TCanvas("Warping studies for") Title = TPaveText (8., 6000, 120., 10500.) Title.Clear() @@ -75,7 +85,7 @@ h_ndf.SetLineColor(kOrange-3) # c1.UseCurrentStyle() - + chi2Iter.GetYaxis().SetRangeUser(0.,100.) chi2Iter.GetXaxis().CenterTitle() chi2Iter.GetXaxis().SetTitleOffset(1.3) chi2Iter.GetXaxis().SetTitleSize(0.04) @@ -95,7 +105,8 @@ truncatedChi2Iter.Draw("SAME HIST") h_ndf.Draw("SAME HIST") c1.SetLogx() - c1.SetLogy() + +# c1.SetLogy() #c1.BuildLegend(0.7, 0.6, 0.9, 0.9) legend.AddEntry(AverageChi2Iter, "Average", "l") legend.AddEntry(truncatedChi2Iter, "Truncated", "l") @@ -103,6 +114,7 @@ legend.AddEntry(h_ndf, "ndf", "l") legend.Draw() Title.Draw() - c1.Print("WarpingStudies/newbinning/Warping_{VAR}_{WARP}.png".format(VAR=var,WARP=warp)) + c1.Print("WarpingPlots/Warping_{DATE}_{PLIST}_{VAR}_{WARP}_corfac{CORFAC}_exclude.png".format(DATE=date,VAR=var,WARP=warp,PLIST=plist,CORFAC=corrfac)) +# c1.Print("WarpingPlots/Warping_{DATE}_{PLIST}_{VAR}_{WARP}.png".format(DATE=date,VAR=var,WARP=warp,PLIST=plist,CORFAC=corrfac)) c1.Clear() diff --git a/ProcessCCPiMacro.py b/ProcessCCPiMacro.py index bb3c333..ed4e5d2 100644 --- a/ProcessCCPiMacro.py +++ b/ProcessCCPiMacro.py @@ -7,10 +7,10 @@ # Constants/Default Args ############################################################################### # Scripts, Files, and Dirs -kGRID_SCRIPT = os.getenv("PWD") + "/grid_ccpi_macro.sh" +kGRID_SCRIPT = os.getenv("PWD") + "/grid_ccpi_macro_2D.sh" kTOPDIR = os.getenv("TOPDIR") -kANATUPLE_DIR = "/pnfs/minerva/persistent/users/zdar/" -kOUTDIR = "/pnfs/{EXPERIMENT}/scratch/users/{USER}/TestMAD/".format( +kANATUPLE_DIR = "/pnfs/minerva/persistent/DataPreservation/p4/FullDetector/" +kOUTDIR = "/pnfs/{EXPERIMENT}/scratch/users/{USER}/TestMAD2D/".format( EXPERIMENT=os.getenv("EXPERIMENT"), USER=os.getenv("USER") ) kCACHE_PNFS_AREA = "/pnfs/{EXPERIMENT}/scratch/users/{USER}/grid_cache/".format( @@ -21,14 +21,17 @@ ) kEV_SEL_MACRO = "event_selection/runEventSelectionGrid.C+" kMC_INPUTS_MACRO = "xsec/makeCrossSectionMCInputs.C+" +kBACKGROUND_BREAKDOWN = "studies/runBackgrounds.C+" +#kMC_MIGRATION_MACRO = "studies/runMigMtxBinning.C+" # Grid Stuff kMINERVA_RELEASE = os.getenv("MINERVA_RELEASE") -kMEMORY = "1GB" +kMEMORY = "8GB" kGRID_OPTIONS = ( "--group minerva " "--resource-provides=usage_model=DEDICATED,OPPORTUNISTIC " - "--lines='+SingularityImage=\\\"/cvmfs/singularity.opensciencegrid.org/fermilab/fnal-wn-sl7:latest\\\"' " +# "--lines='+SingularityImage=\\\"/cvmfs/singularity.opensciencegrid.org/fermilab/fnal-wn-sl7:latest\\\"' " "--role=Analysis " + "--disk=15GB" # "--OS=SL7 " # change to SL7 when submitting from sl7 machines. ) @@ -99,13 +102,11 @@ def MakeTarfile(source_dir, tag): print(source_dir + i) tar.add(source_dir + i, i) tar.close() - # It is done. Send it to scratch. tarfile_fullpath = IFDHMove(tarfile_name, kTARBALL_LOCATION) return tarfile_name, tarfile_fullpath - def MakeUniqueProcessingID(tag): processing_id = "{TAG}{DAY}-{TIME}".format( TAG=tag, DAY=dt.date.today(), TIME=dt.datetime.today().strftime("%H%M") @@ -124,6 +125,8 @@ def GetOptions(): grid_group.add_option("--memory", default=kMEMORY) grid_group.add_option("--ev_sel", action="store_true") grid_group.add_option("--mc_xsec_inputs", action="store_true") + grid_group.add_option("--bg_breakdown", action="store_true") + grid_group.add_option("--mc_migration", action="store_true") # job args job_group = optparse.OptionGroup(parser, "Job Options") @@ -142,6 +145,13 @@ def GetOptions(): default=True, # default: DO systs help="Don't do full systematics. Default: DO systematics", ) + job_group.add_option( + "--test_playlist", + action="store_true", + dest="do_test_playlist", + default=False, # default is Not use test playlist + help="It use a test playlist. Default: It doesn't use the test playlist.", + ) job_group.add_option("--signal_definition", default=0, help="0 = 1piW<1.4") job_group.add_option( "--playlists", @@ -156,13 +166,17 @@ def GetOptions(): options, remainder = parser.parse_args() # require a macro - if options.ev_sel == options.mc_xsec_inputs: + if options.ev_sel == options.mc_xsec_inputs and options.mc_xsec_inputs == options.mc_migration and options.mc_xsec_inputs == options.bg_breakdown: print("Pick a macro!") quit() elif options.ev_sel: options.macro = kEV_SEL_MACRO elif options.mc_xsec_inputs: options.macro = kMC_INPUTS_MACRO + elif options.mc_migration: + options.macro = kMC_MIGRATION_MACRO + elif options.bg_breakdown: + options.macro = kBACKGROUND_BREAKDOWN else: pass @@ -200,7 +214,7 @@ def main(): cache = kCACHE_PNFS_AREA + "/" + processing_id print("sending grid macro to " + cache) MakeDirectory(cache) - grid_script = IFDHCopy("grid_ccpi_macro.sh", cache) + grid_script = IFDHCopy("grid_ccpi_macro_2D.sh", cache) if options.run: print("\nSubmitting run: " + options.run) @@ -214,7 +228,7 @@ def main(): print("Using tuples from" + kANATUPLE_DIR) # loop anatuples - list_of_anatuples = glob.glob(kANATUPLE_DIR + "/Merged_mc_ana_{0}_DualVertex_p3/*".format(i_playlist)) + list_of_anatuples = glob.glob(kANATUPLE_DIR + "/Merged_mc_ana_{0}_DualVertex_p4/*".format(i_playlist)) for anatuple in list_of_anatuples: if not ("MasterAnaDev" in anatuple) or not (".root" in anatuple): continue @@ -233,20 +247,50 @@ def XROOTDify(anatuple): ) anatuple = XROOTDify(anatuple) - - macro = options.macro - macro += ( - '({SIGNAL_DEFINITION},\\\\\\"{PLAYLIST}\\\\\\",{DO_FULL_SYST},' - '{DO_TRUTH},{DO_GRID},\\\\\\"{TUPLE}\\\\\\",{RUN})'.format( - SIGNAL_DEFINITION=options.signal_definition, - PLAYLIST=i_playlist, - DO_FULL_SYST="true" if options.do_full_systematics else "false", - DO_TRUTH="true" if options.do_truth else "false", - DO_GRID="true", - TUPLE=anatuple, - RUN=run, + if options.mc_xsec_inputs: + macro = options.macro + macro += ( + '({SIGNAL_DEFINITION},\\\\\\"{PLAYLIST}\\\\\\",{DO_FULL_SYST},' + '{DO_TRUTH},{DO_TEST},{DO_GRID},\\\\\\"{TUPLE}\\\\\\",{RUN})'.format( + SIGNAL_DEFINITION=options.signal_definition, + PLAYLIST=i_playlist, + DO_FULL_SYST="true" if options.do_full_systematics else "false", + DO_TRUTH="true" if options.do_truth else "false", + DO_TEST="false" if options.do_test_playlist else "true", + DO_GRID="true", + TUPLE=anatuple, + RUN=run, + ) ) - ) + + if options.bg_breakdown: + macro = options.macro + macro += ( + '({SIGNAL_DEFINITION},\\\\\\"{PLAYLIST}\\\\\\",' + '{DO_GRID},\\\\\\"{TUPLE}\\\\\\",{RUN})'.format( + SIGNAL_DEFINITION=options.signal_definition, + PLAYLIST=i_playlist, + DO_GRID="true", + TUPLE=anatuple, + RUN=run, + ) + ) + + + +# if options.mc_migration: +# macro = options.macro +# macro += ( +# '({SIGNAL_DEFINITION},\\\\\\"{PLAYLIST}\\\\\\",' +# '{DO_GRID},\\\\\\"{TUPLE}\\\\\\",{RUN})'.format( +# SIGNAL_DEFINITION=options.signal_definition, +# PLAYLIST=i_playlist, +# DO_GRID="true", +# TUPLE=anatuple, +# RUN=run, +# ) +# ) + macro = '"' + macro + '"' @@ -280,4 +324,4 @@ def XROOTDify(anatuple): if __name__ == "__main__": - main() + main() diff --git a/ccpion_common.h b/ccpion_common.h index 0ceb0b1..d31ba98 100644 --- a/ccpion_common.h +++ b/ccpion_common.h @@ -9,7 +9,7 @@ std::string GetPlaylistFile(std::string plist, bool is_mc, bool use_xrootd = true) { // const std::string processing_date = "20200713"; // new short tracking branches - const std::string processing_date = "production_p3"; // new recoil energy branches + const std::string processing_date = "production_p4"; // new recoil energy branches // const std::string processing_date = "test"; // For test with small MAD tuplas const std::string is_mc_str = is_mc ? "mc" : "data"; std::transform(plist.begin(), plist.end(), plist.begin(), ::toupper); diff --git a/grid_ccpi_macro.sh b/grid_ccpi_macro.sh index fd3055a..21b2977 100644 --- a/grid_ccpi_macro.sh +++ b/grid_ccpi_macro.sh @@ -54,7 +54,7 @@ echo $PLOTUTILSROOT echo echo "======== cd to ME_CCNuPionInc_Ana ========" -cd ${HOME}/cc-ch-pip-ana +cd ${HOME}/2D-cc-ch-pip-ana pwd echo diff --git a/grid_ccpi_macro_2D.sh b/grid_ccpi_macro_2D.sh new file mode 100644 index 0000000..cba6afe --- /dev/null +++ b/grid_ccpi_macro_2D.sh @@ -0,0 +1,147 @@ +#!/bin/bash + +#=============================================================================== +# Setup env variables, cmt config, source setup.sh packages +#=============================================================================== +# The -n option [to export]causes the export property to be removed from each +# name. +# +# CONDOR_DIR_INPUT is the area where `-f` jobsub arguments (i.e. our tarball) +# are dropped. +# +echo "======== Set HOME = TOPDIR = CONDOR_DIR_INPUT ========" +export UPS_OVERRIDE="-H Linux64bit+3.10-2.17" +export -n HOME +export -n TOPDIR +export -n MINERVA_PREFIX +export HOME=${CONDOR_DIR_INPUT} +export TOPDIR=${CONDOR_DIR_INPUT} +export MINERVA_PREFIX=${TOPDIR}/opt +export EXPERIMENT=minerva +export TARFILE=${TARFILE} +export XRD_NETWORKSTACK=IPv4 +echo +cat /etc/os-release + +echo "======== cd to HOME AKA TOPDIR AKA CONDOR_DIR_INPUT ========" +cd $HOME + +echo +echo "======== pwd, ls -a ========" +pwd +ls -a + +echo +echo "======== Untarring... ========" +tar xvzf ${TARFILE} -C ./ > /dev/null + +echo +echo "======== ls -a ========" +ls -a + +source /cvmfs/minerva.opensciencegrid.org/minerva/hep_hpc_products/setups +setup root v6_10_04d -q e14:prof +setup cmake v3_7_1 + + +echo "======== source MAT/opt/bin/setupROOT6OnGPVMs.sh ========" +source opt/bin/setupROOT6OnGPVMs.sh + +echo "======== source MAT/opt/bin/setup.sh ========" +source opt/bin/setup.sh + +echo "======== source MAT/opt/buildGENIEXSecExtract/setup_GENIEXSecExtract.sh ========" +source opt/buildGENIEXSecExtract/setup_GENIEXSecExtract.sh + +echo +echo "======== echo PLOTUTILSROOT ========" +echo $PLOTUTILSROOT + +#echo +#echo "======== printenv ========" +#printenv + +echo +echo "======== cd to ME_CCNuPionInc_Ana ========" +cd ${HOME}/2D-cc-ch-pip-ana +pwd + +echo +echo "======== rm any pre-existing root files that got passed to the grid ========" +rm *.root + +# had some trouble when *.so files already existed +echo +echo "======== clear out pre-existing .so, .d, .o files ========" +./clean +# find . -type f -name '*.o' -delete +# find . -type f -name '*.so' -delete +# find . -type f -name '*.d' -delete +# +##=============================================================================== +## Tell root (via the .rootrc) that every time root is open/run, it should first +## run rootlogon_grid.C, which is located in the cd. +## +## rootlogon_grid contains the PU setup code. +##=============================================================================== +echo +echo "======== echo ~ ========" +echo ~ + +echo +echo "======== make ./.rootrc ========" +echo Rint.Logon: ./rootlogon_grid.C > ./.rootrc + +echo +echo "======== ls -a ========" +ls -a + +echo +echo "======== cat .rootrc ========" +cat .rootrc + +echo +echo "======== cat rootlogon_grid.C ========" +cat rootlogon_grid.C + +# To make sure we're using the right rootlogon.C +echo +echo "======== gEnv->Print() ========" +echo 'gEnv->Print(); gSystem->Exit(0);' | root -b -l | grep Logon + +#echo "======== touch abc.txt; mv abc.txt $CONDOR_DIR_OUT ========" +#touch abc.txt +# +#mv abc.txt $CONDOR_DIR_OUT + +#=============================================================================== +# Ship it +# The "++" loadLibs might be redundant with removing the .so's, but just to be safe +#=============================================================================== +echo +echo "======== MACRO ========" +echo $MACRO + +echo +echo "======== root.exe -b -q loadLibs.C++ MACRO ========" +root.exe -b -q -l loadLibs.C++ ${MACRO} + +echo +echo "======== ls *.root ========" +ls *.root + +echo +echo "Move *.root to CONDOR_DIR_OUT" +mv *.root $CONDOR_DIR_OUT + +echo +echo "======== ls CONDOR_DIR_OUT ========" +ls $CONDOR_DIR_OUT + +#echo +#echo "======== root.exe -l -b -q ========" +#root.exe -l -b -q +# + +echo +echo "done" diff --git a/includes/#CCPiEvent.cxx# b/includes/#CCPiEvent.cxx# new file mode 100644 index 0000000..081eeae --- /dev/null +++ b/includes/#CCPiEvent.cxx# @@ -0,0 +1,762 @@ +ifndef CCPiEvent_cxx +#define CCPiEvent_cxx + +#include "CCPiEvent.h" + +#include "Cuts.h" // kCutsVector +#include "Michel.h" // class Michel, typdef MichelMap +#include "common_functions.h" // GetVar, HasVar + +//============================================================================== +// CTOR +//============================================================================== +CCPiEvent::CCPiEvent(const bool is_mc, const bool is_truth, + const SignalDefinition signal_definition, + CVUniverse* universe) + : m_is_mc(is_mc), + m_is_truth(is_truth), + m_signal_definition(signal_definition), + m_universe(universe), + m_reco_pion_candidate_idxs(), + m_highest_energy_pion_idx(-300) +// m_reco_pion_candidate_idxs_sideband() +{ + m_is_signal = is_mc ? IsSignal(*universe, signal_definition) : false; + m_weight = is_mc ? universe->GetWeight() : 1.; + m_w_type = is_mc ? GetWSidebandType(*universe, signal_definition, + sidebands::kNWFitCategories) + : kNWSidebandTypes; +} + +//============================================================================== +// Helper Functions +//============================================================================== +// Used in analysis pipeline +bool PassesCuts(CCPiEvent& e, bool& is_w_sideband) { + return PassesCuts(*e.m_universe, e.m_reco_pion_candidate_idxs, e.m_is_mc, + e.m_signal_definition, is_w_sideband); +} + +// Only used for studies -- not used in analysis pipeline +bool PassesCuts(CCPiEvent& e, std::vector cuts) { + return PassesCuts(*e.m_universe, e.m_reco_pion_candidate_idxs, e.m_is_mc, + e.m_signal_definition, cuts); +} + +SignalBackgroundType GetSignalBackgroundType(const CCPiEvent& e) { + return GetSignalBackgroundType(*e.m_universe, e.m_signal_definition); +} + +RecoPionIdx GetHighestEnergyPionCandidateIndex(const CCPiEvent& e) { + return e.m_universe->GetHighestEnergyPionCandidateIndex( + e.m_reco_pion_candidate_idxs); +} + +TruePionIdx GetHighestEnergyTruePionIndex(const CCPiEvent& e) { + return e.m_universe->GetHighestEnergyTruePionIndex(); +} + +//============================================================================== +// Fill all histos for an entire event -- call other specialized fill functions +//============================================================================== +void ccpi_event::FillRecoEvent(const CCPiEvent& event, + const std::vector& variables) { + // Fill selection -- total, signal-only, and bg-only + if (event.m_passes_cuts) { + ccpi_event::FillSelected(event, variables); + } + // Fill W Sideband + if (event.m_is_w_sideband) { + ccpi_event::FillWSideband(event, variables); + } + + // Fill Migration + if (event.m_is_mc && event.m_is_signal && event.m_passes_cuts) { + if (HasVar(variables, "tpi") && HasVar(variables, "tpi_true")) + FillMigration(event, variables, std::string("tpi")); + if (HasVar(variables, "thetapi_deg") && + HasVar(variables, "thetapi_deg_true")) + FillMigration(event, variables, std::string("thetapi_deg")); + if (HasVar(variables, "pmu") && HasVar(variables, "pmu_true")) + FillMigration(event, variables, std::string("pmu")); + if (HasVar(variables, "pzmu") && HasVar(variables, "pzmu_true")) + FillMigration(event, variables, std::string("pzmu")); + if (HasVar(variables, "ptmu") && HasVar(variables, "ptmu_true")) + FillMigration(event, variables, std::string("ptmu")); + if (HasVar(variables, "thetamu_deg") && + HasVar(variables, "thetamu_deg_true")) + FillMigration(event, variables, std::string("thetamu_deg")); + if (HasVar(variables, "q2") && HasVar(variables, "q2_true")) + FillMigration(event, variables, std::string("q2")); + if (HasVar(variables, "enu") && HasVar(variables, "enu_true")) + FillMigration(event, variables, std::string("enu")); + if (HasVar(variables, "wexp") && HasVar(variables, "wexp_true")) + FillMigration(event, variables, std::string("wexp")); + if (HasVar(variables, "ehad") && HasVar(variables, "ehad_true")) + FillMigration(event, variables, std::string("ehad")); + if (HasVar(variables, "cosadtheta") && HasVar(variables, "cosadtheta_true")) + FillMigration(event, variables, std::string("cosadtheta")); + if (HasVar(variables, "adphi") && HasVar(variables, "adphi_true")) + FillMigration(event, variables, std::string("adphi")); + if (HasVar(variables, "pimuAngle") && HasVar(variables, "pimuAngle_true")) + FillMigration(event, variables, std::string("pimuAngle")); + if (HasVar(variables, "PT") && HasVar(variables, "PT_true")) + FillMigration(event, variables, std::string("PT")); + } +} +void ccpi_event::FillRecoEvent2D(const CCPiEvent& event, + const std::vector& variables) { + // Fill selection -- total, signal-only, and bg-only + if (event.m_passes_cuts) { + ccpi_event::FillSelected2D(event, variables); + } + // Fill W Sideband +/* if (event.m_is_w_sideband) { + ccpi_event::FillWSideband2D(event, variables); + }*/ + + // Fill Migration + if (event.m_is_mc && event.m_is_signal && event.m_passes_cuts) { + if (HasVar2D(variables, "tpi", "pmu") && HasVar2D(variables, "tpi_true", "pmu_true")) + FillMigration2D(event, variables, std::string("tpi"), std::string("pmu")); + if (HasVar2D(variables, "tpi", "thetapi_deg") && + HasVar2D(variables, "tpi_true", "thetapi_deg_true")) + FillMigration2D(event, variables, std::string("tpi"), std::string("thetapi_deg")); + if (HasVar2D(variables, "pmu", "thetamu_deg") && + HasVar2D(variables, "pmu_true", "thetamu_deg_true")) + FillMigration2D(event, variables, std::string("pmu"), std::string("thetamu_deg")); + if (HasVar2D(variables, "pzmu", "ptmu") && HasVar2D(variables, "pzmu_true", "ptmu_true")) + FillMigration2D(event, variables, std::string("pzmu"), std::string("ptmu")); + if (HasVar2D(variables, "ptmu", "tpi") && HasVar2D(variables, "ptmu_true", "tpi_true")) + FillMigration2D(event, variables, std::string("ptmu"), std::string("tpi")); + } +} + +void ccpi_event::FillTruthEvent(const CCPiEvent& event, + const std::vector& variables) { + // Fill Efficiency Denominator + if (event.m_is_signal) + ccpi_event::FillEfficiencyDenominator(event, variables); +} + +void ccpi_event::FillTruthEvent2D(const CCPiEvent& event, + const std::vector& variables) { + // Fill Efficiency Denominator + if (event.m_is_signal) + ccpi_event::FillEfficiencyDenominator2D(event, variables); +} + +//============================================================================== +// Specialized fill functions -- for xsec calculation +//============================================================================== +// Fill histos with selected (i.e. passes_cuts) events: +// ** sig + bg (true and reco vars, data and mc) +// ** signal only (true vars, for eff num & closure) +// ** bg only (reco and true vars) +void ccpi_event::FillSelected(const CCPiEvent& event, + const std::vector& variables) { + for (auto var : variables) { + // Sanity Checks + if (var->m_is_true && !event.m_is_mc) return; // truth, but not MC? + if (event.m_reco_pion_candidate_idxs.empty()) { + std::cerr << "ccpi_event::FillSelected: empty pion idxs vector\n"; + std::exit(1); + } + + // Get fill value + double fill_val = -999.; + if (var->m_is_true) { + TruePionIdx idx = GetHighestEnergyTruePionIndex(event); + fill_val = var->GetValue(*event.m_universe, idx); + } else { + // RecoPionIdx idx = GetHighestEnergyPionCandidateIndex(event); + RecoPionIdx idx = event.m_highest_energy_pion_idx; + fill_val = var->GetValue(*event.m_universe, idx); + } + + // total = signal & background, together + if (event.m_is_mc) { + var->m_hists.m_selection_mc.FillUniverse(*event.m_universe, fill_val, + event.m_weight); + } else { + var->m_hists.m_selection_data->Fill(fill_val); + } + + // done with data + if (!event.m_is_mc) continue; + + // signal and background individually + if (event.m_is_signal) { + var->m_hists.m_effnum.FillUniverse(*event.m_universe, fill_val, + event.m_weight); + } else { + var->m_hists.m_bg.FillUniverse(*event.m_universe, fill_val, + event.m_weight); + + // Fill bg by W sideband category + switch (event.m_w_type) { + case kWSideband_Signal: + break; + case kWSideband_Low: + var->m_hists.m_bg_loW.FillUniverse(*event.m_universe, fill_val, + event.m_weight); + break; + case kWSideband_Mid: + var->m_hists.m_bg_midW.FillUniverse(*event.m_universe, fill_val, + event.m_weight); + break; + case kWSideband_High: + var->m_hists.m_bg_hiW.FillUniverse(*event.m_universe, fill_val, + event.m_weight); + break; + default: + std::cerr << "FillBackgrounds: no such W category\n"; + std::exit(2); + } + } + } // end variables +} + +void ccpi_event::FillSelected2D(const CCPiEvent& event, + const std::vector& variables) { + for (auto var : variables) { + // Sanity Checks + if (var->m_is_true && !event.m_is_mc) return; // truth, but not MC? + if (event.m_reco_pion_candidate_idxs.empty()) { + std::cerr << "ccpi_event::FillSelected2D: empty pion idxs vector\n"; + std::exit(1); + } + + // Get fill value + double fill_valX = -999.; + double fill_valY = -999.; + if (var->m_is_true) { + TruePionIdx idx = GetHighestEnergyTruePionIndex(event); + fill_valX = var->GetValueX(*event.m_universe, idx); + fill_valY = var->GetValueY(*event.m_universe, idx); + } else { + // RecoPionIdx idx = GetHighestEnergyPionCandidateIndex(event); + RecoPionIdx idx = event.m_highest_energy_pion_idx; + std::string name = var->NameX() + var->NameY(); + fill_valX = var->GetValueX(*event.m_universe, idx); + fill_valY = var->GetValueY(*event.m_universe, idx); + } + + // total = signal & background, together + if (event.m_is_mc) { + var->m_hists2D.m_selection_mc.FillUniverse(*event.m_universe, fill_valX, + fill_valY, event.m_weight); + } else { + var->m_hists2D.m_selection_data->Fill(fill_valX, fill_valY); + } + + // done with data + if (!event.m_is_mc) continue; + + // signal and background individually + if (event.m_is_signal) { + var->m_hists2D.m_effnum.FillUniverse(*event.m_universe, fill_valX, + fill_valY, event.m_weight); + } else { + var->m_hists2D.m_bg.FillUniverse(*event.m_universe, fill_valX, + fill_valY, event.m_weight); + + // Fill bg by W sideband category + switch (event.m_w_type) { + case kWSideband_Signal: + break; + case kWSideband_Low: + var->m_hists2D.m_bg_loW.FillUniverse(*event.m_universe, fill_valX, + fill_valY, event.m_weight); + break; + case kWSideband_Mid: + var->m_hists2D.m_bg_midW.FillUniverse(*event.m_universe, fill_valX, + fill_valY, event.m_weight); + break; + case kWSideband_High: + var->m_hists2D.m_bg_hiW.FillUniverse(*event.m_universe, fill_valX, + fill_valY, event.m_weight); + break; + default: + std::cerr << "FillBackgrounds: no such W category\n"; + std::exit(2); + } + } + } // end variables +} + +// Fill histograms of all variables with events in the sideband region +void ccpi_event::FillWSideband(const CCPiEvent& event, + const std::vector& variables) { + if (!event.m_is_w_sideband) { + std::cerr << "FillWSideband Warning: This event is not in the wsideband " + "region, are you sure you want to be filling?\n"; + } + if (!HasVar(variables, sidebands::kFitVarString)) { + std::cerr << "FillWSideband: variables container is missing fit var\n"; + std::exit(1); + } + if (event.m_reco_pion_candidate_idxs.empty()) { + std::cerr << "FillWSideband: member pion idxs is empty\n"; + std::exit(1); + } + + const RecoPionIdx idx = event.m_highest_energy_pion_idx; + + for (auto var : variables) { + // if (var->m_is_true && !event.m_is_mc) continue; // truth, but not MC? + if (var->m_is_true) continue; // truth pion variables don't generally work + const double fill_val = var->GetValue(*event.m_universe, idx); + + if (event.m_is_mc) { + switch (event.m_w_type) { + case kWSideband_Signal: + var->m_hists.m_wsidebandfit_sig.FillUniverse( + *event.m_universe, fill_val, event.m_weight); + break; + case kWSideband_Low: + var->m_hists.m_wsidebandfit_loW.FillUniverse( + *event.m_universe, fill_val, event.m_weight); + break; + case kWSideband_Mid: + var->m_hists.m_wsidebandfit_midW.FillUniverse( + *event.m_universe, fill_val, event.m_weight); + break; + case kWSideband_High: + var->m_hists.m_wsidebandfit_hiW.FillUniverse( + *event.m_universe, fill_val, event.m_weight); + break; + default: + std::cerr << "FillWSideband: invalid W category\n"; + std::exit(2); + } + } else { + var->m_hists.m_wsidebandfit_data->Fill(fill_val); + } + } // end variables +} +/* +void ccpi_event::FillWSideband2D(const CCPiEvent& event, + const std::vector& variables) { + if (!event.m_is_w_sideband) { + std::cerr << "FillWSideband2D Warning: This event is not in the wsideband " + "region, are you sure you want to be filling?\n"; + } + if (!HasVar2D(variables, sidebands::kFitVarString)) { + std::cerr << "FillWSideband2D: variables container is missing fit var\n"; + std::exit(1); + } + if (event.m_reco_pion_candidate_idxs.empty()) { + std::cerr << "FillWSideband2D: member pion idxs is empty\n"; + std::exit(1); + } + + const RecoPionIdx idx = event.m_highest_energy_pion_idx; + + for (auto var : variables) { + // if (var->m_is_true && !event.m_is_mc) continue; // truth, but not MC? + if (var->m_is_true) continue; // truth pion variables don't generally work + const double fill_valX = var->GetValueX(*event.m_universe, idx); + const double fill_valY = var->GetValueY(*event.m_universe, idx); + + if (event.m_is_mc) { + switch (event.m_w_type) { + case kWSideband_Signal: + var->m_hists2D.m_wsidebandfit_sig.FillUniverse( + *event.m_universe, fill_valX, fill_valY, event.m_weight); + break; + case kWSideband_Low: + var->m_hists2D.m_wsidebandfit_loW.FillUniverse( + *event.m_universe, fill_valX, fill_valY, event.m_weight); + break; + case kWSideband_Mid: + var->m_hists2D.m_wsidebandfit_midW.FillUniverse( + *event.m_universe, fill_valX, fill_valY, event.m_weight); + break; + case kWSideband_High: + var->m_hists2D.m_wsidebandfit_hiW.FillUniverse( + *event.m_universe, fill_valX, fill_valY, event.m_weight); + break; + default: + std::cerr << "FillWSideband2D: invalid W category\n"; + std::exit(2); + } + } else { + var->m_hists2D.m_wsidebandfit_data->Fill(fill_valX, fill_valY); + } + } // end variables +}*/ + + +void ccpi_event::FillMigration(const CCPiEvent& event, + const vector& variables, + std::string name) { + Variable* reco_var = GetVar(variables, name); + Variable* true_var = GetVar(variables, name + string("_true")); + if (true_var == 0) return; + RecoPionIdx reco_idx = event.m_highest_energy_pion_idx; + TruePionIdx true_idx = GetHighestEnergyTruePionIndex(event); + double reco_fill_val = reco_var->GetValue(*event.m_universe, reco_idx); + double true_fill_val = true_var->GetValue(*event.m_universe, true_idx); + reco_var->m_hists.m_migration.FillUniverse(*event.m_universe, reco_fill_val, + true_fill_val, event.m_weight); +} +void ccpi_event::FillMigration2D(const CCPiEvent& event, + const vector& variables, + std::string nameX, std::string nameY) { + Variable2D* reco_var = GetVar2D(variables, nameX, nameY); + Variable2D* true_var = GetVar2D(variables, nameX + string("_true"), + nameY + string("_true")); + if (true_var == 0) return; + RecoPionIdx reco_idx = event.m_highest_energy_pion_idx; + TruePionIdx true_idx = GetHighestEnergyTruePionIndex(event); + double reco_fill_valX = reco_var->GetValueX(*event.m_universe, reco_idx); + double reco_fill_valY = reco_var->GetValueY(*event.m_universe, reco_idx); + double true_fill_valX = true_var->GetValueX(*event.m_universe, true_idx); + double true_fill_valY = true_var->GetValueY(*event.m_universe, true_idx); +// std::cout << reco_var->NameX() << " vs " << reco_var->NameY() << " " +// << true_var->NameX() << " vs " << true_var->NameY() << "\n" +// << reco_fill_valX << " " << reco_fill_valY << " " << true_fill_valX +// << " " << true_fill_valY << "\n"; + reco_var->m_hists2D.m_migration.FillUniverse(*event.m_universe, true_fill_valX, + true_fill_valY, event.m_weight); + reco_var->m_hists2D.m_migration_reco.FillUniverse(*event.m_universe, reco_fill_valX, + reco_fill_valY, event.m_weight); + reco_var->m_hists2D.m_migration_true.FillUniverse(*event.m_universe, true_fill_valX, + true_fill_valY, event.m_weight); + reco_var->m_response.Fill(reco_fill_valX, reco_fill_valY, true_fill_valX, true_fill_valY, event.m_weight); +} + +// Only for true variables +void ccpi_event::FillEfficiencyDenominator( + const CCPiEvent& event, const std::vector& variables) { + for (auto var : variables) { + if (!var->m_is_true) continue; + TruePionIdx idx = GetHighestEnergyTruePionIndex(event); + double fill_val = var->GetValue(*event.m_universe, idx); + try { + var->m_hists.m_effden.FillUniverse(*event.m_universe, fill_val, + event.m_weight); + } catch (...) { + std::cerr << "From ccpi_event::FillEfficiencyDenominator\n"; + std::cerr << "Variable is " << var->Name() << "\n"; + throw; + } + } +} + +void ccpi_event::FillEfficiencyDenominator2D( + const CCPiEvent& event, const std::vector& variables) { + for (auto var : variables) { + if (!var->m_is_true) continue; + TruePionIdx idx = GetHighestEnergyTruePionIndex(event); + double fill_valX = var->GetValueX(*event.m_universe, idx); + double fill_valY = var->GetValueY(*event.m_universe, idx); + try { + var->m_hists2D.m_effden.FillUniverse(*event.m_universe, fill_valX, + fill_valY, event.m_weight); + } catch (...) { + std::cerr << "From ccpi_event::FillEfficiencyDenominator2D\n"; + std::cerr << "Variable is " << var->NameX() << "_vs_" << var->NameY() << "\n"; + throw; + } + } +} + +//============================================================================== +// Specialized fill functions -- for studies +//============================================================================== +// Fill stacked histograms broken down by true W region. For visualizing the +// sideband sample in other variables. +void ccpi_event::FillWSideband_Study(CCPiEvent& event, + std::vector variables) { + // Make all cuts except for a W cut ... + std::vector w_sideband_cuts = kCutsVector; + w_sideband_cuts.erase( + std::find(w_sideband_cuts.begin(), w_sideband_cuts.end(), kWexp)); + // std::vector pion_candidate_idxs; + + event.m_reco_pion_candidate_idxs.clear(); + + if (!PassesCuts(event, w_sideband_cuts)) return; + + const RecoPionIdx pion_idx = event.m_highest_energy_pion_idx; + + // ... and fill wexpreco. + // Maybe we'll wish to expand this to other variables someday. + { + Variable* var = GetVar(variables, sidebands::kFitVarString); + double fill_val = var->GetValue(*event.m_universe, pion_idx); + if (event.m_is_mc) { + var->GetStackComponentHist(event.m_w_type) + ->Fill(fill_val, event.m_weight); + } else { + var->m_hists.m_wsideband_data->Fill(fill_val); + } + } +} + +// Like FillCutVars, this function loops through cuts and calls PassesCut. +// Michel containers updated as we go, but thrown away at the end. +void ccpi_event::FillCounters( + const CCPiEvent& event, + const std::pair& counters) { + EventCount* signal = counters.first; + EventCount* bg = event.m_is_mc ? counters.second : nullptr; + endpoint::MichelMap dummy1, dummy2; + bool pass = true; + // Purity and efficiency + for (auto i_cut : kCutsVector) { + if (event.m_is_truth != IsPrecut(i_cut)) + continue; // truth loop does precuts + pass = pass && PassesCut(*event.m_universe, i_cut, event.m_is_mc, + event.m_signal_definition, dummy1, dummy2); + if (pass) { + if (!event.m_is_mc) { + (*signal)[i_cut] += event.m_weight; + continue; + } + if (event.m_is_signal) { + (*signal)[i_cut] += event.m_weight; // eff/pur numerator + } else { + (*bg)[i_cut] += event.m_weight; + } + } + } // cuts +} + +std::pair ccpi_event::FillCounters( + const CCPiEvent& event, const EventCount& s, const EventCount& b) { + EventCount signal = s; + EventCount bg = b; + + endpoint::MichelMap endpoint_michels; + trackless::MichelEvent vtx_michels; + bool pass = true; + for (auto i_cut : kCutsVector) { + if (event.m_is_truth != IsPrecut(i_cut)) continue; + + bool passes_this_cut = true; + std::tie(passes_this_cut, endpoint_michels, vtx_michels) = + PassesCut(*event.m_universe, i_cut, event.m_is_mc, + event.m_signal_definition, endpoint_michels, vtx_michels); + + pass = pass && passes_this_cut; + + if (!pass) continue; + + if (!event.m_is_mc) { + signal[i_cut] += event.m_weight; // selected data + } else { + if (event.m_is_signal) + signal[i_cut] += event.m_weight; // selected mc signal + else + bg[i_cut] += event.m_weight; // selected mc bg + } + } // cuts loop + return {signal, bg}; +} + +void ccpi_event::FillCutVars(CCPiEvent& event, + const std::vector& variables) { + const CVUniverse* universe = event.m_universe; + const double wgt = event.m_weight; + const bool is_mc = event.m_is_mc; + const SignalDefinition sd = event.m_signal_definition; + + if (universe->ShortName() != "cv") return; + + endpoint::MichelMap endpoint_michels; + endpoint_michels.clear(); + + endpoint::MichelMap vertex_mich; + vertex_mich.clear(); + + // loop cuts + bool pass = true; + for (unsigned int i = 0; i < kCutsVector.size(); ++i) { + ECuts cut = (ECuts)kCutsVector[i]; + ECuts next_cut; + try { + next_cut = (ECuts)(kCutsVector[i + 1]); + } catch (const std::out_of_range& e) { + next_cut = (ECuts)(-1); + } + event.m_reco_pion_candidate_idxs.clear(); + pass = pass && + PassesCut(*universe, cut, is_mc, sd, endpoint_michels, vertex_mich); + if (!pass) continue; + + // fill container of pion candidate idxs + for (auto m : endpoint_michels) + event.m_reco_pion_candidate_idxs.push_back(m.second.had_idx); + + // Get the highest energy pion candidate + // This quantity is only well-defined after you've made the + // AtLeastOneMichel cut. This cut identifies our pion candidates and their + // associated indices. + int pion_idx = -200; + if (cut == kAtLeastOneMichel || cut == kLLR || cut == kNode || + cut == kIsoProngs || cut == kPionMult) { + pion_idx = GetHighestEnergyPionCandidateIndex(event); + event.m_highest_energy_pion_idx = pion_idx; + } + + // Fill Wexp for each cut + if (HasVar(variables, Form("wexp%d", i))) + FillStackedHists(event, GetVar(variables, Form("wexp%d", i))); + + // N Hadron Tracks + if (next_cut == kAtLeastOnePionCandidateTrack && + HasVar(variables, "n_had_tracks")) { + int fill_val = universe->GetInt("MasterAnaDev_hadron_number"); + FillStackedHists(event, GetVar(variables, "n_had_tracks"), fill_val); + } + // Wexp + if (next_cut == kWexp && HasVar(variables, "wexp_cut")) { + FillStackedHists(event, GetVar(variables, "wexp_cut")); + } + // N michels + if (next_cut == kAtLeastOneMichel && HasVar(variables, "michel_count")) { + double fill_val = endpoint::GetQualityMichels(*universe).size(); + FillStackedHists(event, GetVar(variables, "michel_count"), fill_val); + // if (fill_val == 0 && event.m_is_signal) + // universe->PrintArachneLink(); + } + // New Tracking Variables -- check before LLR cut + if (next_cut == kLLR) { + if (HasVar(variables, "n_short_tracks")) + FillStackedHists(event, GetVar(variables, "n_short_tracks")); + if (HasVar(variables, "n_long_tracks")) + FillStackedHists(event, GetVar(variables, "n_long_tracks")); + if (HasVar(variables, "fit_vtx_x")) + FillStackedHists(event, GetVar(variables, "fit_vtx_x")); + if (HasVar(variables, "fit_vtx_y")) + FillStackedHists(event, GetVar(variables, "fit_vtx_y")); + if (HasVar(variables, "fit_vtx_z")) + FillStackedHists(event, GetVar(variables, "fit_vtx_z")); + if (HasVar(variables, "track_reco_meth")) + FillStackedHists(event, GetVar(variables, "track_reco_meth")); + if (HasVar(variables, "n_nodes")) + FillStackedHists(event, GetVar(variables, "n_nodes")); + } + // LLR + if (next_cut == kLLR && HasVar(variables, "llr")) { + FillStackedHists(event, GetVar(variables, "llr")); + } + // Node + if (next_cut == kNode && HasVar(variables, "enode01")) { + FillStackedHists(event, GetVar(variables, "enode01")); + FillStackedHists(event, GetVar(variables, "enode2")); + FillStackedHists(event, GetVar(variables, "enode3")); + FillStackedHists(event, GetVar(variables, "enode4")); + FillStackedHists(event, GetVar(variables, "enode5")); + } + // N Isolated Prongs + if (next_cut == kIsoProngs && HasVar(variables, "n_iso_prongs")) { + FillStackedHists(event, GetVar(variables, "n_iso_prongs")); + } + // Pion Multiplicity + if (next_cut == kPionMult && HasVar(variables, "n_pions")) { + int fill_val = endpoint_michels.size(); + FillStackedHists(event, GetVar(variables, "n_pions"), fill_val); + } + + if (i == kCutsVector.size() - 1) { + if (HasVar(variables, "wexp")) + FillStackedHists(event, GetVar(variables, "wexp")); + if (HasVar(variables, "pmu")) + FillStackedHists(event, GetVar(variables, "pmu")); + if (HasVar(variables, "ptmu")) + FillStackedHists(event, GetVar(variables, "ptmu")); + if (HasVar(variables, "pzmu")) + FillStackedHists(event, GetVar(variables, "pzmu")); + if (HasVar(variables, "tpi")) + FillStackedHists(event, GetVar(variables, "tpi")); + if (HasVar(variables, "tpi_mbr")) + FillStackedHists(event, GetVar(variables, "tpi_mbr")); + if (HasVar(variables, "enu")) + FillStackedHists(event, GetVar(variables, "enu")); + if (HasVar(variables, "enu")) + FillStackedHists(event, GetVar(variables, "enu")); + if (HasVar(variables, "q2")) + FillStackedHists(event, GetVar(variables, "q2")); + if (HasVar(variables, "thetamu_deg")) + FillStackedHists(event, GetVar(variables, "thetamu_deg")); + if (HasVar(variables, "thetapi_deg")) + FillStackedHists(event, GetVar(variables, "thetapi_deg")); + if (HasVar(variables, "ehad")) + FillStackedHists(event, GetVar(variables, "ehad")); + if (HasVar(variables, "cosadtheta")) + FillStackedHists(event, GetVar(variables, "cosadtheta")); + if (HasVar(variables, "adphi")) + FillStackedHists(event, GetVar(variables, "adphi")); + if (HasVar(variables, "pimuAngle")) + FillStackedHists(event, GetVar(variables, "pimuAngle")); + if (HasVar(variables, "PT")) + FillStackedHists(event, GetVar(variables, "PT")); + } + } // end cuts loop +} + +void ccpi_event::FillStackedHists(const CCPiEvent& event, + const std::vector& variables) { + for (auto var : variables) FillStackedHists(event, var); +} + +void ccpi_event::FillStackedHists(const CCPiEvent& event, Variable* v, + double fill_val) { + if (!event.m_is_mc && v->m_is_true) return; + + const RecoPionIdx pion_idx = event.m_highest_energy_pion_idx; + if (fill_val == -999.) fill_val = v->GetValue(*event.m_universe, pion_idx); + + if (!event.m_is_mc) { + v->m_hists.m_selection_data->Fill(fill_val); + return; + } + + v->GetStackComponentHist(GetFSParticleType(*event.m_universe)) + ->Fill(fill_val, event.m_weight); + + v->GetStackComponentHist(GetChannelType(*event.m_universe)) + ->Fill(fill_val, event.m_weight); + + v->GetStackComponentHist(GetHadronType(*event.m_universe, pion_idx)) + ->Fill(fill_val, event.m_weight); + + v->GetStackComponentHist(GetNPionsType(*event.m_universe)) + ->Fill(fill_val, event.m_weight); + + v->GetStackComponentHist(GetNPi0Type(*event.m_universe)) + ->Fill(fill_val, event.m_weight); + + v->GetStackComponentHist(GetNPipType(*event.m_universe)) + ->Fill(fill_val, event.m_weight); + + v->GetStackComponentHist( + GetSignalBackgroundType(*event.m_universe, event.m_signal_definition)) + ->Fill(fill_val, event.m_weight); + + v->GetStackComponentHist( + GetWSidebandType(*event.m_universe, event.m_signal_definition)) + ->Fill(fill_val, event.m_weight); + + v->GetStackComponentHist( + GetMesonBackgroundType(*event.m_universe, event.m_signal_definition)) + ->Fill(fill_val, event.m_weight); + + v->GetStackComponentHist( + GetWBackgroundType(*event.m_universe, event.m_signal_definition)) + ->Fill(fill_val, event.m_weight); + + v->GetStackComponentHist( + GetTruthWType(*event.m_universe, event.m_signal_definition)) + ->Fill(fill_val, event.m_weight); + + v->GetStackComponentHist( + GetCoherentType(*event.m_universe, event.m_signal_definition)) + ->Fill(fill_val, event.m_weight); +} + +#endif // CCPiEvent_cxx diff --git a/includes/Binning.h b/includes/Binning.h index d0fab3b..c57a116 100644 --- a/includes/Binning.h +++ b/includes/Binning.h @@ -19,29 +19,54 @@ TArrayD GetBinning(const std::string var_name) { if (var_name == "enu") { bins_vec = {0., 1.e3, 3.e3, 4.e3, 6.5e3, 9.5e3, 14.e3, 30.e3}; } else if (var_name == "pmu") { - bins_vec = {0., 1.e3, 2.e3, 3.e3, 4.e3, 5.5e3, - 7.5e3, 10.e3, 13.e3, 20.e3, 30.e3}; + bins_vec = { 1.5e3, 3000., 3750., 4750., 5500., 7500., 9500, 20000.}; +// bins_vec = { 1.5e3, 3.e3, 4.e3, 5.5e3, + // 7.5e3, 8.e3/*10.e3, 14.5e3, 20.e3*/}; + } else if (var_name == "pmu_with_tpi") { + bins_vec = {1.5e3, 3.e3, 4.e3, 5.5e3, 7.5e3, + 10.e3, 13.e3, 20.e3}; +// bins_vec = { 1.5e3, 3.e3, 4.e3, 5.5e3, +// 7.5e3, 8.e3/*10.e3, 14.5e3, 20.e3*/}; } else if (var_name == "q2") { - bins_vec = {0, 0.025e6, 0.05e6, 0.1e6, 0.2e6, 0.3e6, 0.4e6, + bins_vec = {0, 0.025e6, 0.05e6, 0.1e6, 0.2e6, 0.3e6, 0.4e6, 0.5e6, 0.7e6, 1.0e6, 1.3e6, 2.0e6, 3.0e6}; } else if (var_name == "thetamu_deg") { - bins_vec = {0., 1., 2., 3., 4., 5., 6., 7., - 8., 9., 10., 11., 12., 14., 16., 20.}; + bins_vec = {0., 2.5, 3.5, 4.25, 5., 6.25, 7.5, 9.5, 11.5, 14., 20.}; + // bins_vec = {0., 1.5, 3., 4.5, 6., 7.5, 9., 11., 15./*, 20.*/}; } else if (var_name == "thetapi_deg") { - bins_vec = {0., 15., 30., 45, 60, 76., 108., 122., 136., 150., 165., 180.}; - } else if (var_name == "tpi" || var_name == "tpi_mbr") { - bins_vec = {0., 35., 68., 100., 133., 166., 200., 350.}; +// bins_vec = {0., 15., 30., 45, 60, 76., 108., 136., 180.}; + bins_vec = {0., 15., 30., 45, 60, 75., 90., 105., 120., 135., 150., 165., 180.}; +// bins_vec = {0., 15., 30., 42., 56., 120., 138., 150., 180.};//108.,165,180 + } else if (var_name == "tpi" || var_name == "tpi_mbr") { + bins_vec = {35., 100., 150., 200., 350.};//Aaron's Binning for tpi +// bins_vec = {35., 70. ,100., 175., 350.};//other bin test + } else if (var_name == "tpi_with_ptmu" ) { + bins_vec = {35., 100., 150., 350.};//Aaron's Binning for tpi + } else if (var_name == "tpi_with_thetapi" ) { + bins_vec = {35., 100., 150., 200, 350.}; +// bins_vec = {35., 42.5, 50, 57., 140., 185., 350.}; } else if (var_name == "wexp") { - bins_vec = {10.e2, 11.e2, 12.e2, 13.e2, 14.e2, 15.e2}; + bins_vec = {0., 10.e2, 11.e2, 12.e2, 13.e2, 14.e2, 15.e2}; } else if (var_name == "wexp_fit") { - bins_vec = {10.e2, 11.e2, 12.e2, 13.e2, 14.e2, 15.e2, - 18.e2, 21.e2, 24.e2, 28.e2, 32.e2}; + bins_vec = {0., 10.e2, 11.e2, 12.e2, 13.e2, 14.e2, + 15.e2, 17.5e2, 20.e2, 25.e2, 30.e2}; /// Aaron's binning +// bins_vec = {0., 10.e2, 11.e2, 12.e2, 13.e2, 14.e2, 15.e2, +// 21.e2, 24.e2, 28.e2, 32.e2}; } else if (var_name == "ptmu") { - bins_vec = {0., 1.e2, 2.e2, 3.e2, 4.e2, 5.e2, - 6.e2, 8.e2, 10.e2, 12.5e2, 15.e2, 25.e2}; +// bins_vec = {0., 1.5e2, 2.5e2, 3.e2, 3.5e2, 4.75e2, +// 9.5e2, 12.e2 /*,20.e2, 25.e2*/}; + bins_vec = {0, 150, 300, 400, 550, 650, 2000}; +// bins_vec = {0, 150, 300, 400, 600, 2500}; // other binning test +// bins_vec = {0., 1.e2, 2.e2, 3.e2, 4.e2, 5.e2, +// 6.e2, 8.e2, 10.e2, 12.5e2, 15.e2, 25.e2}; + } else if (var_name == "ptmu_with_tpi") { + bins_vec = {0., 270., 420., 600., 800., 2000.}; } else if (var_name == "pzmu") { - bins_vec = {0., 1.e3, 2.e3, 3.e3, 4.e3, 5.e3, - 6.0e3, 8.e3, 10.e3, 15.e3, 20.e3}; +// bins_vec = {/*0., */1.5e3, 3.e3, 4.e3, 5.e3, +// 6.0e3, 8.e3, 9.5e3/*10.e3, 15.e3, 20.e3*/}; + bins_vec = {1500, 2500, 3750, 4750, 5250, 8250, 20000}; +// bins_vec = {0., 1.5e3, 3.e3, 4.e3, 5.e3, +// 6.0e3, 7.e3, 8.5e3, 10.e3, 20.e3}; } else if (var_name == "ecal_nopi") { bins_vec = {0.0, 0.025e3, 0.05e3, 0.075e3, 0.1e3, 0.15e3, 0.2e3, 0.25e3, 0.3e3, 0.4e3, 0.5e3, 0.6e3, @@ -64,6 +89,9 @@ TArrayD GetBinning(const std::string var_name) { } else if (var_name == "PT") { bins_vec = {0., 1.e2, 2.e2, 3.e2, 4.e2, 5.e2, 6.e2, 8.e2, 10.e2, 12.5e2, 15.e2, 25.e2, 30.e2}; + } else if (var_name == "enu_with_tpi") { + bins_vec = {0, 4.5e3, 20.0e3}; +// bins_vec = {0., 1.e3, 3.e3, 4.e3, 6.5e3, 9.5e3, 14.e3, 30.e3}; } // prepare an array from the bin vector @@ -118,4 +146,8 @@ TArrayD GetTArrayFromVec(const std::vector& vec) { return TArrayD(size, array); } +int GetNBins(TArrayD arr) { + int size = arr.GetSize(); + return size - 1; +} #endif // Binning_h diff --git a/includes/CCPiEvent.cxx b/includes/CCPiEvent.cxx index f268b46..53c4e38 100644 --- a/includes/CCPiEvent.cxx +++ b/includes/CCPiEvent.cxx @@ -53,22 +53,21 @@ TruePionIdx GetHighestEnergyTruePionIndex(const CCPiEvent& e) { void ccpi_event::FillRecoEvent(const CCPiEvent& event, const std::vector& variables) { // Fill selection -- total, signal-only, and bg-only - if (event.m_passes_cuts) { + if (event.m_passes_cuts || event.m_passes_trackless_cuts) { ccpi_event::FillSelected(event, variables); } // Fill W Sideband - if (event.m_is_w_sideband) { + if (event.m_is_w_sideband || event.m_passes_trackless_sideband) { ccpi_event::FillWSideband(event, variables); } // Fill W Sideband Study - if (event.m_passes_all_cuts_except_w && - event.m_universe->ShortName() == "cv") { + if ((event.m_passes_all_cuts_except_w || event.m_passes_trackless_cuts_except_w) && event.m_universe->ShortName() == "cv") { ccpi_event::FillWSideband_Study(event, variables); } // Fill Migration - if (event.m_is_mc && event.m_is_signal && event.m_passes_cuts) { + if (event.m_is_mc && event.m_is_signal && (event.m_passes_cuts || event.m_passes_trackless_cuts)) { if (HasVar(variables, "tpi") && HasVar(variables, "tpi_true")) FillMigration(event, variables, std::string("tpi")); if (HasVar(variables, "thetapi_deg") && @@ -99,6 +98,73 @@ void ccpi_event::FillRecoEvent(const CCPiEvent& event, FillMigration(event, variables, std::string("pimuAngle")); if (HasVar(variables, "PT") && HasVar(variables, "PT_true")) FillMigration(event, variables, std::string("PT")); + if (HasVar(variables, "mtpi") && HasVar(variables, "mtpi_true")) + FillMigration(event, variables, std::string("mtpi")); + if (HasVar(variables, "mthetapi_deg") && HasVar(variables, "mthetapi_deg_true")) + FillMigration(event, variables, std::string("mthetapi_deg")); + + } +} +void ccpi_event::FillRecoEvent2D(const CCPiEvent& event, + const std::vector& variables1D, + const std::vector& variables) { + // Fill selection -- total, signal-only, and bg-only + if (event.m_passes_cuts || event.m_passes_trackless_cuts) { + ccpi_event::FillSelected2D(event, variables); + } + // Fill W Sideband + if (event.m_is_w_sideband) { + ccpi_event::FillWSideband(event, variables1D); + } + + if (event.m_passes_all_cuts_except_w && + event.m_universe->ShortName() == "cv") { + ccpi_event::FillWSideband_Study(event, variables1D); + } + + + // Fill Migration + if (event.m_is_mc && event.m_is_signal && (event.m_passes_cuts || event.m_passes_trackless_cuts)) { +// std::cout << "ccpi_event::FillRecoEvent2D In migration, universe = " << event.m_universe->ShortName() << "\n"; + if (HasVar2D(variables, "tpi", "pmu") && + HasVar2D(variables, "tpi_true", "pmu_true")) + FillMigration2D(event, variables, std::string("tpi"), std::string("pmu")); + if (HasVar2D(variables, "pmu", "tpi") && + HasVar2D(variables, "pmu_true", "tpi_true")) + FillMigration2D(event, variables, std::string("pmu"), std::string("tpi")); + if (HasVar2D(variables, "tpi", "thetapi_deg") && + HasVar2D(variables, "tpi_true", "thetapi_deg_true")) + FillMigration2D(event, variables, std::string("tpi"), std::string("thetapi_deg")); + if (HasVar2D(variables, "thetapi_deg", "tpi") && + HasVar2D(variables, "thetapi_deg_true", "tpi_true")) + FillMigration2D(event, variables, std::string("thetapi_deg"), std::string("tpi")); +// if (HasVar2D(variables, "pmu", "thetamu_deg") && +// HasVar2D(variables, "pmu_true", "thetamu_deg_true")) +// FillMigration2D(event, variables, std::string("pmu"), std::string("thetamu_deg")); + if (HasVar2D(variables, "pzmu", "ptmu") && + HasVar2D(variables, "pzmu_true", "ptmu_true")) + FillMigration2D(event, variables, std::string("pzmu"), std::string("ptmu")); + if (HasVar2D(variables, "ptmu", "pzmu") && + HasVar2D(variables, "ptmu_true", "pzmu_true")) + FillMigration2D(event, variables, std::string("ptmu"), std::string("pzmu")); + if (HasVar2D(variables, "ptmu", "tpi") && + HasVar2D(variables, "ptmu_true", "tpi_true")) + FillMigration2D(event, variables, std::string("ptmu"), std::string("tpi")); + if (HasVar2D(variables, "tpi", "ptmu") && + HasVar2D(variables, "tpi_true", "ptmu_true")) + FillMigration2D(event, variables, std::string("tpi"), std::string("ptmu")); + if (HasVar2D(variables, "tpi", "enu") && + HasVar2D(variables, "tpi_true", "enu_true")) + FillMigration2D(event, variables, std::string("tpi"), std::string("enu")); + if (HasVar2D(variables, "enu", "tpi") && + HasVar2D(variables, "enu_true", "tpi_true")) + FillMigration2D(event, variables, std::string("enu"), std::string("tpi")); +// if (HasVar2D(variables, "ptmu", "thetamu_deg") && +// HasVar2D(variables, "ptmu_true", "thetamu_deg_true")) +// FillMigration2D(event, variables, std::string("ptmu"), std::string("thetamu_deg")); +// if (HasVar2D(variables, "pzmu", "thetamu_deg") && +// HasVar2D(variables, "pzmu_true", "thetamu_deg_true")) +// FillMigration2D(event, variables, std::string("pzmu"), std::string("thetamu_deg")); } } @@ -109,6 +175,13 @@ void ccpi_event::FillTruthEvent(const CCPiEvent& event, ccpi_event::FillEfficiencyDenominator(event, variables); } +void ccpi_event::FillTruthEvent2D(const CCPiEvent& event, + const std::vector& variables) { + // Fill Efficiency Denominator + if (event.m_is_signal) + ccpi_event::FillEfficiencyDenominator2D(event, variables); +} + //============================================================================== // Specialized fill functions -- for xsec calculation //============================================================================== @@ -121,10 +194,37 @@ void ccpi_event::FillSelected(const CCPiEvent& event, for (auto var : variables) { // Sanity Checks if (var->m_is_true && !event.m_is_mc) return; // truth, but not MC? - if (event.m_reco_pion_candidate_idxs.empty()) { +/* if (event.m_reco_pion_candidate_idxs.empty()) { std::cerr << "ccpi_event::FillSelected: empty pion idxs vector\n"; std::exit(1); - } + }*/ + + if (var->Name() == "bkdtrackedtpi" && + ((!event.m_passes_cuts && event.m_passes_trackless_cuts) || + (event.m_passes_cuts && event.m_passes_trackless_cuts))) + continue; + + if (var->Name() == "bkdtracklesstpi" && + ((event.m_passes_cuts && !event.m_passes_trackless_cuts) || + (event.m_passes_cuts && event.m_passes_trackless_cuts))) + continue; + + if (var->Name() == "bkdmixtpi" && + ((!event.m_passes_cuts && event.m_passes_trackless_cuts) || + (event.m_passes_cuts && !event.m_passes_trackless_cuts))) + continue; + + if (var->Name() == "tpi" && !event.m_passes_cuts) + continue; + + if (var->Name() == "thetapi_deg" && !event.m_passes_cuts) + continue; + + if (var->Name() == "mthetapi_deg" && !event.m_passes_trackless_cuts) + continue; + + if (var->Name() == "mtpi" && !event.m_passes_trackless_cuts) + continue; // Get fill value double fill_val = -999.; @@ -180,6 +280,105 @@ void ccpi_event::FillSelected(const CCPiEvent& event, } // end variables } +void ccpi_event::FillSelected2D(const CCPiEvent& event, + const std::vector& variables) { + for (auto var : variables) { + // Sanity Checks + if (var->m_is_true && !event.m_is_mc) return; // truth, but not MC? +/* if (event.m_reco_pion_candidate_idxs.empty()) { + std::cerr << "ccpi_event::FillSelected2D: empty pion idxs vector\n"; + std::exit(1); + }*/ + + if ((var->NameX() == "bkdtrackedtpi" || var->NameY() == "bkdtrackedtpi") && + ((!event.m_passes_cuts && event.m_passes_trackless_cuts) || + (event.m_passes_cuts && event.m_passes_trackless_cuts))) + continue; + + if ((var->NameX() == "bkdtracklesstpi" || var->NameY() == "bkdtracklesstpi") && + ((event.m_passes_cuts && !event.m_passes_trackless_cuts) || + (event.m_passes_cuts && event.m_passes_trackless_cuts))) + continue; + + if ((var->NameX() == "bkdmixtpi" || var->NameY() == "bkdmixtpi") && + ((!event.m_passes_cuts && event.m_passes_trackless_cuts) || + (event.m_passes_cuts && !event.m_passes_trackless_cuts))) + continue; + + if ((var->NameX() == "tpi" || var->NameY() == "tpi") && !event.m_passes_cuts) + continue; + + if ((var->NameX() == "thetapi_deg" || var->NameY() == "thetapi_deg") && + !event.m_passes_cuts) + continue; + + if ((var->NameX() == "mthetapi_deg" || var->NameY() == "mthetapi_deg") && + !event.m_passes_trackless_cuts) + continue; + + if ((var->NameX() == "mtpi" || var->NameY() == "mtpi") && + !event.m_passes_trackless_cuts) + continue; + + + // Get fill value + double fill_valX = -999.; + double fill_valY = -999.; + if (var->m_is_true) { + TruePionIdx idx = GetHighestEnergyTruePionIndex(event); + fill_valX = var->GetValueX(*event.m_universe, idx); + fill_valY = var->GetValueY(*event.m_universe, idx); + } else { + // RecoPionIdx idx = GetHighestEnergyPionCandidateIndex(event); + RecoPionIdx idx = event.m_highest_energy_pion_idx; + std::string name = var->NameX() + var->NameY(); + fill_valX = var->GetValueX(*event.m_universe, idx); + fill_valY = var->GetValueY(*event.m_universe, idx); + } + + // total = signal & background, together + if (event.m_is_mc) { + var->m_hists2D.m_selection_mc.FillUniverse(*event.m_universe, fill_valX, + fill_valY, event.m_weight); + } else { + var->m_hists2D.m_selection_data->Fill(fill_valX, fill_valY); + } + + // done with data + if (!event.m_is_mc) continue; + + // signal and background individually + if (event.m_is_signal) { + var->m_hists2D.m_effnum.FillUniverse(*event.m_universe, fill_valX, + fill_valY, event.m_weight); + } else { + var->m_hists2D.m_bg.FillUniverse(*event.m_universe, fill_valX, + fill_valY, event.m_weight); + + // Fill bg by W sideband category + switch (event.m_w_type) { + case kWSideband_Signal: + break; + case kWSideband_Low: + var->m_hists2D.m_bg_loW.FillUniverse(*event.m_universe, fill_valX, + fill_valY, event.m_weight); + break; + case kWSideband_Mid: + var->m_hists2D.m_bg_midW.FillUniverse(*event.m_universe, fill_valX, + fill_valY, event.m_weight); + break; + case kWSideband_High: + var->m_hists2D.m_bg_hiW.FillUniverse(*event.m_universe, fill_valX, + fill_valY, event.m_weight); + break; + default: + std::cerr << "FillBackgrounds: no such W category\n"; + std::exit(2); + } + } + } // end variables +} + // Fill histograms of all variables with events in the sideband region void ccpi_event::FillWSideband(const CCPiEvent& event, const std::vector& variables) { @@ -191,18 +390,23 @@ void ccpi_event::FillWSideband(const CCPiEvent& event, std::cerr << "FillWSideband: variables container is missing fit var\n"; std::exit(1); } - if (event.m_reco_pion_candidate_idxs.empty()) { +/* if (event.m_reco_pion_candidate_idxs.empty()) { std::cerr << "FillWSideband: member pion idxs is empty\n"; std::exit(1); - } + }*/ const RecoPionIdx idx = event.m_highest_energy_pion_idx; for (auto var : variables) { // if (var->m_is_true && !event.m_is_mc) continue; // truth, but not MC? if (var->m_is_true) continue; // truth pion variables don't generally work - const double fill_val = var->GetValue(*event.m_universe, idx); + if ((var->Name() == "mthetapi_deg") && + !event.m_passes_trackless_sideband) + continue; + if (var->Name() == "mtpi" && !event.m_passes_trackless_sideband) + continue; + const double fill_val = var->GetValue(*event.m_universe, idx); if (event.m_is_mc) { switch (event.m_w_type) { case kWSideband_Signal: @@ -230,6 +434,58 @@ void ccpi_event::FillWSideband(const CCPiEvent& event, } } // end variables } +/* +void ccpi_event::FillWSideband2D(const CCPiEvent& event, + const std::vector& variables) { + if (!event.m_is_w_sideband) { + std::cerr << "FillWSideband2D Warning: This event is not in the wsideband " + "region, are you sure you want to be filling?\n"; + } + if (!HasVar2D(variables, sidebands::kFitVarString)) { + std::cerr << "FillWSideband2D: variables container is missing fit var\n"; + std::exit(1); + } + if (event.m_reco_pion_candidate_idxs.empty()) { + std::cerr << "FillWSideband2D: member pion idxs is empty\n"; + std::exit(1); + } + + const RecoPionIdx idx = event.m_highest_energy_pion_idx; + + for (auto var : variables) { + // if (var->m_is_true && !event.m_is_mc) continue; // truth, but not MC? + if (var->m_is_true) continue; // truth pion variables don't generally work + const double fill_valX = var->GetValueX(*event.m_universe, idx); + const double fill_valY = var->GetValueY(*event.m_universe, idx); + + if (event.m_is_mc) { + switch (event.m_w_type) { + case kWSideband_Signal: + var->m_hists2D.m_wsidebandfit_sig.FillUniverse( + *event.m_universe, fill_valX, fill_valY, event.m_weight); + break; + case kWSideband_Low: + var->m_hists2D.m_wsidebandfit_loW.FillUniverse( + *event.m_universe, fill_valX, fill_valY, event.m_weight); + break; + case kWSideband_Mid: + var->m_hists2D.m_wsidebandfit_midW.FillUniverse( + *event.m_universe, fill_valX, fill_valY, event.m_weight); + break; + case kWSideband_High: + var->m_hists2D.m_wsidebandfit_hiW.FillUniverse( + *event.m_universe, fill_valX, fill_valY, event.m_weight); + break; + default: + std::cerr << "FillWSideband2D: invalid W category\n"; + std::exit(2); + } + } else { + var->m_hists2D.m_wsidebandfit_data->Fill(fill_valX, fill_valY); + } + } // end variables +}*/ + void ccpi_event::FillMigration(const CCPiEvent& event, const vector& variables, @@ -237,6 +493,32 @@ void ccpi_event::FillMigration(const CCPiEvent& event, Variable* reco_var = GetVar(variables, name); Variable* true_var = GetVar(variables, name + string("_true")); if (true_var == 0) return; + if (name == "bkdtrackedtpi" && + ((!event.m_passes_cuts && event.m_passes_trackless_cuts) || + (event.m_passes_cuts && event.m_passes_trackless_cuts))) + return; + + if (name == "bkdtracklesstpi" && + ((event.m_passes_cuts && !event.m_passes_trackless_cuts) || + (event.m_passes_cuts && event.m_passes_trackless_cuts))) + return; + + if (name == "bkdmixtpi" && + ((!event.m_passes_cuts && event.m_passes_trackless_cuts) || + (event.m_passes_cuts && !event.m_passes_trackless_cuts))) + return; + + if (name == "tpi" && !event.m_passes_cuts) + return; + + if (name == "thetapi_deg" && !event.m_passes_cuts) + return; + + if (name == "mtpi" && !event.m_passes_trackless_cuts) + return; + + if (name == "mthetapi_deg" && !event.m_passes_trackless_cuts) + return; RecoPionIdx reco_idx = event.m_highest_energy_pion_idx; TruePionIdx true_idx = GetHighestEnergyTruePionIndex(event); double reco_fill_val = reco_var->GetValue(*event.m_universe, reco_idx); @@ -244,6 +526,62 @@ void ccpi_event::FillMigration(const CCPiEvent& event, reco_var->m_hists.m_migration.FillUniverse(*event.m_universe, reco_fill_val, true_fill_val, event.m_weight); } +void ccpi_event::FillMigration2D(const CCPiEvent& event, + const vector& variables, + std::string nameX, std::string nameY) { + Variable2D* reco_var = GetVar2D(variables, nameX, nameY); + Variable2D* true_var = GetVar2D(variables, nameX + string("_true"), + nameY + string("_true")); + if (true_var == 0) return; + if ((nameX == "bkdtrackedtpi" || nameY == "bkdtrackedtpi") && + ((!event.m_passes_cuts && event.m_passes_trackless_cuts) || + (event.m_passes_cuts && event.m_passes_trackless_cuts))) + return; + + if ((nameX == "bkdtracklesstpi" || nameY == "bkdtracklesstpi") && + ((event.m_passes_cuts && !event.m_passes_trackless_cuts) || + (event.m_passes_cuts && event.m_passes_trackless_cuts))) + return; + + if ((nameX == "bkdmixtpi" || nameY == "bkdmixtpi") && + ((!event.m_passes_cuts && event.m_passes_trackless_cuts) || + (event.m_passes_cuts && !event.m_passes_trackless_cuts))) + return; + + if ((nameX == "tpi" || nameY == "tpi") && !event.m_passes_cuts) + return; + + if ((nameX == "thetapi_deg" || nameY == "thetapi_deg") && + !event.m_passes_cuts) + return; + + if ((nameX == "mthetapi_deg" || nameY == "mthetapi_deg") && + !event.m_passes_trackless_cuts) + return; + + if ((nameX == "mtpi" || nameY == "mtpi") && + !event.m_passes_trackless_cuts) + return; + RecoPionIdx reco_idx = event.m_highest_energy_pion_idx; + TruePionIdx true_idx = GetHighestEnergyTruePionIndex(event); + double reco_fill_valX = reco_var->GetValueX(*event.m_universe, reco_idx); + double reco_fill_valY = reco_var->GetValueY(*event.m_universe, reco_idx); + double true_fill_valX = true_var->GetValueX(*event.m_universe, true_idx); + double true_fill_valY = true_var->GetValueY(*event.m_universe, true_idx); +// std::cout << reco_var->NameX() << " vs " << reco_var->NameY() << " " +// << true_var->NameX() << " vs " << true_var->NameY() << "\n" +// << reco_fill_valX << " " << reco_fill_valY << " " << true_fill_valX +// << " " << true_fill_valY << "\n"; + reco_var->m_hists2D.m_migration_reco.FillUniverse(*event.m_universe, reco_fill_valX, + reco_fill_valY, event.m_weight); + reco_var->m_hists2D.m_migration_true.FillUniverse(*event.m_universe, true_fill_valX, + true_fill_valY, event.m_weight); + double hBinX = reco_var->m_hists2D.m_migration.hist->GetXaxis()->GetBinCenter(RooUnfoldResponse::FindBin (reco_var->m_hists2D.m_migration_reco.hist, reco_fill_valX, reco_fill_valY)+1) ; + double hBinY = reco_var->m_hists2D.m_migration.hist->GetYaxis()->GetBinCenter(RooUnfoldResponse::FindBin (reco_var->m_hists2D.m_migration_true.hist, true_fill_valX, true_fill_valY)+1) ; + reco_var->m_hists2D.m_migration.FillUniverse(*event.m_universe, hBinX, + hBinY, event.m_weight); +// reco_var->m_hists2D.m_response.FillUniv(reco_fill_valX, reco_fill_valY, true_fill_valX, true_fill_valY,*event.m_universe, event.m_weight); +} // Only for true variables void ccpi_event::FillEfficiencyDenominator( @@ -263,6 +601,24 @@ void ccpi_event::FillEfficiencyDenominator( } } +void ccpi_event::FillEfficiencyDenominator2D( + const CCPiEvent& event, const std::vector& variables) { + for (auto var : variables) { + if (!var->m_is_true) continue; + TruePionIdx idx = GetHighestEnergyTruePionIndex(event); + double fill_valX = var->GetValueX(*event.m_universe, idx); + double fill_valY = var->GetValueY(*event.m_universe, idx); + try { + var->m_hists2D.m_effden.FillUniverse(*event.m_universe, fill_valX, + fill_valY, event.m_weight); + } catch (...) { + std::cerr << "From ccpi_event::FillEfficiencyDenominator2D\n"; + std::cerr << "Variable is " << var->NameX() << "_vs_" << var->NameY() << "\n"; + throw; + } + } +} + //============================================================================== // Specialized fill functions -- for studies //============================================================================== @@ -515,6 +871,11 @@ void ccpi_event::FillStackedHists(const CCPiEvent& event, for (auto var : variables) FillStackedHists(event, var); } +void ccpi_event::FillStackedHists2D(const CCPiEvent& event, + const std::vector& variables) { + for (auto var : variables) FillStackedHists2D(event, var); +} + void ccpi_event::FillStackedHists(const CCPiEvent& event, Variable* v, double fill_val) { if (!event.m_is_mc && v->m_is_true) return; @@ -570,4 +931,59 @@ void ccpi_event::FillStackedHists(const CCPiEvent& event, Variable* v, ->Fill(fill_val, event.m_weight); } +void ccpi_event::FillStackedHists2D(const CCPiEvent& event, Variable2D* v, + double fill_valX, double fill_valY) { + if (!event.m_is_mc && v->m_is_true) return; + + const RecoPionIdx pion_idx = event.m_highest_energy_pion_idx; + if (fill_valX == -999.) fill_valX = v->GetValueX(*event.m_universe, pion_idx); + if (fill_valY == -999.) fill_valY = v->GetValueY(*event.m_universe, pion_idx); + + if (!event.m_is_mc) { + v->m_hists2D.m_selection_data->Fill(fill_valX, fill_valY); + return; + } + + v->GetStackComponentHist(GetFSParticleType(*event.m_universe)) + ->Fill(fill_valX, fill_valY, event.m_weight); + + v->GetStackComponentHist(GetChannelType(*event.m_universe)) + ->Fill(fill_valX, fill_valY, event.m_weight); + + v->GetStackComponentHist(GetHadronType(*event.m_universe, pion_idx)) + ->Fill(fill_valX, fill_valY, event.m_weight); + + v->GetStackComponentHist(GetNPionsType(*event.m_universe)) + ->Fill(fill_valX, fill_valY, event.m_weight); + + v->GetStackComponentHist(GetNPi0Type(*event.m_universe)) + ->Fill(fill_valX, fill_valY, event.m_weight); + + v->GetStackComponentHist(GetNPipType(*event.m_universe)) + ->Fill(fill_valX, fill_valY, event.m_weight); + + v->GetStackComponentHist( + GetSignalBackgroundType(*event.m_universe, event.m_signal_definition)) + ->Fill(fill_valX, fill_valY, event.m_weight); + + v->GetStackComponentHist( + GetWSidebandType(*event.m_universe, event.m_signal_definition)) + ->Fill(fill_valX, fill_valY, event.m_weight); + + v->GetStackComponentHist( + GetMesonBackgroundType(*event.m_universe, event.m_signal_definition)) + ->Fill(fill_valX, fill_valY, event.m_weight); + + v->GetStackComponentHist( + GetWBackgroundType(*event.m_universe, event.m_signal_definition)) + ->Fill(fill_valX, fill_valY, event.m_weight); + + v->GetStackComponentHist( + GetTruthWType(*event.m_universe, event.m_signal_definition)) + ->Fill(fill_valX, fill_valY, event.m_weight); + + v->GetStackComponentHist( + GetCoherentType(*event.m_universe, event.m_signal_definition)) + ->Fill(fill_valX, fill_valY, event.m_weight); +} #endif // CCPiEvent_cxx diff --git a/includes/CCPiEvent.h b/includes/CCPiEvent.h index 2c5c776..46d3fa6 100644 --- a/includes/CCPiEvent.h +++ b/includes/CCPiEvent.h @@ -2,13 +2,15 @@ #define CCPiEvent_h #include "CVUniverse.h" +#include "RooUnfold/RooUnfoldResponse.h" #include "Constants.h" // typedef RecoPionIdx, EventCount, PassesCutsInfo #include "SignalDefinition.h" #include "TruthCategories/Sidebands.h" // WSidebandType #include "TruthCategories/SignalBackground.h" // SignalBackgroundType #include "Variable.h" +#include "Variable2D.h" class Variable; - +class Variable2D; //============================================================================== // CCPiEvent is a container struct holding misc info about a universe-event: // * passes cuts @@ -44,6 +46,9 @@ struct CCPiEvent { // Fixed (directly) outside of constructor -- with time-intensive functions bool m_passes_cuts; + bool m_passes_trackless_cuts; + bool m_passes_trackless_cuts_except_w; + bool m_passes_trackless_sideband; bool m_is_w_sideband; bool m_passes_all_cuts_except_w; RecoPionIdx m_highest_energy_pion_idx; // GetHighestEnergyPionCandidateIndex @@ -59,12 +64,20 @@ SignalBackgroundType GetSignalBackgroundType(const CCPiEvent&); namespace ccpi_event { // Xsec analysis fill functions void FillSelected(const CCPiEvent&, const std::vector&); +void FillSelected2D(const CCPiEvent&, const std::vector&); void FillRecoEvent(const CCPiEvent&, const std::vector&); +void FillRecoEvent2D(const CCPiEvent&, const std::vector&, + const std::vector&); void FillWSideband(const CCPiEvent&, const std::vector&); +//void FillWSideband2D(const CCPiEvent&, const std::vector&); void FillTruthEvent(const CCPiEvent&, const std::vector&); +void FillTruthEvent2D(const CCPiEvent&, const std::vector&); void FillEfficiencyDenominator(const CCPiEvent&, const std::vector&); +void FillEfficiencyDenominator2D(const CCPiEvent&, const std::vector&); void FillMigration(const CCPiEvent&, const std::vector&, std::string name); +void FillMigration2D(const CCPiEvent&, const std::vector&, + std::string nameX, std::string nameY); // Study functions void FillWSideband_Study(const CCPiEvent&, std::vector); @@ -76,8 +89,12 @@ std::pair FillCounters(const CCPiEvent&, void FillCutVars(CCPiEvent&, const std::vector&); void FillStackedHists(const CCPiEvent&, const std::vector&); // all variables +void FillStackedHists2D(const CCPiEvent&, + const std::vector&); // all variables void FillStackedHists(const CCPiEvent&, Variable*, const double fill_value = -999.); // Single variable +void FillStackedHists2D(const CCPiEvent&, Variable2D*, + const double fill_valueX = -999., const double fill_valueY = -999.); // Single variable } // namespace ccpi_event #endif // CCPiEvent diff --git a/includes/CVUniverse.cxx b/includes/CVUniverse.cxx index 46615a5..2bb44f9 100644 --- a/includes/CVUniverse.cxx +++ b/includes/CVUniverse.cxx @@ -40,8 +40,8 @@ void CVUniverse::PrintArachneLink() const { //============================================================================== // Dummy access for variable constructors //============================================================================== -double CVUniverse::GetDummyVar() const { return -999.; } -double CVUniverse::GetDummyHadVar(const int x) const { return -999.; } +double CVUniverse::GetDummyVar() const { return -9991.; } +double CVUniverse::GetDummyHadVar(const int x) const { return -9991.; } //============================================================================== // Get and set pion candidates @@ -122,6 +122,12 @@ void CVUniverse::SetPionCandidates(std::vector c) { // reco-ed by tracking and not by calorimetry } +void CVUniverse::SetPassesTrakedTracklessCuts(bool passesTrackedCuts, + bool passesTracklessCuts){ + m_passesTrackedCuts = passesTrackedCuts; + m_passesTracklessCuts = passesTracklessCuts; +} + //============================================================================== // Analysis Variables //============================================================================== @@ -142,7 +148,8 @@ double CVUniverse::GetThetamuDeg() const { // event-wide double CVUniverse::GetEhad() const { - return GetCalRecoilEnergy() + GetTrackRecoilEnergy(); + return GetEavail() + GetNMichels() * MinervaUnits::M_pion; +// return GetCalRecoilEnergy() + GetTrackRecoilEnergy(); } double CVUniverse::GetEnu() const { return GetEmu() + GetEhad(); } @@ -300,6 +307,54 @@ double CVUniverse::Gett(RecoPionIdx h) const { mu4v.Py(), mu4v.Pz(), GetEmu()); } +double CVUniverse::GetTpiTrackless() const{ + return GetTpiUntracked(m_vtx_michels.m_bestdist); +} + +double CVUniverse::GetBestDistance() const{ + return m_vtx_michels.m_bestdist; +} + +double CVUniverse::GetMixedTpi(RecoPionIdx idx) const { + if (m_passesTrackedCuts){ + return GetTpi(idx); + } + else if (m_passesTracklessCuts) + return GetTpiTrackless(); + else { + std::cout << "CVUniverse::GetMixedTpi It is not passing the correctly the cuts info, there something wrong with the cuts Reco\n"; + std::exit(1); + } +} + +double CVUniverse::GetThetapitrackless() const { + return m_vtx_michels.m_bestthetaangle; +} + +double CVUniverse::GetThetapitracklessDeg() const { + return ConvertRadToDeg(GetThetapitrackless()); +} + +double CVUniverse::GetMixedThetapiDeg(RecoPionIdx Idx) const { + if (m_passesTrackedCuts){ + return GetThetapiDeg(Idx); + } + else if (m_passesTracklessCuts) + return GetThetapitracklessDeg(); + else { + std::cout << "CVUniverse::GetMixedThetapideg It is not passing the correctly the cuts info, there something wrong with the cuts Reco\n"; + std::exit(1); + } +} + +double CVUniverse::GetEavail() const{ + double recoiltracker = GetDouble("blob_recoil_E_tracker") - GetTrackerECALMuFuzz()[0]; //GetTrackerMuFuzz(); + double recoilEcal = GetDouble("blob_recoil_E_ecal") - GetTrackerECALMuFuzz()[1]; //GetECALMuFuzz(); + const double Eavailable_scale = 1.17; + double eavail = recoiltracker + recoilEcal; + return eavail*Eavailable_scale; +} + //============================================================================== // Truth //============================================================================== @@ -493,6 +548,47 @@ std::vector CVUniverse::GetTpiTrueVec() const { return ret; } +double CVUniverse::GetMixedTpiTrue(TruePionIdx idx) const { + if (m_passesTrackedCuts){ + return GetTpiTrue(idx); + } + else if (m_passesTracklessCuts) + return GetTrueTpi(); + else { + std::cout << "CVUniverse::GetMixedTpiTrue It is not passing the correct there something wrong with the cuts True\n"; + std::exit(1); + } +} + +double CVUniverse::GetThetapitracklessTrueDeg() const { + return ConvertRadToDeg(GetThetapitracklessTrue()); +} + +double CVUniverse::GetThetapitracklessTrue() const { + std::vector tpi_vec = GetTpiTrueVec(); // pip and pim + const int n_true_pions = GetNChargedPionsTrue(); + TruePionIdx reigning_idx = -1; + double reigning_tpi = 9999; + for (TruePionIdx idx = 0; idx < n_true_pions; ++idx) { + if (tpi_vec[idx] < reigning_tpi && GetPiChargeTrue(idx) > 0.) { + reigning_idx = idx; + reigning_tpi = tpi_vec[idx]; + } + } + return GetThetapiTrue(reigning_idx); +} + +double CVUniverse::GetMixedThetapiTrueDeg(TruePionIdx idx) const { + if (m_passesTrackedCuts){ + return GetThetapiTrueDeg(idx); + } + else if (m_passesTracklessCuts) + return GetThetapitracklessTrueDeg(); + else { + std::cout << "CVUniverse::GetMixedThetapiTrueDeg It is not passing the correct there something wrong with the cuts True\n"; + std::exit(1); + } +} //============================== // Ehad (GetErecoil) Variables //============================== @@ -581,9 +677,16 @@ double CVUniverse::GetCalRecoilEnergy_DefaultSpline() const { double CVUniverse::GetNonCalRecoilEnergy() const { if (GetPionCandidates().empty()) { #ifndef NDEBUG - std::cout << "CVU::GetNonCalRecoilEnergy WARNING: no pion candidates!\n"; +// std::cout << "CVU::GetNonCalRecoilEnergy WARNING: no pion candidates!\n"; #endif - return 0.; + int nMichels = GetNMichels(); + double pimass = 0; + if (nMichels > 0){ + pimass = nMichels*MinervaUnits::M_pion; + return pimass; + } + else + return 0.; } double etracks = 0.; @@ -811,7 +914,7 @@ int CVUniverse::GetNAnchoredShortTracks() const { return GetInt("n_anchored_short_trk_prongs"); } -int CVUniverse::GetNIsoProngs() const { return GetDouble("iso_prongs_count"); } +int CVUniverse::GetNIsoProngs() const { return GetDouble("n_nonvtx_iso_blobs_all"); } int CVUniverse::GetNNodes(RecoPionIdx hadron) const { return GetVecElem("MasterAnaDev_pion_nNodes", hadron); @@ -855,7 +958,7 @@ double CVUniverse::GetDiffractiveWeight() const { double CVUniverse::GetGenieWarpWeight() const { double wgt = GetVecElem("truth_genie_wgt_MaRES", 4); wgt = 1 + (wgt - 1) * - 2; // double the size of the shift from 1 (e.g. 1.1 --> 1.2) + 0.2; // double the size of the shift from 1 (e.g. 1.1 --> 1.2) return wgt; } @@ -869,7 +972,7 @@ double CVUniverse::GetLowQ2PiWeight(double q2, std::string channel) const { double CVUniverse::GetWeight() const { // Warping strategy is to only turn on one of these at a time. const bool do_genie_warping = false; - const bool do_aniso_warping = false; + const bool do_aniso_warping =false; const bool do_mk_warping = false; double wgt_flux = 1., wgt_2p2h = 1.; @@ -884,6 +987,7 @@ double CVUniverse::GetWeight() const { wgt_sbfit = 1. /* This weight depends of the sidebands, Will we applay this weight?*/ ; + double wgt_pionReweight = 1.; // genie wgt_genie = GetGenieWeight(); @@ -897,7 +1001,7 @@ double CVUniverse::GetWeight() const { wgt_rpa = GetRPAWeight(); // MINOS efficiency - if (!m_is_truth && GetBool("isMinosMatchTrack")) + if (!m_is_truth && GetInt("isMinosMatchTrack") == 1) wgt_mueff = GetMinosEfficiencyWeight(); // 2p2h @@ -923,6 +1027,9 @@ double CVUniverse::GetWeight() const { // Target Mass wgt_target = GetTargetMassWeight(); + + //Tpi Mehreen's weight + wgt_pionReweight = GetUntrackedPionWeight(); // New Weights added taking as reference Aaron's weights @@ -944,7 +1051,7 @@ double CVUniverse::GetWeight() const { return wgt_genie * wgt_flux * wgt_2p2h * wgt_rpa * wgt_lowq2 * wgt_mueff * wgt_anisodd * wgt_michel * wgt_diffractive * wgt_mk * wgt_target * - wgt_fsi * wgt_coh * wgt_geant * wgt_sbfit; + wgt_fsi * wgt_coh * wgt_geant * wgt_sbfit * wgt_pionReweight; } //============================================================================== diff --git a/includes/CVUniverse.h b/includes/CVUniverse.h index 55a8656..1840431 100644 --- a/includes/CVUniverse.h +++ b/includes/CVUniverse.h @@ -22,6 +22,7 @@ class CVUniverse : public PlotUtils::MinervaUniverse { #include "PlotUtils/RecoilEnergyFunctions.h" #include "PlotUtils/TruthFunctions.h" #include "PlotUtils/WeightFunctions.h" +#include "PlotUtils/LowRecoilPionFunctions.h" // CTOR CVUniverse(PlotUtils::ChainWrapper* chw, double nsigma = 0); @@ -35,11 +36,24 @@ class CVUniverse : public PlotUtils::MinervaUniverse { virtual double GetDummyVar() const; virtual double GetDummyHadVar(const int x) const; + bool m_passesTrackedCuts; + bool m_passesTracklessCuts; + bool m_passesTrackedSideband; + bool m_passesTracklessSideband; + bool m_passesTrackedExceptW; + bool m_passesTracklessExceptW; + // No stale cache! virtual void OnNewEntry() override { m_pion_candidates.clear(); m_vtx_michels = LowRecoilPion::MichelEvent(); assert(m_vtx_michels.m_idx == -1); + m_passesTrackedCuts = false; + m_passesTracklessCuts = false; + m_passesTrackedSideband = false; + m_passesTracklessSideband = false; + m_passesTrackedExceptW = false; + m_passesTracklessExceptW = false; } virtual bool IsVerticalOnly() const override { return true; } @@ -55,6 +69,10 @@ class CVUniverse : public PlotUtils::MinervaUniverse { LowRecoilPion::MichelEvent GetVtxMichels() const { return m_vtx_michels; } + void SetPassesTrakedTracklessCuts( + bool passesTrackedCuts, bool passesTracklessCuts, bool tracked_sideband, + bool trackless_sideband, bool tracked_all_ex_w, bool trackless_all_ex_w); + virtual double ApplyCaloTuning(const double& cal_recoil_energy) const { return cal_recoil_energy; @@ -94,6 +112,9 @@ class CVUniverse : public PlotUtils::MinervaUniverse { virtual double GetTpiMBR(RecoPionIdx) const; virtual double GetpimuAngle(RecoPionIdx) const; virtual double Gett(RecoPionIdx) const; + virtual double GetTpiTrackless() const; + virtual double GetBestDistance() const; + virtual double GetMixedTpi(RecoPionIdx) const; //============================================================================== // Truth @@ -123,6 +144,7 @@ class CVUniverse : public PlotUtils::MinervaUniverse { virtual int GetNChargedPionsTrue() const; virtual int GetPiChargeTrue(TruePionIdx) const; virtual std::vector GetTpiTrueVec() const; + virtual double GetMixedTpiTrue(TruePionIdx) const; //============================== // Ehad (GetErecoil) Variables @@ -211,6 +233,14 @@ class CVUniverse : public PlotUtils::MinervaUniverse { virtual double GetTpiUntracked(double michel_range) const { return -2.93 + 0.133 * michel_range + 3.96 * sqrt(michel_range); } + + virtual double GetEavail() const; + virtual double GetThetapitrackless() const; + virtual double GetThetapitracklessDeg() const; + virtual double GetMixedThetapiDeg(RecoPionIdx) const; + virtual double GetThetapitracklessTrue() const; + virtual double GetThetapitracklessTrueDeg() const; + virtual double GetMixedThetapiTrueDeg(TruePionIdx) const; virtual double thetaWRTBeam(double x, double y, double z) const { double pyp = -1.0 * sin(MinervaUnits::numi_beam_angle_rad) * z + cos(MinervaUnits::numi_beam_angle_rad) * y; @@ -226,7 +256,19 @@ class CVUniverse : public PlotUtils::MinervaUniverse { return GetInt("FittedMichel_all_piontrajectory_trackID_sz"); } virtual double GetTrueTpi() const { - int nFSpi = GetNTruePions(); + std::vector tpi_vec = GetTpiTrueVec(); // pip and pim + const int n_true_pions = GetNChargedPionsTrue(); + TruePionIdx reigning_idx = -1; + double reigning_tpi = 9999; + for (TruePionIdx idx = 0; idx < n_true_pions; ++idx) { + if (tpi_vec[idx] < reigning_tpi && GetPiChargeTrue(idx) > 0.) { + reigning_idx = idx; + reigning_tpi = tpi_vec[idx]; + } + } + + return GetTpiTrue(reigning_idx); +/* int nFSpi = GetNTruePions(); double pionKE = 9999.; for (int i = 0; i < nFSpi; i++) { int pdg = GetVecElem("FittedMichel_all_piontrajectory_pdg", i); @@ -239,7 +281,7 @@ class CVUniverse : public PlotUtils::MinervaUniverse { if (tpi <= pionKE) pionKE = tpi; } - return pionKE; + return pionKE;*/ } }; diff --git a/includes/Constants.h b/includes/Constants.h index 6b0e927..2a73560 100644 --- a/includes/Constants.h +++ b/includes/Constants.h @@ -4,6 +4,7 @@ #include "PlotUtils/Hist2DWrapper.h" #include "PlotUtils/HistWrapper.h" #include "PlotUtils/MnvH1D.h" +#include "MinervaUnfold/MnvResponse.h" #include "TObjArray.h" #include "PlotUtils/LowRecoilPionReco.h" #include "PlotUtils/LowRecoilPionCuts.h" @@ -60,7 +61,9 @@ enum ECuts { kPmu, kAtLeastOnePionCandidate, kTrackQuality, - kAllCuts, + kTpiCut, + kThetamu, + kAllCuts }; enum EDataMCTruth { kData, kMC, kTruth, kNDataMCTruthTypes }; @@ -72,8 +75,10 @@ typedef int TruePionIdx; typedef int RecoPionIdx; typedef PlotUtils::MnvH1D MH1D; +typedef PlotUtils::MnvH2D MH2D; typedef PlotUtils::HistWrapper CVHW; typedef PlotUtils::Hist2DWrapper CVH2DW; +typedef MinervaUnfold::MnvResponse MResponse; typedef LowRecoilPion::MichelEvent UntrackedMichels; typedef LowRecoilPion::hasMichel hasMichel; @@ -107,7 +112,7 @@ const double kPmuMaxCutVal = 20000.; // MeV/c const double kZVtxMinCutVal = 5990.; // cm const double kZVtxMaxCutVal = 8340.; // cm const double kApothemCutVal = 850.; // cm -const double kTpiLoCutVal = 35.; // MeV +const double kTpiLoCutVal = 0.; // MeV const double kTpiHiCutVal = 350.; // MeV const bool kUseNueConstraint = true; diff --git a/includes/CutUtils.h b/includes/CutUtils.h index 71ae4d7..1990300 100644 --- a/includes/CutUtils.h +++ b/includes/CutUtils.h @@ -8,14 +8,17 @@ const std::vector kCutsVector = {kNoCuts, kPrecuts, kVtx, kMinosMuon, + kPmu, + kThetamu, kAtLeastOnePionCandidateTrack, kAtLeastOneMichel, kLLR, kNode, + kTpiCut, kWexp, kIsoProngs, - kPionMult, - kPmu}; + kPionMult + }; // Remove W cut from cuts vector const std::vector GetWSidebandCuts() { @@ -83,6 +86,12 @@ std::string GetCutName(ECuts cut) { case kAtLeastOnePionCandidateTrack: return "$>$= 1 Hadron Track"; + case kTpiCut: + return "50 $<$ Tpi $<$ 350 KeV"; + + case kThetamu: + return "$\\theta_\\mu$ $<$ 20"; + case kNode: return "Node"; diff --git a/includes/Cuts.cxx b/includes/Cuts.cxx index 524efc8..810fe23 100644 --- a/includes/Cuts.cxx +++ b/includes/Cuts.cxx @@ -41,6 +41,9 @@ A not-brief note on how the "exclusive" pion cuts work: #include "Michel.h" // endpoint::Michel, endpoint::MichelMap, endpoint::GetQualityMichels #include "TruthCategories/Sidebands.h" // sidebands::kSidebandCutVal #include "utilities.h" // ContainerEraser +#include "PlotUtils/LowRecoilPionReco.h" +#include "PlotUtils/LowRecoilPionCuts.h" +#include "PlotUtils/LowRecoilPionFunctions.h" //============================================================================== // UTILITY @@ -208,7 +211,11 @@ PassesCut(const CVUniverse& univ, const ECuts cut, const bool is_mc, pass = PmuCut(univ); break; - // modify michels + case kThetamu: + pass = ThetamuCut(univ); + break; + + // modify michels case kAtLeastOneMichel: { endpoint_michels = endpoint::GetQualityMichels(univ); vtx_michels = LowRecoilPion::MichelEvent< @@ -227,6 +234,15 @@ PassesCut(const CVUniverse& univ, const ECuts cut, const bool is_mc, break; } + case kTpiCut: { + ContainerEraser::erase_if(endpoint_michels, + [&univ](std::pair mm) { + return !tpiCut(univ, mm.second.had_idx); + }); + pass = endpoint_michels.size() > 0; + break; + } + // modify michels // If a michel's pion fails the node cut, remove it from the michels case kNode: { @@ -301,7 +317,7 @@ bool MinosActivityCut(const CVUniverse& univ) { // Eventwide reco cuts bool MinosMatchCut(const CVUniverse& univ) { - return univ.GetBool("isMinosMatchTrack"); + return univ.GetInt("isMinosMatchTrack") == 1; } // Equivalent to Brandon's, but using standard minos branches bool MinosChargeCut(const CVUniverse& univ) { @@ -376,4 +392,13 @@ bool PmuCut(const CVUniverse& univ) { pmu < CCNuPionIncConsts::kPmuMaxCutVal; } +bool ThetamuCut(const CVUniverse& univ) { + if (univ.GetThetamuDeg() > 20.) return false; + else return true; +} + +bool tpiCut(const CVUniverse& univ, const RecoPionIdx pion_candidate_idx){ + double tpi = univ.GetTpi(pion_candidate_idx); + return tpi > 50 && tpi < 350; +} #endif // Cuts_cxx diff --git a/includes/Cuts.h b/includes/Cuts.h index 3a76e2b..3c15c1c 100644 --- a/includes/Cuts.h +++ b/includes/Cuts.h @@ -64,11 +64,13 @@ bool vtxCut(const CVUniverse& univ); bool zVertexCut(const CVUniverse& univ, const double upZ, const double downZ); bool XYVertexCut(const CVUniverse& univ, const double a); bool PmuCut(const CVUniverse& univ); +bool ThetamuCut(const CVUniverse& univ); // Cuts Definitions -- exclusive, i.e. on pion candidate tracks bool HadronQualityCuts(const CVUniverse&, const RecoPionIdx pion_candidate_idx); bool LLRCut(const CVUniverse&, const RecoPionIdx pion_candidate_idx); bool NodeCut(const CVUniverse&, const RecoPionIdx pion_candidate_idx); +bool tpiCut(const CVUniverse&, const RecoPionIdx pion_candidate_idx); //============================================================================== // Helper diff --git a/includes/HadronVariable.cxx b/includes/HadronVariable.cxx index b082143..0fb32c6 100644 --- a/includes/HadronVariable.cxx +++ b/includes/HadronVariable.cxx @@ -11,7 +11,8 @@ HadronVariable::HadronVariable(const std::string label, const std::string xaxis, PointerToCVUniverseHadronFunction p, const bool is_true) : Variable(label, xaxis, units, nbins, xmin, xmax, PointerToCVUniverseFunction(), is_true), - pointer_to_GetHadValue(p) + pointer_to_GetHadValue(p), + m_aux_pointer_to_GetHadValue(pointer_to_GetHadValue) {} @@ -21,7 +22,8 @@ HadronVariable::HadronVariable(const std::string label, const std::string xaxis, PointerToCVUniverseHadronFunction p, const bool is_true) : Variable(label, xaxis, units, bins_array, PointerToCVUniverseFunction(), is_true), - pointer_to_GetHadValue(p) + pointer_to_GetHadValue(p), + m_aux_pointer_to_GetHadValue(pointer_to_GetHadValue) {} diff --git a/includes/HadronVariable.h b/includes/HadronVariable.h index 87c86e6..220f0f6 100644 --- a/includes/HadronVariable.h +++ b/includes/HadronVariable.h @@ -22,7 +22,7 @@ class HadronVariable : public Variable { std::string units, const TArrayD& bins_array, PointerToCVUniverseHadronFunction p = &CVUniverse::GetDummyHadVar, const bool is_true = false); - + PointerToCVUniverseHadronFunction m_aux_pointer_to_GetHadValue; //========================================================================== // Functions diff --git a/includes/HadronVariable2D.cxx b/includes/HadronVariable2D.cxx new file mode 100644 index 0000000..390138b --- /dev/null +++ b/includes/HadronVariable2D.cxx @@ -0,0 +1,151 @@ +#ifndef HadronVariable2D_cxx +#define HadronVariable2D_cxx + +#include "HadronVariable2D.h" + + +// CTOR -- uniform binning +HadronVariable2D::HadronVariable2D(const std::string labelX, const std::string labelY, + const std::string xaxisX, const std::string xaxisY, + const std::string unitsX, const std::string unitsY, + const int nbinsX, const double xminX, const double xmaxX, + const int nbinsY, const double xminY, const double xmaxY, + PointerToCVUniverseHadronFunction px, + PointerToCVUniverseHadronFunction py, + const bool is_true) + : Variable2D(labelX, labelY, xaxisX, xaxisY, unitsX, unitsY, nbinsX, xminX, xmaxX, nbinsY, xminY, xmaxY, PointerToCVUniverseFunction(), PointerToCVUniverseFunction(), is_true), + pointer_to_GetHadValueX(px), + pointer_to_GetHadValueY(py), + m_pointer_to_GetValueX(&CVUniverse::GetDummyVar), + m_pointer_to_GetValueY(&CVUniverse::GetDummyVar) +// m_type(1) +{} + +// CTOR -- variable binning +HadronVariable2D::HadronVariable2D(const std::string labelX, const std::string labelY, + const std::string xaxisX, const std::string xaxisY, + const std::string unitsX, const std::string unitsY, + const TArrayD& bins_arrayX, const TArrayD& bins_arrayY, + PointerToCVUniverseHadronFunction px, + PointerToCVUniverseHadronFunction py, + const bool is_true) + : Variable2D(labelX, labelY, xaxisX, xaxisY, unitsX, unitsY, bins_arrayX, bins_arrayY, PointerToCVUniverseFunction(), PointerToCVUniverseFunction(), is_true), + pointer_to_GetHadValueX(px), + pointer_to_GetHadValueY(py), + m_pointer_to_GetValueX(&CVUniverse::GetDummyVar), + m_pointer_to_GetValueY(&CVUniverse::GetDummyVar) +// m_type(2) +{} + +HadronVariable2D::HadronVariable2D(const std::string labelX, const std::string labelY, + const std::string xaxisX, const std::string xaxisY, + const std::string unitsX, const std::string unitsY, + const TArrayD& bins_arrayX, const TArrayD& bins_arrayY, + PointerToCVUniverseFunction px, + PointerToCVUniverseHadronFunction py, + const bool is_true) + : Variable2D(labelX, labelY, xaxisX, xaxisY, unitsX, unitsY, bins_arrayX, bins_arrayY, PointerToCVUniverseFunction(), PointerToCVUniverseFunction(), is_true), + m_pointer_to_GetValueX(px), + pointer_to_GetHadValueY(py), + pointer_to_GetHadValueX(&CVUniverse::GetDummyHadVar), + m_pointer_to_GetValueY(&CVUniverse::GetDummyVar) +// m_type(3) +{} + +HadronVariable2D::HadronVariable2D(const std::string labelX, const std::string labelY, + const std::string xaxisX, const std::string xaxisY, + const std::string unitsX, const std::string unitsY, + const TArrayD& bins_arrayX, const TArrayD& bins_arrayY, + PointerToCVUniverseHadronFunction px, + PointerToCVUniverseFunction py, + const bool is_true, int type ) + : Variable2D(labelX, labelY, xaxisX, xaxisY, unitsX, unitsY, bins_arrayX, bins_arrayY, PointerToCVUniverseFunction(), PointerToCVUniverseFunction(), is_true), + pointer_to_GetHadValueX(px), + m_pointer_to_GetValueY(py), + m_pointer_to_GetValueX(&CVUniverse::GetDummyVar), + pointer_to_GetHadValueY(&CVUniverse::GetDummyHadVar) +// m_type(4), +{} + +// CTOR -- using HadronVariable + +HadronVariable2D::HadronVariable2D(const HadronVariable* x, + const HadronVariable* y) + : Variable2D(x->m_label, y->m_label, x->m_xlabel, y->m_xlabel, x->m_units, y->m_units, x->m_hists.m_bins_array, y->m_hists.m_bins_array, PointerToCVUniverseFunction(), PointerToCVUniverseFunction(), x->m_is_true), + pointer_to_GetHadValueX(x->m_aux_pointer_to_GetHadValue), + pointer_to_GetHadValueY(y->m_aux_pointer_to_GetHadValue), + m_pointer_to_GetValueX(&CVUniverse::GetDummyVar), + m_pointer_to_GetValueY(&CVUniverse::GetDummyVar) +// m_type(5) +{} + +HadronVariable2D::HadronVariable2D(const std::string name, + const HadronVariable* x, + const HadronVariable* y) + : Variable2D(name, y->m_label, x->m_xlabel, y->m_xlabel, x->m_units, y->m_units, x->m_hists.m_bins_array, y->m_hists.m_bins_array, PointerToCVUniverseFunction(), PointerToCVUniverseFunction(), x->m_is_true), + pointer_to_GetHadValueX(x->m_aux_pointer_to_GetHadValue), + pointer_to_GetHadValueY(y->m_aux_pointer_to_GetHadValue), + m_pointer_to_GetValueX(&CVUniverse::GetDummyVar), + m_pointer_to_GetValueY(&CVUniverse::GetDummyVar) +// m_type(6) +{} + +HadronVariable2D::HadronVariable2D(const HadronVariable* x, + const Variable* y) + : Variable2D(x->m_label, y->m_label, x->m_xlabel, y->m_xlabel, x->m_units, y->m_units, x->m_hists.m_bins_array, y->m_hists.m_bins_array, PointerToCVUniverseFunction(), PointerToCVUniverseFunction(), x->m_is_true), + pointer_to_GetHadValueX(x->m_aux_pointer_to_GetHadValue), + m_pointer_to_GetValueY(y->m_aux_pointer_to_GetValue), + pointer_to_GetHadValueY(&CVUniverse::GetDummyHadVar), + m_pointer_to_GetValueX(&CVUniverse::GetDummyVar) +// m_type(7) +{} + +HadronVariable2D::HadronVariable2D(const std::string name, + const HadronVariable* x, + const Variable* y) + : Variable2D(name, y->m_label, x->m_xlabel, y->m_xlabel, x->m_units, y->m_units, x->m_hists.m_bins_array, y->m_hists.m_bins_array, PointerToCVUniverseFunction(), PointerToCVUniverseFunction(), x->m_is_true), + pointer_to_GetHadValueX(x->m_aux_pointer_to_GetHadValue), + m_pointer_to_GetValueY(y->m_aux_pointer_to_GetValue), + pointer_to_GetHadValueY(&CVUniverse::GetDummyHadVar), + m_pointer_to_GetValueX(&CVUniverse::GetDummyVar) +// m_type(8) +{} + +HadronVariable2D::HadronVariable2D(const Variable* x, + const HadronVariable* y) + : Variable2D(x->m_label, y->m_label, x->m_xlabel, y->m_xlabel, x->m_units, y->m_units, x->m_hists.m_bins_array, y->m_hists.m_bins_array, PointerToCVUniverseFunction(), PointerToCVUniverseFunction(), x->m_is_true), + m_pointer_to_GetValueX(x->m_aux_pointer_to_GetValue), + pointer_to_GetHadValueY(y->m_aux_pointer_to_GetHadValue), + pointer_to_GetHadValueX(&CVUniverse::GetDummyHadVar), + m_pointer_to_GetValueY(&CVUniverse::GetDummyVar) + // m_type(9) +{} + +HadronVariable2D::HadronVariable2D(const std::string name, + const Variable* x, + const HadronVariable* y) + : Variable2D(name, y->m_label, x->m_xlabel, y->m_xlabel, x->m_units, y->m_units, x->m_hists.m_bins_array, y->m_hists.m_bins_array, PointerToCVUniverseFunction(), PointerToCVUniverseFunction(), x->m_is_true), + m_pointer_to_GetValueX(x->m_aux_pointer_to_GetValue), + pointer_to_GetHadValueY(y->m_aux_pointer_to_GetHadValue), + pointer_to_GetHadValueX(&CVUniverse::GetDummyHadVar), + m_pointer_to_GetValueY(&CVUniverse::GetDummyVar) +// m_type(10) +{} + +// GetValue defines this variable +double HadronVariable2D::GetValueX (const CVUniverse& universe, const int hadron_index) const { + if (pointer_to_GetHadValueX(universe, hadron_index) != -9991.){ +// std::cout << "hadron_index X " << hadron_index << "\n"; + return pointer_to_GetHadValueX(universe, hadron_index); + } + else return m_pointer_to_GetValueX(universe); +} +double HadronVariable2D::GetValueY (const CVUniverse& universe, const int hadron_index) const { + if (pointer_to_GetHadValueY(universe, hadron_index) != -9991.) { +// std::cout << "hadron_index Y " << hadron_index << "\n"; + return pointer_to_GetHadValueY(universe, hadron_index); +} + else return m_pointer_to_GetValueY(universe); +} + +#endif // HadronVariable_h diff --git a/includes/HadronVariable2D.h b/includes/HadronVariable2D.h new file mode 100644 index 0000000..f5ebf16 --- /dev/null +++ b/includes/HadronVariable2D.h @@ -0,0 +1,87 @@ +#ifndef HadronVariable2D_h +#define HadronVariable2D_h + +#include "Variable2D.h" +#include "HadronVariable.h" +class HadronVariable; +class Variable; + +class HadronVariable2D : public Variable2D { + private: + typedef std::function PointerToCVUniverseHadronFunction ; + PointerToCVUniverseHadronFunction pointer_to_GetHadValueX; + PointerToCVUniverseHadronFunction pointer_to_GetHadValueY; + PointerToCVUniverseFunction m_pointer_to_GetValueX; + PointerToCVUniverseFunction m_pointer_to_GetValueY; + + public: + //========================================================================== + // Constructors + //========================================================================== + HadronVariable2D(const std::string labelX, const std::string labelY, + const std::string xaxisX, const std::string xaxisY, + const std::string unitsX, const std::string unitsY, + const int nbinsX, const double xminX, const double xmaxX, + const int nbinsY, const double xminY, const double xmaxY, + PointerToCVUniverseHadronFunction px = &CVUniverse::GetDummyHadVar, + PointerToCVUniverseHadronFunction py = &CVUniverse::GetDummyHadVar, + const bool is_true = false); + + HadronVariable2D(const std::string labelX, const std::string labelY, + const std::string xaxisX, const std::string xaxisY, + const std::string unitsX, const std::string unitsY, + const TArrayD& bins_arrayX, const TArrayD& bins_arrayY, + PointerToCVUniverseHadronFunction px = &CVUniverse::GetDummyHadVar, + PointerToCVUniverseHadronFunction py = &CVUniverse::GetDummyHadVar, + const bool is_true = false); + + HadronVariable2D(const std::string labelX, const std::string labelY, + const std::string xaxisX, const std::string xaxisY, + const std::string unitsX, const std::string unitsY, + const TArrayD& bins_arrayX, const TArrayD& bins_arrayY, + PointerToCVUniverseFunction px = &CVUniverse::GetDummyVar, + PointerToCVUniverseHadronFunction py = &CVUniverse::GetDummyHadVar, + const bool is_true = false); + + HadronVariable2D(const std::string labelX, const std::string labelY, + const std::string xaxisX, const std::string xaxisY, + const std::string unitsX, const std::string unitsY, + const TArrayD& bins_arrayX, const TArrayD& bins_arrayY, + PointerToCVUniverseHadronFunction px = &CVUniverse::GetDummyHadVar, + PointerToCVUniverseFunction py = &CVUniverse::GetDummyVar, + const bool is_true = false, int type = -1); + + HadronVariable2D(const HadronVariable*, + const HadronVariable*); + + HadronVariable2D(const std::string name, + const HadronVariable*, + const HadronVariable*); + + HadronVariable2D(const HadronVariable*, + const Variable*); + + HadronVariable2D(const std::string name, + const HadronVariable*, + const Variable*); + + HadronVariable2D(const Variable*, + const HadronVariable*); + + HadronVariable2D(const std::string name, + const Variable*, + const HadronVariable*); + + +// int m_type; + + //========================================================================== + // Functions + //========================================================================== + // Get the variable's value + virtual double GetValueX (const CVUniverse& universe, const int hadron_index) const; + + virtual double GetValueY (const CVUniverse& universe, const int hadron_index) const; +}; + +#endif // HadronVariable2D_h diff --git a/includes/Histograms.cxx b/includes/Histograms.cxx index bf84176..944682b 100644 --- a/includes/Histograms.cxx +++ b/includes/Histograms.cxx @@ -243,6 +243,10 @@ void Histograms::LoadDataHistsFromFile(TFile& fin) { (PlotUtils::MnvH1D*)fin.Get(Form("cross_section_%s", m_label.c_str())); m_wsideband_data = (PlotUtils::MnvH1D*)fin.Get(Form("wsideband_data_%s", m_label.c_str())); + if (m_label == "wexp_fit"){ + m_wsidebandfit_data = + (PlotUtils::MnvH1D*)fin.Get(Form("wsidebandfit_data_%s", m_label.c_str())); + } } // Initialize Hists diff --git a/includes/Histograms2D.cxx b/includes/Histograms2D.cxx new file mode 100644 index 0000000..7c3f850 --- /dev/null +++ b/includes/Histograms2D.cxx @@ -0,0 +1,476 @@ +#ifndef Histograms2D_cxx +#define Histograms2D_cxx + +#include +#include "Histograms.h" +#include "Histograms2D.h" +// CTOR -- default +Histograms2D::Histograms2D() + : m_labelX(), m_xlabelX(), + m_labelY(), m_xlabelY(), + m_bins_arrayX(0), + m_bins_arrayY(0), + m_selection_data(), m_selection_mc(), m_bg(), + m_bg_loW(), m_bg_midW(), m_bg_hiW(), + m_effnum(), m_effden(), + m_stacked_w(), m_stacked_hadron(), + m_stacked_fspart(), m_stacked_channel(), + m_stacked_npi(), m_stacked_npi0(), m_stacked_npip(), + m_stacked_sigbg(), m_stacked_wbg(), m_stacked_mesonbg(), + m_stacked_coherent(), + m_wsidebandfit_data(), m_wsidebandfit_sig(), + m_wsidebandfit_loW(), m_wsidebandfit_midW(), m_wsidebandfit_hiW(), + m_stacked_wsideband(), m_wsideband_data(), + m_tuned_bg(), m_bg_subbed_data(), + m_migration(), m_unfolded(), m_cross_section(), + m_migration_reco(), m_migration_true(), m_response(), + m_responseTrue(), m_responseReco(), m_responseMigration() +{} + + +// CTOR -- uniform binning +Histograms2D::Histograms2D(const std::string labelX, const std::string labelY, + const std::string xlabelX, const std::string xlabelY, + const int nbinsX, const int nbinsY, const double xminX, + const double xminY, const double xmaxX, const double xmaxY) + : m_labelX(labelX), m_xlabelX(xlabelX), + m_labelY(labelY), m_xlabelY(xlabelY), + m_bins_arrayX(MakeUniformBinArray(nbinsX, xminX, xmaxX)), + m_bins_arrayY(MakeUniformBinArray(nbinsY, xminY, xmaxY)), + m_selection_data(), m_selection_mc(), m_bg(), + m_bg_loW(), m_bg_midW(), m_bg_hiW(), + m_effnum(), m_effden(), + m_stacked_w(), m_stacked_hadron(), + m_stacked_fspart(), m_stacked_channel(), + m_stacked_npi(), m_stacked_npi0(), m_stacked_npip(), + m_stacked_sigbg(), m_stacked_wbg(), m_stacked_mesonbg(), + m_stacked_coherent(), + m_wsidebandfit_data(), m_wsidebandfit_sig(), + m_wsidebandfit_loW(), m_wsidebandfit_midW(), m_wsidebandfit_hiW(), + m_stacked_wsideband(), m_wsideband_data(), + m_tuned_bg(), m_bg_subbed_data(), + m_migration(), m_unfolded(), m_cross_section(), + m_migration_reco(), m_migration_true(), m_response(), + m_responseTrue(), m_responseReco(), m_responseMigration() +{} + + +// CTOR -- variable binning +Histograms2D::Histograms2D(const std::string labelX, const std::string labelY, + const std::string xlabelX, const std::string xlabelY, + const TArrayD& bins_arrayX, const TArrayD& bins_arrayY) + : m_labelX(labelX), m_xlabelX(xlabelX), + m_labelY(labelY), m_xlabelY(xlabelY), + m_bins_arrayX(GetSortedArray(bins_arrayX)), + m_bins_arrayY(GetSortedArray(bins_arrayY)), + m_selection_data(), m_selection_mc(), m_bg(), + m_bg_loW(), m_bg_midW(), m_bg_hiW(), + m_effnum(), m_effden(), + m_stacked_w(), m_stacked_hadron(), + m_stacked_fspart(), m_stacked_channel(), + m_stacked_npi(), m_stacked_npi0(), m_stacked_npip(), + m_stacked_sigbg(), m_stacked_wbg(), m_stacked_mesonbg(), + m_stacked_coherent(), + m_wsidebandfit_data(), m_wsidebandfit_sig(), + m_wsidebandfit_loW(), m_wsidebandfit_midW(), m_wsidebandfit_hiW(), + m_stacked_wsideband(), m_wsideband_data(), + m_tuned_bg(), m_bg_subbed_data(), + m_migration(), m_unfolded(), m_cross_section(), + m_migration_reco(), m_migration_true(), m_response(), + m_responseTrue(), m_responseReco(), m_responseMigration() +{} + + +// Load hists from file + void Histograms2D::LoadMCHistsFromFile(TFile& fin, UniverseMap& error_bands, + bool is_true) { + m_selection_mc = LoadH2DWFromFile(fin, error_bands, "selection_mc"); + + m_bg = LoadH2DWFromFile(fin, error_bands, "bg"); + m_bg_loW = LoadH2DWFromFile(fin, error_bands, "bg_loW"); + m_bg_midW = LoadH2DWFromFile(fin, error_bands, "bg_midW"); + m_bg_hiW = LoadH2DWFromFile(fin, error_bands, "bg_hiW"); + m_tuned_bg = (PlotUtils::MnvH2D*)fin.Get(Form("tuned_bg_%s_vs_%s", + m_labelX.c_str(), m_labelY.c_str())); + + m_effnum = LoadH2DWFromFile(fin, error_bands, "effnum"); + m_effden = LoadH2DWFromFile(fin, error_bands, "effden"); + + if (m_labelX == sidebands::kFitVarString) { + m_wsidebandfit_sig = LoadH2DWFromFile(fin, error_bands, "wsidebandfit_sig"); + m_wsidebandfit_loW = LoadH2DWFromFile(fin, error_bands, "wsidebandfit_loW"); + m_wsidebandfit_midW = LoadH2DWFromFile(fin, error_bands, "wsidebandfit_midW"); + m_wsidebandfit_hiW = LoadH2DWFromFile(fin, error_bands, "wsidebandfit_hiW"); + } + + if (!is_true && m_labelX != sidebands::kFitVarString) { + m_migration = LoadH2DWFromFile(fin, error_bands, "migration"); + m_migration_reco = LoadH2DWFromFile(fin, error_bands, "migration_reco"); + m_migration_true = LoadH2DWFromFile(fin, error_bands, "migration_truth"); +// m_responseMigration = (PlotUtils::MnvH2D*)fin.Get(Form("Migration2d_%s_vs_%s_migration",m_labelX.c_str(), m_labelY.c_str())); +// m_responseMigration = LoadH2DWFromFile(fin, error_bands, "Migration2d") + assert(m_migration.hist); + assert(m_migration_reco.hist); + assert(m_migration_true.hist); + } + } + + +/* CVHW Histograms2D::LoadHWFromFile(TFile& fin, UniverseMap& error_bands, + std::string name) { + const bool do_erase_bands = false; + PlotUtils::MnvH2D* hist = + (PlotUtils::MnvH2D*)fin.Get(Form("%s_%s_vs_%s", name.c_str(), m_labelX.c_str(), m_labelY.c_str())); + + if (hist == 0) { + std::cout << name << " hist doesn't exist. skipping...\n"; + return CVH2DW(); + } + else { + TArrayD bins_arrayX = *(hist->GetXaxis()->GetXbins()); + TArrayD bins_arrayY = *(hist->GetYaxis()->GetXbins()); + // Source histo has uniform binning + if (bins_arrayX.GetSize() == 0 && bins_arrayY.GetSize() == 0) { + bins_arrayX.Reset(); + bins_arrayY.Reset(); + bins_arrayX = MakeUniformBinArray(hist->GetXaxis()->GetNbins(), + hist->GetXaxis()->GetXmin(), + hist->GetXaxis()->GetXmax()); + bins_arrayY = MakeUniformBinArray(hist->GetYaxis()->GetNbins(), + hist->GetYaxis()->GetXmin(), + hist->GetYaxis()->GetXmax()); + hist = dynamic_cast( hist->Rebin(bins_array.GetSize()-1, + hist->GetName(), + bins_array.GetArray()) ); + } + + // Compare source and destination binnings + for(int i = 0; i < NBins(); ++i) { + if (m_bins_array[i] != bins_array[i]) { + std::cout << "WARNING! Binning mismatch for " << m_label << "\n"; + std::cout << "Aligning output binning to match source binning\n"; + m_bins_array = bins_array; + break; + } + } + + return CVHW(hist, error_bands, do_erase_bands); + } + }*/ + + + CVH2DW Histograms2D::LoadH2DWFromFile(TFile& fin, UniverseMap& error_bands, + std::string name) { + const bool do_erase_bands = false; + PlotUtils::MnvH2D* hist = + (PlotUtils::MnvH2D*)fin.Get(Form("%s_%s_vs_%s", name.c_str(), m_labelX.c_str(), m_labelY.c_str())); + assert(hist); + return CVH2DW(hist, error_bands, do_erase_bands); + } + + void Histograms2D::LoadDataHistsFromFile(TFile& fin) { + m_selection_data = (PlotUtils::MnvH2D*)fin.Get(Form("selection_data_%s_vs_%s", m_labelX.c_str(), m_labelY.c_str())); + m_bg_subbed_data = (PlotUtils::MnvH2D*)fin.Get(Form("bg_subbed_data_%s_vs_%s", m_labelX.c_str(), m_labelY.c_str())); + m_unfolded = (PlotUtils::MnvH2D*)fin.Get(Form("unfolded_%s_vs_%s", m_labelX.c_str(), m_labelY.c_str())); + m_cross_section = (PlotUtils::MnvH2D*)fin.Get(Form("D_cross_section_%s_vs_%s", m_labelX.c_str(), m_labelY.c_str())); + } + + +// Initialize Hists + template + void Histograms2D::InitializeAllHists(T systematic_univs, + T systematic_univs_truth) { + // Event Section Analysis + InitializeSelectionHists(systematic_univs, systematic_univs_truth); + + // Migration Matrix + InitializeMigrationHist(systematic_univs); + + // Sidebands +// InitializeSidebandHists(systematic_univs); + + // Data + InitializeDataHists(); + + // Event Selection Stacked +// InitializeStackedHists(); + } + + + template + void Histograms2D::InitializeSelectionHists(T systematic_univs, + T systematic_univs_truth) { + const Double_t* binsX = m_bins_arrayX.GetArray(); + const Double_t* binsY = m_bins_arrayY.GetArray(); + const char* labelX = m_labelX.c_str(); + const char* labelY = m_labelY.c_str(); + + MH2D* selection_mc = new MH2D(Form("selection_mc_%s_vs_%s", labelX, labelY), + Form("%s_%s", labelX, labelY), NBinsX(), binsX, + NBinsY(), binsY); + + MH2D* bg = new MH2D(Form("bg_%s_vs_%s", labelX, labelY), + Form("%s_%s", labelX, labelY), NBinsX(), binsX, + NBinsY(), binsY); + + MH2D* bg_loW = new MH2D(Form("bg_loW_%s_vs_%s", labelX, labelY), + Form("%s_%s", labelX, labelY), NBinsX(), binsX, + NBinsY(), binsY); + + MH2D* bg_midW = new MH2D(Form("bg_midW_%s_vs_%s", labelX, labelY), + Form("%s_%s", labelX, labelY), NBinsX(), binsX, + NBinsY(), binsY); + + MH2D* bg_hiW = new MH2D(Form("bg_hiW_%s_vs_%s", labelX, labelY), + Form("%s_%s", labelX, labelY), NBinsX(), binsX, + NBinsY(), binsY); + + MH2D* effnum = new MH2D(Form("effnum_%s_vs_%s", labelX, labelY), + Form("%s_%s", labelX, labelY), NBinsX(), binsX, + NBinsY(), binsY); + + MH2D* effden = new MH2D(Form("effden_%s_vs_%s", labelX, labelY), + Form("%s_%s", labelX, labelY), NBinsX(), binsX, + NBinsY(), binsY); + + const bool clear_bands = true; + m_selection_mc = CVH2DW(selection_mc, systematic_univs, clear_bands); + m_bg = CVH2DW(bg, systematic_univs, clear_bands); + m_bg_loW = CVH2DW(bg_loW, systematic_univs, clear_bands); + m_bg_midW = CVH2DW(bg_midW, systematic_univs, clear_bands); + m_bg_hiW = CVH2DW(bg_hiW, systematic_univs, clear_bands); + m_effnum = CVH2DW(effnum, systematic_univs, clear_bands); + m_effden = CVH2DW(effden, systematic_univs_truth, clear_bands); + + delete selection_mc; + delete bg; + delete bg_loW; + delete bg_midW; + delete bg_hiW; + delete effnum; + delete effden; + } + + + template + void Histograms2D::InitializeSidebandHists(T systematic_univs) { + const Double_t* binsX = m_bins_arrayX.GetArray(); + const Double_t* binsY = m_bins_arrayY.GetArray(); + const char* labelX = m_labelX.c_str(); + const char* labelY = m_labelY.c_str(); + MH2D* wsidebandfit_sig = new MH2D(Form("wsidebandfit_sig_%s_vs_%s", labelX, labelY), + Form("%s_%s", labelX, labelY), NBinsX(), binsX, + NBinsY(), binsY); + + MH2D* wsidebandfit_loW = new MH2D(Form("wsidebandfit_loW_%s_vs_%s", labelX, labelY), + Form("%s_%s", labelX, labelY), NBinsX(), binsX, + NBinsY(), binsY); + + MH2D* wsidebandfit_midW = new MH2D(Form("wsidebandfit_midW_%s_vs_%s", labelX, labelY), + Form("%s_%s", labelX, labelY), NBinsX(), binsX, + NBinsY(), binsY); + + MH2D* wsidebandfit_hiW = new MH2D(Form("wsidebandfit_hiW_%s_vs_%s", labelX, labelY), + Form("%s_%s", labelX, labelY), NBinsX(), binsX, + NBinsY(), binsY); + + const bool clear_bands = true; + m_wsidebandfit_sig = CVH2DW(wsidebandfit_sig, systematic_univs, clear_bands); + m_wsidebandfit_loW = CVH2DW(wsidebandfit_loW, systematic_univs, clear_bands); + m_wsidebandfit_midW = CVH2DW(wsidebandfit_midW, systematic_univs, clear_bands); + m_wsidebandfit_hiW = CVH2DW(wsidebandfit_hiW, systematic_univs, clear_bands); + + delete wsidebandfit_sig; + delete wsidebandfit_loW; + delete wsidebandfit_midW; + delete wsidebandfit_hiW; + } + + + void Histograms2D::InitializeStackedHists() { + // Event Selection Stacked + m_stacked_w = StackedHistogram2D( + m_labelX, m_labelY, m_xlabelX, m_xlabelY, m_bins_arrayX, + m_bins_arrayY, int(kNWTypes)); + + m_stacked_sigbg = StackedHistogram2D( + m_labelX, m_labelY, m_xlabelX, m_xlabelY, m_bins_arrayX, + m_bins_arrayY, int(kNSignalBackgroundTypes)); + + m_stacked_wbg = StackedHistogram2D( + m_labelX, m_labelY, m_xlabelX, m_xlabelY, m_bins_arrayX, + m_bins_arrayY, int(kNWBackgroundTypes), 4); + + m_stacked_mesonbg = StackedHistogram2D( + m_labelX, m_labelY, m_xlabelX, m_xlabelY, m_bins_arrayX, + m_bins_arrayY, int(kNMesonBackgroundTypes)); + + m_stacked_hadron = StackedHistogram2D( + m_labelX, m_labelY, m_xlabelX, m_xlabelY, m_bins_arrayX, + m_bins_arrayY, int(kNHadronTypes), 3); + + m_stacked_fspart = StackedHistogram2D( + m_labelX, m_labelY, m_xlabelX, m_xlabelY, m_bins_arrayX, + m_bins_arrayY, int(kNFSParticleTypes)); + + m_stacked_channel = StackedHistogram2D( + m_labelX, m_labelY, m_xlabelX, m_xlabelY, m_bins_arrayX, + m_bins_arrayY, int(kNChannelTypes)); + + m_stacked_npi = StackedHistogram2D( + m_labelX, m_labelY, m_xlabelX, m_xlabelY, m_bins_arrayX, + m_bins_arrayY, int(kNNPionsTypes), 2); + + m_stacked_npi0 = StackedHistogram2D( + m_labelX, m_labelY, m_xlabelX, m_xlabelY, m_bins_arrayX, + m_bins_arrayY, int(kNNPi0Types), 2); + + m_stacked_npip = StackedHistogram2D( + m_labelX, m_labelY, m_xlabelX, m_xlabelY, m_bins_arrayX, + m_bins_arrayY, int(kNNPipTypes), 2); + + m_stacked_coherent = StackedHistogram2D( + m_labelX, m_labelY, m_xlabelX, m_xlabelY, m_bins_arrayX, + m_bins_arrayY, int(kNCoherentTypes), 5); + + // Sideband Stacked + m_stacked_wsideband = StackedHistogram2D( + m_labelX, m_labelY, m_xlabelX, m_xlabelY, m_bins_arrayX, + m_bins_arrayY, kNWSidebandTypes, + sidebands::kWSideband_ColorScheme ); + } + + void Histograms2D::InitializeDataHists() { + const Double_t* binsX = m_bins_arrayX.GetArray(); + const Double_t* binsY = m_bins_arrayY.GetArray(); + const char* labelX = m_labelX.c_str(); + const char* labelY = m_labelY.c_str(); + m_selection_data = new MH2D(Form("selection_mc_%s_vs_%s", labelX, labelY), + Form("%s_%s", labelX, labelY), NBinsX(), binsX, + NBinsY(), binsY); + + m_wsidebandfit_data = new MH2D(Form("wsidebandfit_data_%s_vs_%s", labelX, labelY), + Form("%s_%s", labelX, labelY), NBinsX(), binsX, + NBinsY(), binsY); + + m_wsideband_data = new MH2D(Form("wsideband_data_%s_vs_%s", labelX, labelY), + Form("%s_%s", labelX, labelY), NBinsX(), binsX, + NBinsY(), binsY); + + m_bg_subbed_data = new MH2D(Form("bg_subbed_data_%s_vs_%s", labelX, labelY), + Form("%s_%s", labelX, labelY), NBinsX(), binsX, + NBinsY(), binsY); + + m_unfolded = new MH2D(Form("unfolded_%s_vs_%s", labelX, labelY), + Form("%s_%s", labelX, labelY), NBinsX(), binsX, + NBinsY(), binsY); + + m_cross_section = new MH2D(Form("cross_section_%s_vs_%s", labelX, labelY), + Form("%s_%s", labelX, labelY), NBinsX(), binsX, + NBinsY(), binsY); + } + + + template + void Histograms2D::InitializeMigrationHist(T systematic_univs) { + const Double_t* binsX = m_bins_arrayX.GetArray(); + const Double_t* binsY = m_bins_arrayY.GetArray(); + const char* labelX = m_labelX.c_str(); + const char* labelY = m_labelY.c_str(); + const Int_t migrationBinsX = (NBinsX()+2) * (NBinsY()+2); + const Int_t migrationBinsY = (NBinsX()+2) * (NBinsY()+2); + + PlotUtils::MnvH2D* migration = new PlotUtils::MnvH2D(Form("migration_%s_vs_%s", + labelX, labelY), Form("%s_%s", labelX, labelY), + migrationBinsX, 0.0, Double_t(migrationBinsX), + migrationBinsY, 0.0, Double_t(migrationBinsY)); + PlotUtils::MnvH2D* migration_reco = new PlotUtils::MnvH2D(Form("migration_reco_%s_vs_%s", labelX, labelY), Form("%s_%s", labelX, labelY), + NBinsX(), binsX, NBinsY(), binsY); + PlotUtils::MnvH2D* migration_true = new PlotUtils::MnvH2D(Form("migration_truth_%s_vs_%s", labelX, + labelY), Form("%s_%s", labelX, labelY), + NBinsX(), binsX, NBinsY(), binsY); + + /* m_response = 0; new PlotUtils::MnvH2D(Form("migration2D_%s_vs_%s", labelX, + labelY), Form("%s_%s", labelX, labelY), + NBinsX(), binsX, NBinsY(), binsY); + m_responseReco = 0; new PlotUtils::MnvH2D(Form("migration2D_%s_vs_%s_reco", labelX, + labelY), Form("%s_%s", labelX, labelY), + NBinsX(), binsX, NBinsY(), binsY); + m_responseTrue = 0; new PlotUtils::MnvH2D(Form("migration2D_%s_vs_%s_true", labelX, + labelY), Form("%s_%s", labelX, labelY), + NBinsX(), binsX, NBinsY(), binsY);*/ +// m_response.Setup(Form("Migration2d_%s_vs_%s", labelX, labelY), +// Form("Migration2d %s vs %s", labelX, labelY), +// NBinsX(), binsX, NBinsY(), binsY, systematic_univs); + const bool clear_bands = true; + m_migration = CVH2DW(migration, systematic_univs, clear_bands); + m_migration_reco = CVH2DW(migration_reco, systematic_univs, clear_bands); + m_migration_true = CVH2DW(migration_true, systematic_univs, clear_bands); + delete migration; + delete migration_reco; + delete migration_true; + } + + +//Accessor functions + std::map Histograms2D::GetStackMap (WType type ) const { + return m_stacked_w.m_hist_map; + } + + + std::map Histograms2D::GetStackMap (SignalBackgroundType type ) const { + return m_stacked_sigbg.m_hist_map; + } + + + std::map Histograms2D::GetStackMap (WBackgroundType type ) const { + return m_stacked_wbg.m_hist_map; + } + + + std::map Histograms2D::GetStackMap (MesonBackgroundType type ) const { + return m_stacked_mesonbg.m_hist_map; + } + + + std::map Histograms2D::GetStackMap (HadronType type ) const { + return m_stacked_hadron.m_hist_map; + } + + + std::map Histograms2D::GetStackMap (FSParticleType type ) const { + return m_stacked_fspart.m_hist_map; + } + + + std::map Histograms2D::GetStackMap (ChannelType type ) const { + return m_stacked_channel.m_hist_map; + } + + + std::map Histograms2D::GetStackMap (NPionsType type ) const { + return m_stacked_npi.m_hist_map; + } + + + std::map Histograms2D::GetStackMap (NPi0Type type ) const { + return m_stacked_npi0.m_hist_map; + } + + + std::map Histograms2D::GetStackMap (NPipType type ) const { + return m_stacked_npip.m_hist_map; + } + + + std::map Histograms2D::GetStackMap (WSidebandType type ) const { + return m_stacked_wsideband.m_hist_map; + } + + + std::map Histograms2D::GetStackMap (CoherentType type) const { + return m_stacked_coherent.m_hist_map; + } + + +#endif // Histograms_cxx diff --git a/includes/Histograms2D.h b/includes/Histograms2D.h new file mode 100644 index 0000000..9ebde3d --- /dev/null +++ b/includes/Histograms2D.h @@ -0,0 +1,150 @@ +//============================================================================== +// Container class that holds a lot of histograms for a specific variable +// Also knows how to initialize those histograms +//============================================================================== +#ifndef Histograms2D_h +#define Histograms2D_h + +#include "TFile.h" +#include "TArrayD.h" +#include "utilities.h" // uniq +#include "StackedHistogram.h" +#include "StackedHistogram2D.h" +#include "TruthMatching.h" +#include "CVUniverse.h" +#include "Constants.h" // typedefs MH1D, MH2D, CVHW, CVH2DW +#include "Binning.h" // MakeUniformBinArray + +class Histograms2D { + public: + //========================================================================== + // Constructors + //========================================================================== + Histograms2D(); + + Histograms2D(const std::string labelX, const std::string labelY, + const std::string xlabelX, const std::string xlabelY, + const int nbinsX, const int nbinsY, const double xminX, + const double xminY, const double xmaxX, const double xmaxY); + + Histograms2D(const std::string labelX, const std::string labelY, + const std::string xlabelX, const std::string xlabelY, + const TArrayD& bins_arrayX, const TArrayD& bins_arrayY); + + + //========================================================================== + // Data Members + //========================================================================== + // Basic Data Members + std::string m_labelX; + std::string m_labelY; + std::string m_xlabelX; + std::string m_xlabelY; + TArrayD m_bins_arrayX; + TArrayD m_bins_arrayY; + + // Histograms2D -- Event Selection + MH2D* m_selection_data; // DATA after cuts + CVH2DW m_selection_mc; // MC after cuts, with systematics + CVH2DW m_bg; // BACKGROUND + CVH2DW m_bg_loW; // BACKGROUND + CVH2DW m_bg_midW; // BACKGROUND + CVH2DW m_bg_hiW; // BACKGROUND + CVH2DW m_effnum; // EFF num + CVH2DW m_effden; // EFF den + + // Histograms2D -- Later-stage Cross Section Calculation + MH2D* m_tuned_bg; + MH2D* m_bg_subbed_data; + MH2D* m_efficiency; + MH2D* m_unfolded; + MH2D* m_cross_section; + + // Migration + CVH2DW m_migration; + CVH2DW m_migration_reco; + CVH2DW m_migration_true; + MResponse m_response; + MH2D* m_responseMigration; + MH2D* m_responseTrue; + MH2D* m_responseReco; + + // Histograms2D -- Sidebands + MH2D* m_wsidebandfit_data; + CVH2DW m_wsidebandfit_sig; + CVH2DW m_wsidebandfit_loW; + CVH2DW m_wsidebandfit_midW; + CVH2DW m_wsidebandfit_hiW; + + MH2D* m_wsideband_data; + + // Stacked Histograms2D -- Cut Studies + StackedHistogram2D m_stacked_w; + StackedHistogram2D m_stacked_sigbg; + StackedHistogram2D m_stacked_wbg; + StackedHistogram2D m_stacked_mesonbg; + StackedHistogram2D m_stacked_hadron; + StackedHistogram2D m_stacked_fspart; + StackedHistogram2D m_stacked_channel; + StackedHistogram2D m_stacked_npi; + StackedHistogram2D m_stacked_npi0; + StackedHistogram2D m_stacked_npip; + StackedHistogram2D m_stacked_coherent; + + StackedHistogram2D m_stacked_wsideband; + + + //========================================================================== + // Functions + //========================================================================== + int NBinsX() const { return m_bins_arrayX.GetSize()-1; } + int NBinsY() const { return m_bins_arrayY.GetSize()-1; } + double XMinX() const { return m_bins_arrayX[0]; } + double XMinY() const { return m_bins_arrayY[0]; } + double XMaxX() const { return m_bins_arrayX[NBinsX()]; } + double XMaxY() const { return m_bins_arrayY[NBinsY()]; } + void PrintBinningX() const { + for(int i = 0; i <= NBinsX(); ++i) std::cout << m_bins_arrayX[i] << " "; + std::cout << "\n"; + } + void PrintBinningY() const { + for(int i = 0; i <= NBinsY(); ++i) std::cout << m_bins_arrayY[i] << " "; + std::cout << "\n"; + } + + + // Histogram Initialization + template void InitializeAllHists(T systematic_univs, T systematic_univs_truth); + template void InitializeSelectionHists(T systematic_univs, T systematic_univs_truth); + template void InitializeSidebandHists(T systematic_univs); + template void InitializeMigrationHist(T systematic_univs); + void InitializeDataHists(); + void InitializeStackedHists(); + + // Stack Map Access + std::map GetStackMap (WType type) const; + std::map GetStackMap (SignalBackgroundType type) const; + std::map GetStackMap (WBackgroundType type) const; + std::map GetStackMap (MesonBackgroundType type) const; + std::map GetStackMap (HadronType type) const; + std::map GetStackMap (FSParticleType type) const; + std::map GetStackMap (ChannelType type) const; + std::map GetStackMap (NPionsType type) const; + std::map GetStackMap (NPi0Type type) const; + std::map GetStackMap (NPipType type) const; + std::map GetStackMap (WSidebandType type) const; + std::map GetStackMap (CoherentType type) const; + + // Load MC hists from file + void LoadDataHistsFromFile(TFile& fin); + void LoadMCHistsFromFile(TFile& fin, UniverseMap& error_bands, bool is_true); +// CVHW LoadHWFromFile(TFile& fin, UniverseMap& error_bands, std::string name); + CVH2DW LoadH2DWFromFile(TFile& fin, UniverseMap& error_bands, std::string name); +}; + + +// Template member functions need to be available in the header. +#include "Histograms2D.cxx" + + +#endif // Histograms_h diff --git a/includes/LateralSystematics.h b/includes/LateralSystematics.h index 8ee30d0..b8dbd7a 100644 --- a/includes/LateralSystematics.h +++ b/includes/LateralSystematics.h @@ -17,21 +17,23 @@ class BirksShiftUniverse : public CVUniverse { {} - virtual double GetTpi(int hadron) const { + virtual double GetTpi(int hadron) const override { double shift_val = GetVecElem("MasterAnaDev_pion_E_Birks", hadron); return shift_val+CVUniverse::GetTpi(hadron); } - virtual double GetdEdxScore(int hadron) const { + virtual double GetdEdxScore(int hadron) const override { double shift_val = GetVecElem("MasterAnaDev_piFit_score1_Birks", hadron); return shift_val+CVUniverse::GetdEdxScore(hadron); } - virtual std::string ShortName() const { return "Birks"; } - virtual std::string LatexName() const { return "Birks"; } + virtual std::string ShortName() const override { return "Birks"; } + virtual std::string LatexName() const override { return "Birks"; } + virtual bool IsVerticalOnly() const override { return false; } + }; diff --git a/includes/MacroUtil.cxx b/includes/MacroUtil.cxx index aee4733..20ccb2b 100644 --- a/includes/MacroUtil.cxx +++ b/includes/MacroUtil.cxx @@ -34,7 +34,20 @@ CCPi::MacroUtil::MacroUtil(const int signal_definition_int, m_signal_definition(SignalDefinition::SignalDefinitionMap().at(signal_definition_int)) { Init(); } - +/* +CCPi::MacroUtil::MacroUtil(const int signal_definition, + const std::string& mc_file_list, + const std::string& plist, const bool do_truth, + const bool is_grid, const bool do_systematics, + const std::string TreeName) + : PlotUtils::MacroUtil(TreeName, mc_file_list, plist, do_truth), + m_do_data(false), + m_do_mc(true), + m_do_truth(do_truth), + m_do_systematics(do_systematics), + m_is_grid(is_grid) { + Init(signal_definition); +}*/ // CTOR Data, MC (and Truth) CCPi::MacroUtil::MacroUtil(const int signal_definition_int, const std::string& mc_file_list, @@ -103,6 +116,7 @@ void CCPi::MacroUtil::InitSystematics() { MinervaUniverse::SetReadoutVolume("Tracker"); MinervaUniverse::SetMHRWeightNeutronCVReweight(true); MinervaUniverse::SetMHRWeightElastics(true); + MinervaUniverse::RPAMaterials(false); // Set playlist -- for systematics, flux, and other stuff(?) // If we're only doing data, we don't care what playlist FRW wants to use // (Indeed, this further helps us because we want to loop over ALL data in diff --git a/includes/MacroUtil.h b/includes/MacroUtil.h index de1274a..99c4df6 100644 --- a/includes/MacroUtil.h +++ b/includes/MacroUtil.h @@ -52,6 +52,10 @@ class MacroUtil : public PlotUtils::MacroUtil { const std::string& plist, const bool do_truth, const bool is_grid, const bool do_systematics); + MacroUtil(const int signal_definition, const std::string& mc_file_list, + const std::string& plist, const bool do_truth, const bool is_grid, + const bool do_systematics, const std::string TreeName); + // Data, MC (and Truth) MacroUtil(const int signal_definition, const std::string& mc_file_list, const std::string& data_file_list, const std::string& plist, diff --git a/includes/StackedHistogram2D.cxx b/includes/StackedHistogram2D.cxx new file mode 100644 index 0000000..f581c03 --- /dev/null +++ b/includes/StackedHistogram2D.cxx @@ -0,0 +1,98 @@ +#ifndef StackedHistogram2D_cxx +#define StackedHistogram2D_cxx + +#include "StackedHistogram.h" +#include "StackedHistogram2D.h" +#include "utilities.h" // uniq + +// CTOR -- default +template +StackedHistogram2D::StackedHistogram2D() + : m_labelX(), + m_labelY(), + m_xlabelX(), + m_xlabelY(), + m_bins_arrayX(0), + m_bins_arrayY(0), + m_nhists(0), + m_color_scheme(0), + m_hist_map(), + m_hist_array() +{} + + +// CTOR -- uniform binning +template +StackedHistogram2D::StackedHistogram2D(std::string labelX, std::string labelY, + std::string xlabelX, std::string xlabelY, + int nbinsX, double xminX, double xmaxX, + int nbinsY, double xminY, double xmaxY, + int nhists, int color_scheme) + : m_labelX(labelX), + m_labelY(labelY), + m_xlabelX(xlabelX), + m_xlabelY(xlabelY), + m_bins_arrayX(MakeUniformBinArray(nbinsX, xminX, xmaxX)), + m_bins_arrayY(MakeUniformBinArray(nbinsY, xminY, xmaxY)), + m_nhists(nhists), + m_color_scheme(color_scheme), + m_hist_map(), + m_hist_array() +{ + Initialize(); +} + + +// CTOR -- variable binning +template +StackedHistogram2D::StackedHistogram2D(std::string labelX, std::string labelY, + std::string xlabelX, std::string xlabelY, + const TArrayD& bins_arrayX, const TArrayD& bins_arrayY, + int nhists, int color_scheme) + : m_labelX(labelX), + m_labelY(labelY), + m_xlabelX(xlabelX), + m_xlabelY(xlabelY), + m_bins_arrayX(GetSortedArray(bins_arrayX)), + m_bins_arrayY(GetSortedArray(bins_arrayY)), + m_nhists(nhists), + m_color_scheme(color_scheme), + m_hist_map(), + m_hist_array() +{ + Initialize(); +} + + +// Add component hists to stack +template +void StackedHistogram2D::Initialize() { + for (int i=0; i != m_nhists; ++i){ + T type = static_cast(i); + PlotUtils::MnvH2D* component_hist = MakeStackComponentHist(type); + m_hist_map[type] = component_hist; + m_hist_array.Add(component_hist); + } +} + + +// Make component hist +template +PlotUtils::MnvH2D* StackedHistogram2D::MakeStackComponentHist(const T type) const { + std::string legend_name = GetTruthClassification_LegendLabel(type); + std::string short_name = GetTruthClassification_Name(type); + + PlotUtils::MnvH2D* hist = nullptr; + + hist = new PlotUtils::MnvH2D( + uniq(), Form("%s_vs_%s_%s", m_labelX.c_str(), m_labelY.c_str(), short_name.c_str()), + NBinsX(), m_bins_arrayX.GetArray(), NBinsY(), m_bins_arrayY.GetArray()); + +// SetHistColorScheme(hist, int(type), m_color_scheme); + + hist->SetTitle(legend_name.c_str()); + return hist; +} + + +#endif // StackedHistogram_cxx diff --git a/includes/StackedHistogram2D.h b/includes/StackedHistogram2D.h new file mode 100644 index 0000000..9b2f573 --- /dev/null +++ b/includes/StackedHistogram2D.h @@ -0,0 +1,65 @@ +#ifndef StackedHistogram2D_h +#define StackedHistogram2D_h + +#include "TArrayD.h" +#include "Constants.h" // CCNuPionIncPlotting, SetHistColorScheme +#include "PlotUtils/MnvH1D.h" +#include "PlotUtils/MnvH2D.h" +#include "Binning.h" // MakeUniformBinArray + +template +class StackedHistogram2D { + public: + //========================================================================== + // Constructors + //========================================================================== + StackedHistogram2D(); + + StackedHistogram2D(std::string labelX, std::string labelY, + std::string xlabelX, std::string xlabelY, + int nbinsX, double xminX, double xmaxX, + int nbinsY, double xminY, double xmaxY, + int nhists, int color_scheme = 0); + + StackedHistogram2D(std::string labelX, std::string labelY, + std::string xlabelX, std::string xlabelY, + const TArrayD& bins_arrayX, const TArrayD& bins_arrayY, + int nhists, int color_scheme = 0); + + + //========================================================================== + // Data Members + //========================================================================== + std::string m_labelX; + std::string m_labelY; + std::string m_xlabelX; + std::string m_xlabelY; + TArrayD m_bins_arrayX; + TArrayD m_bins_arrayY; + int m_color_scheme; + int m_nhists; + + std::map m_hist_map; + TObjArray m_hist_array; + + + //========================================================================== + // Functions + //========================================================================== + int NBinsX() const { return m_bins_arrayX.GetSize()-1; } + int NBinsY() const { return m_bins_arrayY.GetSize()-1; } + double XMinX() const { return m_bins_arrayX[0]; } + double XMinY() const { return m_bins_arrayY[0]; } + double XMaxX() const { return m_bins_arrayX[NBinsX()]; } + double XMaxY() const { return m_bins_arrayY[NBinsY()]; } + void Initialize(); + PlotUtils::MnvH2D* MakeStackComponentHist(const T type) const; +}; + + +// Template member functions need to be available in the header. +#include "StackedHistogram.cxx" +#include "StackedHistogram2D.cxx" + + +#endif diff --git a/includes/Systematics.h b/includes/Systematics.h index c665ae1..e3a2d83 100644 --- a/includes/Systematics.h +++ b/includes/Systematics.h @@ -103,11 +103,14 @@ UniverseMap GetSystematicUniversesMap(PlotUtils::ChainWrapper* chain, error_bands[std::string("NodeCutEff")].push_back( new NodeCutEffUniverse(chain, sigma)); + + error_bands[std::string("Target_Mass_CH")].push_back( + new PlotUtils::TargetMassScintillatorUniverse(chain, sigma)); } - // UniverseMap geant_bands = - // PlotUtils::GetGeantHadronSystematicsMap( chain ); - // error_bands.insert(geant_bands.begin(), geant_bands.end()); + UniverseMap geant_bands = + PlotUtils::GetGeantHadronSystematicsMap( chain ); + error_bands.insert(geant_bands.begin(), geant_bands.end()); //======================================================================== // FLUX @@ -222,10 +225,10 @@ UniverseMap GetSystematicUniversesMap(PlotUtils::ChainWrapper* chain, //======================================================================== // Target Mass errors //======================================================================== - UniverseMap error_bands_tarmass = - GetTargetMassSystematicsMap( chain ); - error_bands.insert(error_bands_tarmass.begin(), - error_bands_tarmass.end()); + // UniverseMap error_bands_tarmass = + // GetTargetMassSystematicsMap( chain ); + // error_bands.insert(error_bands_tarmass.begin(), + // error_bands_tarmass.end()); } for (auto band : error_bands) { diff --git a/includes/Variable.cxx b/includes/Variable.cxx index fb02484..c8b4853 100644 --- a/includes/Variable.cxx +++ b/includes/Variable.cxx @@ -9,8 +9,10 @@ // CTOR -- default Variable::Variable() : m_label(), + m_xlabel(), m_units(), m_pointer_to_GetValue(&CVUniverse::GetDummyVar), + m_aux_pointer_to_GetValue(m_pointer_to_GetValue), m_hists(), m_is_true(false) {} @@ -23,8 +25,10 @@ Variable::Variable(const std::string label, const std::string xlabel, PointerToCVUniverseFunction p, const bool is_true) : m_label(label), + m_xlabel(xlabel), m_units(units), m_pointer_to_GetValue(p), + m_aux_pointer_to_GetValue(m_pointer_to_GetValue), m_hists(m_label, xlabel, nbins, xmin, xmax), m_is_true(is_true) {} @@ -37,8 +41,10 @@ Variable::Variable(const std::string label, const std::string xlabel, PointerToCVUniverseFunction p, const bool is_true) : m_label(label), + m_xlabel(xlabel), m_units(units), m_pointer_to_GetValue(p), + m_aux_pointer_to_GetValue(m_pointer_to_GetValue), m_hists(m_label, xlabel, bins_array), m_is_true(is_true) {} diff --git a/includes/Variable.h b/includes/Variable.h index 238b0de..f20aafe 100644 --- a/includes/Variable.h +++ b/includes/Variable.h @@ -36,6 +36,8 @@ class Variable { std::string m_label; std::string m_units; Histograms m_hists; + std::string m_xlabel; + PointerToCVUniverseFunction m_aux_pointer_to_GetValue; bool m_is_true; // also, a pointer to CV universe function for Getting value (private) diff --git a/includes/Variable2D.cxx b/includes/Variable2D.cxx new file mode 100644 index 0000000..5a7b16c --- /dev/null +++ b/includes/Variable2D.cxx @@ -0,0 +1,223 @@ +#ifndef Variable2D_cxx +#define Variable2D_cxx + +#include "Variable.h" +#include "Variable2D.h" +#include "TruthMatching.h" +#include // exit + + +// CTOR -- default +Variable2D::Variable2D() + : m_labelX(), + m_labelY(), + m_unitsX(), + m_unitsY(), + m_pointer_to_GetValueX(&CVUniverse::GetDummyVar), + m_pointer_to_GetValueY(&CVUniverse::GetDummyVar), + m_hists2D(), + m_is_true(false)/*, + m_response()*/ +{} + + +// CTOR -- uniform binning +Variable2D::Variable2D(const std::string labelX, const std::string labelY, + const std::string xaxisX, const std::string xaxisY, + const std::string unitsX, const std::string unitsY, + const int nbinsX, const double xminX, const double xmaxX, + const int nbinsY, const double xminY, const double xmaxY, + PointerToCVUniverseFunction px, + PointerToCVUniverseFunction py, + const bool is_true) + : m_labelX(labelX), + m_labelY(labelY), + m_unitsX(unitsX), + m_unitsY(unitsY), + m_pointer_to_GetValueX(px), + m_pointer_to_GetValueY(py), + m_hists2D(m_labelX, labelY, xaxisX, xaxisY, nbinsX, nbinsY, xminX, xminY, xmaxX, xmaxY), + m_is_true(is_true)/*, + m_response(Form("Migration2d_%s_vs_%s", labelX.c_str(), labelY.c_str()), + Form("Migration2d %s vs %s", labelX.c_str(), labelY.c_str()), + nbinsX, MakeUniformBinArray(nbinsX, xminX, xmaxX).GetArray(), + nbinsY, MakeUniformBinArray(nbinsY, xminY, xmaxY).GetArray(), + nbinsX, MakeUniformBinArray(nbinsX, xminX, xmaxX).GetArray(), + nbinsY, MakeUniformBinArray(nbinsY, xminY, xmaxY).GetArray() + )*/ +{} + + +// CTOR -- variable binning +Variable2D::Variable2D(const std::string labelX, const std::string labelY, + const std::string xaxisX, const std::string xaxisY, + const std::string unitsX, const std::string unitsY, + const TArrayD& bins_arrayX, const TArrayD& bins_arrayY, + PointerToCVUniverseFunction px, + PointerToCVUniverseFunction py, + const bool is_true) + : m_labelX(labelX), + m_labelY(labelY), + m_unitsX(unitsX), + m_unitsY(unitsY), + m_pointer_to_GetValueX(px), + m_pointer_to_GetValueY(py), + m_hists2D(m_labelX, labelY, xaxisX, xaxisY, bins_arrayX, bins_arrayY), + m_is_true(is_true)/*, + m_response(Form("Migration2d_%s_vs_%s", labelX.c_str(), labelY.c_str()), + Form("Migration2d %s vs %s", labelX.c_str(), labelY.c_str()), + GetNBins(bins_arrayX), bins_arrayX.GetArray(), + GetNBins(bins_arrayY), bins_arrayY.GetArray(), + GetNBins(bins_arrayX), bins_arrayX.GetArray(), + GetNBins(bins_arrayY), bins_arrayY.GetArray() + )*/ +{} + +// CTOR -- using other declared histograms + +Variable2D::Variable2D(const Variable* x, + const Variable* y) + : m_labelX(x->m_label), + m_labelY(y->m_label), + m_unitsX(x->m_units), + m_unitsY(y->m_units), + m_pointer_to_GetValueX(x->m_aux_pointer_to_GetValue), + m_pointer_to_GetValueY(y->m_aux_pointer_to_GetValue), + m_hists2D(x->m_label, y->m_label, x->m_xlabel, y->m_xlabel, x->m_hists.m_bins_array, y->m_hists.m_bins_array), + m_is_true(x->m_is_true)/*, + m_response(Form("Migration2d_%s_vs_%s", x->m_label.c_str(), y->m_label.c_str()), + Form("Migration2d %s vs %s", x->m_label.c_str(), y->m_label.c_str()), + GetNBins(x->m_hists.m_bins_array), x->m_hists.m_bins_array.GetArray(), + GetNBins(y->m_hists.m_bins_array), y->m_hists.m_bins_array.GetArray(), + GetNBins(x->m_hists.m_bins_array), x->m_hists.m_bins_array.GetArray(), + GetNBins(y->m_hists.m_bins_array), y->m_hists.m_bins_array.GetArray() + )*/ +{} + +Variable2D::Variable2D(const std::string name, + const Variable* x, + const Variable* y) + + : m_labelX(name), + m_labelY(y->m_label), + m_unitsX(x->m_units), + m_unitsY(y->m_units), + m_pointer_to_GetValueX(x->m_aux_pointer_to_GetValue), + m_pointer_to_GetValueY(y->m_aux_pointer_to_GetValue), + m_hists2D(name, y->m_label, x->m_xlabel, y->m_xlabel, x->m_hists.m_bins_array, y->m_hists.m_bins_array), + m_is_true(x->m_is_true)/*, + m_response(Form("%s", name.c_str()), + Form("Migration2d %s", name.c_str()), + GetNBins(x->m_hists.m_bins_array), x->m_hists.m_bins_array.GetArray(), + GetNBins(y->m_hists.m_bins_array), y->m_hists.m_bins_array.GetArray(), + GetNBins(x->m_hists.m_bins_array), x->m_hists.m_bins_array.GetArray(), + GetNBins(y->m_hists.m_bins_array), y->m_hists.m_bins_array.GetArray() + )*/ +{} + +// GetValue defines this variable +double Variable2D::GetValueX (const CVUniverse& universe, + const int hadron_ID) const { +// std::cout << "Variable2D.h GetValueX " << m_pointer_to_GetValueX(universe) << "\n"; + return m_pointer_to_GetValueX(universe); +} + +double Variable2D::GetValueY (const CVUniverse& universe, + const int hadron_ID) const { +// std::cout << "Variable2D.h GetValueY " << m_pointer_to_GetValueY(universe) << "\n"; + return m_pointer_to_GetValueY(universe); +} + + +// Histogram Initialization +template +void Variable2D::InitializeAllHists(T systematic_univs, T systematic_univs_truth) { + m_hists2D.InitializeAllHists(systematic_univs, systematic_univs_truth); +} + + +template +void Variable2D::InitializeSidebandHists(T systematic_univs) { + m_hists2D.InitializeSidebandHists(systematic_univs); +} + + +void Variable2D::InitializeStackedHists(){ + m_hists2D.InitializeStackedHists(); +} + +void Variable2D::InitializeDataHists(){ + m_hists2D.InitializeDataHists(); +} + + +// Histogram Access +template +PlotUtils::MnvH2D* Variable2D::GetStackComponentHist(T type) const { + std::map stack_map = m_hists2D.GetStackMap(type); + return stack_map[type]; +} + + +// Save with the object names that hists were initialized with +void Variable2D::WriteMCHists(TFile& fout) const { + fout.cd(); + m_hists2D.m_selection_mc.hist -> Write(); + m_hists2D.m_bg.hist -> Write(); + m_hists2D.m_bg_loW.hist -> Write(); + m_hists2D.m_bg_midW.hist -> Write(); + m_hists2D.m_bg_hiW.hist -> Write(); + m_hists2D.m_effnum.hist -> Write(); + m_hists2D.m_effden.hist -> Write(); +/*if (NameX() == sidebands::kFitVarString) { + m_hists2D.m_wsidebandfit_sig.hist ->Write(); + m_hists2D.m_wsidebandfit_loW.hist ->Write(); + m_hists2D.m_wsidebandfit_midW.hist->Write(); + m_hists2D.m_wsidebandfit_hiW.hist ->Write(); + }*/ + if (!m_is_true && NameX() != sidebands::kFitVarString){ + m_hists2D.m_migration.hist->Write(); + m_hists2D.m_migration_reco.hist->Write(); + m_hists2D.m_migration_true.hist->Write(); +// m_hists2D.m_response.GetMigrationObjectsFromW(m_hists2D.m_responseMigration, +// m_hists2D.m_responseReco, +// m_hists2D.m_responseTrue) +// m_hists2D.m_responseMigration->Write(); +// m_hists2D.m_responseReco->Write(); +// m_hists2D.m_responseTrue->Write(); + } +} + + +void Variable2D::LoadDataHistsFromFile(TFile& fin) { + m_hists2D.LoadDataHistsFromFile(fin); +} + + +void Variable2D::LoadMCHistsFromFile(TFile& fin, UniverseMap& error_bands) { + m_hists2D.LoadMCHistsFromFile(fin, error_bands, m_is_true); +} + + +template +TObjArray Variable2D::GetStackArray(T type) const { + if(std::is_same::value) return m_hists2D.m_stacked_w.m_hist_array; + else if(std::is_same::value) return m_hists2D.m_stacked_sigbg.m_hist_array; + else if(std::is_same::value) return m_hists2D.m_stacked_wbg.m_hist_array; + else if(std::is_same::value) return m_hists2D.m_stacked_mesonbg.m_hist_array; + else if(std::is_same::value) return m_hists2D.m_stacked_hadron.m_hist_array; + else if(std::is_same::value) return m_hists2D.m_stacked_fspart.m_hist_array; + else if(std::is_same::value) return m_hists2D.m_stacked_channel.m_hist_array; + else if(std::is_same::value) return m_hists2D.m_stacked_npi.m_hist_array; + else if(std::is_same::value) return m_hists2D.m_stacked_npi0.m_hist_array; + else if(std::is_same::value) return m_hists2D.m_stacked_npip.m_hist_array; + else if(std::is_same::value) return m_hists2D.m_stacked_wsideband.m_hist_array; + else if(std::is_same::value) return m_hists2D.m_stacked_coherent.m_hist_array; + else{ + std::cerr << "GetStackArray: Unknown truth type.\n"; + std::exit(1); + } +} + + +#endif // Variable_cxx diff --git a/includes/Variable2D.h b/includes/Variable2D.h new file mode 100644 index 0000000..f70fa5a --- /dev/null +++ b/includes/Variable2D.h @@ -0,0 +1,108 @@ +#ifndef Variable2D_h +#define Variable2D_h + +#include +#include "TArrayD.h" +#include "CVUniverse.h" +#include "Histograms.h" +#include "Histograms2D.h" +#include "Variable.h" +#include "Constants.h" +#include "Binning.h" +class Variable; + +class Variable2D { + protected: + typedef std::function PointerToCVUniverseFunction; + PointerToCVUniverseFunction m_pointer_to_GetValueX; + PointerToCVUniverseFunction m_pointer_to_GetValueY; + + public: + //========================================================================== + // Constructors + //========================================================================== + Variable2D(); + + Variable2D(const std::string labelX, const std::string labelY, + const std::string xaxisX, const std::string xaxisY, + const std::string unitsX, const std::string unitsY, + const int nbinsX, const double xminX, const double xmaxX, + const int nbinsY, const double xminY, const double xmaxY, + PointerToCVUniverseFunction px = &CVUniverse::GetDummyVar, + PointerToCVUniverseFunction py = &CVUniverse::GetDummyVar, + const bool is_true = false); + + Variable2D(const std::string labelX, const std::string labelY, + const std::string xaxisX, const std::string xaxisY, + const std::string unitsX, const std::string unitsY, + const TArrayD& bins_arrayX, const TArrayD& bins_arrayY, + PointerToCVUniverseFunction px = &CVUniverse::GetDummyVar, + PointerToCVUniverseFunction py = &CVUniverse::GetDummyVar, + const bool is_true = false); + + Variable2D(const Variable*, + const Variable*); + + Variable2D(const std::string name, + const Variable*, + const Variable*); + + //========================================================================== + // Data members + //========================================================================== + std::string m_labelX; + std::string m_unitsX; + Histograms2D m_hists2D; + std::string m_labelY; + std::string m_unitsY; +// MResponse m_response; + bool m_is_true; + // also, a pointer to CV universe function for Getting value (private) + + //========================================================================== + // Functions + //========================================================================== + // Access + std::string NameX() const { return m_labelX; } + std::string NameY() const { return m_labelY; } + int NBinsX() const { return m_hists2D.NBinsX(); } + int NBinsY() const { return m_hists2D.NBinsY(); } + int XMinX() const { return m_hists2D.XMinX(); } + int XMinY() const { return m_hists2D.XMinY(); } + int XMaxX() const { return m_hists2D.XMaxX(); } + int XMaxY() const { return m_hists2D.XMaxY(); } + + // Get the variable's value + virtual double GetValueX (const CVUniverse& universe, const int hadron_ID = -1) const; + virtual double GetValueY (const CVUniverse& universe, const int hadron_ID = -1) const; + + // Histogram Initialization + template + void InitializeAllHists(T systematic_univs, T systematic_univs_truth); + template + void InitializeSidebandHists(T systematic_univs); + void InitializeStackedHists(); + void InitializeDataHists(); + + // Write and Load MC Hists to/from a file + void WriteMCHists(TFile& fout) const; + void LoadDataHistsFromFile(TFile& fin); + void LoadMCHistsFromFile(TFile& fin, UniverseMap& error_bands); + + + // Histogram Access + template + PlotUtils::MnvH2D* GetStackComponentHist(T type) const; + + template + TObjArray GetStackArray(T type) const ; + + // Get Histograms from File + //void GetMCHists(TFile& fin); +}; + + +#include "Variable2D.cxx" + + +#endif // Variable_h diff --git a/includes/common_functions.h b/includes/common_functions.h index 2e43a15..da7f906 100644 --- a/includes/common_functions.h +++ b/includes/common_functions.h @@ -10,6 +10,7 @@ #include "Constants.h" // CCNuPionIncConsts::PI #include "MacroUtil.h" #include "Variable.h" +#include "Variable2D.h" class Variable; @@ -51,6 +52,19 @@ void InitializeHW(Variable* var, std::string name, std::string label, delete hist; } +void InitializeHW2D(Variable2D* var, std::string name, std::string label, + UniverseMap error_bands, CVH2DW& hw) { + MH2D* hist = new MH2D(name.c_str(), label.c_str(), var->NBinsX(), + var->m_hists2D.m_bins_arrayX.GetArray(), var->NBinsY(), + var->m_hists2D.m_bins_arrayY.GetArray()); + + // make CVH2DW from MH1D + const bool clear_bands = true; + hw = CVH2DW(hist, error_bands, clear_bands); + + delete hist; +} + // Copy all hists of one file into another file void CopyHists(TFile& fin, TFile& fout) { TIter nextkey(fin.GetListOfKeys()); @@ -105,6 +119,24 @@ void SaveDataHistsToFile(TFile& fout, std::vector variables) { } } +void SaveDataHistsToFile2D(TFile& fout, std::vector variables2D) { + std::cout << "Saving Data Hists\n\n"; + // fout.cd(); + for (auto v2D : variables2D) { + std::string nameX = v2D->NameX(); + std::string nameY = v2D->NameY(); + v2D->m_hists2D.m_selection_data->GetXaxis()->SetTitle( + v2D->m_hists2D.m_selection_mc.hist->GetXaxis()->GetTitle()); + v2D->m_hists2D.m_selection_data->Write(Form("selection_data_%s_vs_%s", nameX.c_str(), nameY.c_str())); + /*if (name == sidebands::kFitVarString) { + v2D->m_hists.m_wsidebandfit_data->Write( + Form("wsidebandfit_data_%s", name.c_str())); + }*/ + } +} + + + // Does a vector of variables contain a certain variable? bool HasVar(std::vector variables, std::string name) { auto it = find_if (variables.begin(), variables.end(), @@ -115,6 +147,14 @@ bool HasVar(std::vector variables, std::string name) { return false; } + +bool HasVar2D(std::vector variables, std::string nameX, std::string nameY) { + for (auto var2D : variables ) + if (var2D->NameX() == nameX && var2D->NameY() == nameY) return true; + + return false; +} + // Get a certain variable from a vector of variables Variable* GetVar(std::vector variables, std::string name) { auto it = find_if (variables.begin(), variables.end(), @@ -128,4 +168,12 @@ Variable* GetVar(std::vector variables, std::string name) { } } +Variable2D* GetVar2D(std::vector variables, std::string nameX, std::string nameY) { + for (auto var2D : variables ) + if (var2D->NameX() == nameX && var2D->NameY() == nameY) return var2D; + + std::cerr << nameX << "_vs_" << nameY << " variable not found!\n"; + return nullptr; +} + #endif // common_functions_h diff --git a/loadLibs.C b/loadLibs.C index 9321253..9cc7d0f 100644 --- a/loadLibs.C +++ b/loadLibs.C @@ -9,7 +9,7 @@ void loadIncludes(bool verbose_cvu) { const char* cvu_flags = verbose_cvu ? "kfg" : "kf"; std::cout << cvu_flags << "\n"; TString path( - TString::Format("%s/cc-ch-pip-ana/includes/", gSystem->Getenv("TOPDIR"))); + TString::Format("%s/2D-cc-ch-pip-ana/includes/", gSystem->Getenv("TOPDIR"))); // std::cout << "path " << path << "\n"; TString oldpath = gSystem->GetIncludePath(); oldpath += " -I"; @@ -25,6 +25,10 @@ void loadIncludes(bool verbose_cvu) { gSystem->CompileMacro("CCPiEvent.cxx", "k"); gSystem->CompileMacro("WSidebandFitter.cxx", "k"); gSystem->CompileMacro("CohDiffractiveSystematics.cxx", "k"); + gSystem->CompileMacro("StackedHistogram2D.cxx", "k"); + gSystem->CompileMacro("Histograms2D.cxx", "k"); + gSystem->CompileMacro("Variable2D.cxx", "k"); + gSystem->CompileMacro("HadronVariable2D.cxx", "k"); } void loadLibs(bool verbose_cvu = true) { diff --git a/runTransWarp2D.sh b/runTransWarp2D.sh new file mode 100644 index 0000000..d150e0f --- /dev/null +++ b/runTransWarp2D.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +#Usage: runTransWarp.sh runEventLoopMC.root warped.root + +#declare -a VARIABLE=("adphi" "cosadtheta" "ehad" "enu" "pimuAngle" "pmu" "ptmu" "pzmu" "q2" "thetamu_deg" "thetapi_deg" "tpi" "wexp") +declare -a VARIABLE=("pzmu%s_vs_ptmu%s" "pmu%s_vs_tpi%s" "tpi%s_vs_thetapi_deg%s" "tpi%s_vs_ptmu%s" "enu%s_vs_tpi%s") +#declare -a VARIABLE=("tpi%s_vs_ptmu%s") +#declare -a VARIABLE=("pzmu%s_vs_ptmu%s" "ptmu%s_vs_pzmu%s" "tpi%s_vs_pmu%s" "pmu%s_vs_tpi%s" "tpi%s_vs_thetapi_deg%s" "thetapi_deg%s_vs_tpi%s" "ptmu%s_vs_tpi%s" "tpi%s_vs_ptmu%s" "enu%s_vs_tpi%s" "tpi%s_vs_enu%s" ) +#declare -a VARIABLE=() +#declare -a warps=("NOMINAL") +#declare -a VARIABLE=("tpi") +declare -a warps=("WARP1" "WARP2" "WARP3") +#Ximaxaxis=(1500 10000 1000 100 650 75 4000 100 100 50 550 275 800 10000 10000 200 100 2200 75 4000 100 50 50 850 150 150 1100 10000 1200 100 450 75 4500 100 75 50 200 50 550 1000 10000 1400 100 450 75 5000 100 250 50 500 100 5000) +Ximaxaxis=(5000 5000 5000 5000 5000 5000 5000 5000 5000 5000 5000) +true_tag="_true" +reco_tag="" +DATE="20240611" +PLIST="ALL" +#MIGRATION_FILE=$1 +#TRUE_HIST=effnum_${VARIABLE} +#WARPED_FILE=$2 +#RECO_HIST=selection_mc_${VARIABLE} + +OUTFILE_NAME="/minerva/data/users/granados/WarpingStudies/Warping/2DWarping/" +#OUTFILE_NAME=$(basename $2) +#counter=0 + +for TAG in "${warps[@]}"; do + counter=0 + for v in "${VARIABLE[@]}"; do + MIGRATION_FILE="MCXSecInputs_${DATE}_${PLIST}_tracked_noSys_p4_NOMINAL.root" + WARPED_FILE="MCXSecInputs_${DATE}_${PLIST}_tracked_noSys_p4_${TAG}.root" + reco_var=$(printf "$v" $reco_tag $reco_tag) + true_var=$(printf "$v" $true_tag $true_tag) + TransWarpExtraction --output_file ${OUTFILE_NAME}Warping_2D_${PLIST}_${DATE}_${TAG}_${reco_var}.root --data effnum_${reco_var} --data_file $WARPED_FILE --data_truth effnum_${true_var} --data_truth_file $WARPED_FILE --migration migration_${reco_var} --migration_file $MIGRATION_FILE --reco effnum_${reco_var} --reco_file $MIGRATION_FILE --truth effnum_${true_var} --truth_file $MIGRATION_FILE --num_uni 500 --max_chi2 ${Ximaxaxis[${counter}]} --step_chi2 0.5 --num_iter 0,1,2,3,4,5,6,7,8,9,10,20,30,50,100 --log_scale -C 0.5 --num_dim 2 #--exclude_bins 3,4,13,18,19,21,24 + echo "Variable ${reco_var} ${true_var} Warp ${TAG} Xi Y Axis ${Ximaxaxis[${counter}]}" +# cd ../MAT/macros/ +# python PrintWarpingStudy.py -i ${OUTFILE_NAME}Warping_2D${TAG}_${reco_var}.root -o ${OUTFILE_NAME}${reco_var}_${TAG} -L +# cd - + let counter=counter+1 + done # vars +done #warps diff --git a/setSL7.sh b/setSL7.sh deleted file mode 100644 index 36e3caa..0000000 --- a/setSL7.sh +++ /dev/null @@ -1,5 +0,0 @@ -source /cvmfs/minerva.opensciencegrid.org/minerva/hep_hpc_products/setups -setup root v6_10_04d -q e14:prof -setup cmake v3_7_1 - -source /cvmfs/minerva.opensciencegrid.org/minerva/setup/setup_minerva_products.sh diff --git a/studies/RecoilComparison.C b/studies/RecoilComparison.C new file mode 100644 index 0000000..81b212d --- /dev/null +++ b/studies/RecoilComparison.C @@ -0,0 +1,184 @@ +#include "TFile.h" +#include "TTree.h" +#include "TH1.h" +#include "TH2.h" +#include "TCanvas.h" + +#include +#include +#include +#include +#include +using namespace std; + +//This does an event by event comparison of the branches in "names" and prints out the event IDs where they don't match. +void RecoilComparison(){ + TString oldFileName = "/pnfs/minerva/persistent/users/bmesserl/pions/20210307/merged/mc/ME1A/CCNuPionInc_mc_AnaTuple_run00110030_Playlist.root"; + TString newFileName = "/pnfs/minerva/persistent/users/granados/MADtuplas/merged/20230329/mc/ME1A/MasterAnaDev_mc_AnaTuple_run00110030_Playlist.root"; + + cout << "opening: " << oldFileName << endl; + TFile* oldFile = new TFile(oldFileName,"READ"); + cout << "opening: " << newFileName << endl; + TFile* newFile = new TFile(newFileName,"READ"); + + //TTree* oldTree = (TTree*)oldFile->Get("CCQENu"); + TTree* oldTree = (TTree*)oldFile->Get("CCNuPionInc"); + TTree* newTree = (TTree*)newFile->Get("MasterAnaDev"); + + double newID; + newTree->SetBranchAddress("eventID",&newID); + int newEntries = newTree->GetEntries(); + + map indexNew; + + cout << newEntries << endl; + for (int i=0; i < newEntries; ++i){ + if (i%(newEntries/100)==0) cout << i <<"/"<< newEntries << endl; + newTree->GetEntry(i); + if (newID < 0) continue; + //cout << "NEW Non-negative ID" << endl; + indexNew[newID]=i; + } + + cout << "Setting NHit" << endl; + double passive_em_ID_Old; + oldTree->SetBranchAddress("part_response_recoil_passive_em_id",&passive_em_ID_Old); + TH1D* h_passive_em_ID = new TH1D("passive_em_ID_Old","passive_em_ID Comparison;Diff.;Events",80,-20,20); + + double prong_Score_Old; + oldTree->SetBranchAddress("prong_part_score",&prong_Score_Old); + TH1D* h_prong_part_score = new TH1D("prong_part_score","prong_part_score;Diff.;Events",80,-20,20); + + int n_prongs_Old; + oldTree->SetBranchAddress("n_prongs",&n_prongs_Old); + TH1D* h_n_prongs = new TH1D("n_prongs","n_prongs MAD - CCNuPionInc;Diff.;Events",20,-10,10); + + int n_long_tracks_Old; + oldTree->SetBranchAddress("n_long_tracks",&n_long_tracks_Old); + TH1D* h_n_long_tracks = new TH1D("n_long_tracks","n_long_tracks MAD - CCNuPionInc;Diff.;Events",20,-10,10); + + int n_short_tracks_Old; + oldTree->SetBranchAddress("n_short_tracks",&n_short_tracks_Old); + TH1D* h_n_short_tracks = new TH1D("n_short_tracks","n_short_tracks MAD - CCNuPionInc;Diff.;Events",20,-10,10); + + +/* + cout << "Stteing NVtx" << endl; + int nVtxOld; + oldTree->SetBranchAddress("event_vertex_time_diff_sz",&nVtxOld); + + cout << "Setting Vtx Diff" << endl; + double vtxDiffOld[200]; + oldTree->SetBranchAddress("event_vertex_time_diff",&vtxDiffOld); + TH1D* hCompareVtxDiff = new TH1D("hCompareVtxDiff","Vertex 0 Time Diff. Comparison;Diff.;Events",50,-25,25); + + cout << "Setting Recoil." << endl; + double oldRecoil[200]; + oldTree->SetBranchAddress("recoil_summed_energy",&oldRecoil); + TH1D* hCompareRecoil = new TH1D("hCompareRecoil","Recoil Summed Comparison;Percent Diff.;Events",201,-100.5,100.5); + TH2D* h2DRecoil = new TH2D("h2DRecoil","Recoil Summed 2D Comparison;CCQENu;Percent Diff.",200,0,10000,200,-100,100); + + cout << "Setting Recoil Non" << endl; + double oldRecNon; + oldTree->SetBranchAddress("recoil_energy_nonmuon_nonvtx100mm",&oldRecNon); + TH1D* hCompareRecNon = new TH1D("hCompareRecNon","Recoil NonVtx Comparison;Percent Diff.;Events",201,-100.5,100.5); + TH2D* h2DRecNon = new TH2D("h2DRecNon","Recoil NonVtx 2D Comparison;CCQENu;Percent Diff.",200,0,10000,200,-100,100); + + cout << "Setting Recoil Vtx" << endl; + double oldRecVtx; + oldTree->SetBranchAddress("recoil_energy_nonmuon_vtx100mm",&oldRecVtx); + TH1D* hCompareRecVtx = new TH1D("hCompareRecVtx","Recoil Vtx Comparison;Percent Diff.;Events",201,-100.5,100.5); + TH2D* h2DRecVtx = new TH2D("h2DRecVtx","Recoil Vtx 2D Comparison;CCQENu;Percent Diff.",200,0,10000,200,-100,100); + + cout << "Added Comparison" << endl; + TH1D* hCompareRecAdded = new TH1D("hCompareRecAdded","Recoil Vtx+Non-Vtx Comparison;Percent Diff.;Events",201,-100.5,100.5); +*/ + cout << "Setting New NHit" << endl; + double passive_em_ID_New; + newTree->SetBranchAddress("part_response_recoil_passive_em_id",&passive_em_ID_New); + + double prong_part_score_New; + newTree->SetBranchAddress("prong_part_score",&prong_part_score_New); + + int n_prongs_New; + newTree->SetBranchAddress("n_prongs",&n_prongs_New); + + int n_long_tracks_New; + newTree->SetBranchAddress("n_long_tracks",&n_long_tracks_New); + + int n_short_tracks_New; + newTree->SetBranchAddress("n_short_tracks",&n_short_tracks_New); + + +/* + cout << "Setting New Vtx Diff" << endl; + double vtxDiffNew[200]; + newTree->SetBranchAddress("event_vertex_time_diff",&vtxDiffNew); + + cout << "Setting New Recoil" << endl; + double newRecoil[200]; + newTree->SetBranchAddress("recoil_summed_energy",&newRecoil); + + cout << "Setting New Recoil Non" << endl; + double newRecNon; + newTree->SetBranchAddress("recoil_energy_nonmuon_nonvtx100mm",&newRecNon); + + cout << "Setting New Recoil Vtx" << endl; + double newRecVtx; + newTree->SetBranchAddress("recoil_energy_nonmuon_vtx100mm",&newRecVtx); +*/ + double oldID; + oldTree->SetBranchAddress("eventID",&oldID); + int oldEntries = oldTree->GetEntries(); + TCanvas* c1 = new TCanvas(); + + for (int i=0; i < oldEntries; ++i){ + if (i%(oldEntries/100)==0) cout << i << "/" << oldEntries << endl; + oldTree->GetEntry(i); + if (oldID < 0) continue; +// if (oldRecoil[0]<=0) continue; + double ID = oldID; + + if (indexNew[ID] ){ + newTree->GetEntry(indexNew[ID]); + if (n_prongs_New - n_prongs_Old == 0.) h_passive_em_ID->Fill(passive_em_ID_New - passive_em_ID_Old); + h_n_prongs->Fill(n_prongs_New - n_prongs_Old); + h_n_long_tracks->Fill(n_long_tracks_New - n_long_tracks_Old); + h_n_short_tracks->Fill(n_short_tracks_New - n_short_tracks_Old); + //hCompareNHits->Fill(nHitsNew-nHitsOld); + //for (int j=0; jFill(vtxDiffNew[j]-vtxDiffOld[j]); +/* hCompareRecoil->Fill(100.0*(newRecoil[0]-oldRecoil[0])/oldRecoil[0]); + double oldRecAdded = oldRecNon + oldRecVtx; + double newRecAdded = newRecNon + newRecVtx; + if (oldRecAdded > 0) hCompareRecAdded->Fill(100.0*(newRecAdded-oldRecAdded)/oldRecAdded); + if (oldRecNon >0) hCompareRecNon->Fill(100.0*(newRecNon-oldRecNon)/oldRecNon); + if (oldRecVtx >0) hCompareRecVtx->Fill(100.0*(newRecVtx-oldRecVtx)/oldRecVtx); + h2DRecoil->Fill(oldRecoil[0],100.0*(newRecoil[0]-oldRecoil[0])/oldRecoil[0]); + if (oldRecNon > 0) h2DRecNon->Fill(oldRecNon,100.0*(newRecNon-oldRecNon)/oldRecNon); + if (oldRecVtx > 0) h2DRecVtx->Fill(oldRecVtx,100.0*(newRecVtx-oldRecVtx)/oldRecVtx);*/ + } + else continue; + } + h_n_prongs->Draw("HIST"); + c1->SetLogy(); + c1->Print("n_prongs_compare.png"); + + TCanvas* c4 = new TCanvas(); + h_passive_em_ID->Draw("HIST"); + c4->SetLogy(); + c4->Print("passive_em_ID.png"); + + TCanvas* c2 = new TCanvas(); + h_n_long_tracks->Draw("HIST"); + c2->SetLogy(); + c2->Print("n_long_tracks.png"); + + TCanvas* c3 = new TCanvas(); + h_n_short_tracks->Draw("HIST"); + c3->SetLogy(); + c3->Print("n_short_tracks.png"); + + + + cout << "DONE" << endl; +} diff --git a/studies/runBackgrounds.C b/studies/runBackgrounds.C index b2011ad..0731a23 100644 --- a/studies/runBackgrounds.C +++ b/studies/runBackgrounds.C @@ -21,7 +21,7 @@ class HadronVariable; // Loop //============================================================================== void LoopAndFillBackgrounds(const CCPi::MacroUtil& util, CVUniverse* universe, - std::vector& variables) { + std::vector& variables, std::vector& variables2D) { bool is_mc = true; bool is_truth = false; @@ -29,19 +29,26 @@ void LoopAndFillBackgrounds(const CCPi::MacroUtil& util, CVUniverse* universe, for(Long64_t i_event=0; i_event < util.GetMCEntries(); ++i_event) { //for(Long64_t i_event=0; i_event < 5000; ++i_event) { if (i_event%500000==0) std::cout << (i_event/1000) << "k " << std::endl; +// if (i_event == 100000) break; universe->SetEntry(i_event); CCPiEvent event(is_mc, is_truth, util.m_signal_definition, universe); bool is_w_sideband = false; - event.m_passes_cuts = PassesCuts(event, is_w_sideband); + PassesCutsInfo cuts_info = PassesCuts(event); + std::tie(event.m_passes_cuts, event.m_is_w_sideband, + event.m_passes_all_cuts_except_w, + event.m_reco_pion_candidate_idxs) = cuts_info.GetAll(); event.m_highest_energy_pion_idx = GetHighestEnergyPionCandidateIndex(event); + universe->SetPionCandidates(event.m_reco_pion_candidate_idxs); + event.m_weight = universe->GetWeight(); if (event.m_passes_cuts && !event.m_is_signal) { - ccpi_event::FillStackedHists(event, variables); +// ccpi_event::FillStackedHists(event, variables); + ccpi_event::FillStackedHists2D(event, variables2D); } } // events std::cout << "*** Done ***\n\n"; } - +/* // Plot void PlotAllBackgrounds(Variable* v, const CCPi::MacroUtil& util) { std::string tag; @@ -87,18 +94,30 @@ void PlotAllBackgrounds(Variable* v, const CCPi::MacroUtil& util) { PlotBackground(v, v->m_hists.m_selection_data, v->GetStackArray(kB_HighW), data_pot, util.m_mc_pot, util.m_signal_definition, "WBG", ymax, draw_arrow); +}*/ + +void SavingStacked(TFile& fout, TObjArray plotsArray, std::string var, + std::string type) { + int size = plotsArray.GetEntries(); + for (int i = 0; i < size; ++i) { + fout.cd(); + TObject* obj = + plotsArray.At(i)->Clone(Form("%s_%s_%d", var.c_str(), type.c_str(), i)); + PlotUtils::MnvH2D* h = dynamic_cast(obj); + h->Write(); + fout.Flush(); + } } - //============================================================================== // Main //============================================================================== -void runBackgrounds(int signal_definition_int = 0, - const char* plist = "ME1L") { - +void runBackgrounds(int signal_definition_int = 0, const char* plist = "ME1A", + bool is_grid = false, std::string input_file = "", + int run = 0) { // INPUT TUPLES - std::string input_file = ""; - bool is_grid = false; +// std::string input_file = ""; +// bool is_grid = false; const bool is_mc = true; std::string mc_file_list; assert(!(is_grid && input_file.empty()) && @@ -108,6 +127,7 @@ void runBackgrounds(int signal_definition_int = 0, ? GetPlaylistFile(plist, is_mc /*, use_xrootd*/) : input_file; + TFile fout(Form("Background_Breakdown_%s_%d.root", plist, run), "RECREATE"); // Init macro utility object const std::string macro("runBackgrounds"); @@ -126,20 +146,40 @@ void runBackgrounds(int signal_definition_int = 0, std::vector variables = GetAnalysisVariables(util.m_signal_definition, do_truth_vars); + std::vector variables2D = + GetAnalysisVariables2D(util.m_signal_definition, do_truth_vars); + for (auto var : variables) { var->InitializeStackedHists(); var->InitializeDataHists(); } + for (auto var2D : variables2D) { + var2D->InitializeStackedHists(); + var2D->InitializeDataHists(); + } // Fill CVUniverse* cvu = util.m_error_bands.at("cv").at(0); - LoopAndFillBackgrounds(util, cvu, variables); + LoopAndFillBackgrounds(util, cvu, variables, variables2D); + // Plot + WritePOT(fout, true, util.m_mc_pot); + fout.cd(); // Plot - for (auto v : variables) - PlotAllBackgrounds(v, util); + for (auto v2D : variables2D){ + SavingStacked(fout, v2D->GetStackArray(kOtherInt), v2D->NameX() + "_vs_" + v2D->NameY(), "FSP"); + SavingStacked(fout, v2D->GetStackArray(kCCQE), v2D->NameX() + "_vs_" + v2D->NameY(), "Int"); + SavingStacked(fout, v2D->GetStackArray(kPim), v2D->NameX() + "_vs_" + v2D->NameY(), "Hadrons"); + SavingStacked(fout, v2D->GetStackArray(kOnePion), v2D->NameX() + "_vs_" + v2D->NameY(), "Npi"); + SavingStacked(fout, v2D->GetStackArray(kOnePi0), v2D->NameX() + "_vs_" + v2D->NameY(), "Npi0"); + SavingStacked(fout, v2D->GetStackArray(kOnePip), v2D->NameX() + "_vs_" + v2D->NameY(), "Npip"); + SavingStacked(fout, v2D->GetStackArray(kWSideband_Low), v2D->NameX() + "_vs_" + v2D->NameY(), "WSB"); + SavingStacked(fout, v2D->GetStackArray(kB_Meson), v2D->NameX() + "_vs_" + v2D->NameY(), "Msn"); + SavingStacked(fout, v2D->GetStackArray(kB_HighW), v2D->NameX() + "_vs_" + v2D->NameY(), "WBG"); +// if (!is_grid) PlotAllBackgrounds(v, util); + } } #endif // runBackgrounds_C diff --git a/studies/runMigMtxBinning.C b/studies/runMigMtxBinning.C new file mode 100644 index 0000000..f60595c --- /dev/null +++ b/studies/runMigMtxBinning.C @@ -0,0 +1,1212 @@ + +#ifndef runMigMtxBinning_C +#define runMigMtxBinning_C + +#include "PlotUtils/MnvH1D.h" +#include "PlotUtils/MnvH2D.h" +#include "TCanvas.h" +#include "TFile.h" +#include "TH2D.h" +#include "TMatrixD.h" +#include "TTree.h" +#ifndef MNVROOT6 +#define MNVROOT6 +#include "PlotUtils/MnvPlotter.h" +#endif // MNVROOT6 + +#include "includes/Binning.h" +#include "includes/CCPiEvent.h" +#include "includes/MacroUtil.h" +#include "includes/CVUniverse.h" +#include "includes/Cuts.h" +#include "includes/SignalDefinition.h" +#include "includes/Variable.h" +#include "includes/Variable2D.h" +#include "includes/common_functions.h" +#include "../xsec/makeCrossSectionMCInputs.C" // GetAnalysisVariables +#include "../xsec/plotting_functions.h" +#include "../xsec/plotting_functions2D.h" + +typedef std::vector> Matrix; + + +//============================================================================== +// Loop and fill Tree with true and false points +//============================================================================== +void Loop(const CCPi::MacroUtil& util, CVUniverse* universe, + const EDataMCTruth& type, + std::vector& variables2D, + std::string fName, + std::string treeName, std::string xvar, std::string yvar){ + TFile f(Form("%s.root",fName.c_str()),"recreate"); + typedef struct {Double_t vxt, vxr, vyt, vyr;} POINT; + POINT point; + Double_t pntpmuthetamu[4]; + Double_t pntptmutpi[4]; + Double_t pntpzmuptmu[4]; + Double_t pnttpipmu[4]; + Double_t pnttpithetapi[4]; + TTree tree(treeName.c_str(), "Tree with the MigMtx points"); + tree.Branch("pmu_vs_thetamu_deg", &pntpmuthetamu, "pntpmuthetamu[4]/D"); + tree.Branch("ptmu_vs_tpi", &pntptmutpi, "pntptmutpi[4]/D"); + tree.Branch("pzmu_vs_ptmu", &pntpzmuptmu, "pntpzmuptmu[4]/D"); + tree.Branch("tpi_vs_pmu", &pnttpipmu, "pnttpipmu[4]/D"); + tree.Branch("tpi_vs_thetapi_deg", &pnttpithetapi, "pnttpithetapi[4]/D"); + + bool is_mc = true, is_truth = false; + Long64_t n_entries = util.GetMCEntries(); + for (Long64_t i_event = 0; i_event < n_entries; ++i_event) { + if (i_event % (n_entries / 10) == 0) + std::cout << (i_event / 1000) << "k " << std::endl; + universe->SetEntry(i_event); +// if (i_event == 4000) break; + CCPiEvent event(is_mc, is_truth, util.m_signal_definition, universe); + + PassesCutsInfo cuts_info = PassesCuts(event); + std::tie(event.m_passes_cuts, event.m_is_w_sideband, event.m_passes_all_cuts_except_w, event.m_reco_pion_candidate_idxs) = cuts_info.GetAll(); + event.m_highest_energy_pion_idx = GetHighestEnergyPionCandidateIndex(event); + + universe->SetPionCandidates(event.m_reco_pion_candidate_idxs); + + event.m_weight = universe->GetWeight(); + + if (event.m_is_signal && event.m_passes_cuts) { +// std::cout << "simon\n"; + //for (auto var2D : variables2D){ +// if (var2D->m_is_true) continue; + Variable2D* reco_pmuthetamu = GetVar2D(variables2D, "pmu", "thetamu_deg"); + Variable2D* true_pmuthetamu = GetVar2D(variables2D, "pmu_true", "thetamu_deg_true"); + if (true_pmuthetamu == 0) continue; + Variable2D* reco_pzmuptmu = GetVar2D(variables2D, "pzmu", "ptmu"); + Variable2D* true_pzmuptmu = GetVar2D(variables2D, "pzmu_true", "ptmu_true"); + if (true_pzmuptmu == 0) continue; + Variable2D* reco_tpithetapi = GetVar2D(variables2D, "tpi", "thetapi_deg"); + Variable2D* true_tpithetapi = GetVar2D(variables2D, "tpi_true", "thetapi_deg_true"); + if (true_tpithetapi == 0) continue; + RecoPionIdx reco_idx = event.m_highest_energy_pion_idx; + TruePionIdx true_idx = event.m_universe->GetHighestEnergyTruePionIndex(); + + double reco_fill_pmu = reco_pmuthetamu->GetValueX(*event.m_universe, reco_idx); + double reco_fill_thetamu = reco_pmuthetamu->GetValueY(*event.m_universe, reco_idx); + double reco_fill_ptmu = reco_pzmuptmu->GetValueY(*event.m_universe, reco_idx); + double reco_fill_pzmu = reco_pzmuptmu->GetValueX(*event.m_universe, reco_idx); + double reco_fill_tpi = reco_tpithetapi->GetValueY(*event.m_universe, reco_idx); + double reco_fill_thetapi = reco_tpithetapi->GetValueY(*event.m_universe, reco_idx); + + double true_fill_pmu = true_pmuthetamu->GetValueX(*event.m_universe, true_idx); + double true_fill_thetamu = true_pmuthetamu->GetValueY(*event.m_universe, true_idx); + double true_fill_ptmu = true_pzmuptmu->GetValueY(*event.m_universe, true_idx); + double true_fill_pzmu = true_pzmuptmu->GetValueX(*event.m_universe, true_idx); + double true_fill_tpi = true_tpithetapi->GetValueY(*event.m_universe, true_idx); + double true_fill_thetapi = true_tpithetapi->GetValueY(*event.m_universe, true_idx); + pntpmuthetamu[0] = true_fill_pmu*event.m_weight; + pntpmuthetamu[1] = reco_fill_pmu*event.m_weight; + pntpmuthetamu[2] = true_fill_thetamu*event.m_weight; + pntpmuthetamu[3] = reco_fill_thetamu*event.m_weight; + + pntptmutpi[0] = true_fill_ptmu*event.m_weight; + pntptmutpi[1] = reco_fill_ptmu*event.m_weight; + pntptmutpi[2] = true_fill_tpi*event.m_weight; + pntptmutpi[3] = reco_fill_tpi*event.m_weight; + + pntpzmuptmu[0] = true_fill_pzmu*event.m_weight; + pntpzmuptmu[1] = reco_fill_pzmu*event.m_weight; + pntpzmuptmu[2] = true_fill_ptmu*event.m_weight; + pntpzmuptmu[3] = reco_fill_ptmu*event.m_weight; + + pnttpipmu[0] = true_fill_tpi*event.m_weight; + pnttpipmu[1] = reco_fill_tpi*event.m_weight; + pnttpipmu[2] = true_fill_pmu*event.m_weight; + pnttpipmu[3] = reco_fill_pmu*event.m_weight; + + pnttpithetapi[0] = true_fill_tpi*event.m_weight; + pnttpithetapi[1] = reco_fill_tpi*event.m_weight; + pnttpithetapi[2] = true_fill_thetapi*event.m_weight; + pnttpithetapi[3] = reco_fill_thetapi*event.m_weight; + // std::cout << pnt[0] << " " << pnt[1] << " " << pnt[2] << " " << pnt[3] << "\n"; + tree.Fill(); + //} + } + + } // events + f.cd(); + tree.Write(); +} + +void LoopforTrueEvents(std::string MigFileName, std::string TreeName, std::string tag, + int NBinsx, int NBinsy, + TArrayD binedgesx, TArrayD binedgesy){ + + TFile *MigFile = new TFile(Form("%s.root", MigFileName.c_str()),"update"); + TTree *MigTree = (TTree*)MigFile->Get(TreeName.c_str()); + Int_t cord[3]; + Double_t pnt[4]; + TBranch *bTrueEvbin = MigTree->Branch(Form("TrueEventBinningLocation%s",tag.c_str()),&cord,"cord[3]/I"); + TBranch *MigVal = MigTree->GetBranch("pmu_vs_theta_mu"); + MigVal->SetAddress(&pnt); + + Long64_t nentries = MigTree->GetEntries(); + std::cout << "Entries = " << nentries << "\n"; + for (Long64_t entry = 0;entry < nentries; entry++){ + MigVal->GetEntry(entry); +// if (entry == 10) break; + int i, j, x, y; + for(i = 0; i < NBinsx; ++i){ + if (pnt[0] > binedgesx[i] && pnt[0] < binedgesx[i+1]){ + x = i + 1; + break; + } + } + for(j = 0; j < NBinsy; ++j){ + if (pnt[2] > binedgesy[j] && pnt[2] < binedgesy[j+1]){ + y = j + 1; + break; + } + } + cord[0] = entry; + cord[1] = x; + cord[2] = y; +// std::cout << cord[0] << " " << cord[1] << " " << cord[2] << "\n"; + bTrueEvbin->Fill(); + + } + MigFile->cd(); + MigTree->Write(); +} + +//template +std::vector byStaError(std::vector xbinedges, std::vector ybinedges, + int& xnbins, int& ynbins, Matrix& truemtrx, int x, int y, double nentries){ +// for (int i = 0; i <= ynbins; ++i){ +// std::cout << "que pinche pablo ybinedges = " << ybinedges[i] << "\n"; +// } + + double currval = nentries, val; + int xhigher, yhigher, z = 0; + std::vector NewBinning; + if (x > 0 && y > 0 && x < xnbins - 1 && y < ynbins - 1){ + for (int j = y - 1; j < y + 2; j++){ + for(int i = x - 1; i < x + 2; ++i){ + val = truemtrx[i][j]; + if (i == x && j == y) continue; + if (val == 0 ){ z++; continue;} + if (val >= currval) continue; + if (val <= currval){ + currval = val; + xhigher = i; + yhigher = j; + } + } + } + + if (xhigher < x){ xbinedges.erase(xbinedges.begin()+x); xnbins = xnbins -1;} + if (xhigher > x){ xbinedges.erase(xbinedges.begin()+x+1); xnbins = xnbins -1;} + if (yhigher < y){ ybinedges.erase(ybinedges.begin()+y); ynbins = ynbins -1;} + if (yhigher > y){ ybinedges.erase(ybinedges.begin()+y+1); ynbins = ynbins -1;} + if ((xhigher == x && yhigher == y) || z == 8){ + xbinedges.erase(xbinedges.begin()+x+1); + xbinedges.erase(xbinedges.begin()+x); + ybinedges.erase(ybinedges.begin()+y); + ybinedges.erase(ybinedges.begin()+y+1); + ynbins = ynbins -2; + xnbins = xnbins -2; + } + } + + else if (x == 0 && y == 0){ + for (int j = y; j < y + 2; j++){ + for(int i = x; i < x + 2; ++i){ + val = truemtrx[i][j]; + if (i == x && j == y) continue; + if (val == 0 ) { z++; continue;} + if (val >= currval) continue; + if (val <= currval){ + currval = val; + xhigher = i; + yhigher = j; + } + } + } + + if (xhigher > x){ xbinedges.erase(xbinedges.begin()+x+1); xnbins = xnbins -1;} + + if (yhigher > y){ ybinedges.erase(ybinedges.begin()+y+1); ynbins = ynbins -1;} + if ((xhigher == x && yhigher == y) || z == 3){ + xbinedges.erase(xbinedges.begin()+x+1); + ybinedges.erase(ybinedges.begin()+y+1); + ynbins = ynbins -1; + xnbins = xnbins -1; + } + } + + else if (x > 0 && y == 0 && x < xnbins - 1){ + for (int j = y; j < y + 2; j++){ + for(int i = x - 1; i < x + 2; ++i){ + val = truemtrx[i][j]; + if (i == x && j == y) continue; + if (val == 0 ) { z++; continue;} + if (val >= currval) continue; + if (val <= currval){ + currval = val; + xhigher = i; + yhigher = j; + } + } + } + + if (xhigher < x){ xbinedges.erase(xbinedges.begin()+x); xnbins = xnbins -1;} + if (xhigher > x){ xbinedges.erase(xbinedges.begin()+x+1); xnbins = xnbins -1;} + if (yhigher > y){ ybinedges.erase(ybinedges.begin()+y+1); ynbins = ynbins -1;} + if ((xhigher == x && yhigher == y) || z == 5){ + xbinedges.erase(xbinedges.begin()+x+1); + xbinedges.erase(xbinedges.begin()+x); + ybinedges.erase(ybinedges.begin()+y+1); + ynbins = ynbins -1; + xnbins = xnbins -2; + } + } + + else if (y == 0 && x == xnbins - 1){ + for (int j = y; j < y + 2; j++){ + for(int i = x - 1; i < x + 1; ++i){ + val = truemtrx[i][j]; + if (i == x && j == y) continue; + if (val == 0 ) { z++; continue;} + if (val >= currval) continue; + if (val <= currval){ + currval = val; + xhigher = i; + yhigher = j; + } + } + } + + if (xhigher < x){ xbinedges.erase(xbinedges.begin()+x); xnbins = xnbins -1;} + if (yhigher > y){ ybinedges.erase(ybinedges.begin()+y+1); ynbins = ynbins -1;} + if ((xhigher == x && yhigher == y) || z == 3){ + xbinedges.erase(xbinedges.begin()+x); + ybinedges.erase(ybinedges.begin()+y+1); + ynbins = ynbins -1; + xnbins = xnbins -1; + } + } + + else if ( y > 0 && x == xnbins - 1 && y < ynbins - 1){ + for (int j = y - 1; j < y + 2; j++){ + for(int i = x - 1; i < x + 1; ++i){ + val = truemtrx[i][j]; + if (i == x && j == y) continue; + if (val == 0 ) { z++; continue;} + if (val >= currval) continue; + if (val <= currval){ + currval = val; + xhigher = i; + yhigher = j; + } + } + } + if (xhigher < x){ xbinedges.erase(xbinedges.begin()+x); xnbins = xnbins -1;} + if (yhigher < y){ ybinedges.erase(ybinedges.begin()+y); ynbins = ynbins -1;} + if (yhigher > y){ ybinedges.erase(ybinedges.begin()+y+1); ynbins = ynbins -1;} + if ((xhigher == x && yhigher == y) || z == 5){ + xbinedges.erase(xbinedges.begin()+x); + ybinedges.erase(ybinedges.begin()+y); + ybinedges.erase(ybinedges.begin()+y+1); + ynbins = ynbins -2; + xnbins = xnbins -1; + } + } + + else if (x == xnbins - 1 && y == ynbins - 1){ + for (int j = y - 1; j < y + 1; j++){ + for(int i = x - 1; i < x + 1; ++i){ + val = truemtrx[i][j]; + if (i == x && j == y) continue; + if (val == 0 ) { z++; continue;} + if (val >= currval) continue; + if (val <= currval){ + currval = val; + xhigher = i; + yhigher = j; + } + } + } + + if (xhigher < x){ xbinedges.erase(xbinedges.begin()+x); xnbins = xnbins -1;} + if (yhigher < y){ ybinedges.erase(ybinedges.begin()+y); ynbins = ynbins -1;} + if ((xhigher == x && yhigher == y) || z == 3){ + xbinedges.erase(xbinedges.begin()+x); + ybinedges.erase(ybinedges.begin()+y); + ynbins = ynbins -1; + xnbins = xnbins -1; + } + } + + else if (x > 0 && x < xnbins - 1 && y == ynbins - 1){ + for (int j = y - 1; j < y + 1; j++){ + for(int i = x - 1; i < x + 2; ++i){ + val = truemtrx[i][j]; + if (i == x && j == y) continue; + if (val == 0 ) { z++; continue;} + if (val >= currval) continue; + if (val <= currval){ + currval = val; + xhigher = i; + yhigher = j; + } + } + } + + if (xhigher < x){ xbinedges.erase(xbinedges.begin()+x); xnbins = xnbins -1;} + if (xhigher > x){ xbinedges.erase(xbinedges.begin()+x+1); xnbins = xnbins -1;} + + if (yhigher < y){ ybinedges.erase(ybinedges.begin()+y); ynbins = ynbins -1;} + if ((xhigher == x && yhigher == y) || z == 5) { + xbinedges.erase(xbinedges.begin()+x+1); + xbinedges.erase(xbinedges.begin()+x); + ybinedges.erase(ybinedges.begin()+y); + ynbins = ynbins -1; + xnbins = xnbins -2; + } + } + + else if (x == 0 && y == ynbins - 1){ + for (int j = y - 1; j < y + 1; j++){ + for(int i = x; i < x + 2; ++i){ + val = truemtrx[i][j]; + if (i == x && j == y) continue; + if (val == 0 ) { z++; continue;} + if (val >= currval) continue; + if (val <= currval){ + currval = val; + xhigher = i; + yhigher = j; + } + } + } + + if (xhigher > x){ xbinedges.erase(xbinedges.begin()+x+1); xnbins = xnbins -1;} + + if (yhigher < y){ ybinedges.erase(ybinedges.begin()+y); ynbins = ynbins -1;} + if ((xhigher == x && yhigher == y) || z == 3){ + xbinedges.erase(xbinedges.begin()+x+1); + ybinedges.erase(ybinedges.begin()+y); + ynbins = ynbins -1; + xnbins = xnbins -1; + } + } + + else if (x == 0 && y > 0 && y < ynbins - 1){ + for (int j = y - 1; j < y + 2; j++){ + for(int i = x; i < x + 2; ++i){ + val = truemtrx[i][j]; + if (i == x && j == y) continue; + if (val == 0 ) { z++; continue;} + if (val >= currval) continue; + if (val <= currval){ + currval = val; + xhigher = i; + yhigher = j; + } + } + } +// for (int i = 0; i <= ynbins; ++i){ +// std::cout << "que pedro ybinedges = " << ybinedges[i] << "\n"; +// } + if (xhigher > x){ xbinedges.erase(xbinedges.begin()+x+1); xnbins = xnbins -1;} + if (yhigher < y){ ybinedges.erase(ybinedges.begin()+y); ynbins = ynbins -1;} + if (yhigher > y){ ybinedges.erase(ybinedges.begin()+y+1); ynbins = ynbins -1;} + if ((xhigher == x && yhigher == y) || z == 5){ + xbinedges.erase(xbinedges.begin()+x+1); + ybinedges.erase(ybinedges.begin()+y); + ybinedges.erase(ybinedges.begin()+y+1); + xnbins = xnbins -1; + ynbins = ynbins -2; + } +// for (int i = 0; i <= ynbins; ++i){ +// std::cout << "que pex ybinedges = " << ybinedges[i] << "\n"; +// } + } + else std::cerr << "Algo esta mal carnal AAAAAAAAAAAAAAAAAAAh!"; + +// std::cout << "" << xbinedges.size() << "\n"; + + for (int i = 0; i <= xnbins; ++i) + NewBinning.push_back(xbinedges[i]); + + for (int i = 0; i <= ynbins; ++i){ + NewBinning.push_back(ybinedges[i]); +// std::cout << "yxbinedges = " << ybinedges[i] << "\n"; + } + return NewBinning; + +} +//============================================================================== +// Main +//============================================================================== +void runMigMtxBinning(int signal_definition_int = 0, + std::string plist = "ME1L", bool is_grid = false, + std::string input_file = "", int run = 0) { + + // Macro Utility + std::string mc_file_list; + + assert(!(is_grid && input_file.empty()) && + "On the grid, infile must be specified."); + // const bool use_xrootd = false; + mc_file_list = input_file.empty() + ? GetPlaylistFile(plist, true /*, use_xrootd*/) + : input_file; + + const std::string macro("runMigMtxBinning"); + const bool do_truth = false, + do_systematics = false; + CCPi::MacroUtil util(signal_definition_int, mc_file_list, plist, do_truth, + is_grid, do_systematics); + util.PrintMacroConfiguration(macro); + + std::string xvar = "ptmu"; + std::string yvar = "tpi"; + std::string MigFileName ("Migration_AllVar_ALL_Weight"); +// std::string MigFileName (Form("Migration_%d",run)); + std::string TreeName = "Migration"; + std::string tag = ""; + + // Variables and their histograms + std::vector variables2D = + GetAnalysisVariables2D(util.m_signal_definition, true); + // Starting the Loop + CVUniverse* cvu = util.m_error_bands.at("cv").at(0); + if (is_grid) Loop(util, cvu, kMC, variables2D, MigFileName, TreeName, xvar, yvar); + else { + Variable2D* var = GetVar2D(variables2D, xvar, yvar); + TArrayD oldedgesx = CCPi::GetBinning(xvar), + oldedgesy = CCPi::GetBinning(yvar); + int NBinsx = var->NBinsX(), + NBinsy = var->NBinsY(); + + double xmin = oldedgesx[0], +// xmax = oldedgesx[NBinsx], + xmax = 5500., + ymin = oldedgesy[0], + ymax = oldedgesy[NBinsy]; + ymin = 9.5; + ymax = 20.; +// xmin = 8250; + + const double xstep = (xmax - xmin)/10, + ystep = (ymax - ymin)/10; + + std::vector xedges, yedges; + xedges.push_back(xmin); + xedges.push_back(xstep); + xedges.push_back(xmax); + yedges.push_back(ymin); + yedges.push_back(ystep); + yedges.push_back(ymax); + + int xbin = 0, + ybin = 0, + dxcount = 0, + dycount = 0; + + const double match = 0.5, + minerr = 0.05; + + + std::vector test; + for (int i = 0; i < 10; ++i) + test.push_back(i*2); + + test.erase(test.end()-2); + test.erase(test.begin()+3+1); + for(int i = 0; i < test.size(); i++) + std::cout << test[i] << " "; + std::cout << "\n"; + + + // Taking the tree with the reco and true points + TFile *f = new TFile(Form("%s.root", MigFileName.c_str()),"READ"); + TTree *T = (TTree*)f->Get(Form("%s%s",TreeName.c_str(),tag.c_str())); + + Double_t pnt[4]; + + TBranch *MigVal = T->GetBranch(Form("%s_vs_%s", xvar.c_str(), yvar.c_str())); + MigVal->SetAddress(&pnt); + + bool Rebinning = true; + bool allxrange = false; + bool allyrange = false; + int count = 0; + std::cout << "Entries = " << T->GetEntries() << "\n"; + Long64_t nentries = T->GetEntries(); + int counter =0; + + // ------------------------------------------------------ + // I'm developing a new algoritm to have a better binning + // ------------------------------------------------------ + + int xnbins = 8, ynbins = 4; + + const double xbinwidth = (xmax - xmin)/xnbins, + ybinwidth = (ymax - ymin)/ynbins; + + std::vector xbinedges; + std::vector ybinedges; + xbinedges = {0., 250., 350., 400., 500, 600, 8000., 2000., 2500.}; + ybinedges = {35., 100., 140., 180., 350.}; + xbinedges.push_back(xmin); + ybinedges.push_back(ymin); +/* for (int i = 1; i <= xnbins;i++){ + xbinedges.push_back(xbinedges[i-1] + xbinwidth); + } + for (int j = 1; j <= ynbins;j++){ + ybinedges.push_back(ybinedges[j-1] + ybinwidth); + }*/ + + double currselval, binval, currselvalm, binvalm; + int x, y, xm, ym, migFactor; + Matrix truemtrx( xnbins,vector(ynbins,0.)); + Matrix recomtrx(xnbins,vector(ynbins,0.)); + double goodrecomtrx [xnbins][ynbins]; + double badRecoCounter [xnbins][ynbins]; + double badReco [xnbins][ynbins][2]; + double Dx, Dy, medx, medy; + + while (Rebinning){ + + for (int j = 0; j < ynbins; j++){ + for(int i = 0; i < xnbins; ++i){ + truemtrx[i][j] = 0.; + recomtrx[i][j] = 0.; + goodrecomtrx[i][j] = 0.; + badRecoCounter[i][j] = 0.; + } + } + + for (int j = 0; j < ynbins; j++){ + for(int i = 0; i < xnbins; ++i){ + badReco [i][j][0] = 0; + badReco [i][j][1] = 0; + } + } + + for (Long64_t entry = 0; entry < nentries; ++entry){ + if (entry % 10000 == 0) + std::cout << (entry / 10000) << "k" << std::endl; + MigVal->GetEntry(entry); + //Getting the reco and true values for each event + double truex = pnt[0]; + double truey = pnt[2]; + double recox = pnt[1]; + double recoy = pnt[3]; + + for (int j = 0; j < ynbins; j++){ + for(int i = 0; i < xnbins; ++i){ + if (truex > xbinedges[i] && truex < xbinedges[i+1] && + truey > ybinedges[j] && truey < ybinedges[j+1]){ + truemtrx [i][j] = truemtrx [i][j] + 1.; + break; + } + } + } + + for (int j = 0; j < ynbins; j++){ + for(int i = 0; i < xnbins; ++i){ + if (recox > xbinedges[i] && recox < xbinedges[i+1] && + recoy > ybinedges[j] && recoy < ybinedges[j+1]){ + recomtrx [i][j] = recomtrx [i][j] + 1.; + break; + } + } + } + + for (int j = 0; j < ynbins; j++){ + for(int i = 0; i < xnbins; ++i){ + if (truex > xbinedges[i] && truex < xbinedges[i+1] && + truey > ybinedges[j] && truey < ybinedges[j+1]){ + medx = (xbinedges[i+1] - xbinedges[i])/2 + xbinedges[i]; + medy = (ybinedges[j+1] - ybinedges[j])/2 + ybinedges[j]; + if (recox > xbinedges[i] && recox < xbinedges[i+1] && + recoy > ybinedges[j] && recoy < ybinedges[j+1] ){ + goodrecomtrx [i][j] = goodrecomtrx [i][j] + 1; + break; + } + else { + Dx = recox - medx; + Dy = recoy - medy; + badReco [i][j][0] = badReco [i][j][0] + Dx; + badReco [i][j][1] = badReco [i][j][1] + Dy; + badRecoCounter[i][j] = badRecoCounter[i][j] + 1.; +/* if (j == 0) { + std::cout << i << ", "<< j << "\n"; + std::cout << "medx = " << medx << " medy = "<< medy << "\n"; + std::cout << "truex = " << truex << " truey = "<< truey << "\n"; + std::cout << "recox = " << recox << " recoy = "<< recoy << "\n"; + std::cout << "Dx = " << Dx << " Dy = "<< Dy << "\n"; + } + if (recoy < 0) std::cout << "Negative ptmu >:/ \n";*/ +/* if (recox < xbinedges[i]) + badReco [i][j][0] = badReco[i][j][0] - 1.; + if (recox > xbinedges[i+1]) + badReco [i][j][0] = badReco[i][j][0] + 1.; + if (recoy < ybinedges[j]) + badReco [i][j][1] = badReco[i][j][1] - 1.; + if (recoy > ybinedges[j+1]) + badReco [i][j][1] = badReco[i][j][1] + 1.;*/ + break; + } + } + } + } + }// End of loop for the the tree + + //found the smaller bin != to cero + + currselval = nentries; + x = 0; + y = 0; + xm = 0; + ym = 0; + migFactor = 1; + for (int j = 0; j < ynbins; j++){ + for(int i = 0; i < xnbins; ++i){ + // migFactor = goodrecomtrx[i][j]/truemtrx[i][j]; + binval = truemtrx[i][j] * migFactor; + if (binval == 0 ) continue; + if (binval >= currselval) continue; + if (binval <= currselval){ + currselval = binval; + x = i; + y = j; + } + } + } + for (int j = 0; j < ynbins; j++){ + for(int i = 0; i < xnbins; ++i){ + binvalm = goodrecomtrx[x][y]/truemtrx[i][j]; + if (binvalm == 0 ) continue; + if (binvalm >= currselvalm) continue; + if (binvalm <= currselvalm){ + currselvalm = binvalm; + xm = i; + ym = j; + } + } + } +/* + for(int j = 0; j < ynbins; j++){ + for(int i = 0; i < xnbins; i++){ + std::cout << truemtrx[i][j] << "\t"; + } + std::cout << "\n"; + } +*/ + bool isgoodreconstructed = false, isgoodstats = false; + double diagonal = goodrecomtrx[xm][ym]/truemtrx[xm][ym]; + double StatError = 1/sqrt(currselval); + + std::cout << "Truth Matrix \n"; + for(int j = 0; j < ynbins; j++){ + for(int i = 0; i < xnbins; i++){ + std::cout << truemtrx[i][j] << "\t"; + } + std::cout << "\n"; + } + std::cout << "Reconstructed Matrix \n"; + for(int j = 0; j < ynbins; j++){ + for(int i = 0; i < xnbins; i++){ + std::cout << recomtrx[i][j] << "\t"; + } + std::cout << "\n"; + } + std::cout << "Migration Matrix \n"; + for(int j = 0; j < ynbins; j++){ + for(int i = 0; i < xnbins; i++){ + std::cout << goodrecomtrx[i][j]/truemtrx[i][j] << " "; + } + std::cout << "\n"; + } + std::cout << "Truth Error Matrix \n"; + for(int j = 0; j < ynbins; j++){ + for(int i = 0; i < xnbins; i++){ + std::cout << 1/sqrt(truemtrx[i][j]) << " "; + } + std::cout << "\n"; + } + + std::cout << "Bad Reco \n"; + for(int j = 0; j < ynbins; j++){ + for(int i = 0; i < xnbins; i++){ +// std::cout << "(" << badReco [i][j][0]/(truemtrx[i][j]-goodrecomtrx[i][j]) << ","<< badReco [i][j][1]/(truemtrx[i][j]-goodrecomtrx[i][j]) << ")" << " "; + std::cout << "(" << badReco [i][j][0]/badRecoCounter[i][j] << ","<< badReco [i][j][1]/badRecoCounter[i][j] << ")" << " "; + } + std::cout << "\n"; + } + std::cout << "N xbins = "<< xnbins << " N y bins = " << ynbins << "\n"; + std::cout << "The smaller bin is " << x << "," << y << "\n"; + std::cout << "The value is " << currselval << "\n"; + +// for (int i = 0; i <= ynbins; ++i){ +// std::cout << "que pedro pinche pablo ybinedges = " << ybinedges[i] << "\n"; +// } + + std::cout << "X binning edges "; + for (int i = 0; i < xnbins + 1; i++) + std::cout << xbinedges[i] << "\t"; + std::cout << "\n Ybinning edges "; + for (int i = 0; i < ynbins + 1; i++) + std::cout << ybinedges[i] << "\t"; + std::cout << "\n"; + + if (diagonal >= match) isgoodreconstructed = true; + if (StatError <= minerr) isgoodstats = true; + if (isgoodreconstructed && isgoodstats )Rebinning = false; + else if (!isgoodstats){ +// std::vector newBins = byStaError(xbinedges, ybinedges, xnbins, ynbins, truemtrx, +// x,y, (double)nentries); +// if (xnbins < xbinedges.size()-1) xbinedges.erase(xbinedges.begin()); +// if (ynbins < ybinedges.size()-1) ybinedges.erase(ybinedges.begin()); + +// std::cout << "NewBins size = " << newBins.size() << "\n"; +// for (int i = 0; i < newBins.size(); ++i) +// std::cout << "NewBins = " << newBins[i] << "\n"; +/* +// std::cout << "xnbins = " << xnbins << "\n"; + for (int i = 0; i <= xnbins ; ++i){ + xbinedges[i] = newBins [i]; +// std::cout << "xbinedges = " << xbinedges[i] << "\n"; + } + +// std::cout << "xnbins = " << xnbins << "\n"; + for (int i = 0; i <= ynbins; ++i){ + ybinedges[i] = newBins [i+xnbins+1]; +// std::cout << "yxbinedges = " << ybinedges[i] << "\n"; + }*/ + + double currval = nentries, val; + int xhigher, yhigher; + if (x > 0 && y > 0 && x < xnbins - 1 && y < ynbins - 1){ + for (int j = y - 1; j < y + 2; j++){ + for(int i = x - 1; i < x + 2; ++i){ + val = truemtrx[i][j]; + if (i == x && j == y) continue; + if (val == 0 ) continue; + if (val >= currval) continue; + if (val <= currval){ + currval = val; + xhigher = i; + yhigher = j; + } + } + } + + if (xhigher < x){ xbinedges.erase(xbinedges.begin()+x); xnbins = xnbins -1;} + if (xhigher > x){ xbinedges.erase(xbinedges.begin()+x+1); xnbins = xnbins -1;} + if (yhigher < y){ ybinedges.erase(ybinedges.begin()+y); ynbins = ynbins -1;} + if (yhigher > y){ ybinedges.erase(ybinedges.begin()+y+1); ynbins = ynbins -1;} + if (xhigher == x && yhigher == y){ + xbinedges.erase(xbinedges.begin()+x+1); + xbinedges.erase(xbinedges.begin()+x); + ybinedges.erase(ybinedges.begin()+y); + ybinedges.erase(ybinedges.begin()+y+1); + ynbins = ynbins -2; + xnbins = xnbins -2; + } + } + + else if (x == 0 && y == 0){ + for (int j = y; j < y + 2; j++){ + for(int i = x; i < x + 2; ++i){ + val = truemtrx[i][j]; + if (i == x && j == y) continue; + if (val == 0 ) continue; + if (val >= currval) continue; + if (val <= currval){ + currval = val; + xhigher = i; + yhigher = j; + } + } + } + + if (xhigher > x){ xbinedges.erase(xbinedges.begin()+x+1); xnbins = xnbins -1;} + + if (yhigher > y){ ybinedges.erase(ybinedges.begin()+y+1); ynbins = ynbins -1;} + if (xhigher == x && yhigher == y){ + xbinedges.erase(xbinedges.begin()+x+1); + ybinedges.erase(ybinedges.begin()+y+1); + ynbins = ynbins -1; + xnbins = xnbins -1; + } + } + + else if (x > 0 && y == 0 && x < xnbins - 1){ + for (int j = y; j < y + 2; j++){ + for(int i = x - 1; i < x + 2; ++i){ + val = truemtrx[i][j]; + if (i == x && j == y) continue; + if (val == 0 ) continue; + if (val >= currval) continue; + if (val <= currval){ + currval = val; + xhigher = i; + yhigher = j; + } + } + } + + if (xhigher < x){ xbinedges.erase(xbinedges.begin()+x); xnbins = xnbins -1;} + if (xhigher > x){ xbinedges.erase(xbinedges.begin()+x+1); xnbins = xnbins -1;} + if (yhigher > y){ ybinedges.erase(ybinedges.begin()+y+1); ynbins = ynbins -1;} + if (xhigher == x && yhigher == y){ + xbinedges.erase(xbinedges.begin()+x+1); + xbinedges.erase(xbinedges.begin()+x); + ybinedges.erase(ybinedges.begin()+y+1); + ynbins = ynbins -1; + xnbins = xnbins -2; + } + } + + else if (y == 0 && x == xnbins - 1){ + for (int j = y; j < y + 2; j++){ + for(int i = x - 1; i < x + 1; ++i){ + val = truemtrx[i][j]; + if (i == x && j == y) continue; + if (val == 0 ) continue; + if (val >= currval) continue; + if (val <= currval){ + currval = val; + xhigher = i; + yhigher = j; + } + } + } + + if (xhigher < x){ xbinedges.erase(xbinedges.begin()+x); xnbins = xnbins -1;} + if (yhigher > y){ ybinedges.erase(ybinedges.begin()+y+1); ynbins = ynbins -1;} + if (xhigher == x && yhigher == y){ + xbinedges.erase(xbinedges.begin()+x); + ybinedges.erase(ybinedges.begin()+y+1); + ynbins = ynbins -1; + xnbins = xnbins -1; + } + } + + else if ( y > 0 && x == xnbins - 1 && y < ynbins - 1){ + for (int j = y - 1; j < y + 2; j++){ + for(int i = x - 1; i < x + 1; ++i){ + val = truemtrx[i][j]; + if (i == x && j == y) continue; + if (val == 0 ) continue; + if (val >= currval) continue; + if (val <= currval){ + currval = val; + xhigher = i; + yhigher = j; + } + } + } + std::cout << "Que pex Xh = " << xhigher << " Yh = " << yhigher << " X = " << x << " Y = " << y <<"\n"; + if (xhigher < x){ xbinedges.erase(xbinedges.begin()+x); xnbins = xnbins -1;} + if (yhigher < y){ ybinedges.erase(ybinedges.begin()+y); ynbins = ynbins -1;} + if (yhigher > y){ ybinedges.erase(ybinedges.begin()+y+1); ynbins = ynbins -1;} + if (xhigher == x && yhigher == y){ + xbinedges.erase(xbinedges.begin()+x); + ybinedges.erase(ybinedges.begin()+y); + ybinedges.erase(ybinedges.begin()+y+1); + ynbins = ynbins -2; + xnbins = xnbins -1; + } + } + + else if (x == xnbins - 1 && y == ynbins - 1){ + for (int j = y - 1; j < y + 1; j++){ + for(int i = x - 1; i < x + 1; ++i){ + val = truemtrx[i][j]; + if (i == x && j == y) continue; + if (val == 0 ) continue; + if (val >= currval) continue; + if (val <= currval){ + currval = val; + xhigher = i; + yhigher = j; + } + } + } + + if (xhigher < x){ xbinedges.erase(xbinedges.begin()+x); xnbins = xnbins -1;} + if (yhigher < y){ ybinedges.erase(ybinedges.begin()+y); ynbins = ynbins -1;} + if (xhigher == x && yhigher == y){ + xbinedges.erase(xbinedges.begin()+x); + ybinedges.erase(ybinedges.begin()+y); + ynbins = ynbins -1; + xnbins = xnbins -1; + } + } + + else if (x > 0 && x < xnbins - 1 && y == ynbins - 1){ + for (int j = y - 1; j < y + 1; j++){ + for(int i = x - 1; i < x + 2; ++i){ + val = truemtrx[i][j]; + if (i == x && j == y) continue; + if (val == 0 ) continue; + if (val >= currval) continue; + if (val <= currval){ + currval = val; + xhigher = i; + yhigher = j; + } + } + } + + if (xhigher < x){ xbinedges.erase(xbinedges.begin()+x); xnbins = xnbins -1;} + if (xhigher > x){ xbinedges.erase(xbinedges.begin()+x+1); xnbins = xnbins -1;} + + if (yhigher < y){ ybinedges.erase(ybinedges.begin()+y); ynbins = ynbins -1;} + if (xhigher == x && yhigher == y) { + xbinedges.erase(xbinedges.begin()+x+1); + xbinedges.erase(xbinedges.begin()+x); + ybinedges.erase(ybinedges.begin()+y); + ynbins = ynbins -1; + xnbins = xnbins -2; + } + } + + else if (x == 0 && y == ynbins - 1){ + for (int j = y - 1; j < y + 1; j++){ + for(int i = x; i < x + 2; ++i){ + val = truemtrx[i][j]; + if (i == x && j == y) continue; + if (val == 0 ) continue; + if (val >= currval) continue; + if (val <= currval){ + currval = val; + xhigher = i; + yhigher = j; + } + } + } + + if (xhigher > x){ xbinedges.erase(xbinedges.begin()+x+1); xnbins = xnbins -1;} + + if (yhigher < y){ ybinedges.erase(ybinedges.begin()+y); ynbins = ynbins -1;} + if (xhigher == x && yhigher == y){ + xbinedges.erase(xbinedges.begin()+x+1); + ybinedges.erase(ybinedges.begin()+y); + ynbins = ynbins -1; + xnbins = xnbins -1; + } + } + + else if (x == 0 && y > 0 && y < ynbins - 1){ + for (int j = y - 1; j < y + 2; j++){ + for(int i = x; i < x + 2; ++i){ + val = truemtrx[i][j]; + if (i == x && j == y) continue; + if (val == 0 ) continue; + if (val >= currval) continue; + if (val <= currval){ + currval = val; + xhigher = i; + yhigher = j; + } + } + } + + if (xhigher > x){ xbinedges.erase(xbinedges.begin()+x+1); xnbins = xnbins -1;} + + if (yhigher < y){ ybinedges.erase(ybinedges.begin()+y); ynbins = ynbins -1;} + if (yhigher > y){ ybinedges.erase(ybinedges.begin()+y+1); ynbins = ynbins -1;} + if (xhigher == x && yhigher == y){ + xbinedges.erase(xbinedges.begin()+x+1); + ybinedges.erase(ybinedges.begin()+y); + ybinedges.erase(ybinedges.begin()+y+1); + xnbins = xnbins -1; + ynbins = ynbins -2; + } + } + else std::cerr << "Algo esta mal carnal AAAAAAAAAAAAAAAAAAAh!"; + } + else Rebinning = false; + + + Rebinning = false; + } + + + for(int j = 0; j < ynbins; j++){ + for(int i = 0; i < xnbins; i++){ + std::cout << truemtrx[i][j] << "\t"; + } + std::cout << "\n"; + } + + + std::cout << "The smaller bin is " << x << "," << y << "\n"; + std::cout << "The value is " << currselval << "\n"; + + std::cout << "X binning edges "; + for (int i = 0; i < xnbins + 1; i++) + std::cout << xbinedges[i] << "\t"; + std::cout << "\n Ybinning edges "; + for (int i = 0; i < ynbins + 1; i++) + std::cout << ybinedges[i] << "\t"; + std::cout << "\n"; + }//End of !is_grid + +// Starting the Loop to satisfy the requerements +/* while (Rebinning){ + int xrecoutL = 0, + xrecoutR = 0, + yrecoutD = 0, + yrecoutU = 0, + goodReco = 0; + + dxcount = 0; + dycount = 0; + count = 0; + + // std::vector passedEvents; +// passedEvents.push_back(-1); + // Statiting the Loop for all the events + + for (Long64_t entry = 0; entry < nentries; ++entry){ + if (entry % 10000 == 0) + std::cout << (entry / 10000) << "k" << std::endl; +// if (passed) continue; + MigVal->GetEntry(entry); + //Getting the reco and true values for each event + double truex = pnt[0]; + double truey = pnt[2]; + double recox = pnt[1]; + double recoy = pnt[3]; + + if (truex < xedges[xbin] || truex > xedges[xbin + 1] || + truey < yedges[ybin] || truey > yedges[ybin + 1]){ + if (truex > (xedges[xbin + 1] + xstep) || truey > (yedges[ybin + 1] + ystep)){ + continue;} + else if (truex > xedges[xbin + 1] && truex < (xedges[xbin + 1] + xstep) && + truey > yedges[ybin] && truey < (yedges[ybin + 1] + ystep)){ + dxcount = dxcount + 1; + } + else if (truex > xedges[xbin] && truex < (xedges[xbin + 1] + xstep) && + truey > yedges[ybin + 1] && truey < (yedges[ybin + 1] + ystep)){ + dycount = dycount + 1; + } + } + +// passedEvents.push_back(entry); + count++; + if (recox > xedges[xbin] && recox < xedges[xbin + 1] && + recoy > yedges[ybin] && recoy < yedges[ybin + 1]) goodReco++; + else if (recox < xedges[xbin]) xrecoutL++; + else if (recox > xedges[xbin + 1]) xrecoutR++; + else if (recoy < yedges[ybin]) yrecoutD++; + else if (recoy > yedges[ybin + 1]) yrecoutU++; + else std::cerr << "Algo anda mal carnal\n"; + + } + + double currError = 1/sqrt((double)count); + double diagonal = (double)goodReco/(double)count; + bool metmtxcriteria = true; + bool meterrcriteria = true; + // we obtain if the migration matrix is goin to Left-Right, Down-Up + double xLR = (double)xrecoutR/(double)xrecoutL, + yDU = (double)yrecoutU/(double)yrecoutD; + if (currError > minerr) meterrcriteria = false; + if (diagonal < match) metmtxcriteria = false; + +// std::cout << "Count = " << count << " goodReco = " << goodReco << "\n"; + + if (metmtxcriteria && meterrcriteria){ + if (xedges[xbin + 1] == xmax && yedges[ybin + 1] == ymax){ + Rebinning = false; + } + else if (xedges[xbin + 1] < xmax){ + if (ybin == 0) { + xbin = xbin + 1; + xedges.push_back(xedges[xbin + 1]); + xedges[xbin + 1] = xedges[xbin] + xstep; + } + else { + xbin = xbin + 1; + allxrange = false; + } + } + else if (xedges[xbin + 1] == xmax){ + xbin = 0; + ybin = ybin + 1; + } + else std::cerr << "Algo raro pasa carnal, se cumplen los dos criterios"; + } + else { + if (allxrange && allyrange){ + std::cout << "Ultimo bin no optimizado :("; + Rebinning = false; + } + else if (allxrange){ + yedges[ybin + 1] = yedges[ybin + 1] + ystep; + } + else if (allyrange){ + xedges[xbin + 1] = xedges[xbin + 1] + xstep; + } + else if ((double)dxcount*xLR > (double)dycount*yDU){ + if (xmax <= xedges[xbin + 1] + xstep){ + xedges.erase(xedges.end()-2); + allxrange = true; + } + else { + xedges[xbin + 1] = xedges[xbin + 1] + xstep; + } + } + else if ((double)dxcount*xLR < (double)dycount*yDU){ + if (ymax <= yedges[xbin + 1] + ystep){ + yedges.erase(yedges.end()-2); + allyrange = true; + } + else { + yedges[ybin + 1] = yedges[ybin + 1] + ystep; + } + } + else { + if (ymax < yedges[xbin + 1] + ystep){ + yedges.erase(yedges.end()-2); + allyrange = true; + } + else if (xmax < xedges[xbin + 1] + xstep){ + xedges.erase(xedges.end()-2); + allxrange = true; + } + else { + xedges[xbin + 1] = xedges[xbin + 1] + xstep; + yedges[ybin + 1] = yedges[ybin + 1] + ystep; + } + } + + if(!allxrange || !allyrange){ + if (xmax <= xedges[xbin + 1] + xstep){ + xedges.erase(xedges.end()-2); + allxrange = true; + } + if (ymax < yedges[xbin + 1] + ystep){ + yedges.erase(yedges.end()-2); + allyrange = true; + } + } + + }// end it doesn't met a creteria + + if (counter == 3) Rebinning = false; + counter ++; + + } // end of while +*/ + + std::cout << "\n It's done \n"; + //============================================================================ +} + +#endif // runMigMtxBinning_C + diff --git a/xsec/binningStudy.C b/xsec/binningStudy.C index 45803c3..85bcaa3 100644 --- a/xsec/binningStudy.C +++ b/xsec/binningStudy.C @@ -11,6 +11,7 @@ #include "makeCrossSectionMCInputs.C" // GetAnalysisVariables #include "includes/MacroUtil.h" #include "plotting_functions.h" +#include "plotting_functions2D.h" #include "includes/Binning.h" //#include "includes/common_stuff.h" // SetBinVec @@ -29,7 +30,7 @@ void binningStudy(int signal_definition_int = 0) { // In and outfiles //TFile fin("rootfiles/MCXSecInputs_20190616_FineBins.root", "READ"); - TFile fin("MCXSecInputs_20220225.root", "READ"); + TFile fin("MCXSecInputs_20231001_ME1A_untrackedpion_15thetabin_noSys.root", "READ"); cout << "Reading input from " << fin.GetName() << endl; // Set up macro utility object -- which does the systematics for us @@ -44,9 +45,15 @@ void binningStudy(int signal_definition_int = 0) { const bool do_truth_vars = true; std::vector variables = GetAnalysisVariables(util.m_signal_definition, do_truth_vars); + std::vector variables2D = + GetAnalysisVariables2D(util.m_signal_definition, do_truth_vars); ContainerEraser::erase_if(variables, [](Variable* v) { return v->Name() == "wexp_fit"; }); + const bool do_frac_unc = true; + const bool include_stat = false; + const bool do_cov_area_norm = false; + for (auto var : variables) { if (var->m_is_true) continue; @@ -60,11 +67,8 @@ void binningStudy(int signal_definition_int = 0) { std::cout << "Plotting stuff\n"; - const bool do_frac_unc = true; - const bool include_stat = false; - const bool do_cov_area_norm = false; - EventSelectionPlotInfo plot_info(var, util.m_mc_pot, util.m_data_pot, + const Plotter plot_info(var, util.m_mc_pot, util.m_data_pot, do_frac_unc, do_cov_area_norm, include_stat, util.m_signal_definition); //PlotDataMCWithError(eff, nullptr, plot_info, "EffWError"); @@ -120,6 +124,55 @@ void binningStudy(int signal_definition_int = 0) { //PlotEfficiency_ErrorSummary(plot_info); } + for (auto var2D : variables2D) { + const EventSelectionPlotInfo2D plot_info2D( + var2D, util.m_mc_pot, util.m_data_pot, do_frac_unc, do_cov_area_norm, + include_stat, util.m_signal_definition); + var2D->LoadMCHistsFromFile(fin, util.m_error_bands); + if (!var2D->m_is_true){ + PlotUtils::MnvH2D* mig2D = + (PlotUtils::MnvH2D*)var2D->m_hists2D.m_migration.hist->Clone(uniq()); + int nbinsx = var2D->NBinsX(); + int xmtxbins = nbinsx + 2; + int nbinsy = var2D->NBinsY(); + int ymtxbinx = nbinsy + 2; + double sumreco, sumtrue; + int x, y; + for (int bin = 1; bin <= nbinsy; ++bin){ + PlotUtils::MnvH2D* migration_reco = + new PlotUtils::MnvH2D(Form("MigMtx_reco_%s_vs_%s_Bin%i", var2D->NameX().c_str(), + var2D->NameY().c_str(), bin), Form("%s_%s", var2D->NameX().c_str(), + var2D->NameY().c_str()), nbinsx, 0.0, (double)nbinsx, + nbinsx, 0.0, (double)nbinsx); + PlotUtils::MnvH2D* migration_true = + new PlotUtils::MnvH2D(Form("MigMtx_true_%s_vs_%s_Bin%i", var2D->NameX().c_str(), + var2D->NameY().c_str(), bin), Form("%s_%s", var2D->NameX().c_str(), + var2D->NameY().c_str()), nbinsx, 0.0, (double)nbinsx, + nbinsx, 0.0, (double)nbinsx); + for (int j = 1; j <= nbinsx; ++j) { //it is going row by row in the + //internal matrix + y = bin*xmtxbins + j; + for (int i = 1; i <= nbinsx; ++i){ //It is going columb by columb + //in the internal matrix + x = bin*xmtxbins + i; + sumreco = 0; + sumtrue = 0; + for (int c = 0; c < nbinsy; ++c){ //It is used to sum the + //matrices vertically or horizontally + sumreco += mig2D->GetBinContent(x, y + c*xmtxbins); + sumtrue += mig2D->GetBinContent(x + c*xmtxbins, y); + } + migration_reco->SetBinContent(i, j, sumreco); + migration_true->SetBinContent(i, j, sumtrue); + } + } + // Here we print the resultant projected migration matrix + PlotMigration_AbsoluteBins(migration_reco, Form("reco_%s_vs_%s_Bin%i", var2D->NameX().c_str(),var2D->NameY().c_str(), bin)); + PlotMigration_AbsoluteBins(migration_true, Form("true_%s_vs_%s_Bin%i", var2D->NameX().c_str(),var2D->NameY().c_str(), bin)); + } + PlotMigration2D(plot_info2D, mig2D, var2D->NameX(), var2D->NameY()); + } + } //============================================================================ } diff --git a/xsec/crossSectionDataFromFile.C b/xsec/crossSectionDataFromFile.C index 780fbbe..94431e4 100644 --- a/xsec/crossSectionDataFromFile.C +++ b/xsec/crossSectionDataFromFile.C @@ -2,6 +2,7 @@ #define crossSectionDataFromFile_C #include "MinervaUnfold/MnvUnfold.h" +#include "MinervaUnfold/MnvResponse.h" #include "PlotUtils/ChainWrapper.h" #include "PlotUtils/FluxReweighter.h" #include "PlotUtils/MnvH1D.h" @@ -16,13 +17,15 @@ #include "includes/Systematics.h" // GetSystematicUniversesMap #include "includes/TruthCategories/Sidebands.h" // sidebands::kFitVarString, IsWSideband #include "includes/Variable.h" +#include "includes/Variable2D.h" #include "includes/WSidebandFitter.h" #include "includes/common_functions.h" // GetVar, CopyHists, WritePOT, erase_if, uniq -#include "makeCrossSectionMCInputs.C" // GetAnalysisVariables +#include "makeCrossSectionMCInputs.C" // GetAnalysisVariables #include "plotting_functions.h" void LoopAndFillData(const CCPi::MacroUtil& util, - std::vector variables) { + std::vector variables, + std::vector variables2D) { // Fill data distributions. const bool is_mc = false; const bool is_truth = false; @@ -30,13 +33,40 @@ void LoopAndFillData(const CCPi::MacroUtil& util, for (Long64_t i_event = 0; i_event < util.GetDataEntries(); ++i_event) { if (i_event % 500000 == 0) std::cout << (i_event / 1000) << "k " << std::endl; +// if (i_event == 20000) break; util.m_data_universe->SetEntry(i_event); CCPiEvent event(is_mc, is_truth, util.m_signal_definition, util.m_data_universe); + util.m_data_universe->SetTruth(false); // Check cuts // And extract whether this is w sideband and get candidate pion indices + LowRecoilPion::Cluster d; + LowRecoilPion::Cluster c(*util.m_data_universe,0); + LowRecoilPion::Michel m(*util.m_data_universe,0); + LowRecoilPion::MichelEvent trackless_michels; + + bool good_trackless_michels = LowRecoilPion::hasMichel>::hasMichelCut(*util.m_data_universe, trackless_michels); + good_trackless_michels = good_trackless_michels && LowRecoilPion::BestMichelDistance2D>::BestMichelDistance2DCut(*util.m_data_universe, trackless_michels); + good_trackless_michels = good_trackless_michels && LowRecoilPion::GetClosestMichel>::GetClosestMichelCut(*util.m_data_universe, trackless_michels); + + util.m_data_universe->SetVtxMichels(trackless_michels); + + bool pass = true; + pass = pass && util.m_data_universe->GetNMichels() == 1; + pass = pass && util.m_data_universe->GetTpiTrackless() < 350.; + pass = pass && util.m_data_universe->GetPmu() > 1500.; + pass = pass && util.m_data_universe->GetPmu() < 20000.; + pass = pass && util.m_data_universe->GetNIsoProngs() < 2; + pass = pass && util.m_data_universe->IsInHexagon(util.m_data_universe->GetVecElem("vtx", 0), util.m_data_universe->GetVecElem("vtx", 1), 850.); + pass = pass && util.m_data_universe->GetVecElem("vtx", 2) > 5990.; + pass = pass && util.m_data_universe->GetVecElem("vtx", 2) < 8340.; + pass = pass && util.m_data_universe->GetBool("isMinosMatchTrack"); + pass = pass && util.m_data_universe->GetDouble("MasterAnaDev_minos_trk_qp") < 0.0; + pass = pass && util.m_data_universe->GetThetamuDeg() < 20; + + PassesCutsInfo cuts_info = PassesCuts(event); // Set what we've learned to the event @@ -44,8 +74,32 @@ void LoopAndFillData(const CCPi::MacroUtil& util, event.m_passes_all_cuts_except_w, event.m_reco_pion_candidate_idxs) = cuts_info.GetAll(); event.m_highest_energy_pion_idx = GetHighestEnergyPionCandidateIndex(event); + // event.m_is_w_sideband = IsWSideband(event); + util.m_data_universe->SetVtxMichels(trackless_michels); + + if (true){ + event.m_passes_cuts = false; + event.m_is_w_sideband = false; + event.m_passes_all_cuts_except_w = false; + } + event.m_passes_trackless_cuts_except_w = false; + event.m_passes_trackless_sideband = false; + if (pass && util.m_data_universe->GetWexp() > 1400.){ + event.m_passes_trackless_cuts_except_w = true; + if (util.m_data_universe->GetWexp() > 1500.) event.m_passes_trackless_sideband = true; + pass = false; + } + if (false){ + good_trackless_michels = good_trackless_michels && false; + pass = pass && false; + } + event.m_passes_trackless_cuts = good_trackless_michels && pass; + event.m_passes_trackless_sideband = event.m_passes_trackless_sideband && good_trackless_michels; + event.m_passes_trackless_cuts_except_w = event.m_passes_trackless_cuts_except_w && good_trackless_michels; + util.m_data_universe->SetPassesTrakedTracklessCuts(event.m_passes_cuts || event.m_passes_all_cuts_except_w, event.m_passes_trackless_cuts || event.m_passes_trackless_cuts_except_w); ccpi_event::FillRecoEvent(event, variables); + ccpi_event::FillRecoEvent2D(event, variables2D); } std::cout << "*** Done Data ***\n\n"; } @@ -97,12 +151,9 @@ void DoWSidebandTune(CCPi::MacroUtil& util, Variable* fit_var, CVHW& loW_wgt, WSidebandFitter wsb_fitter = WSidebandFitter(*universe, fit_var->m_hists, util.m_pot_scale); wsb_fitter.Fit(); - std::cout << "low weight:" << (wsb_fitter.m_fit_scale)[kLoWParamId] - << "\n"; - std::cout << "mid weight:" << (wsb_fitter.m_fit_scale)[kMidWParamId] - << "\n"; - std::cout << "hi weight:" << (wsb_fitter.m_fit_scale)[kHiWParamId] - << "\n"; + std::cout << "low weight:" << (wsb_fitter.m_fit_scale)[kLoWParamId] << "\n"; + std::cout << "mid weight:" << (wsb_fitter.m_fit_scale)[kMidWParamId] << "\n"; + std::cout << "hi weight:" << (wsb_fitter.m_fit_scale)[kHiWParamId] << "\n"; // Store the outputs of the fits in HistWrappers loW_wgt.univHist(universe)->SetBinContent( 1, (wsb_fitter.m_fit_scale)[kLoWParamId]); @@ -172,6 +223,38 @@ void RebinFitParamHists(UniverseMap error_bands, const double nbins, hiW_wgt_rebin.SyncCVHistos(); } +void RebinFitParamHists2D(UniverseMap error_bands, const double nXbins, + const double nYbins, const CVHW& loW_wgt, + const CVHW& midW_wgt,const CVHW& hiW_wgt, + CVH2DW& loW_wgt_rebin, CVH2DW& midW_wgt_rebin, + CVH2DW& hiW_wgt_rebin) { + for (auto error_band : error_bands) { + std::vector universes = error_band.second; + for (auto universe : universes) { + // Get scales in this universe + const double loW_scale = loW_wgt.univHist(universe)->GetBinContent(1); + const double midW_scale = midW_wgt.univHist(universe)->GetBinContent(1); + const double hiW_scale = hiW_wgt.univHist(universe)->GetBinContent(1); + + // loop bins + for (int i = 1; i <= nXbins; ++i) { + for (int j = 1; j <= nYbins; ++j){ + // std::cout << loW_wgt_rebin.hist->GetXaxis()->GetBinLowEdge(i) << + // std::endl; + loW_wgt_rebin.univHist(universe)->SetBinContent(i, j, loW_scale); + midW_wgt_rebin.univHist(universe)->SetBinContent(i, j, midW_scale); + hiW_wgt_rebin.univHist(universe)->SetBinContent(i, j, hiW_scale); + } + } + } // universes + } // error bands + + // Be sure to drink your ovaltine!! + loW_wgt_rebin.SyncCVHistos(); + midW_wgt_rebin.SyncCVHistos(); + hiW_wgt_rebin.SyncCVHistos(); +} + // Apply the sideband tunes to the untuned BG // return tuned BG void ScaleBG(Variable* var, CCPi::MacroUtil& util, const CVHW& loW_wgt, @@ -241,6 +324,76 @@ void ScaleBG(Variable* var, CCPi::MacroUtil& util, const CVHW& loW_wgt, var->m_hists.m_tuned_bg = tuned_bg; } +void ScaleBG2D(Variable2D* var, CCPi::MacroUtil& util, const CVHW& loW_wgt, + const CVHW& midW_wgt, const CVHW& hiW_wgt) { + // REBIN FIT PARAMS FOR THIS VARIABLE + // temp HW's with same binning and error bands as variable + PlotUtils::Hist2DWrapper loW_wgt_rebin, midW_wgt_rebin, + hiW_wgt_rebin; + + InitializeHW2D( + var, Form("loW_fit_wgt_%s_vs_%s", var->NameX().c_str(), var->NameY().c_str()), + Form("W Sideband Fit Weight -- low W -- %s_vs_%s", var->NameX().c_str(), var->NameY().c_str()), + util.m_error_bands, loW_wgt_rebin); + InitializeHW2D( + var, Form("midW_fit_wgt_%s_vs_%s", var->NameX().c_str(), var->NameY().c_str()), + Form("W Sideband Fit Weight -- mid W -- %s_vs_%s", var->NameX().c_str(), var->NameY().c_str()), + util.m_error_bands, midW_wgt_rebin); + InitializeHW2D( + var, Form("hiW_fit_wgt_%s_vs_%s", var->NameX().c_str(), var->NameY().c_str()), + Form("W Sideband Fit Weight -- hi W -- %s_vs_%s", var->NameX().c_str(), var->NameY().c_str()), + util.m_error_bands, hiW_wgt_rebin); + + // For these MnvH1Ds ^ set each bin of each universe with the universe's fit + // weights + RebinFitParamHists2D(util.m_error_bands, var->NBinsX(), var->NBinsY(), loW_wgt, midW_wgt, + hiW_wgt, loW_wgt_rebin, midW_wgt_rebin, hiW_wgt_rebin); + + // APPLY TUNE TO EACH BG COMPONENT + // tuned bg component = clone (untuned component) + PlotUtils::MnvH2D* tuned_bg_loW = + (PlotUtils::MnvH2D*)var->m_hists2D.m_bg_loW.hist->Clone(uniq()); + PlotUtils::MnvH2D* tuned_bg_midW = + (PlotUtils::MnvH2D*)var->m_hists2D.m_bg_midW.hist->Clone(uniq()); + PlotUtils::MnvH2D* tuned_bg_hiW = + (PlotUtils::MnvH2D*)var->m_hists2D.m_bg_hiW.hist->Clone(uniq()); + + // tuned bg component = untuned component * component wgt + tuned_bg_loW->Multiply(tuned_bg_loW, loW_wgt_rebin.hist); + tuned_bg_midW->Multiply(tuned_bg_midW, midW_wgt_rebin.hist); + tuned_bg_hiW->Multiply(tuned_bg_hiW, hiW_wgt_rebin.hist); + + // SUM TUNED COMPONENTS + // total tuned bg = sum of tuned components + PlotUtils::MnvH2D* tuned_bg = (PlotUtils::MnvH2D*)tuned_bg_loW->Clone(uniq()); + tuned_bg->Add(tuned_bg_midW); + tuned_bg->Add(tuned_bg_hiW); + + // WRITE TUNED BG + tuned_bg_loW->Write(Form("tuned_bg_loW_%s_vs_%s", var->NameX().c_str(), var->NameY().c_str())); + tuned_bg_midW->Write(Form("tuned_bg_midW_%s_vs_%s", var->NameX().c_str(), var->NameY().c_str())); + tuned_bg_hiW->Write(Form("tuned_bg_hiW_%s_vs_%s", var->NameX().c_str(), var->NameY().c_str())); + tuned_bg->Write(Form("tuned_bg_%s_vs_%s", var->NameX().c_str(), var->NameY().c_str())); + + //// SCALE TUNED BG TO DATA + // tuned_bg_loW ->Scale(util.m_pot_scale); + // tuned_bg_midW->Scale(util.m_pot_scale); + // tuned_bg_hiW ->Scale(util.m_pot_scale); + // tuned_bg ->Scale(util.m_pot_scale); + + //// WRITE TUNED & SCALED BG + // tuned_bg_loW ->Write(Form("tuned_bg_loW_POTscaled_%s", + // var->Name().c_str())); + // tuned_bg_midW->Write(Form("tuned_bg_midW_POTscaled_%s", + // var->Name().c_str())); tuned_bg_hiW + // ->Write(Form("tuned_bg_hiW_POTscaled_%s", var->Name().c_str())); tuned_bg + // ->Write(Form("tuned_bg_POTscaled_%s", var->Name().c_str())); + + var->m_hists2D.m_tuned_bg = tuned_bg; +} + + + //============================================================================== // Main //============================================================================== @@ -252,10 +405,10 @@ void crossSectionDataFromFile(int signal_definition_int = 0, //============================================================================ // I/O - TFile fin("MCXSecInputs_0110_ME1A_0_2023-02-13.root", "READ"); + TFile fin("MCXSecInputs_20240619_ALL_tracked_Sys_p4.root", "READ"); std::cout << "Reading input from " << fin.GetName() << endl; - TFile fout("DataXSecInputs_2023-02-14.root", "RECREATE"); + TFile fout("DataXSecInputs_20240619_ALL_tracked_Sys_p4.root", "RECREATE"); std::cout << "Output file is " << fout.GetName() << "\n"; std::cout << "Copying all hists from fin to fout\n"; @@ -266,9 +419,9 @@ void crossSectionDataFromFile(int signal_definition_int = 0, // systematics const bool use_xrootd = true; std::string data_file_list = - GetPlaylistFile(plist, false, do_test_playlist, use_xrootd); + GetPlaylistFile(plist, false, use_xrootd); std::string mc_file_list = - GetPlaylistFile("ME1A", true, do_test_playlist, use_xrootd); + GetPlaylistFile("ME1A", true, use_xrootd); // Macro Utility bool do_truth = false, is_grid = false, do_systematics = true; @@ -282,12 +435,14 @@ void crossSectionDataFromFile(int signal_definition_int = 0, fout.WriteStreamerInfo(); // save the POT's in case we crash fout.Save(); // save the POT's in case we crash - util.PrintMacroConfiguration(macro); + util.PrintMacroConfiguration(util.m_name); // Variables and histograms -- load in MC hists from fin const bool do_truth_vars = true; std::vector variables = GetAnalysisVariables(util.m_signal_definition, do_truth_vars); + std::vector variables2D = + GetAnalysisVariables2D(util.m_signal_definition, do_truth_vars); { // remove unwanted variables ContainerEraser::erase_if( @@ -307,12 +462,16 @@ void crossSectionDataFromFile(int signal_definition_int = 0, v->LoadMCHistsFromFile(fin, util.m_error_bands); v->InitializeDataHists(); } - + for (auto v2D : variables2D) { + std::cout << "Loading hists for variable " << v2D->NameX() << "_vs_" << v2D->NameY() << "\n"; + v2D->LoadMCHistsFromFile(fin, util.m_error_bands); + v2D->InitializeDataHists(); + } //============================================================================ // Loop Data and Make Event Selection //============================================================================ - LoopAndFillData(util, variables); + LoopAndFillData(util, variables, variables2D); // Add empty error bands to data hists and fill their CVs for (auto v : variables) { @@ -321,7 +480,14 @@ void crossSectionDataFromFile(int signal_definition_int = 0, *v->m_hists.m_selection_mc.hist); } + for (auto v2D : variables2D) { + v2D->m_hists2D.m_selection_data->ClearAllErrorBands(); + v2D->m_hists2D.m_selection_data->AddMissingErrorBandsAndFillWithCV( + *v2D->m_hists2D.m_selection_mc.hist); + } + SaveDataHistsToFile(fout, variables); + SaveDataHistsToFile2D(fout, variables2D); //============================================================================ // Tune Sideband @@ -364,7 +530,7 @@ void crossSectionDataFromFile(int signal_definition_int = 0, if (var->m_is_true) continue; if (var->Name() == std::string("tpi_mbr")) continue; if (var->Name() == sidebands::kFitVarString) continue; - + const char* name = var->Name().c_str(); std::cout << "Calculating Cross Section for " << name << "\n"; @@ -408,10 +574,10 @@ void crossSectionDataFromFile(int signal_definition_int = 0, PlotUtils::MnvH1D* bg_sub_data = (PlotUtils::MnvH1D*)var->m_hists.m_bg_subbed_data->Clone(uniq()); int n_iterations = 4; - if (var->Name() == "tpi" || var->Name() == "wexp" || +/* if (var->Name() == "tpi" || var->Name() == "wexp" || var->Name() == "thetapi") n_iterations = 10; - +*/ mnv_unfold.UnfoldHisto(var->m_hists.m_unfolded, migration, bg_sub_data, RooUnfold::kBayes, n_iterations); @@ -617,6 +783,278 @@ void crossSectionDataFromFile(int signal_definition_int = 0, std::cout << " Done flux, targets, and POT normalization\n"; } // vars loop + + for (auto var2D : variables2D) { + // skip non-analysis variables + if (var2D->m_is_true) continue; + // if (var->Name() == sidebands::kFitVarString) continue; + + const char* nameX = var2D->NameX().c_str(); + const char* nameY = var2D->NameY().c_str(); + std::cout << "Calculating 2D Cross Section for " << nameX << " vs " << nameY << "\n"; + + // We'll need the true version of this variable later on. Get it now. + Variable2D* true_var2D = GetVar2D(variables2D, var2D->NameX() + std::string("_true"), var2D->NameY() + std::string("_true")); + + //============================================================================ + // Scale BG + // i.e. apply W sideband fit to the BG in the signal region. + //============================================================================ + ScaleBG2D(var2D, util, hw_loW_fit_wgt, hw_midW_fit_wgt, hw_hiW_fit_wgt); + + // POT scale the tuned BG + PlotUtils::MnvH2D* tuned_POTscaled_bg2D = + (PlotUtils::MnvH2D*)var2D->m_hists2D.m_tuned_bg->Clone(uniq()); + tuned_POTscaled_bg2D->Scale(util.m_pot_scale); + + std::cout << " Done BG Tune\n"; + + //============================================================================ + // Subtract BG 2D + //============================================================================ + // (Make sure empty error bands have been added to data hists) + var2D->m_hists2D.m_bg_subbed_data = + (PlotUtils::MnvH2D*)var2D->m_hists2D.m_selection_data->Clone(uniq()); + var2D->m_hists2D.m_bg_subbed_data->Add(tuned_POTscaled_bg2D, -1); + + // Write BG Sub Data + fout.cd(); + var2D->m_hists2D.m_bg_subbed_data->Write(Form("bg_subbed_data_%s_vs_%s", nameX, nameY)); + + std::cout << " Done BG Sub 2D\n"; + + //============================================================================ + // Unfold 2D + //============================================================================ + MinervaUnfold::MnvUnfold mnv_unfold2D ; + const char* name2D = Form("%s_vs_%s", nameX, nameY); + PlotUtils::MnvH2D* h_mc_reco = (PlotUtils::MnvH2D*)var2D->m_hists2D.m_migration_reco.hist->Clone(uniq()); + PlotUtils::MnvH2D* h_mc_true = (PlotUtils::MnvH2D*)var2D->m_hists2D.m_migration_true.hist->Clone(uniq()); + mnv_unfold2D.setUseBetterStatErrorCalc(true); + PlotUtils::MnvH2D* bg_sub_data2D = + (PlotUtils::MnvH2D*)var2D->m_hists2D.m_bg_subbed_data->Clone(uniq()); + PlotUtils::MnvH2D* h_migration = + (PlotUtils::MnvH2D*)var2D->m_hists2D.m_migration.hist->Clone(uniq()); + + int n_iterations = 4; + if (var2D->NameX() == "tpi" && var2D->NameY() == "pmu") + n_iterations = 5; + if (var2D->NameX() == "ptmu" && var2D->NameY() == "tpi") + n_iterations = 6; + if (var2D->NameX() == "pzmu" && var2D->NameY() == "ptmu") + n_iterations = 4; + + if (!mnv_unfold2D.UnfoldHisto2D(var2D->m_hists2D.m_unfolded, + h_migration, + h_mc_reco, + h_mc_true, + bg_sub_data2D, + n_iterations, + true)) + std::cout << "Algo no salio bien carnal \n"; + + + // copypasta + // Blurgh. We want the covariance matrix induced by the unfolding, + // but MnvUnfold will only give that back to us with a call to a + // different version of UnfoldHisto that only takes a TH1D, and + // not a MnvH1D (so we can't just combine it with the previous call) + TMatrixD unfolding_cov_matrix_orig_2D; + TH2D* unfolded_dummy_2D = + new TH2D(var2D->m_hists2D.m_unfolded->GetCVHistoWithStatError()); + TH2D* migration_dummy_2D = new TH2D(h_migration->GetCVHistoWithStatError()); + TH2D* bg_sub_data_dummy_2D = new TH2D(bg_sub_data2D->GetCVHistoWithStatError()); + mnv_unfold2D.UnfoldHisto2D(unfolded_dummy_2D, unfolding_cov_matrix_orig_2D, + h_migration, h_mc_reco, h_mc_true, + bg_sub_data_dummy_2D, n_iterations); + + // Add cov matrix to unfolded hist + var2D->m_hists2D.m_unfolded->PushCovMatrix( + Form("unfolding_cov_matrix_%s_vs_%s", nameX, nameY), unfolding_cov_matrix_orig_2D); + + // Write unfolded + fout.cd(); + var2D->m_hists2D.m_unfolded->Write(Form("unfolded_%s_vs_%s", nameX, nameY)); + std::cout << " Done Unfolding2D\n"; + + //============================================================================ + // Efficiency Correct 2D + //============================================================================ + // Calculate efficiency + + /* + Delete me + { // Somehow effnum and effden have 200 flux universes + MnvVertErrorBand *poppedFluxErrorBand = + true_var->m_hists.m_effnum.hist->PopVertErrorBand("Flux"); + std::vector fluxUniverses = poppedFluxErrorBand->GetHists(); + fluxUniverses.resize(100); + true_var->m_hists.m_effnum.hist->AddVertErrorBand("Flux",fluxUniverses); + } + { // Somehow effnum and effden have 200 flux universes + MnvVertErrorBand *poppedFluxErrorBand = + true_var->m_hists.m_effden.hist->PopVertErrorBand("Flux"); + std::vector fluxUniverses = poppedFluxErrorBand->GetHists(); + fluxUniverses.resize(100); + true_var->m_hists.m_effden.hist->AddVertErrorBand("Flux",fluxUniverses); + } + */ + + var2D->m_hists2D.m_efficiency = + (PlotUtils::MnvH2D*)true_var2D->m_hists2D.m_effnum.hist->Clone(uniq()); + var2D->m_hists2D.m_efficiency->Divide(true_var2D->m_hists2D.m_effnum.hist, + true_var2D->m_hists2D.m_effden.hist); + + // if(var->Name() == "ptmu") + // PrintUniverseContent(true_var->m_hists.m_effnum.hist); + // if(var->Name() == "ptmu") + // PrintUniverseContent(true_var->m_hists.m_effden.hist); + + PlotUtils::MnvH2D* h_efficiency_corrected_data = + (PlotUtils::MnvH2D*)var2D->m_hists2D.m_unfolded->Clone(uniq()); + // h_efficiency_corrected_data->ClearSysErrorMatrices(); // maybe we'll + // write a new matrix when we divide? NOPE doesn't work. + + // Efficiency correct + h_efficiency_corrected_data->Divide(var2D->m_hists2D.m_unfolded, + var2D->m_hists2D.m_efficiency); +/* + TMatrixD unfolding_cov_matrix_effcor = + h_efficiency_corrected_data->GetSysErrorMatrix( + Form("unfolding_cov_matrix_%s", name)); +*/ + { // Check to make sure the covariance matrix got divided correctly + // for (int i = 0; i < unfolding_cov_matrix_effcor.GetNcols(); ++i) { + // for (int j = 0; j < unfolding_cov_matrix_effcor.GetNrows(); ++j) { + // std::cout << unfolding_cov_matrix_effcor[j][i] - + // unfolding_cov_matrix_orig[j][i]; + // } + // std::cout << "\n"; + //} + } + + // Write efficiency and efficiency-corrected data + fout.cd(); + var2D->m_hists2D.m_efficiency->Write(Form("efficiency2D_%s_vs_%s", nameX, nameY)); + h_efficiency_corrected_data->Write( + Form("efficiency_corrected_data_2D_%s_vs_%s", nameX, nameY)); + + std::cout << " Done Efficiency Correcting 2D\n"; + + //============================================================================ + // Normalization -- integrated flux, targets, POT (and don't forget MC, + // too!) + //============================================================================ + // Init the normalization hist from the eff corr just to get the error bands + PlotUtils::MnvH2D* h_flux_normalization = + (PlotUtils::MnvH2D*)h_efficiency_corrected_data->Clone( + "flux_normalization"); + h_flux_normalization->ClearAllErrorBands(); + h_flux_normalization->Reset(); + + // Get the flux histo, to be integrated + static PlotUtils::FluxReweighter* frw = new PlotUtils::FluxReweighter( + 14, CCNuPionIncConsts::kUseNueConstraint, "minervame1D1M1NWeightedAve", + PlotUtils::FluxReweighter::gen2thin, + PlotUtils::FluxReweighter::g4numiv6, + CCNuPionIncConsts::kNFluxUniverses); + + fout.cd(); // FRW opens a new file and changes our current dir. + + h_flux_normalization = frw->GetIntegratedFluxReweighted( + 14, h_efficiency_corrected_data, 0., 100.); + + //{ // Truncate flux universes to 10!! + // MnvVertErrorBand *poppedFluxErrorBand = + // h_flux_normalization->PopVertErrorBand("Flux"); std::vector + // fluxUniverses = poppedFluxErrorBand->GetHists(); + // fluxUniverses.resize(10); + // h_flux_normalization->AddVertErrorBand("Flux",fluxUniverses); + //} + + { //// Truncate flux universes to 10!! + // MnvVertErrorBand *poppedFluxErrorBand = + // h_flux_normalization->PopVertErrorBand("Flux"); std::vector + // fluxUniverses = poppedFluxErrorBand->GetHists(); std::cout << "flux + // universes: " << fluxUniverses.size() << "\n"; + ////fluxUniverses.resize(10); + ////h_flux_normalization->AddVertErrorBand("Flux",fluxUniverses); + } + + //// remove redundant error bands + // h_flux_normalization->PopVertErrorBand("Flux_BeamFocus"); + // h_flux_normalization->PopVertErrorBand("ppfx1_Total"); + + // Convert flux units from nu/m^2/POT to nu/cm^2/POT + h_flux_normalization->Scale(1.0e-4); + + // Divide flux integral + PlotUtils::MnvH2D* h_cross_section = + (PlotUtils::MnvH2D*)h_efficiency_corrected_data->Clone(uniq()); + + h_cross_section->AddMissingErrorBandsAndFillWithCV(*h_flux_normalization); + + h_cross_section->Divide(h_cross_section, h_flux_normalization); + + // targets and POT norm + static const double apothem = 865.; + static const double upstream = 5900.; // ~module 25 plane 1 + static const double downstream = 8430.; // ~module 81 plane 1 + + double n_target_nucleons = + PlotUtils::TargetUtils::Get().GetTrackerNNucleons(upstream, downstream, + false, // isMC + apothem); + + std::cout << " flux_integral cv = " + << h_flux_normalization->GetBinContent(1) << "\n"; + std::cout << " N target nucleons = " << n_target_nucleons << "\n"; + std::cout << " data pot = " << util.m_data_pot << "\n"; + static const double data_scale = + 1.0 / (n_target_nucleons * util.m_data_pot); + h_cross_section->Scale(data_scale); + + // Write data cross section + fout.cd(); + h_cross_section->Write(Form("D_cross_section_%s_vs_%s", nameX, nameY)); + + // Begin MC normalization + PlotUtils::MnvH2D* h_mc_cross_section = + (PlotUtils::MnvH2D*)true_var2D->m_hists2D.m_effden.hist->Clone(uniq()); + + h_mc_cross_section->AddMissingErrorBandsAndFillWithCV( + *h_flux_normalization); + h_mc_cross_section->Divide(h_mc_cross_section, h_flux_normalization); + + std::cout << " mc pot = " << util.m_mc_pot << "\n"; + static const double mc_scale = 1.0 / (n_target_nucleons * util.m_mc_pot); + h_mc_cross_section->Scale(mc_scale); + + // Write mc cross section + fout.cd(); + h_mc_cross_section->Write(Form("D_mc_cross_section_%s_vs_%s", nameX, nameY)); + + // Set covariance matrix diagonal to zero + // copypasta + // Jeremy tells me that the covariance matrix has the diagonal + // errors on it, which are already included elsewhere, so we have to + // subtract them off before adding the unfolding covariance matrix + // back on + TMatrixD unfolding_cov_matrix = h_cross_section->GetSysErrorMatrix( + Form("2D_unfolding_cov_matrix_%s_vs_%s", nameX, nameY)); + for (int i = 0; i < unfolding_cov_matrix.GetNrows(); ++i) + unfolding_cov_matrix(i, i) = 0; + h_cross_section->PushCovMatrix(Form("unfolding_cov_matrix_%s_vs_%s", nameX, nameY), + unfolding_cov_matrix); + + // Write scaled covariance matrix + fout.cd(); + unfolding_cov_matrix.Write(Form("unfolding_cov_matrix_%s_vs_%s", nameX, nameY)); + + std::cout << " Done flux, targets, and POT normalization\n"; + + + }// End of loop 2D variables } // PlotUtils::MnvH1D* efficiency_numerator = diff --git a/xsec/makeCrossSectionMCInputs.C b/xsec/makeCrossSectionMCInputs.C index 85707b6..3f0d8b8 100644 --- a/xsec/makeCrossSectionMCInputs.C +++ b/xsec/makeCrossSectionMCInputs.C @@ -10,19 +10,30 @@ #include "includes/CVUniverse.h" #include "includes/Constants.h" #include "includes/Cuts.h" -#include "includes/HadronVariable.h" #include "includes/MacroUtil.h" #include "includes/SignalDefinition.h" #include "includes/TruthCategories/Sidebands.h" // sidebands::kFitVarString, IsWSideband +#include "includes/common_functions.h" // GetVar, WritePOT +#include "includes/utilities.h" + +#include "ccpion_common.h" // GetPlaylistFile +#include "includes/HadronVariable.h" +#include "includes/HadronVariable2D.h" +#include "includes/Variable2D.h" #include "includes/Variable.h" -#include "includes/common_functions.h" // GetVar, WritePOT +//class Variable; +//class Variable2D; +//class HadronVariable; +//class HadronVariable2D; //============================================================================== // Helper Functions //============================================================================== namespace make_xsec_mc_inputs { typedef Variable Var; +typedef Variable2D Var2D; typedef HadronVariable HVar; +typedef HadronVariable2D HVar2D; std::vector GetOnePiVariables(bool include_truth_vars = true) { const int nadphibins = 16; @@ -39,6 +50,16 @@ std::vector GetOnePiVariables(bool include_truth_vars = true) { new HVar("thetapi_deg", "#theta_{#pi}", "deg", CCPi::GetBinning("thetapi_deg"), &CVUniverse::GetThetapiDeg); + HVar* pimuAngle = + new HVar("pimuAngle", "p_{#pi}p_{#mu} angle", "deg", + CCPi::GetBinning("pimuAngle"), &CVUniverse::GetpimuAngle); + + HVar* PT = + new HVar("PT", "P^{T}", "MeV", + CCPi::GetBinning("PT"), &CVUniverse::GetPT); + HVar* ALR = new HVar("ALR", "ALR", "0cp,1L,2R", CCPi::GetBinning("ALR"), + &CVUniverse::GetALR); + Var* pmu = new Var("pmu", "p_{#mu}", "MeV", CCPi::GetBinning("pmu"), &CVUniverse::GetPmu); @@ -65,6 +86,18 @@ std::vector GetOnePiVariables(bool include_truth_vars = true) { Var* pzmu = new Var("pzmu", "p^{z}_{#mu}", "MeV", CCPi::GetBinning("pzmu"), &CVUniverse::GetPZmu); + HVar* cosadtheta = new HVar("cosadtheta", "cos(#theta_{Adler})", "", CCPi::GetBinning("cosadtheta"), + &CVUniverse::GetAdlerCosTheta); + + HVar* adphi = new HVar("adphi", "#phi_{Adler}", "rad", nadphibins, adphimin, adphimax, + &CVUniverse::GetAdlerPhi); + + Var* mehreen_tpi = new Var("mtpi", "Mehreen T_{#pi}", "MeV", CCPi::GetBinning("mtpi"), + &CVUniverse::GetTpiTrackless); + + Var* mehreen_thetapi_deg = new Var("mthetapi_deg", "Mehreen #theta_{#pi}", "deg", + CCPi::GetBinning("thetapi_deg"), &CVUniverse::GetThetapitracklessDeg); + // True Variables bool is_true = true; HVar* tpi_true = @@ -76,6 +109,9 @@ std::vector GetOnePiVariables(bool include_truth_vars = true) { thetapi_deg->m_hists.m_bins_array, &CVUniverse::GetThetapiTrueDeg, is_true); + HVar* ALR_true = new HVar("ALR", "ALR_True", ALR->m_units, ALR->m_hists.m_bins_array, + &CVUniverse::GetALRTrue, is_true); + Var* pmu_true = new Var("pmu_true", "p_{#mu} True", pmu->m_units, pmu->m_hists.m_bins_array, &CVUniverse::GetPmuTrue, is_true); @@ -98,41 +134,196 @@ std::vector GetOnePiVariables(bool include_truth_vars = true) { wexp->m_hists.m_bins_array, &CVUniverse::GetWexpTrue, is_true); Var* ptmu_true = - new Var("ptmu_true", "pt_{#mu} True", "MeV", ptmu->m_hists.m_bins_array, + new Var("ptmu_true", "p^{t}_{#mu} True", "MeV", ptmu->m_hists.m_bins_array, &CVUniverse::GetPTmuTrue, is_true); Var* pzmu_true = - new Var("pzmu_true", "pz_{#mu} True", "MeV", pzmu->m_hists.m_bins_array, + new Var("pzmu_true", "p^{z}_{#mu} True", "MeV", pzmu->m_hists.m_bins_array, &CVUniverse::GetPZmuTrue, is_true); + HVar* cosadtheta_true = new HVar("cosadtheta_true", "cos(#theta_{Adler}) True", "", cosadtheta->m_hists.m_bins_array, + &CVUniverse::GetAdlerCosThetaTrue, is_true); + + HVar* adphi_true = new HVar("adphi_true", "#phi_{Adler} True", "rad", nadphibins, adphimin, adphimax, + &CVUniverse::GetAdlerPhiTrue, is_true); + + HVar* pimuAngle_true = + new HVar("pimuAngle_true", "p_{#pi}p_{#mu} angle True", "deg", + pimuAngle->m_hists.m_bins_array, &CVUniverse::GetpimuAngleTrue, is_true); + + HVar* PT_true = + new HVar("PT_true", "P^{T} True", "MeV", + PT->m_hists.m_bins_array, &CVUniverse::GetPTTrue, is_true); + + Var* mehreen_tpi_true = + new Var("mtpi_true", "Mehreen T_{#pi} True", "MeV", + mehreen_tpi->m_hists.m_bins_array, &CVUniverse::GetTrueTpi, + is_true); + + Var* mehreen_thetapi_deg_true = + new Var("mthetapi_deg_true", "Mehreen #theta_{#pi} True", "deg", + mehreen_thetapi_deg->m_hists.m_bins_array, &CVUniverse::GetThetapitracklessTrueDeg, + is_true); + // Ehad variables Var* ehad = new Var("ehad", "ehad", "MeV", CCPi::GetBinning("ehad"), &CVUniverse::GetEhad); - Var* ehad_true = - new Var("ehad_true", "ehad True", "MeV", ehad->m_hists.m_bins_array, - &CVUniverse::GetEhadTrue); + Var* ehad_true = new Var("ehad_true", "ehad True", "MeV", ehad->m_hists.m_bins_array, + &CVUniverse::GetEhadTrue); ehad_true->m_is_true = true; - std::vector variables = {tpi, tpi_mbr, thetapi_deg, pmu, - thetamu_deg, enu, q2, wexp, - wexp_fit, ptmu, pzmu, ehad}; + std::vector variables = {tpi, /* tpi_mbr, thetapi_deg,*/ pmu, + thetamu_deg, enu,/* q2, wexp,*/ + wexp_fit, ptmu, pzmu/* ehad,*/ + /* cosadtheta, adphi, pimuAngle, PT, ALR*/}; if (include_truth_vars) { variables.push_back(tpi_true); - variables.push_back(thetapi_deg_true); +// variables.push_back(thetapi_deg_true); variables.push_back(pmu_true); variables.push_back(thetamu_deg_true); variables.push_back(enu_true); - variables.push_back(q2_true); +// variables.push_back(q2_true); variables.push_back(wexp_true); variables.push_back(ptmu_true); variables.push_back(pzmu_true); - variables.push_back(ehad_true); +// variables.push_back(ehad_true); +// variables.push_back(cosadtheta_true); +// variables.push_back(adphi_true); +// variables.push_back(pimuAngle_true); +// variables.push_back(PT_true); + //variables.push_back(ALR_true); } + + return variables; +} +std::vector GetOnePiHadronVariables(bool include_truth_vars = true){ + // Reco Variables + HVar* tpi = new HVar("tpi", "T_{#pi}", "MeV", CCPi::GetBinning("tpi"), + &CVUniverse::GetTpi); + // True Variables + bool is_true = true; + HVar* tpi_true = + new HVar("tpi_true", "T_{#pi} True", tpi->m_units, + tpi->m_hists.m_bins_array, &CVUniverse::GetTpiTrue, is_true); + std::vector variables = {tpi}; + + if (include_truth_vars) { + variables.push_back(tpi_true); + } return variables; } +std::vector GetOnePiVariables2D(bool include_truth_vars = true){ + + std::vector var1D = GetOnePiVariables(true); + std::vector Hvar1D = GetOnePiHadronVariables(true); + bool is_true = true; + // Reco 2D Variables + Var2D* pzmu_pTmu = new Var2D(var1D[6], var1D[5]); + Var2D* pTmu_pzmu = new Var2D(var1D[5], var1D[6]); +// Var2D* pmu_thetamu = new Var2D(var1D[1], var1D[2]); + + HVar2D* tpi_thetapi_deg = new HVar2D("tpi", "thetapi_deg", "T_{#pi}", + "#theta_{#pi}", "MeV", "deg", + CCPi::GetBinning("tpi"), CCPi::GetBinning("thetapi_deg"), + &CVUniverse::GetTpi, &CVUniverse::GetThetapiDeg); + HVar2D* thetapi_deg_tpi = new HVar2D("thetapi_deg", "tpi", "#theta_{#pi}","T_{#pi}", + "deg", "MeV", + CCPi::GetBinning("thetapi_deg"), CCPi::GetBinning("tpi"), + &CVUniverse::GetThetapiDeg, &CVUniverse::GetTpi); + + HVar2D* tpi_pmu = new HVar2D("tpi", "pmu", "T_{#pi}", "p_{#mu}", "MeV", "MeV", + CCPi::GetBinning("tpi"), CCPi::GetBinning("pmu_with_tpi"), + &CVUniverse::GetTpi, &CVUniverse::GetPmu); + HVar2D* pmu_tpi = new HVar2D("pmu", "tpi", "p_{#mu}", "T_{#pi}", "MeV", "MeV", + CCPi::GetBinning("pmu_with_tpi"), CCPi::GetBinning("tpi"), + &CVUniverse::GetPmu, &CVUniverse::GetTpi); + + + HVar2D* pTmu_tpi = new HVar2D("ptmu", "tpi", "p^{t}_{#mu}", "T_{#pi}", "MeV", "MeV", + CCPi::GetBinning("ptmu_with_tpi"), + CCPi::GetBinning("tpi_with_ptmu"), + &CVUniverse::GetPTmu, &CVUniverse::GetTpi); + HVar2D* tpi_pTmu = new HVar2D("tpi", "ptmu", "T_{#pi}", "p^{t}_{#mu}", "MeV", "MeV", + CCPi::GetBinning("tpi_with_ptmu"), + CCPi::GetBinning("ptmu_with_tpi"), + &CVUniverse::GetTpi, &CVUniverse::GetPTmu); + + HVar2D* tpi_enu = new HVar2D("tpi", "enu", "T_{#pi}", "E_{#nu}", "MeV", "MeV", + CCPi::GetBinning("tpi"), CCPi::GetBinning("enu_with_tpi"), + &CVUniverse::GetTpi, &CVUniverse::GetEnu); + HVar2D* enu_tpi = new HVar2D("enu", "tpi", "E_{#nu}", "T_{#pi}", "MeV", "MeV", + CCPi::GetBinning("enu_with_tpi"), CCPi::GetBinning("tpi"), + &CVUniverse::GetEnu, &CVUniverse::GetTpi); +// Var2D* pzmu_thetamu = new Var2D(var1D[5], var1D[2]); +// Var2D* ptmu_thetamu = new Var2D(var1D[4], var1D[2]); + + + // True 2d Variables + Var2D* pzmu_pTmu_true = new Var2D(var1D[13], var1D[12]); + Var2D* pTmu_pzmu_true = new Var2D(var1D[12], var1D[13]); +// Var2D* pmu_thetamu_true = new Var2D(var1D[7], var1D[8]); + + HVar2D* tpi_thetapi_deg_true = new HVar2D("tpi_true", "thetapi_deg_true", + "T_{#pi} true", "#theta_{#pi} true", "MeV", "deg", + CCPi::GetBinning("tpi"), CCPi::GetBinning("thetapi_deg"), + &CVUniverse::GetTpiTrue, &CVUniverse::GetThetapiTrueDeg, + is_true); + HVar2D* thetapi_deg_tpi_true = new HVar2D("thetapi_deg_true", "tpi_true", + "#theta_{#pi} true", "T_{#pi} true", "deg", "MeV", + CCPi::GetBinning("thetapi_deg"), CCPi::GetBinning("tpi"), + &CVUniverse::GetThetapiTrueDeg, &CVUniverse::GetTpiTrue, + is_true); + + HVar2D* tpi_pmu_true = new HVar2D("tpi_true", "pmu_true", "T_{#pi} True", + "p_{#mu} True", "MeV", "MeV", + CCPi::GetBinning("tpi"), CCPi::GetBinning("pmu_with_tpi"), + &CVUniverse::GetTpiTrue, &CVUniverse::GetPmuTrue, is_true); + HVar2D* pmu_tpi_true = new HVar2D("pmu_true", "tpi_true", "p_{#mu} True", "T_{#pi} True", + "MeV", "MeV", + CCPi::GetBinning("pmu_with_tpi"), CCPi::GetBinning("tpi"), + &CVUniverse::GetPmuTrue, &CVUniverse::GetTpiTrue, is_true); + + HVar2D* pTmu_tpi_true = new HVar2D("ptmu_true", "tpi_true", "p^{t}_{#mu} True", + "T_{#pi} True", "MeV", "MeV", + CCPi::GetBinning("ptmu_with_tpi"), + CCPi::GetBinning("tpi_with_ptmu"), + &CVUniverse::GetPTmuTrue, &CVUniverse::GetTpiTrue, is_true); + HVar2D* tpi_pTmu_true = new HVar2D("tpi_true", "ptmu_true", "T_{#pi} True", + "p^{t}_{#mu} True", "MeV", "MeV", + CCPi::GetBinning("tpi_with_ptmu"), + CCPi::GetBinning("ptmu_with_tpi"), + &CVUniverse::GetTpiTrue, &CVUniverse::GetPTmuTrue, is_true); + + HVar2D* tpi_enu_true = new HVar2D("tpi_true", "enu_true", "T_{#pi} True", "E_{#nu} True", + "MeV", "MeV", + CCPi::GetBinning("tpi"), CCPi::GetBinning("enu_with_tpi"), + &CVUniverse::GetTpiTrue, &CVUniverse::GetEnuTrue, is_true); + HVar2D* enu_tpi_true = new HVar2D("enu_true", "tpi_true", "E_{#nu} True", "T_{#pi} True", + "MeV", "MeV", + CCPi::GetBinning("enu_with_tpi"), CCPi::GetBinning("tpi"), + &CVUniverse::GetEnuTrue, &CVUniverse::GetTpiTrue, is_true); + + pzmu_pTmu_true->m_is_true = true; +// Var2D* ptmu_thetamu_true = new Var2D(var1D[10], var1D[8]); + std::vector variables2D = {pzmu_pTmu, pTmu_pzmu, tpi_thetapi_deg, thetapi_deg_tpi, pmu_tpi, tpi_pmu, tpi_pTmu, pTmu_tpi, tpi_enu, enu_tpi}; + if (include_truth_vars){ + variables2D.push_back(pzmu_pTmu_true); + variables2D.push_back(pTmu_pzmu_true); + variables2D.push_back(tpi_thetapi_deg_true); + variables2D.push_back(thetapi_deg_tpi_true); + variables2D.push_back(tpi_pmu_true); + variables2D.push_back(pmu_tpi_true); + variables2D.push_back(pTmu_tpi_true); + variables2D.push_back(tpi_pTmu_true); + variables2D.push_back(tpi_enu_true); + variables2D.push_back(enu_tpi_true); + } + return variables2D; +} + std::map GetOnePiVariables_Map( bool include_truth_vars = true) { std::map var_map; @@ -141,6 +332,14 @@ std::map GetOnePiVariables_Map( return var_map; } +std::map GetOnePiVariables2D_Map( + bool include_truth_vars = true) { + std::map var2D_map; + std::vector var_vec = GetOnePiVariables2D(include_truth_vars); + for (auto v : var_vec) var2D_map[v->NameX() + "_vs_" + v->NameY()] = v; + return var2D_map; +} + } // namespace make_xsec_mc_inputs std::vector GetAnalysisVariables( @@ -154,6 +353,21 @@ std::vector GetAnalysisVariables( return get_variables.at(signal_definition.m_id)(include_truth_vars); } +std::vector GetAnalysisVariables2D(const SignalDefinition signal_definition, + bool include_truth_vars = false) { + std::vector variables2D; + variables2D = make_xsec_mc_inputs::GetOnePiVariables2D(include_truth_vars); +/* switch (signal_definition) { + case kOnePi: + variables2D = make_xsec_mc_inputs::GetOnePiVariables2D(include_truth_vars); + break; + default: + std::cerr << "Variables for other SDs not yet implemented.\n"; + std::exit(1); + }*/ + return variables2D; +} + void SyncAllHists(Variable& v) { v.m_hists.m_selection_mc.SyncCVHistos(); v.m_hists.m_bg.SyncCVHistos(); @@ -168,6 +382,24 @@ void SyncAllHists(Variable& v) { v.m_hists.m_effden.SyncCVHistos(); } + +void SyncAllHists2D(Variable2D& v2D){ + v2D.m_hists2D.m_selection_mc.SyncCVHistos(); + v2D.m_hists2D.m_bg.SyncCVHistos(); + v2D.m_hists2D.m_bg_loW.SyncCVHistos(); + v2D.m_hists2D.m_bg_midW.SyncCVHistos(); + v2D.m_hists2D.m_bg_hiW.SyncCVHistos(); +//v2D.m_hists2D.m_wsidebandfit_sig.SyncCVHistos(); +//v2D.m_hists2D.m_wsidebandfit_loW.SyncCVHistos(); +//v2D.m_hists2D.m_wsidebandfit_midW.SyncCVHistos(); +//v2D.m_hists2D.m_wsidebandfit_hiW.SyncCVHistos(); + v2D.m_hists2D.m_effnum.SyncCVHistos(); + v2D.m_hists2D.m_migration.SyncCVHistos(); + v2D.m_hists2D.m_migration_reco.SyncCVHistos(); + v2D.m_hists2D.m_migration_true.SyncCVHistos(); + v2D.m_hists2D.m_effden.SyncCVHistos(); +} + // Given a macro, make an output filename with a timestamp std::string GetOutFilename(const CCPi::MacroUtil& util, const int run = 0) { auto time = std::time(nullptr); @@ -182,24 +414,27 @@ std::string GetOutFilename(const CCPi::MacroUtil& util, const int run = 0) { timestamp.c_str())); } + //============================================================================== // Loop and Fill //============================================================================== void LoopAndFillMCXSecInputs(const UniverseMap& error_bands, const Long64_t n_entries, const bool is_truth, const SignalDefinition& signal_definition, - std::vector& variables) { + std::vector& variables, + std::vector& variables2D) { const bool is_mc = true; for (auto band : error_bands) { std::vector universes = band.second; for (auto universe : universes) universe->SetTruth(is_truth); } - for (Long64_t i_event = 0; i_event < n_entries; ++i_event) { + //for (Long64_t i_event = 0; i_event < 5000; ++i_event) { if (i_event % (n_entries / 10) == 0) std::cout << (i_event / 1000) << "k " << std::endl; + //if (i_event == 50000) break; // Variables that hold info about whether the CVU passes cuts PassesCutsInfo cv_cuts_info; bool checked_cv = false; @@ -209,19 +444,21 @@ void LoopAndFillMCXSecInputs(const UniverseMap& error_bands, std::vector universes = error_band.second; for (auto universe : universes) { universe->SetEntry(i_event); - // std::cout << universe->ShortName() << "\n"; - // if (universe->GetDouble("mc_incoming") == 12 && + //std::cout << universe->ShortName() << "\n"; + //if (universe->GetDouble("mc_incoming") == 12 && // universe->ShortName() == "cv") // universe->PrintArachneLink(); // CCPiEvent keeps track of lots of event properties CCPiEvent event(is_mc, is_truth, signal_definition, universe); - event.m_weight = universe->GetWeight(); - // Fill truth -- modify the histograms owned by variables and return by - // reference :/ - if (is_truth) { + //=============== + // FILL TRUTH + //=============== + if (type == kTruth) { + universe->SetPassesTrakedTracklessCuts(true,true); ccpi_event::FillTruthEvent(event, variables); + ccpi_event::FillTruthEvent2D(event, variables2D); continue; } @@ -231,6 +468,40 @@ void LoopAndFillMCXSecInputs(const UniverseMap& error_bands, // Namely, for all vertical-only universes (meaning only the event // weight differs from CV) no need to recheck cuts. PassesCutsInfo cuts_info; + LowRecoilPion::Cluster d; + LowRecoilPion::Cluster c(*universe,0); + LowRecoilPion::Michel m(*universe,0); + LowRecoilPion::MichelEvent trackless_michels; + + //=============== + // CHECK CUTS + //=============== + // Universe only affects weights + + bool good_trackless_michels = LowRecoilPion::hasMichel>::hasMichelCut(*universe, trackless_michels); + good_trackless_michels = good_trackless_michels && LowRecoilPion::BestMichelDistance2D>::BestMichelDistance2DCut(*universe, trackless_michels); + good_trackless_michels = good_trackless_michels && LowRecoilPion::GetClosestMichel>::GetClosestMichelCut(*universe, trackless_michels); + +// if (good_trackless_michels) { +// trackless_michels.m_allmichels[trackless_michels.m_idx].GetPionAngle(*universe); +// std::cout << "Angle = " << trackless_michels.m_bestthetaangle << "\n"; + +// } + universe->SetVtxMichels(trackless_michels); + + bool pass = true; + pass = pass && universe->GetNMichels() == 1; + pass = pass && universe->GetTpiTrackless() < 350.; + pass = pass && universe->GetPmu() > 1500.; + pass = pass && universe->GetPmu() < 20000.; + pass = pass && universe->GetNIsoProngs() < 2; + pass = pass && universe->IsInHexagon(universe->GetVecElem("vtx", 0), universe->GetVecElem("vtx", 1), 850.); + pass = pass && universe->GetVecElem("vtx", 2) > 5990.; + pass = pass && universe->GetVecElem("vtx", 2) < 8340.; + pass = pass && universe->GetBool("isMinosMatchTrack"); + pass = pass && universe->GetDouble("MasterAnaDev_minos_trk_qp") < 0.0; + pass = pass && universe->GetThetamuDeg() < 20; + if (universe->IsVerticalOnly()) { if (!checked_cv) { cv_cuts_info = PassesCuts(event); @@ -253,12 +524,42 @@ void LoopAndFillMCXSecInputs(const UniverseMap& error_bands, universe->SetPionCandidates(event.m_reco_pion_candidate_idxs); // Re-call GetWeight because the node cut efficiency systematic + // Need to re-call this because the node cut efficiency systematic // needs a pion candidate to calculate its weight. event.m_weight = universe->GetWeight(); - - // Fill reco -- modify the histograms owned by variables and return by - // reference :/ + universe->SetVtxMichels(trackless_michels); + event.m_passes_trackless_cuts_except_w = false; + event.m_passes_trackless_sideband = false; + if (pass && universe->GetWexp() > 1400.){ + event.m_passes_trackless_cuts_except_w = true; + if (universe->GetWexp() > 1500.) event.m_passes_trackless_sideband = true; + pass = false; + } + event.m_passes_trackless_cuts = good_trackless_michels && pass; + event.m_passes_trackless_sideband = event.m_passes_trackless_sideband && good_trackless_michels; + event.m_passes_trackless_cuts_except_w = event.m_passes_trackless_cuts_except_w && good_trackless_michels; + universe->SetPassesTrakedTracklessCuts(event.m_passes_cuts || event.m_passes_all_cuts_except_w, event.m_passes_trackless_cuts || event.m_passes_trackless_cuts_except_w); + + + //=============== + // FILL RECO + //=============== +/* if (i_event == 4216){ + std::cout << "Event = " << i_event << "\n"; + std::cout << "Pass the cuts? " << event.m_passes_trackless_cuts << "\n"; + std::cout << "Pass the sidebands? " << event.m_passes_trackless_cuts << "\n"; + std::cout << "Pass cuts exept W " << event.m_passes_trackless_cuts << "\n"; + std::cout << "Pass tracked cuts? " << event.m_passes_cuts << "\n"; + std::cout << "Pass tracked cuts? " << event.m_is_w_sideband << "\n"; + }*/ +/* if (event.m_is_signal && event.m_passes_trackless_cuts){ + std::cout << "Is Signal and pass cuts, Event " << i_event << "\n"; + std::cout << "Thetapi reco = " << universe->GetThetapitracklessDeg() << "\n"; + std::cout << "Thetapi true = " << universe->GetThetapitracklessTrueDeg() << "\n"; +// std::cout << "thetapi from trackless_michels = " << trackless_michels.best_angle << "\n"; + }*/ ccpi_event::FillRecoEvent(event, variables); + ccpi_event::FillRecoEvent2D(event, variables2D); } // universes } // error bands } // events @@ -301,19 +602,26 @@ void makeCrossSectionMCInputs(int signal_definition_int = 0, const bool do_truth_vars = true; std::vector variables = GetAnalysisVariables(util.m_signal_definition, do_truth_vars); + + std::vector variables2D = + GetAnalysisVariables2D(util.m_signal_definition, do_truth_vars); + for (auto v : variables) v->InitializeAllHists(util.m_error_bands, util.m_error_bands_truth); + for (auto v2D : variables2D){ + v2D->InitializeAllHists(util.m_error_bands, util.m_error_bands_truth); + } // 5. Loop MC Reco -- process events and fill histograms owned by variables bool is_truth = false; LoopAndFillMCXSecInputs(util.m_error_bands, util.GetMCEntries(), is_truth, - util.m_signal_definition, variables); + util.m_signal_definition, variables, variables2D); // 6. Loop Truth if (util.m_do_truth) { is_truth = true; LoopAndFillMCXSecInputs(util.m_error_bands_truth, util.GetTruthEntries(), - is_truth, util.m_signal_definition, variables); + is_truth, util.m_signal_definition, variables, variables2D); } // 7. Write to file @@ -324,6 +632,13 @@ void makeCrossSectionMCInputs(int signal_definition_int = 0, SyncAllHists(*v); v->WriteMCHists(fout); } + for (auto v2D : variables2D) { +// v2D->m_response.GetMigrationObjects(v2D->m_hists2D.m_response, v2D->m_hists2D.m_responseReco, v2D->m_hists2D.m_responseTrue); +// v2D->m_hists2D.m_response = v2D->m_response.GetMigrationMatrix(); + SyncAllHists2D(*v2D); + v2D->WriteMCHists(fout); + } + } #endif // makeXsecMCInputs_C diff --git a/xsec/plotCrossSectionFromFile.C b/xsec/plotCrossSectionFromFile.C index a747177..832f9c3 100644 --- a/xsec/plotCrossSectionFromFile.C +++ b/xsec/plotCrossSectionFromFile.C @@ -15,9 +15,11 @@ #include "includes/MacroUtil.h" #include "includes/Plotter.h" #include "includes/Variable.h" +#include "includes/Variable2D.h" #include "includes/common_functions.h" #include "makeCrossSectionMCInputs.C" // GetAnalysisVariables #include "plotting_functions.h" +#include "plotting_functions2D.h" void SetPOT(TFile& fin, CCPi::MacroUtil& util) { util.m_mc_pot = -1; @@ -42,11 +44,19 @@ void SetPOT(TFile& fin, CCPi::MacroUtil& util) { // Main //============================================================================== void plotCrossSectionFromFile(int signal_definition_int = 0, - int plot_errors = 1) { + int plot_errors = 0) { // Infiles - TFile fin("DataXSecInputs_2023-02-21.root", "READ"); + TFile fin("DataXSecInputs_20240619_ALL_tracked_Sys_p4.root", "READ"); cout << "Reading input from " << fin.GetName() << endl; + TFile finCCPi("DataXSecInputs_20240605_ALL_tracked_sys_p4.root", "READ"); + // TFile + // finCCPi("/minerva/app/users/granados/cmtuser/Minerva_v22r1p1_CCPionInc/Ana/CCPionInc/ana/ME_CCNuPionInc_Ana/DataXSec_20211010_NewTupla.root", + // "READ"); + + // TFile finCCPi("../ME_CCNuPionInc_Ana/DataXSec_20210901_CCPi.root", + // "READ"); + // Set up macro utility object...which gets the list of systematics for us... // which we need in order to read in HistWrappers...which we don't need at // this point...indeed we only need MnvH1Ds...so that's a TODO: write a @@ -56,9 +66,9 @@ void plotCrossSectionFromFile(int signal_definition_int = 0, // INPUT TUPLES // Don't actually use the MC chain, only load it to indirectly access it's // systematics - const std::string plist = "ME1A"; - std::string data_file_list = GetPlaylistFile(plist, false); - std::string mc_file_list = GetPlaylistFile(plist, true); + const std::string plist = "ME1P"; + std::string data_file_list = GetPlaylistFile(plist, false,false); + std::string mc_file_list = GetPlaylistFile(plist, true,false); //std::string data_file_list = GetTestPlaylist(false); //std::string mc_file_list = GetTestPlaylist(true); @@ -75,6 +85,9 @@ void plotCrossSectionFromFile(int signal_definition_int = 0, const bool do_truth_vars = true; std::vector variables = GetAnalysisVariables(util.m_signal_definition, do_truth_vars); + std::vector variables2D = + GetAnalysisVariables2D(util.m_signal_definition, do_truth_vars); + for (auto var : variables) { if (var->Name() == sidebands::kFitVarString) { @@ -89,12 +102,14 @@ void plotCrossSectionFromFile(int signal_definition_int = 0, // if(var->Name() == "ptmu") // PrintUniverseContent(var->m_hists.m_cross_section); } - + for (auto var2D : variables2D) { + var2D->LoadMCHistsFromFile(fin, util.m_error_bands); + var2D->LoadDataHistsFromFile(fin); + } { // remove unwanted variables ContainerEraser::erase_if(variables, [](Variable* v) { return v->Name() == "tpi_mbr"; // || v->Name() == "wexp_fit"; }); - // ContainerEraser::erase_if(variables, [](Variable* v) { // return v->Name() == "tpi" || v->Name() == "enu"; }); // ContainerEraser::erase_if(variables, [](Variable* v) { @@ -106,10 +121,11 @@ void plotCrossSectionFromFile(int signal_definition_int = 0, } // PLOT Event Selection, BGs (error) - if (true) { + if ( true) { const bool do_frac_unc = true; const bool include_stat = true; bool do_cov_area_norm = false; + if (false){// Begining of block for 1D analysis results for (auto var : variables) { if (var->Name() == "wexp_fit") continue; std::cout << var->Name() << "\n"; @@ -135,11 +151,29 @@ void plotCrossSectionFromFile(int signal_definition_int = 0, if (plot_errors) PlotVar_ErrorSummary(plot_info); if (plot_errors) PlotBG_ErrorSummary(plot_info, do_tuned_bg); } + } + }//End of Block for 1D Analysis results + for (auto var2D : variables2D){ + EventSelectionPlotInfo2D plot_info2D(var2D, util.m_mc_pot, util.m_data_pot, + do_frac_unc, do_cov_area_norm, + include_stat, util.m_signal_definition); + bool do_bin_width_norm = true, do_log_scale = false, do_bg = true; + bool do_tuned_bg = false; + if (var2D->m_is_true) continue; + do_tuned_bg = false; + PlotVar_Selection2D(plot_info2D, do_bg, do_log_scale, do_tuned_bg, + do_bin_width_norm); +// PlotVar_ErrorSummary2D(plot_info2D); + do_tuned_bg = true; + PlotVar_Selection2D(plot_info2D, do_bg, do_log_scale, do_tuned_bg, + do_bin_width_norm); } } + // 1D and 2D Comparison, in this section I make a proyection of the 2D plots to + // 1D plot, in this way I can know if the distributions ar filled correctly. // PLOT Efficiency & Migration - if (true) { + if ( true) { const bool do_frac_unc = true; const bool include_stat = true; const bool do_cov_area_norm = false; @@ -180,10 +214,37 @@ void plotCrossSectionFromFile(int signal_definition_int = 0, PlotMigration_VariableBins(mig, var->Name()); } } + for (auto var2D : variables2D){ + const EventSelectionPlotInfo2D plot_info2D( + var2D, util.m_mc_pot, util.m_data_pot, do_frac_unc, do_cov_area_norm, + include_stat, util.m_signal_definition); + + // Migration 2D + if (!var2D->m_is_true){ + PlotUtils::MnvH2D* mig2D = + (PlotUtils::MnvH2D*)var2D->m_hists2D->m_migration.hist->Clone(uniq()); + PlotMigration2D(plot_info2D, mig2D, var2D->NameX(), var2D->NameY()); + + } + // Efficiency 2D + if (var2D->m_is_true){ + PlotUtils::MnvH2D* eff = + (PlotUtils::MnvH2D*)var2D->m_hists2D.m_effnum.hist->Clone(uniq()); + PlotUtils::MnvH2D* effnum = + (PlotUtils::MnvH2D*)var2D->m_hists2D.m_effnum.hist->Clone(uniq()); + PlotUtils::MnvH2D* effden = + (PlotUtils::MnvH2D*)var2D->m_hists2D.m_effden.hist->Clone(uniq()); + eff->Divide(effnum, effden); + var2D->m_hists2D.m_efficiency = (PlotUtils::MnvH2D*)eff->Clone(uniq()); + + PlotMC2D(plot_info2D, eff, "Efficiency"); + PlotEfficiency_ErrorSummary2D(plot_info2D); + } + } } // PLOT Background Subtraction - if (true) { + if ( true) { const bool do_frac_unc = true; const bool include_stat = true; const bool do_cov_area_norm = false; @@ -209,10 +270,28 @@ void plotCrossSectionFromFile(int signal_definition_int = 0, if (plot_errors) PlotBGSub_ErrorSummary(plot_info); } + for (auto var2D : variables2D){ + EventSelectionPlotInfo2D plot_info2D(var2D, util.m_mc_pot, util.m_data_pot, + do_frac_unc, do_cov_area_norm, + include_stat, util.m_signal_definition); + double ymax = -1.; + bool do_log_scale = false; + bool do_bg = true; + bool do_tuned_bg = true; + bool do_bin_width_norm = true; + + if (var2D->m_is_true) continue; + PlotBG_ErrorSummary2D(plot_info2D, do_tuned_bg); + do_tuned_bg = false; + PlotBG_ErrorSummary2D(plot_info2D, do_tuned_bg); + Plot_BGSub2D(plot_info2D, ".", ymax, do_log_scale, do_bin_width_norm); + } + + } // PLOT W Sideband Fit - if (true) { + if ( true) { const bool do_frac_unc = true; const bool do_cov_area_norm = false; const bool include_stat = true; @@ -243,27 +322,28 @@ void plotCrossSectionFromFile(int signal_definition_int = 0, var->GetStackArray(static_cast(0)), util.m_data_pot, util.m_mc_pot, util.m_signal_definition, tag, ymax); - + std::cout << "Checar aqui \n"; // TODO plot pre/postfit - // for (auto var : variables) { - // tag = "SidebandRegion"; - // bool do_prefit = true; - // bool do_bin_width_norm = true; - // CVUniverse* universe = util.m_error_bands.at("cv").at(0); - // PlotFittedW(var, *universe, hw_loW_fit_wgt, hw_midW_fit_wgt, - // hw_hiW_fit_wgt, util.m_data_pot, util.m_mc_pot, - // util.m_signal_definition, do_prefit, tag, ymax, - // do_bin_width_norm); - // do_prefit = false; - // PlotFittedW(var, *universe, hw_loW_fit_wgt, hw_midW_fit_wgt, - // hw_hiW_fit_wgt, util.m_data_pot, util.m_mc_pot, - // util.m_signal_definition, do_prefit, tag, ymax, - // do_bin_width_norm); - //} + for (auto var : variables) { + if (var->Name() != "wexp_fit") continue; + tag = "SidebandRegion"; + bool do_prefit = true; + bool do_bin_width_norm = true; + CVUniverse* universe = util.m_error_bands.at("cv").at(0); + PlotFittedW(var, *universe, loW_fit_wgt, midW_fit_wgt, + hiW_fit_wgt, util.m_data_pot, util.m_mc_pot, + util.m_signal_definition, do_prefit, tag, ymax, + do_bin_width_norm); + do_prefit = false; + PlotFittedW(var, *universe, loW_fit_wgt, midW_fit_wgt, + hiW_fit_wgt, util.m_data_pot, util.m_mc_pot, + util.m_signal_definition, do_prefit, tag, ymax, + do_bin_width_norm); + } } // PLOT unfolded - if (true) { + if ( true) { const bool do_frac_unc = true; const bool include_stat = true; const bool do_cov_area_norm = false; @@ -284,10 +364,22 @@ void plotCrossSectionFromFile(int signal_definition_int = 0, true_var->m_hists.m_effnum.hist); if (plot_errors) PlotUnfolded_ErrorSummary(plot_info); } + for (auto reco_var2D : variables2D){ + if (reco_var2D->m_is_true) continue; + Variable2D* true_var2D = GetVar2D(variables2D, reco_var2D->NameX() + "_true", + reco_var2D->NameY() + "_true"); + EventSelectionPlotInfo2D plot_info2D(reco_var2D, util.m_mc_pot, util.m_data_pot, + do_frac_unc, do_cov_area_norm, + include_stat, util.m_signal_definition); + Plot_Unfolded2D(plot_info2D, reco_var2D->m_hists2D.m_unfolded, + true_var2D->m_hists2D.m_effnum.hist); + PlotUnfolded_ErrorSummary2D (plot_info2D); + + } } // PLOT cross section - if (true) { + if ( true) { const bool do_frac_unc = true; const bool include_stat = true; const bool do_cov_area_norm = false; @@ -375,6 +467,31 @@ void plotCrossSectionFromFile(int signal_definition_int = 0, // PrintChi2Info(plot_info, reco_var->m_hists.m_cross_section, // m_mc_cross_section); // this one works } + for (auto reco_var2D : variables2D){ + if (reco_var2D->m_is_true) continue; + Variable2D* true_var2D = + GetVar2D(variables2D, reco_var2D->NameX() + std::string("_true"), + reco_var2D->NameY() + std::string("_true")); + EventSelectionPlotInfo2D plot_info2D(reco_var2D, util.m_mc_pot, util.m_data_pot, + do_frac_unc, do_cov_area_norm, + include_stat, util.m_signal_definition); + + PlotUtils::MnvH2D* m_mc_cross_section = (PlotUtils::MnvH2D*)fin.Get( + Form("D_mc_cross_section_%s_vs_%s", reco_var2D->NameX().c_str(), + reco_var2D->NameY().c_str())); + + // std::vector x_bands = + // reco_var->m_hists.m_cross_section->GetVertErrorBandNames(); + // if(reco_var->Name() == "ptmu") + // for (auto s : x_bands) std::cout << s << "\n"; + + // std::cout << reco_var->Name() << "\n"; + + Plot_CrossSection2D(plot_info2D, reco_var2D->m_hists2D.m_cross_section, + m_mc_cross_section); + PlotCrossSection_ErrorSummary2D(plot_info2D); + } + } //============================================================================ diff --git a/xsec/plotting_functions.h b/xsec/plotting_functions.h index 342390d..83488b0 100644 --- a/xsec/plotting_functions.h +++ b/xsec/plotting_functions.h @@ -161,6 +161,7 @@ PlotUtils::MnvH1D* RebinQ2Plot(const PlotUtils::MnvH1D& old_hist) { //============================================================================== // Some Systematics General Functions //============================================================================== + void SetErrorGroups(MnvPlotter& mnv_plotter) { mnv_plotter.error_summary_group_map.clear(); mnv_plotter.error_summary_group_map["Flux"].push_back("Flux"); @@ -1169,14 +1170,14 @@ void PlotWSidebandStacked(const Variable* variable, } mnvPlotter.DrawDataStackedMC(data, &array, pot_scale, "TR", "Data", -1, -1, - 1001, variable->m_hists.m_xlabel.c_str(), - y_label.c_str()); + 1001, Form("%s %s",variable->m_hists.m_xlabel.c_str(), variable->m_units.c_str()), + y_label.c_str()); double arrow_height = data->GetBinContent(data->GetMaximumBin()) * data->GetNormBinWidth() / data->GetBinWidth(data->GetMaximumBin()); double arrow_location = signal_definition.m_w_max + 100.; - mnvPlotter.AddCutArrow(arrow_location, 0.0, arrow_height, 200., "R"); + mnvPlotter.AddCutArrow(arrow_location, 0.0, 150, 200., "R"); mnvPlotter.WritePreliminary("TL"); mnvPlotter.AddPOTNormBox(data_pot, mc_pot, 0.3, 0.85); mnvPlotter.AddHistoTitle(tag.c_str()); @@ -1184,9 +1185,9 @@ void PlotWSidebandStacked(const Variable* variable, } void PlotFittedW(const Variable* variable, const CVUniverse& universe, - const PlotUtils::HistWrapper& loW_fit, - const PlotUtils::HistWrapper& midW_fit, - const PlotUtils::HistWrapper& hiW_fit, + const PlotUtils::MnvH1D* loW_fit, + const PlotUtils::MnvH1D* midW_fit, + const PlotUtils::MnvH1D* hiW_fit, float data_pot, float mc_pot, SignalDefinition signal_definition, bool do_prefit = false, std::string tag = "", double ymax = -1, @@ -1226,9 +1227,9 @@ void PlotFittedW(const Variable* variable, const CVUniverse& universe, if (do_prefit) { ; } else { - h_loW->Scale(loW_fit.univHist(&universe)->GetBinContent(1)); - h_midW->Scale(midW_fit.univHist(&universe)->GetBinContent(1)); - h_hiW->Scale(hiW_fit.univHist(&universe)->GetBinContent(1)); + h_loW->Scale(loW_fit->GetBinContent(1)); + h_midW->Scale(midW_fit->GetBinContent(1)); + h_hiW->Scale(hiW_fit->GetBinContent(1)); } std::string y_label = "Events"; @@ -1277,8 +1278,8 @@ void PlotFittedW(const Variable* variable, const CVUniverse& universe, // Draw mnvPlotter.DrawDataStackedMC(h_data, array, pot_scale, "TR", "Data", -1, -1, - 1001, variable->m_hists.m_xlabel.c_str(), - y_label.c_str()); + 1001, Form("%s %s",variable->m_hists.m_xlabel.c_str(), variable->m_units.c_str()), + y_label.c_str()); mnvPlotter.WritePreliminary("TL"); mnvPlotter.AddPOTNormBox(data_pot, mc_pot, 0.3, 0.85); @@ -1661,6 +1662,7 @@ void PlotMC(PlotUtils::MnvH1D* hist, Plotter p, std::string tag, // Y-axis label if (ylabel != "") hist->GetYaxis()->SetTitle(ylabel.c_str()); // PlotUtils::MnvH1D* tmp_bg = nullptr; + if (true) hist->Scale(1., "width"); p.m_mnv_plotter.DrawMCWithErrorBand( hist); // I think that this call only shows stat errors. p.m_mnv_plotter.MultiPrint(&canvas, tag.c_str(), "png"); @@ -1686,13 +1688,13 @@ void PlotRatio(PlotUtils::MnvH1D* num, PlotUtils::MnvH1D* denom, std::string v, cout << "Plotting ratio " << label << endl; TCanvas* c2 = new TCanvas(); - std::string yaxisLabel = "mc/gxse"; + std::string yaxisLabel = "MAD/CCPionInc"; PlotUtils::MnvPlotter* ratio = new PlotUtils::MnvPlotter(); ratio->PlotUtils::MnvPlotter::DrawDataMCRatio( num, denom, norm, drawSysLines, drawOneLine, plotMin, plotMax, yaxisLabel.c_str(), covAreaNormalize); - ratio->AddHistoTitle(Form("%s %s", label.c_str(), l.c_str()), titleSize); - c2->Print(Form("%s_%s.png", label.c_str(), l.c_str())); + ratio->AddHistoTitle(Form("%s", l.c_str()), titleSize); + c2->Print(Form("%s.png", label.c_str())); } void PlotRatio1(PlotUtils::MnvH1D* num, PlotUtils::MnvH1D* denom, diff --git a/xsec/plotting_functions2D.h b/xsec/plotting_functions2D.h new file mode 100644 index 0000000..def010e --- /dev/null +++ b/xsec/plotting_functions2D.h @@ -0,0 +1,1769 @@ +//#ifndef plotting_functions2D_h +//#define plotting_functions2D_h + +#include +#include +#include + +#include "../includes/myPlotStyle.h" +#include "PlotUtils/MnvColors.h" +#include "PlotUtils/MnvH1D.h" +#include "PlotUtils/HistogramUtils.h" +#ifndef MNVROOT6 +#define MNVROOT6 +#include "PlotUtils/MnvPlotter.h" +#endif +#include "PlotUtils/MnvVertErrorBand.h" +#include "SignalDefinition.h" +#include "Systematics.h" // namespace systematics +#include "TAxis.h" +#include "TCanvas.h" +#include "TF1.h" +#include "TGaxis.h" +#include "TGraph.h" +#include "TLatex.h" +#include "TLegend.h" +#include "TLegendEntry.h" +#include "TLine.h" +#include "TList.h" +#include "TPad.h" +#include "TPaveStats.h" +#include "TObject.h" +//#include "TStyle.h" +#include "TText.h" +#include "Variable.h" +#include "Variable2D.h" +#include "PlotUtils/GridCanvas.h" +#include "plotting_functions.h" + +class Variable; +class Variable2D; +std::map< std::string, std::vector> error_names; +//============================================================================== +// Container class +//============================================================================== +class EventSelectionPlotInfo2D { + public: + + // Constructor with Var2D + EventSelectionPlotInfo2D(Variable2D* variable2D, float mc_pot, float data_pot, + bool do_frac_unc, bool do_cov_area_norm, + bool include_stat, SignalDefinition signal_definition) + : m_mnv_plotter(kCCNuPionIncStyle), + m_variable2D(variable2D), + m_mc_pot(mc_pot), + m_data_pot(data_pot), + m_do_frac_unc(do_frac_unc), + m_do_cov_area_norm(do_cov_area_norm), + m_include_stat(include_stat), +// m_error_names(), + m_signal_definition(signal_definition) { + m_do_frac_unc_str = m_do_frac_unc ? "Frac" : "Abs"; + m_do_cov_area_norm_str = m_do_cov_area_norm ? "CovAreaNorm" : ""; + } + + // Constructor without var + EventSelectionPlotInfo2D(float mc_pot, float data_pot, bool do_frac_unc, + bool do_cov_area_norm, bool include_stat, + SignalDefinition signal_definition) + : m_mnv_plotter(kCCNuPionIncStyle), + m_variable2D(nullptr), + m_mc_pot(mc_pot), + m_data_pot(data_pot), + m_do_frac_unc(do_frac_unc), + m_do_cov_area_norm(do_cov_area_norm), + m_include_stat(include_stat), +// m_error_names(), + m_signal_definition(signal_definition) { + m_do_frac_unc_str = m_do_frac_unc ? "Frac" : "Abs"; + m_do_cov_area_norm_str = m_do_cov_area_norm ? "CovAreaNorm" : ""; + } + + // Members + MnvPlotter m_mnv_plotter; + Variable2D* m_variable2D; + float m_mc_pot; + float m_data_pot; + bool m_do_frac_unc; + bool m_do_cov_area_norm; + bool m_include_stat; + SignalDefinition m_signal_definition; + std::string m_do_frac_unc_str; + std::string m_do_cov_area_norm_str; + // Add X label + void SetXLabel(PlotUtils::MnvH2D* hist) { + std::string label = + m_variable2D->m_hists2D.m_labelX + " (" + m_variable2D->m_unitsX + ")"; + if (hist) hist->GetXaxis()->SetTitle(label.c_str()); + } + + // Add X label + void SetXLabel(TH2* hist) { + std::string label = + m_variable2D->m_hists2D.m_labelX + " (" + m_variable2D->m_unitsX + ")"; + if (hist) hist->GetXaxis()->SetTitle(label.c_str()); + } + + // Add title to the MnvPlotter + void SetTitle() { + if (!gPad) + throw std::runtime_error("Need a TCanvas. Please make one first."); + std::string title = GetSignalName(m_signal_definition); + m_mnv_plotter.AddHistoTitle(title.c_str()); + } + + void SetTitle(std::string title) { + if (!gPad) + throw std::runtime_error("Need a TCanvas. Please make one first."); + m_mnv_plotter.AddHistoTitle(title.c_str()); + } +}; +//------------------------------------- +//--------------Multipliers------------ +//------------------------------------- +void SetErrorGroups2D(MnvPlotter& mnv_plotter); +std::vector GetMultipliers(TH2D* data_hist){ +// std::cout << "Inside GetMultipliers\n"; + std::vector multipliers; + double Max = data_hist->GetMaximum(); + double currentvalue = 0; + for (int j = 1; j <= data_hist->GetNbinsY(); ++j){ + currentvalue = 0; + for(int i = 1; i <= data_hist->GetNbinsX(); ++i ){ + if (data_hist->GetBinContent(i,j) > currentvalue) + currentvalue = data_hist->GetBinContent(i,j); + } + if (currentvalue == 0) multipliers.push_back(1.); + else multipliers.push_back((double)nearbyint(Max/currentvalue)); + } + return multipliers; +} +std::vector GetMultipliers(std::vector hvec){ +// std::cout << "Inside GetMultipliers(vec)\n"; + std::vector multipliers; + double Max = 0; + for (int k = 0; k < (int)hvec.size(); ++k){ + for (int j = 1; j <= (int)hvec[0]->GetNbinsY(); ++j){ + for (int i = 1; i <= (int)hvec[0]->GetNbinsX(); ++i){ + if (Max < hvec[k]->GetBinContent(i, j)) Max = hvec[k]->GetBinContent(i, j); + } + } + } +// std::cout << "Max " << Max << "\n"; + + double currentvalue = 0; +// std::cout << "hvec size = " << hvec.size() << "\n"; + for (int j = 1; j <= hvec[0]->GetNbinsY(); ++j){ + currentvalue = 0; + for (int k = 0; k < (int)hvec.size(); ++k){ + for(int i = 1; i <= hvec[k]->GetNbinsX(); ++i ){ +// std::cout << "Instance i = " << i << " j = " << j << +// " k = " << k << "\n" ; + if (hvec[k]->GetBinContent(i,j) > currentvalue) + currentvalue = hvec[k]->GetBinContent(i,j); +// std::cout << "Current value after = " << currentvalue << "\n"; + } + } + if (currentvalue == 0) multipliers.push_back(1.); + else multipliers.push_back((double)nearbyint(Max/currentvalue)); +// std::cout << "Multiplier " << j-1 << " = " << multipliers[j-1] << "\n"; + } + return multipliers; +} +/* +void AddToTmp( TObject* obj ) +{ + //note: build this everytime to avoid obj unused compiler warning + if ( 0 == obj ) + { + Warning( "MnvPlotter::AddToTmp", "Attempting to add NULL object to garbage."); + return; + } + +//#if DO_GARBAGE_COLLECTION + + //Error("MnvPlotter::AddToTmp", Form( "Adding object '%s' at index %d.", obj->GetName(), fTmpObjects.GetEntries() ) ); + + //! Add to array if the object isn't in the array already + if ( ! fTmpObjects.FindObject( obj ) ) + fTmpObjects.AddLast( obj ); +//#endif +} +*/ +void Plot2D(EventSelectionPlotInfo2D p, std::vector hvect, + std::vector names, std::string label = "", + std::string ylabel = "", std::string outdir = ".", double ymax = -1, + bool do_log_scale = false, bool do_bin_width_norm = true) { + std::cout << label + " 2D " << p.m_variable2D->NameX() << " vs " << p.m_variable2D->NameY()<< std::endl; + int nxpads = 4; + int nypads = p.m_variable2D->NBinsY()/3; + if (p.m_variable2D->NBinsY() < 4){ + nxpads = p.m_variable2D->NBinsY(); + nypads = 1; + } + if (p.m_variable2D->NBinsY() > 4 && p.m_variable2D->NBinsY() < 8 ) + nypads = 2; + PlotUtils::GridCanvas* GridPlot =new PlotUtils::GridCanvas(Form("2D_%s_%s_vs_%s", ylabel.c_str(), p.m_variable2D->NameX().c_str(), p.m_variable2D->NameY().c_str()), nxpads, nypads, 1400, 600); + GridPlot->SetTitle(Form("%s", ylabel.c_str())); + // Make sure we remembered to load the source histos from the input file. +// TCanvas canvas("c1", "c1"); + // Get Hists + TH2D* hist = (TH2D*)hvect[0]->Clone("hist"); + + + // Y-axis range +// if (ymax > 0) p.m_mnv_plotter.axis_maximum = ymax; + + // X label + p.SetXLabel(hist); + + // Overall Normalization + double pot_scale = -99.; + if (p.m_do_cov_area_norm) { + pot_scale = 1.; + } else { + pot_scale = p.m_data_pot / p.m_mc_pot; + } + + // Bin Width Normalization + std::string yaxis = ylabel; +/* if (do_bin_width_norm) { + hist->Scale(1., "width"); + // Y labe + yaxis = yaxis + " / " + p.m_variable2D->m_unitsY; + }*/ + + // Draw + //std::cout << "Number of bins " << p.m_variable2D->NBinsY() <<"\n"; + double mx[p.m_variable2D->NBinsY()]; + std::vector mult = GetMultipliers(hvect); + std::vector bins; + for (int i = 0; i < p.m_variable2D->NBinsY(); ++i){ + bins.push_back(i+1); +// std::cout << "Pasa 1\n"; + if (mult[i] > 1000.) mx[i] = 1.; + else mx[i] = mult[i]; + } + bins.push_back(p.m_variable2D->NBinsY()+1); +// std::cout << "Pasa 2 " << sizeof(mx)/sizeof(double) <<"\n"; + auto legend = new TLegend(0.88,0.9,1.,0.5); + legend->SetFillStyle(0); + legend->SetLineColor(0); + legend->AddEntry(hist, Form("%s", names[0].c_str()), "l"); + + GridPlot->SetRightMargin(0.12); + GridPlot->SetLeftMargin(0.07); + hist->GetXaxis()->SetLabelSize(0.03); + GridPlot->SetInterpadSpace(0.008); + // GridPlot->ResetPads(); + // Draw + GridPlot->DrawOneHist( hist, "E2", false, bins, false, mx); + for (int i = 1; i < (int)hvect.size(); ++i){ + legend->AddEntry(hvect[i], Form("%s", names[i].c_str()), "l"); + GridPlot->DrawOneHist( hvect[i], "HIST SAME", false, bins, false, mx); + } + GridPlot->DrawBinRanges(hist, 2, bins, Form("%s (%s)", + p.m_variable2D->m_hists2D.m_xlabelY.c_str(), + p.m_variable2D->m_unitsY.c_str()), 0.03, ".2f", 2); + GridPlot->DrawMultipliers( sizeof(mx)/sizeof(double) , mx); + GridPlot->SetXTitle(Form("%s (%s)",p.m_variable2D->m_hists2D.m_xlabelX.c_str(), + p.m_variable2D->m_unitsX.c_str())); + p.SetTitle(label + " " + p.m_variable2D->m_hists2D.m_xlabelX.c_str() + + " vs " + p.m_variable2D->m_hists2D.m_xlabelY.c_str()); + GridPlot->SetYTitle(yaxis.c_str()); + GridPlot->SetTitle(Form("%ss", label.c_str())); +// GridPlot->ResetPads(); + GridPlot->Draw(); + legend->Draw(); + GridPlot->Update(); + std::string logy_str = do_log_scale ? "_logscale" : ""; + + std::string bwn_str = do_bin_width_norm ? "_BWN" : ""; + + GridPlot->Print(Form("2D_ErrorSummary_%s_%s_vs_%s_%s.png", label.c_str(), + p.m_variable2D->NameX().c_str(), + p.m_variable2D->NameY().c_str(), + bwn_str.c_str())); +} + +int AddInQuadrature2D(TH2D* a, const TH2D * b) { + + if( a->GetNbinsX() != b->GetNbinsX() || a->GetNbinsY() != b->GetNbinsY()) { + Error("AddInQuadrature2D", "Histogram axes not compatible. Doing nothing." ); + return 1; + } + + int firstBinx = 0; + int firstBiny = 0; + int lastBinx = a->GetNbinsX()+1; + int lastBiny = a->GetNbinsY()+1; + for(int iBiny = firstBiny; iBiny <= lastBiny; ++iBiny){ + for( int iBinx = firstBinx; iBinx <= lastBinx; ++iBinx ) + { + const double aVal = a->GetBinContent(iBinx,iBiny); + const double bVal = b->GetBinContent(iBinx,iBiny); + const double aErr = a->GetBinError(iBinx,iBiny); + const double bErr = b->GetBinError(iBinx,iBiny); + + const double val = sqrt( aVal*aVal + bVal*bVal ); + const double err = ( 1E-8 < fabs(val) ) ? sqrt( pow(aVal*aErr,2) + pow(bVal*bErr,2) ) / val : 0.; + + a->SetBinContent(iBinx, iBiny, val); + a->SetBinError(iBinx, iBiny, err); + } + } + return 1; +} + +std::vector DrawErrorSummary2D( + EventSelectionPlotInfo2D p, + PlotUtils::MnvH2D* h, + // const std::string& legPos = "TR", + const bool includeStat = true, + const bool solidLinesOnly = true, + const double ignoreThreshold = 0.00001, + const bool covAreaNormalize = false, + const std::string& errorGroupName = "", + const bool asfrac = false, + const std::string &Ytitle = "", + bool ignoreUngrouped = false, + const double axis_minimum = MnvHist::AutoAxisLimit, + const double axis_maximum = MnvHist::AutoAxisLimit + ) +{ + if ( ! h ) + { + TH2D* noHist = NULL; + std::vector noHists; + noHists.push_back(noHist); + Error("DrawErrorSummary2D", "You passed me a NULL MnvH2D. Nothing to do."); + return noHists; + } + + //set max digits to the default, since we almost never want scientific notation for errors. + //restore the setting before returning. + const int oldMaxDigits = TGaxis::GetMaxDigits(); + int axis_max_digits = 3; + TGaxis::SetMaxDigits( axis_max_digits ); + + // Store the pieces for a legend + vector hists; + vector names; + vector opts; + std::string stat_error_name = "Statistical"; + bool useDifferentLineStyles = !solidLinesOnly; + + //! Get the total error and apply styles + TH2D *hTotalErr = (TH2D*)h->GetTotalError( includeStat, asfrac, covAreaNormalize ).Clone( Form("h_total_err_errSum_%d", __LINE__) ); + //AddToTmp( hTotalErr ); + + //Error("DrawDataMCErrorSummary", Form("Total Err Max: %.2f",hTotalErr->GetMaximum() ) ); + + p.m_mnv_plotter.ApplyNextLineStyle( hTotalErr, true, useDifferentLineStyles ); + + //respect max/min setting the user may have used + if ( MnvHist::IsAutoAxisLimit( axis_minimum ) ) + hTotalErr->SetMinimum( 0. ); + else + hTotalErr->SetMinimum( axis_minimum ); + + if ( MnvHist::IsAutoAxisLimit( axis_maximum ) ) + hTotalErr->SetMaximum( p.m_mnv_plotter.headroom * hTotalErr->GetMaximum() ); + else + hTotalErr->SetMaximum( axis_maximum ); + + hTotalErr->GetYaxis()->SetTitle( "Fractional Uncertainty" ); + if (!asfrac )hTotalErr->GetYaxis()->SetTitle( Ytitle.c_str() ); + if (errorGroupName == "") { + if (!asfrac) hTotalErr->Scale( hTotalErr->GetBinWidth(1), "width" ); +// hTotalErr->Draw( "HIST" ); + const string totalName = ( includeStat ? "Total Uncertainty" : "Total Sys. Uncertainty" ); + hists.push_back( hTotalErr ); + names.push_back( totalName ); + opts.push_back( "l" ); + } + + if ( includeStat && errorGroupName == "") + { + TH2D *statErr = (TH2D*)h->GetStatError(asfrac).Clone( Form("this_stat_err_%d", __LINE__) ); + //AddToTmp( statErr ); + + statErr->SetLineColor( 12 );//dark gray + statErr->SetLineStyle( 2 ); //dashed + statErr->SetLineWidth( 3 ); + statErr->Draw("HIST SAME"); + hists.push_back( statErr ); + names.push_back( stat_error_name ); + opts.push_back( "l" ); + } + + TH2D *hTmpErr = (TH2D*)hTotalErr->Clone( Form("h_tmp_err_errSum_%d", __LINE__) ); + hTmpErr->Reset(); + map errGroupHists; + + // plot each of the fractional contributions from all the errors. + // first, we make a list of error bands to plot... + bool drawn_already = (errorGroupName == "") ? true : false; + vector errNames = h->GetVertErrorBandNames(); + vector otherNames = h->GetLatErrorBandNames(); + errNames.insert( errNames.end(), otherNames.begin(), otherNames.end() ); + otherNames = h->GetUncorrErrorNames(); + errNames.insert( errNames.end(), otherNames.begin(), otherNames.end() ); + PlotUtils::MnvPlotter mnv_plotter(PlotUtils::kCCNuPionIncStyle); + for ( vector::const_iterator it_name = errNames.begin(); + it_name != errNames.end(); + ++it_name) + { + TH2D * hErr = NULL; + + if (h->HasVertErrorBand(*it_name)) + hErr = dynamic_cast(h->GetVertErrorBand(*it_name)->GetErrorBand( asfrac, covAreaNormalize ).Clone( Form("tmp_vertError_%s", (*it_name).c_str()) )); + else if (h->HasLatErrorBand(*it_name)) + hErr = dynamic_cast(h->GetLatErrorBand(*it_name)->GetErrorBand( asfrac, covAreaNormalize ).Clone( Form("tmp_latError_%s", (*it_name).c_str()) )); + else + throw std::runtime_error( Form("MnvPlotter::DrawErrorSummary(): Couldn't determine error band type for error name '%s'", (*it_name).c_str()) ); + + //is this histogram part of a group? + bool inGroup = false; + for (MnvPlotter::ErrorSummaryGroupMap::const_iterator itGroup = p.m_mnv_plotter.error_summary_group_map.begin(); + itGroup != p.m_mnv_plotter.error_summary_group_map.end(); ++itGroup ) { + const string& errName = itGroup->first; + const vector& histNames = itGroup->second; + + //if this histogram is not in the group we're considering, skip to the next one + if ( find( histNames.begin(), histNames.end(), *it_name) == histNames.end() ) + continue; + //std::cout << " MnvPlotter found " << errName << " " << *it_name << std::endl; + // if plotting the errors from only one group, + // we don't want to "sub-group" them any further. + // therefore we don't do any adding of histograms. + if (errorGroupName==errName) { + inGroup=true; + break; + } + // otherwise, if no group was specifically chosen, + // then (since this error band is already known to be in this group) + // we need to add it into the histogram for the group + // (or create that histogram if it doesn't exist yet). + else if (errorGroupName == "") { + map::iterator itGroupHist = errGroupHists.find(errName); + + if ( errGroupHists.end() == itGroupHist ) { + errGroupHists[ errName ] = hErr; + } + else { + AddInQuadrature2D( itGroupHist->second, hErr ); + delete hErr; + } + + inGroup = true; + break; + } + } + + // if we haven't selected a group whose constituents we want to see... + if ( errorGroupName=="" ) { + // we never want to show the individual plots + // when a histogram was included in a group: + // the sums will be drawn later. + if (inGroup) + continue; + + // ... when we are ignoring ungrouped errors, + // then NOTHING gets drawn here: + // the grouped errors were added to the group histogram + // above (and so we don't want them here), + // and the ungrouped ones we're ignoring altogether. + if (ignoreUngrouped) + continue; + } + // if we DID select a group to draw the constituents of, + // and this histogram isn't part of it, + // then we also don't want to see it. + else if ( errorGroupName != "" && !inGroup) + continue; + + //AddToTmp( hErr ); + + // don't draw any errors that have no bins above threshold + if ( 0 < ignoreThreshold && hErr->GetBinContent( hErr->GetMaximumBin() ) < ignoreThreshold ) + continue; + + p.m_mnv_plotter.ApplyNextLineStyle( hErr, false, useDifferentLineStyles); + + hErr->GetXaxis()->SetTitle(h->GetXaxis()->GetTitle()); + + map::const_iterator itErrCol = p.m_mnv_plotter.error_color_map.find( *it_name ); + if ( p.m_mnv_plotter.error_color_map.end() != itErrCol ) + hErr->SetLineColor( itErrCol->second ); + + hErr->SetLineWidth( p.m_mnv_plotter.mc_line_width ); + if (drawn_already) { + hErr->Draw( "HIST SAME" ); + } + else { + drawn_already = true; + hTmpErr->GetYaxis()->SetTitle( "Fractional Uncertainty" ); + if (!asfrac) hTmpErr->GetYaxis()->SetTitle( Ytitle.c_str() ); + if (!asfrac) hTmpErr->Scale(hTmpErr->GetBinWidth(1),"width"); + hTmpErr->Draw("HIST"); + + ////respect max/min setting the user may have used + if ( MnvHist::IsAutoAxisLimit( axis_minimum ) ) + hErr->SetMinimum( 0. ); + else + hErr->SetMinimum( axis_minimum ); + + //if (inGroup) { + //hErr->SetMaximum( headroom * axis_maximum_group ); + //} + if ( MnvHist::IsAutoAxisLimit( axis_maximum ) ) + hErr->SetMaximum( p.m_mnv_plotter.headroom * hTotalErr->GetMaximum() ); + else + hErr->SetMaximum( axis_maximum); + + hErr->GetYaxis()->SetTitle( "Fractional Uncertainty" ); + if (!asfrac) hErr->GetYaxis()->SetTitle( Ytitle.c_str() ); + //if (!asfrac) hErr->Scale(hErr->GetBinWidth(1),"width"); + hErr->Draw("HIST SAME"); + } + hists.push_back( hErr ); + names.push_back( *it_name ); + opts.push_back( "l" ); + } + + //add error groups + for ( map::iterator itGroup = errGroupHists.begin(); itGroup != errGroupHists.end(); ++itGroup ) + { + // std::cout << " (plot " << h->GetName() << ") drawing error group '" << itGroup->first << "'" << std::endl; + const string& name = itGroup->first; + TH2D* hist = itGroup->second; + + if ( 0 < ignoreThreshold && hist->GetBinContent( hist->GetMaximumBin() ) < ignoreThreshold ) + { + // std::cout << " (... ignored because its maximum (" << hist->GetBinContent( hist->GetMaximumBin() ) << ") was below threshold)" << std::endl; + continue; + } + + p.m_mnv_plotter.ApplyNextLineStyle( hist, false, useDifferentLineStyles); + + map::const_iterator itErrCol = p.m_mnv_plotter.error_color_map.find( name ); + if ( p.m_mnv_plotter.error_color_map.end() != itErrCol ) + hist->SetLineColor( itErrCol->second ); + + hist->SetLineWidth( p.m_mnv_plotter.mc_line_width ); + if (!asfrac)hist->Scale(hist->GetBinWidth(1),"width"); + hist->Draw( "HIST SAME" ); + hists.push_back( hist ); + names.push_back( name ); + opts.push_back( "l" ); + } + std::vector vecNames; + if (errorGroupName == ""){ + error_names.insert(pair>("Totals", names)); + vecNames = error_names["Totals"]; + } + else{ + error_names.insert(pair>(errorGroupName, names)); + vecNames = error_names[errorGroupName]; + } +/* std::string legPos = "BR"; + if ( legPos != "N" ) + { + size_t legendWidth = p.m_mnv_plotter.GetLegendWidthInLetters( names ); + double x1,y1,x2,y2; + p.m_mnv_plotter.DecodeLegendPosition( x1, y1, x2, y2, legPos, hists.size(), legendWidth ); + p.m_mnv_plotter.AddPlotLegend( hists, names, opts, x1, y1, x2-x1, y2-y1, p.m_mnv_plotter.legend_text_size ); + }*/ + + gPad->RedrawAxis(); + gPad->Update(); + + TGaxis::SetMaxDigits( oldMaxDigits ); + + return hists; +} + + + +//============================================================================== +// Some Systematics General Functions +//============================================================================== +void SetErrorGroups2D(MnvPlotter& mnv_plotter, bool is_subgroups = false) { + mnv_plotter.error_summary_group_map.clear(); + if (!is_subgroups){ + mnv_plotter.error_summary_group_map["LowQ2Pi"].push_back("LowQ2Pi"); + mnv_plotter.error_summary_group_map["Muon"].push_back("Muon_Energy_MINOS"); + mnv_plotter.error_summary_group_map["Muon"].push_back("Muon_Energy_MINERvA"); + mnv_plotter.error_summary_group_map["Muon"].push_back( + "Muon_Energy_Resolution"); + mnv_plotter.error_summary_group_map["Muon"].push_back( + "MINOS_Reconstruction_Efficiency"); + mnv_plotter.error_summary_group_map["Muon"].push_back("MuonAngleXResolution"); + mnv_plotter.error_summary_group_map["Muon"].push_back("MuonAngleYResolution"); + mnv_plotter.error_summary_group_map["Muon"].push_back("MuonResolution"); + mnv_plotter.error_summary_group_map["Pion_Reconstruction"].push_back("MichelEfficiency"); + mnv_plotter.error_summary_group_map["Flux"].push_back("Flux"); + mnv_plotter.error_summary_group_map["Others"].push_back("Target_Mass_CH"); + mnv_plotter.error_summary_group_map["Others"].push_back("Target_Mass_C"); + mnv_plotter.error_summary_group_map["Others"].push_back("Target_Mass_Fe"); + mnv_plotter.error_summary_group_map["Others"].push_back("Target_Mass_H2O"); + mnv_plotter.error_summary_group_map["Others"].push_back("Target_Mass_Pb"); + mnv_plotter.error_summary_group_map["Others"].push_back("response_em"); + mnv_plotter.error_summary_group_map["Others"].push_back("response_meson"); + mnv_plotter.error_summary_group_map["Others"].push_back("response_other"); + mnv_plotter.error_summary_group_map["Others"].push_back("response_proton"); + mnv_plotter.error_summary_group_map["Others"].push_back("GEANT_Proton"); + mnv_plotter.error_summary_group_map["Others"].push_back("GEANT_Pion"); + mnv_plotter.error_summary_group_map["Others"].push_back("GEANT_Neutron"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back("GENIE_D2_NormCCRES"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back( + "DiffractiveModelUnc"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back( + "CoherentPiUnc_C"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back( + "CoherentPiUnc_CH"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back( + "CoherentPiUnc_Fe"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back( + "CoherentPiUnc_H2O"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back( + "CoherentPiUnc_Pb"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back("GENIE_Rvn1pi"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back("GENIE_Rvp1pi"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back("GENIE_Rvn2pi"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back("GENIE_Rvp2pi"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back( + "RPA_LowQ2"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back( + "RPA_HighQ2"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back( + "Low_Recoil_2p2h_Tune"); + for (auto g : systematics::kGenieSystematics_InteractionModel) + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back(g); + for (auto g : systematics::kGenieSystematics_FSI_nucleons) + mnv_plotter.error_summary_group_map["GENIE_FSI"].push_back(g); + + for (auto g : systematics::kGenieSystematics_FSI_pions) + mnv_plotter.error_summary_group_map["GENIE_FSI"].push_back(g); + mnv_plotter.error_summary_group_map["Pion_Reconstruction"].push_back("TrackAngle"); + mnv_plotter.error_summary_group_map["Muon"].push_back("BeamAngle"); + mnv_plotter.error_summary_group_map["Muon"].push_back("BeamAngleX"); + mnv_plotter.error_summary_group_map["Muon"].push_back("BeamAngleY"); + mnv_plotter.error_summary_group_map["Pion_Reconstruction"].push_back("Birks"); + mnv_plotter.error_summary_group_map["Pion_Reconstruction"].push_back("BetheBloch"); + mnv_plotter.error_summary_group_map["Pion_Reconstruction"].push_back("Mass"); + mnv_plotter.error_summary_group_map["Pion_Reconstruction"].push_back("NodeCutEff"); + } + if (is_subgroups){ + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back("NonRESPi"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back("MnvTunes"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back("CCQE"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back("RESPi"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back( + "Coherent-Diffractive"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back( + "DIS-Hadronization"); + mnv_plotter.error_summary_group_map["Cross_Section_Models"].push_back("Elastic"); + + mnv_plotter.error_summary_group_map["NonRESPi"].push_back("GENIE_Rvn1pi"); + mnv_plotter.error_summary_group_map["NonRESPi"].push_back("GENIE_Rvp1pi"); + mnv_plotter.error_summary_group_map["NonRESPi"].push_back("GENIE_Rvn2pi"); + mnv_plotter.error_summary_group_map["NonRESPi"].push_back("GENIE_Rvp2pi"); + mnv_plotter.error_summary_group_map["MnvTunes"].push_back( + "Low_Recoil_2p2h_Tune"); + mnv_plotter.error_summary_group_map["MnvTunes"].push_back( + "RPA_LowQ2"); + mnv_plotter.error_summary_group_map["MnvTunes"].push_back( + "RPA_HighQ2"); + mnv_plotter.error_summary_group_map["CCQE"].push_back("GENIE_MaCCQE"); + mnv_plotter.error_summary_group_map["CCQE"].push_back("GENIE_VecFFCCQEshape"); + mnv_plotter.error_summary_group_map["CCQE"].push_back("GENIE_CCQEPauliSupViaKF"); + mnv_plotter.error_summary_group_map["RESPi"].push_back("GENIE_D2_MaRES"); + mnv_plotter.error_summary_group_map["RESPi"].push_back("GENIE_EP_MvRES"); + mnv_plotter.error_summary_group_map["RESPi"].push_back("GENIE_NormNCRES"); + mnv_plotter.error_summary_group_map["RESPi"].push_back("GENIE_Theta_Delta2Npi"); + mnv_plotter.error_summary_group_map["RESPi"].push_back("GENIE_D2_NormCCRES"); + mnv_plotter.error_summary_group_map["Coherent-Diffractive"].push_back("DiffractiveModelUnc"); + mnv_plotter.error_summary_group_map["Coherent-Diffractive"].push_back( + "CoherentPiUnc_CH"); + mnv_plotter.error_summary_group_map["DIS-Hadronization"].push_back("GENIE_AhtBY"); + mnv_plotter.error_summary_group_map["DIS-Hadronization"].push_back("GENIE_BhtBY"); + mnv_plotter.error_summary_group_map["DIS-Hadronization"].push_back("GENIE_CV1uBY"); + mnv_plotter.error_summary_group_map["DIS-Hadronization"].push_back("GENIE_CV2uBY"); + mnv_plotter.error_summary_group_map["DIS-Hadronization"].push_back("GENIE_NormDISCC"); + mnv_plotter.error_summary_group_map["Elastic"].push_back("GENIE_MaNCEL"); + mnv_plotter.error_summary_group_map["Elastic"].push_back("GENIE_EtaNCEL"); + + + + } + //-- define colors of the standard errors + mnv_plotter.error_color_map.clear(); + + /* + //Systematic color scheme + mnv_plotter.error_color_map["Flux"] = kYellow-3; + mnv_plotter.error_color_map["Genie_FSI"] = kGreen+2; + mnv_plotter.error_color_map["Genie_InteractionModel"] = kPink+2; + mnv_plotter.error_color_map["Detector"] = kCyan+2; + mnv_plotter.error_color_map["RPA"] = kOrange+2; + mnv_plotter.error_color_map["NonResPi"] = kRed+2; + mnv_plotter.error_color_map["Low_Recoil_2p2h_Tune"] = kViolet+2; + */ +} + +TH2D* AddingGroups(MnvPlotter& mnv_plotter, PlotUtils::MnvH2D& h, + std::string subgroup) { + SetErrorGroups2D(mnv_plotter, true); + std::vector group = + mnv_plotter.error_summary_group_map[subgroup]; + TH2D* ErrGroup = (TH2D*)h.Clone(Form("%s", subgroup.c_str())); + ErrGroup->Reset(); + for (int i = 0; i < (int)group.size(); ++i) { + TH2D* hErr = dynamic_cast( + h.GetVertErrorBand(group[i])->GetErrorBand(true, false).Clone(uniq())); + AddInQuadrature2D(ErrGroup, hErr); +// std::cout << "Error " << group[i] << " " << hErr->GetBinContent(2,2) << " Errorgroup " << ErrGroup->GetBinContent(2,2) << "\n"; + } +// std::vector ErrGroupVec; +//std::cout << "ErrorGroup " << subgroup << " " << ErrGroup->GetBinContent(2,2) << "\n"; + return ErrGroup; +// ErrGroupVec.push_back(ErrGroup); +// h.AddVertErrorBand( subgroup, ErrGroupVec); +/* for (int j = 1; j < (int)ErrGroup->GetNbinsY(); ++j){ + for(int i = 1; i < (int)ErrGroup->GetNbinsY(); ++i) + h.GetVertErrorBand(subgroup)->GetErrorBand(false, false).SetBinContent(i, j, ErrGroup->GetBinContent(i, j)); + }*/ +} + +void NiceColors(EventSelectionPlotInfo2D p, std::vector hvec, + std::vector names){ + +// p.m_mnv_plotter.good_colors = MnvColors::GetColors(MnvColors::k36Palette); + if(hvec.size() != names.size()){ + std::cout << "The size of the vectors are not compatible\n"; + return; + } + std::string alias = "Cross Section Models"; + + for (int i = 0; i < (int)hvec.size(); ++i){ +// if (names[i] == "NonRESPi") alias = "Sidebands"; +// else alias = names[i]; +// map::const_iterator itErrCol = p.m_mnv_plotter.error_color_map.find(alias); +// if ( p.m_mnv_plotter.error_color_map.end() != itErrCol ) +// std::cout << "Colors = " << itErrCol->second << "\n"; + hvec[i]->SetLineColor(206+(i*3)); + hvec[i]->SetLineWidth(p.m_mnv_plotter.mc_line_width); + + } +} + +void Plot_ErrorGroup2D(EventSelectionPlotInfo2D p, PlotUtils::MnvH2D* h, + std::string error_group_name, std::string tag, + double ignore_threshold = 0., double ymax = -1.) { + //std::cout << "Error Group name = " << error_group_name << "\n"; + int nxpads = 4; + int nypads = p.m_variable2D->NBinsY()/3; + if (p.m_variable2D->NBinsY() < 4){ + nxpads = p.m_variable2D->NBinsY(); + nypads = 1; + } + if (p.m_variable2D->NBinsY() > 4 && p.m_variable2D->NBinsY() < 8 ) + nypads = 2; + PlotUtils::GridCanvas* gridCanvas = new PlotUtils::GridCanvas(Form("2D_ErrorSummary_%s_%s_vs_%s_%s", tag.c_str(), p.m_variable2D->NameX().c_str(), p.m_variable2D->NameY().c_str(), error_group_name.c_str()), nxpads, nypads, 1400, 600); + std::cout << "N of pads = " << gridCanvas->GetPads().size() << "\n"; + p.m_mnv_plotter.good_colors = MnvColors::GetColors(MnvColors::k36Palette); + // Clone hist + PlotUtils::MnvH2D* hist = (PlotUtils::MnvH2D*)h->Clone("hist"); + + // X label + p.SetXLabel(hist); + + // For groups MnvPlotter sets the ymax to headroom*axis_maximum_group + // Or for summary, ymax = axis_maximum + if (ymax != -1.) { + p.m_mnv_plotter.axis_maximum = ymax; + p.m_mnv_plotter.axis_maximum_group = ymax; + p.m_mnv_plotter.headroom = 1.; + } + + const char* legend_position = error_group_name == "" ? "N" : "TR"; + std::vector ErrorHists = DrawErrorSummary2D(p, + hist, p.m_include_stat, true, ignore_threshold, + p.m_do_cov_area_norm, error_group_name, p.m_do_frac_unc); +/* double mx[11]; + std::cout << "Antes de GetMultipliers\n"; + std::vector mult = GetMultipliers(ErrorHists[0]); + std::cout << "Despues de GetMultipliers\n"; + std::cout << "Antes del ciclo de multipliers\n"; + for (int i = 0; i < 11; ++i){ + if (mult[i] > 1000) mx[i] = 1.; + else mx[i] = mult[i]; + }*/ + std::vector mult = GetMultipliers(ErrorHists); + double mx[p.m_variable2D->NBinsY()]; + std::vector bins; + for (int i = 0; i < p.m_variable2D->NBinsY(); ++i){ + bins.push_back(i+1); + if (mult[i] > 1000.) mx[i] = 1.; + else mx[i] = mult[i]; + } + bins.push_back(p.m_variable2D->NBinsY()+1); + + auto legend = new TLegend(0.88,0.9,1.,0.5); + std::vector names; + names = error_names[error_group_name]; + if (error_group_name != ""){ + Plot2D(p, ErrorHists, names, Form("%s_%s", tag.c_str(), + error_group_name.c_str()), "Fractional Uncertainty"); + } + else { + gridCanvas->SetRightMargin(0.12); + gridCanvas->SetLeftMargin(0.07); +// gridCanvas->ResetPads(); + ErrorHists[0]->GetXaxis()->SetLabelSize(0.03); + gridCanvas->SetInterpadSpace(0.008); + std::vector names; + + gridCanvas->DrawOneHist( ErrorHists[0] , "HIST", false, bins, false, mx); + legend->SetNColumns(1); + legend->SetFillStyle(0); + legend->SetLineColor(0); + if (error_group_name == ""){ + names = error_names["Totals"]; + legend->AddEntry(ErrorHists[0], names[0].c_str(), "l"); + } + else { + names = error_names[error_group_name]; + legend->AddEntry(ErrorHists[0], names[0].c_str(), "l"); + } + // Draw + for (int i = 1; i < (int)ErrorHists.size(); ++i) { + if (error_group_name == ""){ + legend->AddEntry(ErrorHists[i], names[i].c_str(), "l"); + } + else + legend->AddEntry(ErrorHists[0], names[i].c_str(), "l"); + gridCanvas->DrawOneHist( ErrorHists[i], "SAME HIST", false, bins, false, mx); + } + gridCanvas->DrawBinRanges(ErrorHists[0], 2, bins, Form("%s (%s)",p.m_variable2D->m_hists2D.m_xlabelY.c_str(), p.m_variable2D->m_unitsY.c_str()), 0.03, ".2f", 2); + //gridCanvas->SetYLimits(ignore_threshold, 1.); + gridCanvas->DrawMultipliers(sizeof(mx)/sizeof(double), mx); + gridCanvas->SetXTitle(Form("%s (%s)",p.m_variable2D->m_hists2D.m_xlabelX.c_str(), p.m_variable2D->m_unitsX.c_str())); + p.SetTitle(Form("%s %s vs %s", tag.c_str(), p.m_variable2D->m_hists2D.m_xlabelX.c_str(), + p.m_variable2D->m_hists2D.m_xlabelY.c_str())); + std::string yaxis = "Fractional Uncertainty "; + gridCanvas->SetYTitle(yaxis.c_str()); +// gridCanvas->ResetPads(); + gridCanvas->Draw(); + legend->Draw(); + + gridCanvas->Print(Form("2D_ErrorSummary_%s_%s_vs_%s_%s.png", tag.c_str(), + p.m_variable2D->NameX().c_str(), + p.m_variable2D->NameY().c_str(), + error_group_name.c_str())); + } +} + +//------------------------------------- +//------Event Selection Plots---------- +//------------------------------------- + +void PlotVar_Selection2D(EventSelectionPlotInfo2D p, bool do_bg = true, + bool do_log_scale = false, bool do_tuned_bg = false, + bool do_bin_width_norm = true){ + + std::cout << "Plotting Selection 2D" << p.m_variable2D->NameX() << "_vs_" << p.m_variable2D->NameY() << std::endl; + int nxpads = 4; + int nypads = p.m_variable2D->NBinsY()/3; + if (p.m_variable2D->NBinsY() < 4){ + nxpads = p.m_variable2D->NBinsY(); + nypads = 1; + } + if (p.m_variable2D->NBinsY() > 4 && p.m_variable2D->NBinsY() < 8 ) + nypads = 2; + PlotUtils::GridCanvas* StackedPlot =new PlotUtils::GridCanvas(Form("2D_Sel_%s_vs_%s",p.m_variable2D->NameX().c_str(), p.m_variable2D->NameY().c_str()), nxpads, nypads, 1400, 600); + // Make sure we remembered to load the source histos from the input file. + assert(p.m_variable2D->m_hists2D.m_selection_data); + assert(p.m_variable2D->m_hists2D.m_selection_mc.hist); + + // Get Hists + TH2D* data = nullptr; + if (!p.m_variable2D->m_is_true) + data = (TH2D*)p.m_variable2D->m_hists2D.m_selection_data->Clone( + "data"); + TH2D* mc = + (TH2D*)p.m_variable2D->m_hists2D.m_selection_mc.hist->Clone( + "mc"); + TH2D* mc_error = + new TH2D(p.m_variable2D->m_hists2D.m_selection_mc.hist->GetCVHistoWithError()); + + // Background + TH2D* tmp_bg = nullptr; + if (do_bg) { + if (do_tuned_bg) + tmp_bg = (TH2D*)(p.m_variable2D->m_hists2D.m_tuned_bg) + ->Clone("bg_tmp"); + else + tmp_bg = (TH2D*)(p.m_variable2D->m_hists2D.m_bg.hist) + ->Clone("bg_tmp"); + } else + tmp_bg = NULL; + + data->SetMarkerStyle(20); + data->SetMarkerSize(0.8); + data->SetMarkerColor(1); + data->SetLineWidth(1); + data->SetLineStyle(1); + data->SetLineColor(1); + tmp_bg->SetFillStyle(3000); + tmp_bg->SetFillColor(46); + tmp_bg->SetLineColor(46); + tmp_bg->SetLineWidth(1); + + mc->SetFillColor(0); + mc->SetLineColor(2); + mc->SetLineStyle(1); + mc->SetLineWidth(3); + + mc_error->SetFillColor(kRed-10); + mc_error->SetFillStyle(1001); + mc_error->SetMarkerStyle(0); + + // Log Scale +/* if (do_log_scale) { + canvas.SetLogy(); + p.m_mnv_plotter.axis_minimum = 1; + }*/ + + // Y-axis limit +// if (ymax > 0) p.m_mnv_plotter.axis_maximum = ymax; + + // X label + // p.SetXLabel(p.m_variable->m_hists2D.m_selection_mc.hist); + p.SetXLabel(mc_error); + p.SetXLabel(mc); + // p.SetXLabel(data); + + // Overall Normalization + double pot_scale = -99.; + if (p.m_do_cov_area_norm) + pot_scale = 1.; + else + pot_scale = p.m_data_pot / p.m_mc_pot; + + // Bin Width Normalization + if (do_bin_width_norm) { + if (tmp_bg) tmp_bg->Scale(pot_scale, "width"); + if (data) data->Scale(1., "width"); + mc->Scale(pot_scale, "width"); + mc_error->Scale(pot_scale, "width"); + // Y label +// std::string yaxis = "N Events / " + p.m_variable2D->m_unitsY; +// mc->GetYaxis()->SetTitle(yaxis.c_str()); + } + double mx[p.m_variable2D->NBinsY()]; + std::vector mult = GetMultipliers(data); + std::vector bins; + for (int i = 0; i < p.m_variable2D->NBinsY(); ++i){ + bins.push_back(i+1); + if (mult[i] > 1000) mx[i] = 1.; + else mx[i] = mult[i]; + } + bins.push_back(p.m_variable2D->NBinsY()+1); + + auto legend = new TLegend(0.88,0.9,1.,0.7); + legend->SetFillStyle(0); + legend->SetLineWidth(0); + legend->AddEntry(mc, "MC", "l"); + legend->AddEntry(tmp_bg, "BG", "f"); + legend->AddEntry(data, "Data", "p"); + + mc_error->GetXaxis()->SetLabelSize(0.03); + StackedPlot->SetTopMargin(0.1); + StackedPlot->SetRightMargin(0.12); + StackedPlot->SetLeftMargin(0.05); + StackedPlot->SetInterpadSpace(0.008); + StackedPlot->ResetPads(); + + // Draw + StackedPlot->DrawOneHist( mc_error, "E2", false, bins, false, mx); + StackedPlot->DrawOneHist( mc, "SAME HIST", false, bins, false, mx); + StackedPlot->DrawOneHist( tmp_bg, "SAME HIST", false, bins, false, mx); + StackedPlot->DrawOneHist(data, "SAME E1", false, bins, false, mx); + StackedPlot->DrawBinRanges(data, 2, bins, Form("%s (%s)",p.m_variable2D->m_hists2D.m_xlabelY.c_str(), p.m_variable2D->m_unitsY.c_str()), 0.03, ".2f", 2); + StackedPlot->DrawMultipliers(sizeof(mx)/sizeof(double), mx); + StackedPlot->SetXTitle(Form("%s (%s)",p.m_variable2D->m_hists2D.m_xlabelX.c_str(), p.m_variable2D->m_unitsX.c_str())); + p.SetTitle(Form("Selection %s vs %s", p.m_variable2D->m_hists2D.m_xlabelX.c_str(), + p.m_variable2D->m_hists2D.m_xlabelY.c_str())); + std::string yaxis = "N Events / " + p.m_variable2D->m_unitsY; + StackedPlot->SetYTitle(yaxis.c_str()); + StackedPlot->SetTitleSize(20); + StackedPlot->ResetPads(); + StackedPlot->Draw(); + legend->Draw(); + + std::string logy_str = do_log_scale ? "_logscale" : ""; + + std::string bg_str = do_tuned_bg ? "_tunedBG" : "_untunedBG"; + + std::string bwn_str = do_bin_width_norm ? "_BWN" : ""; + + StackedPlot->Print(Form("2D_Sel_%s_vs_%s_%s_%s.png", + p.m_variable2D->NameX().c_str(), + p.m_variable2D->NameY().c_str(), bg_str.c_str(), + bwn_str.c_str())); + +} + +void PlotVar_ErrorSummary2D(EventSelectionPlotInfo2D p) { + // Make sure we remembered to load the source histos from the input file. + assert(p.m_variable2D->m_hists2D.m_selection_mc.hist); + + SetErrorGroups2D(p.m_mnv_plotter, false); + + PlotUtils::MnvH2D* sel = + (PlotUtils::MnvH2D*)p.m_variable2D->m_hists2D.m_selection_mc.hist->Clone( + uniq()); + Plot_ErrorGroup2D(p, sel, "", "Sel", 0.0, 0.35); +// Plot_ErrorGroup(p, sel, "LEGENDONLY", "Sel", 0.0, 0.2); + Plot_ErrorGroup2D(p, sel, "2p2h", "Sel", 0.0, 0.01); + Plot_ErrorGroup2D(p, sel, "Detector", "Sel", 0.0, 0.15); + Plot_ErrorGroup2D(p, sel, "Flux", "Sel", 0.0, 0.15); + Plot_ErrorGroup2D(p, sel, "Genie_FSI_nucleons", "Sel", 0.004, 0.06); + Plot_ErrorGroup2D(p, sel, "Genie_FSI_pions", "Sel", 0.01, 0.1); + Plot_ErrorGroup2D(p, sel, "Genie_InteractionModel", "Sel", 0.01, 0.2); + Plot_ErrorGroup2D(p, sel, "Muon", "Sel", 0.0, 0.14); + Plot_ErrorGroup2D(p, sel, "NonResPi", "Sel", 0.0, 0.06); + Plot_ErrorGroup2D(p, sel, "RPA", "Sel", 0.0, 0.012); + // Plot_ErrorGroup(p, sel, "Michel", "Sel", 0.0, 0.15); + Plot_ErrorGroup2D(p, sel, "GENIE", "Sel", 0.0, 0.30); +// Plot_ErrorGroup2D(p, sel, "Target", "Sel", 0.0, 0.15); + Plot_ErrorGroup2D(p, sel, "Response", "Sel", 0.0, 0.05); + Plot_ErrorGroup2D(p, sel, "Diffractive", "Sel", 0.0, 0.15); + Plot_ErrorGroup2D(p, sel, "PhysicsModel", "Sel", 0.0, 0.15); +} + + + + +//============================================================================== +// Background-Subtracted +//============================================================================== +void Plot_BGSub2D(EventSelectionPlotInfo2D p, std::string outdir = ".", + double ymax = -1, bool do_log_scale = false, + bool do_bin_width_norm = true) { + std::cout << "Plotting BG-subtracted Data " << p.m_variable2D->NameX() + << " vs " << p.m_variable2D->NameY() + << std::endl; + + // Make sure we remembered to load the source histos from the input file. + assert(p.m_variable2D->m_hists2D.m_bg_subbed_data); + assert(p.m_variable2D->m_hists2D.m_effnum.hist); + int nxpads = 4; + int nypads = p.m_variable2D->NBinsY()/3; + if (p.m_variable2D->NBinsY() < 4){ + nxpads = p.m_variable2D->NBinsY(); + nypads = 1; + } + if (p.m_variable2D->NBinsY() > 4 && p.m_variable2D->NBinsY() < 8 ) + nypads = 2; + + PlotUtils::GridCanvas* StackedPlot =new PlotUtils::GridCanvas(Form("2D_BG_%s_vs_%s",p.m_variable2D->NameX().c_str(), p.m_variable2D->NameY().c_str()), nxpads, nypads, 1400, 600); + StackedPlot->SetTitle("Background Subtracted"); + + + // Get Hists + TH2D* bg_sub_data_w_tot_error = + new TH2D(p.m_variable2D->m_hists2D.m_bg_subbed_data->GetCVHistoWithError()); + TH2D* bg_sub_data_w_stat_error = new TH2D( + p.m_variable2D->m_hists2D.m_bg_subbed_data->GetCVHistoWithStatError()); + TH2D* effnum_cv = + new TH2D(p.m_variable2D->m_hists2D.m_effnum.hist->GetCVHistoWithStatError()); + TH2D* effnum_w_stat_error = + new TH2D(p.m_variable2D->m_hists2D.m_effnum.hist->GetCVHistoWithStatError()); + + bg_sub_data_w_tot_error->SetMarkerStyle(20); + bg_sub_data_w_tot_error->SetMarkerSize(0.8); + bg_sub_data_w_tot_error->SetMarkerColor(1); + bg_sub_data_w_tot_error->SetLineWidth(1); + bg_sub_data_w_tot_error->SetLineStyle(1); + bg_sub_data_w_tot_error->SetLineColor(1); + bg_sub_data_w_stat_error->SetMarkerStyle(20); + bg_sub_data_w_stat_error->SetMarkerSize(0.8); + bg_sub_data_w_stat_error->SetMarkerColor(1); + bg_sub_data_w_stat_error->SetLineWidth(1); + bg_sub_data_w_stat_error->SetLineStyle(1); + bg_sub_data_w_stat_error->SetLineColor(1); + + effnum_cv->SetFillColor(0); + effnum_cv->SetLineColor(2); + effnum_cv->SetLineStyle(1); + effnum_cv->SetLineWidth(3); + + effnum_w_stat_error->SetFillColor(kRed-10); + effnum_w_stat_error->SetFillStyle(1001); + effnum_w_stat_error->SetMarkerStyle(0); + + // Log Scale +/* if (do_log_scale) { + canvas.SetLogy(); + p.m_mnv_plotter.axis_minimum = 1; + } +*/ + // Y-axis range +//if (ymax > 0) p.m_mnv_plotter.axis_maximum = ymax; + + // X label + p.SetXLabel(bg_sub_data_w_tot_error); + p.SetXLabel(bg_sub_data_w_stat_error); + p.SetXLabel(effnum_w_stat_error); + + // Overall Normalization + double pot_scale = -99.; + // PlotUtils::MnvH1D* tmp_bg = nullptr; + if (p.m_do_cov_area_norm) { + pot_scale = 1.; + } else { + pot_scale = p.m_data_pot / p.m_mc_pot; + } + + // Bin Width Normalization + std::string yaxis = "N Events"; + if (do_bin_width_norm) { + bg_sub_data_w_tot_error->Scale(1., "width"); + bg_sub_data_w_stat_error->Scale(1., "width"); + effnum_w_stat_error->Scale(pot_scale, "width"); + effnum_cv->Scale(pot_scale, "width"); + // Y label + yaxis = yaxis + " / " + p.m_variable2D->m_unitsY; +// effnum_w_stat_error->GetYaxis()->SetTitle(yaxis.c_str()); + } + // Draw +// const bool use_hist_titles = false; +// p.m_mnv_plotter.DrawDataMCWithErrorBand(bg_sub_data_w_tot_error, +// effnum_w_stat_error, pot_scale, "TR", +// use_hist_titles); + + // p.m_mnv_plotter.DrawDataMCWithErrorBand(bg_sub_data_w_stat_error, + // effnum_w_stat_error, pot_scale, "TR"); + // p.m_mnv_plotter.DrawDataMC(bg_sub_data_w_tot_error, effnum_w_stat_error, + // pot_scale, "TR"); + // p.m_mnv_plotter.DrawDataMCWithErrorBand(bg_sub_data_w_error, effnum, + // pot_scale, "TR", + // use_hist_titles, NULL, NULL, + // p.m_do_cov_area_norm, + // p.m_include_stat); + + // POT info +//if (p.m_do_cov_area_norm) +// p.m_mnv_plotter.AddAreaNormBox(p.m_data_pot, p.m_mc_pot, 0.3, 0.88); +//else +// p.m_mnv_plotter.AddPOTNormBox(p.m_data_pot, p.m_mc_pot, 0.3, 0.88); + + // Label re: error bars +//p.m_mnv_plotter.AddPlotLabel("MC stat-only errors", 0.7, 0.75, 0.03); + + // Plot Title +// p.m_mnv_plotter.title_size = 0.04; +// StackedPlot->SetTitleSize(10.); + double mx[p.m_variable2D->NBinsY()]; + std::vector mult = GetMultipliers(bg_sub_data_w_stat_error); + std::vector bins; + for (int i = 0; i < p.m_variable2D->NBinsY(); ++i){ + bins.push_back(i+1); + if (mult[i] > 1000) mx[i] = 1.; + else mx[i] = mult[i]; + } + bins.push_back(p.m_variable2D->NBinsY()+1); + +// std::vector bins = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + + auto legend = new TLegend(0.92,0.65,0.98,0.78); + legend->SetFillStyle(0); + legend->SetLineColor(0); + legend->AddEntry(effnum_cv, "MC", "l"); +//legend->AddEntry(tmp_bg, "BG", "f"); + legend->AddEntry(bg_sub_data_w_stat_error, "Data", "p"); + + StackedPlot->SetRightMargin(0.12); + StackedPlot->SetLeftMargin(0.07); + StackedPlot->SetInterpadSpace(0.008); + StackedPlot->ResetPads(); + effnum_w_stat_error->GetXaxis()->SetLabelSize(0.03); + // Draw + StackedPlot->DrawOneHist( effnum_w_stat_error, "E2", false, bins, false, mx); + StackedPlot->DrawOneHist( effnum_cv, "SAME HIST", false, bins, false, mx); + StackedPlot->DrawOneHist(bg_sub_data_w_stat_error, "SAME E1", false, bins, false, mx); + StackedPlot->DrawBinRanges(bg_sub_data_w_stat_error, 2, bins, Form("%s (%s)",p.m_variable2D->m_hists2D.m_xlabelY.c_str(), p.m_variable2D->m_unitsY.c_str()), 0.03, ".2f", 2); + StackedPlot->DrawMultipliers(sizeof(mx)/sizeof(double), mx); + StackedPlot->SetXTitle(Form("%s (%s)",p.m_variable2D->m_hists2D.m_xlabelX.c_str(), p.m_variable2D->m_unitsX.c_str())); + p.SetTitle(Form("Background Subtracted %s vs %s", p.m_variable2D->m_hists2D.m_xlabelX.c_str(), + p.m_variable2D->m_hists2D.m_xlabelY.c_str())); + StackedPlot->SetYTitle(yaxis.c_str()); + StackedPlot->SetTitle("Background Subtracted"); + StackedPlot->ResetPads(); + StackedPlot->SetHistTexts(); + StackedPlot->Draw(); + legend->Draw(); + std::string logy_str = do_log_scale ? "_logscale" : ""; + + std::string bwn_str = do_bin_width_norm ? "_BWN" : ""; + + StackedPlot->Print(Form("2D_BG_%s_vs_%s_%s.png", + p.m_variable2D->NameX().c_str(), + p.m_variable2D->NameY().c_str(), + bwn_str.c_str())); + +} + +// Error Summary BG +void PlotBG_ErrorSummary2D(EventSelectionPlotInfo2D p, bool do_tuned = false) { + SetErrorGroups2D(p.m_mnv_plotter, false); + PlotUtils::MnvH2D* bg; + + if (do_tuned) + bg = + (PlotUtils::MnvH2D*)p.m_variable2D->m_hists2D.m_tuned_bg->Clone("tuned_bg"); + else + bg = (PlotUtils::MnvH2D*)p.m_variable2D->m_hists2D.m_bg.hist->Clone("bg"); + + std::string name = p.m_variable2D->NameX() + "_vs_" + p.m_variable2D->NameY(); + std::string tuned_str = do_tuned ? "BGTuned" : "BGUntuned"; + + // name, ignore threshold, ymax +// Plot_ErrorGroup(p, bg, "LEGENDONLY", tuned_str, 0.0); + Plot_ErrorGroup2D(p, bg, "", tuned_str, 0.0); +// Plot_ErrorGroup(p, bg, "2p2h", tuned_str, 0.0, 0.05); +// Plot_ErrorGroup(p, bg, "Detector", tuned_str, detector_threshold, +// detector_ymax); +// Plot_ErrorGroup(p, bg, "Flux", tuned_str, 0.0, 0.15); +// Plot_ErrorGroup(p, bg, "Genie_FSI_pions", tuned_str, FSI_threshold, FSI_ymax); +// Plot_ErrorGroup(p, bg, "Genie_FSI_nucleons", tuned_str, FSI_threshold, +// FSI_ymax); +// Plot_ErrorGroup(p, bg, "Genie_InteractionModel", tuned_str, Int_threshold, +// Int_ymax); +// Plot_ErrorGroup(p, bg, "NonResPi", tuned_str, 0.0, 0.1); +// Plot_ErrorGroup(p, bg, "RPA", tuned_str, 0.0, 0.1); +// Plot_ErrorGroup(p, bg, "Target", tuned_str, 0.0, 0.15); +// Plot_ErrorGroup(p, bg, "Response", tuned_str, 0.0, 0.30); +// Plot_ErrorGroup(p, bg, "Diffractive", tuned_str, 0.0, 0.05); +// Plot_ErrorGroup(p, bg, "PhysicsModel", tuned_str, 0.0, 0.05); +} +void PlotMigration2D(EventSelectionPlotInfo2D p, PlotUtils::MnvH2D* hist, std::string nameX, std::string nameY) { + TGaxis::SetExponentOffset(-0.035, -0.048, "x"); + TH2D* htmp = GetHistWithUnderOverFlow(hist); + TH2D* htmp2 = RowNormalize(htmp); + htmp2->GetXaxis()->SetTitle(Form("Reconstructed %s per %s bin", p.m_variable2D->m_hists2D.m_xlabelX.c_str(), p.m_variable2D->m_hists2D.m_xlabelY.c_str())); + htmp2->GetYaxis()->SetTitle(Form("Truth %s per %s bin", p.m_variable2D->m_hists2D.m_xlabelX.c_str(), p.m_variable2D->m_hists2D.m_xlabelY.c_str())); + TCanvas c("c1", "c1"); + PlotUtils::MnvPlotter mnv_plotter(PlotUtils::kCCNuPionIncStyle); + mnv_plotter.SetWhiteRainbowPalette(); +// mnv_plotter.SetRedHeatPalette(); + bool draw_as_matrix = false; + bool coarseContours = false; + bool includeFlows = true; + bool no_text = true; + gStyle->SetHistMinimumZero(kFALSE); + mnv_plotter.DrawNormalizedMigrationHistogram(htmp2, draw_as_matrix, coarseContours, + includeFlows, no_text); + // gStyle->SetPaintTextFormat("2.0f"); + // htmp2->SetMarkerSize(2); + // htmp2->Draw("colz text"); + p.SetTitle("Migration matrix"); + c.Update(); + c.Print(Form("2D_Migration_VarBins_%s_vs_%s.png", nameX.c_str(), nameY.c_str())); + // c.SetLogz(); + // c.Update(); + // c.Print("WMigrationMatrix_Wbins_logz.png"); + TGaxis::SetExponentOffset(0, 0, "x"); +} + +void Plot_Unfolded2D(EventSelectionPlotInfo2D p, MnvH2D* data, MnvH2D* mc, + std::string outdir = ".", double ymax = -1, + bool do_log_scale = false, bool do_bin_width_norm = true) { + std::cout << "Plotting Unfoldeding " << p.m_variable2D->NameX() << " vs " << p.m_variable2D->NameY()<< std::endl; + int nxpads = 4; + int nypads = p.m_variable2D->NBinsY()/3; + if (p.m_variable2D->NBinsY() < 4){ + nxpads = p.m_variable2D->NBinsY(); + nypads = 1; + } + if (p.m_variable2D->NBinsY() > 4 && p.m_variable2D->NBinsY() < 8 ) + nypads = 2; + PlotUtils::GridCanvas* GridPlot =new PlotUtils::GridCanvas(Form("2D_Unfold_%s_vs_%s",p.m_variable2D->NameX().c_str(), p.m_variable2D->NameY().c_str()), nxpads, nypads, 1400, 600); + GridPlot->SetTitle("Unfolding"); + + // Make sure we remembered to load the source histos from the input file. + assert(data); + assert(mc); + +// TCanvas canvas("c1", "c1"); + + // Get Hists + PlotUtils::MnvH2D* unfolded = (PlotUtils::MnvH2D*)data->Clone("unfolded"); + PlotUtils::MnvH2D* effnum_true = (PlotUtils::MnvH2D*)mc->Clone("effnum_true"); + TH2D* unfolded_w_tot_error = new TH2D(unfolded->GetCVHistoWithError()); + TH2D* unfolded_w_stat_error = new TH2D(unfolded->GetCVHistoWithStatError()); + TH2D* effnum_cv = + new TH2D(effnum_true->GetCVHistoWithStatError()); + TH2D* effnum_w_stat_error = + new TH2D(effnum_true->GetCVHistoWithStatError()); + + unfolded_w_tot_error->SetMarkerStyle(20); + unfolded_w_tot_error->SetMarkerSize(0.8); + unfolded_w_tot_error->SetMarkerColor(1); + unfolded_w_tot_error->SetLineWidth(1); + unfolded_w_tot_error->SetLineStyle(1); + unfolded_w_tot_error->SetLineColor(1); + unfolded_w_stat_error->SetMarkerStyle(20); + unfolded_w_stat_error->SetMarkerSize(0.8); + unfolded_w_stat_error->SetMarkerColor(1); + unfolded_w_stat_error->SetLineWidth(1); + unfolded_w_stat_error->SetLineStyle(1); + unfolded_w_stat_error->SetLineColor(1); + effnum_cv->SetFillColor(0); + effnum_cv->SetLineColor(2); + effnum_cv->SetLineStyle(1); + effnum_cv->SetLineWidth(3); + + effnum_w_stat_error->SetFillColor(kRed-10); + effnum_w_stat_error->SetFillStyle(1001); + effnum_w_stat_error->SetMarkerStyle(0); + + + // Log Scale +/* if (do_log_scale) { + canvas.SetLogy(); + p.m_mnv_plotter.axis_minimum = 1; + } +*/ + // Y-axis range +// if (ymax > 0) p.m_mnv_plotter.axis_maximum = ymax; + + // X label + p.SetXLabel(effnum_w_stat_error); + p.SetXLabel(unfolded_w_tot_error); + p.SetXLabel(unfolded_w_stat_error); + p.SetXLabel(effnum_cv); + + // Overall Normalization + double pot_scale = -99.; + if (p.m_do_cov_area_norm) { + pot_scale = 1.; + } else { + pot_scale = p.m_data_pot / p.m_mc_pot; + } + + // Bin Width Normalization + std::string yaxis = "N Events"; + if (do_bin_width_norm) { + unfolded_w_tot_error->Scale(1., "width"); + unfolded_w_stat_error->Scale(1., "width"); + effnum_w_stat_error->Scale(pot_scale, "width"); + effnum_cv->Scale(pot_scale, "width"); + + // Y label + yaxis = yaxis + " / " + p.m_variable2D->m_unitsY; + } + + // Draw + double mx[p.m_variable2D->NBinsY()]; + std::vector mult = GetMultipliers(unfolded_w_stat_error); + std::vector bins; + for (int i = 0; i < p.m_variable2D->NBinsY(); ++i){ + bins.push_back(i+1); + if (mult[i] > 1000) mx[i] = 1.; + else mx[i] = mult[i]; + } + bins.push_back(p.m_variable2D->NBinsY()+1); + +// std::vector bins = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + + auto legend = new TLegend(0.92,0.65,0.98,0.78); + legend->SetFillStyle(0); + legend->SetLineColor(0); + legend->AddEntry(effnum_cv, "MC", "l"); +//legend->AddEntry(tmp_bg, "BG", "f"); + legend->AddEntry(unfolded_w_stat_error, "Data", "p"); + + GridPlot->SetRightMargin(0.12); + GridPlot->SetLeftMargin(0.07); + GridPlot->SetInterpadSpace(0.008); + GridPlot->ResetPads(); + effnum_w_stat_error->GetXaxis()->SetLabelSize(0.03); + // Draw + GridPlot->DrawOneHist( effnum_w_stat_error, "E2", false, bins, false, mx); + GridPlot->DrawOneHist( effnum_cv, "SAME HIST", false, bins, false, mx); + GridPlot->DrawOneHist(unfolded_w_stat_error, "SAME E1", false, bins, false, mx); + GridPlot->DrawBinRanges(unfolded_w_stat_error, 2, bins, Form("%s (%s)",p.m_variable2D->m_hists2D.m_xlabelY.c_str(), p.m_variable2D->m_unitsY.c_str()), 0.03, ".2f", 2); + GridPlot->DrawMultipliers(sizeof(mx)/sizeof(double), mx); + GridPlot->SetXTitle(Form("%s (%s)",p.m_variable2D->m_hists2D.m_xlabelX.c_str(), p.m_variable2D->m_unitsX.c_str())); + p.SetTitle(Form("Unfolded %s vs %s", p.m_variable2D->m_hists2D.m_xlabelX.c_str(), + p.m_variable2D->m_hists2D.m_xlabelY.c_str())); + GridPlot->SetYTitle(yaxis.c_str()); +//GridPlot->SetTitle(Form("Background Subtracted %s", GetSignalName(p.m_signal_definition).c_str())); + GridPlot->ResetPads(); + GridPlot->Draw(); + legend->Draw(); + std::string logy_str = do_log_scale ? "_logscale" : ""; + + std::string bwn_str = do_bin_width_norm ? "_BWN" : ""; + + GridPlot->Print(Form("2D_Unfolded_%s_vs_%s_%s.png", + p.m_variable2D->NameX().c_str(), + p.m_variable2D->NameY().c_str(), + bwn_str.c_str())); + + +} +void PlotUnfolded_ErrorSummary2D(EventSelectionPlotInfo2D p) { + SetErrorGroups2D(p.m_mnv_plotter, false); + std::cout << "In errorSummary2D Unfolded \n"; + PlotUtils::MnvH2D* unf = + (PlotUtils::MnvH2D*)p.m_variable2D->m_hists2D.m_unfolded->Clone(uniq()); + +// Plot_ErrorGroup2D(p, unf, "LEGENDONLY", "Unfolded", 0.0); + Plot_ErrorGroup2D(p, unf, "", "Unfolded", 0.0); +// Plot_ErrorGroup2D(p, unf, "2p2h", "Unfolded", 0.0, 0.02); +// Plot_ErrorGroup2D(p, unf, "Detector", "Unfolded", 0.0, 0.08); +// Plot_ErrorGroup2D(p, unf, "Flux", "Unfolded", 0.0, 0.06); +// Plot_ErrorGroup2D(p, unf, "Genie_FSI_nucleons", "Unfolded", 0.01, 0.1); +// Plot_ErrorGroup2D(p, unf, "Genie_FSI_pions", "Unfolded", 0.01, 0.1); +// Plot_ErrorGroup2D(p, unf, "Genie_InteractionModel", "Unfolded", 0.01, 0.1); +// Plot_ErrorGroup2D(p, unf, "NonResPi", "Unfolded", 0.0, 0.1); +// Plot_ErrorGroup2D(p, unf, "RPA", "Unfolded", 0.0, 0.02); +// Plot_ErrorGroup2D(p, unf, "Target", "Unfolded", 0.0, 0.1); +// Plot_ErrorGroup2D(p, unf, "Response", "Unfolded", 0.0, 0.24); +// Plot_ErrorGroup2D(p, unf, "Diffractive", "Unfolded", 0.0, 0.02); +// Plot_ErrorGroup2D(p, unf, "PhysicsModel", "Unfolded", 0.0, 0.02); +// Plot_ErrorGroup2D(p, unf, "Muon", "Unfolded", 0.0, 0.14); +} +void PlotMC2D(EventSelectionPlotInfo2D p, MnvH2D* mc, std::string ylabel = "", + std::string outdir = ".", double ymax = -1, + bool do_log_scale = false, bool do_bin_width_norm = true) { + std::cout << ylabel + " 2D " << p.m_variable2D->NameX() << " vs " << p.m_variable2D->NameY()<< std::endl; + int nxpads = 4; + int nypads = p.m_variable2D->NBinsY()/4; + if (p.m_variable2D->NBinsY() < 4){ + nxpads = p.m_variable2D->NBinsY(); + nypads = 1; + } + if (p.m_variable2D->NBinsY() > 4 && p.m_variable2D->NBinsY() < 8 ) + nypads = 2; + PlotUtils::GridCanvas* GridPlot =new PlotUtils::GridCanvas(Form("2D_%s_%s_vs_%s", ylabel.c_str(), p.m_variable2D->NameX().c_str(), p.m_variable2D->NameY().c_str()), nxpads, nypads, 1400, 600); + GridPlot->SetTitle(Form("%s", ylabel.c_str())); + // Make sure we remembered to load the source histos from the input file. + assert(mc); +// TCanvas canvas("c1", "c1"); + // Get Hists + PlotUtils::MnvH2D* hist = (PlotUtils::MnvH2D*)mc->Clone("hist"); + TH2D* hist_w_cv = + new TH2D(hist->GetCVHistoWithError()); + TH2D* hist_w_tot_error = + new TH2D(hist->GetCVHistoWithError()); + + hist_w_tot_error->SetFillColor(kRed-10); + hist_w_tot_error->SetFillStyle(1001); + hist_w_tot_error->SetMarkerStyle(0); + + hist_w_cv->SetFillColor(0); + hist_w_cv->SetLineColor(2); + hist_w_cv->SetLineStyle(1); + hist_w_cv->SetLineWidth(3); + + + // Log Scale +/* if (do_log_scale) { + canvas.SetLogy(); + p.m_mnv_plotter.axis_minimum = 1; + } +*/ + // Y-axis range +// if (ymax > 0) p.m_mnv_plotter.axis_maximum = ymax; + + // X label + p.SetXLabel(hist_w_tot_error); + + // Overall Normalization + double pot_scale = -99.; + if (p.m_do_cov_area_norm) { + pot_scale = 1.; + } else { + pot_scale = p.m_data_pot / p.m_mc_pot; + } + + // Bin Width Normalization + std::string yaxis = ylabel; + if (do_bin_width_norm) { + hist_w_tot_error->Scale(pot_scale, "width"); + hist_w_cv->Scale(pot_scale, "width"); + // Y label + yaxis = yaxis + " / " + p.m_variable2D->m_unitsY; + } + + // Draw +// std::cout << "Number of bins " << p.m_variable2D->NBinsY() <<"\n"; + double mx[p.m_variable2D->NBinsY()]; + std::vector mult = GetMultipliers(hist_w_cv); + std::vector bins; + for (int i = 0; i < p.m_variable2D->NBinsY(); ++i){ + bins.push_back(i+1); +// std::cout << "Pasa 1\n"; + if (mult[i] > 1000.) mx[i] = 1.; + else mx[i] = mult[i]; + } + bins.push_back(p.m_variable2D->NBinsY()+1); +// std::cout << "Pasa 2 " << sizeof(mx)/sizeof(double) <<"\n"; + auto legend = new TLegend(0.92,0.65,0.98,0.78); + legend->SetFillStyle(0); + legend->SetLineColor(0); + legend->AddEntry(hist_w_cv, "MC", "l"); + + GridPlot->SetRightMargin(0.12); + GridPlot->SetLeftMargin(0.07); + GridPlot->SetInterpadSpace(0.008); + GridPlot->ResetPads(); + hist_w_tot_error->GetXaxis()->SetLabelSize(0.03); + // Draw + GridPlot->DrawOneHist( hist_w_tot_error, "E2", false, bins, false, mx); + GridPlot->DrawOneHist( hist_w_cv, "SAME HIST", false, bins, false, mx); + GridPlot->DrawBinRanges(hist_w_cv, 2, bins, Form("%s (%s)", + p.m_variable2D->m_hists2D.m_xlabelY.c_str(), + p.m_variable2D->m_unitsY.c_str()), 0.03, ".2f", 2); + GridPlot->DrawMultipliers( sizeof(mx)/sizeof(double) , mx); + GridPlot->SetXTitle(Form("%s (%s)",p.m_variable2D->m_hists2D.m_xlabelX.c_str(), + p.m_variable2D->m_unitsX.c_str())); + p.SetTitle(ylabel + " " + p.m_variable2D->m_hists2D.m_xlabelX.c_str() + + " vs " + p.m_variable2D->m_hists2D.m_xlabelY.c_str()); + GridPlot->SetYTitle(yaxis.c_str()); + GridPlot->SetTitle(Form("%s", ylabel.c_str())); +// GridPlot->ResetPads(); + GridPlot->Draw(); + legend->Draw(); + GridPlot->Update(); + std::string logy_str = do_log_scale ? "_logscale" : ""; + + std::string bwn_str = do_bin_width_norm ? "_BWN" : ""; + + GridPlot->Print(Form("2D_%s_%s_vs_%s_%s.png", ylabel.c_str(), + p.m_variable2D->NameX().c_str(), + p.m_variable2D->NameY().c_str(), + bwn_str.c_str())); +} + +void PlotEfficiency_ErrorSummary2D(EventSelectionPlotInfo2D p) { + SetErrorGroups2D(p.m_mnv_plotter, false); + std::cout << "In errorSummary2D Efficiency \n"; + PlotUtils::MnvH2D* eff = + (PlotUtils::MnvH2D*)p.m_variable2D->m_hists2D.m_efficiency->Clone(uniq()); + +// Plot_ErrorGroup2D(p, eff, "LEGENDONLY", "Unfolded", 0.0); + Plot_ErrorGroup2D(p, eff, "", "Efficiency", 0.0); +// Plot_ErrorGroup2D(p, eff, "2p2h", "Unfolded", 0.0, 0.02); +// Plot_ErrorGroup2D(p, eff, "Detector", "Unfolded", 0.0, 0.08); +// Plot_ErrorGroup2D(p, eff, "Flux", "Unfolded", 0.0, 0.06); +// Plot_ErrorGroup2D(p, eff, "Genie_FSI_nucleons", "Unfolded", 0.01, 0.1); +// Plot_ErrorGroup2D(p, eff, "Genie_FSI_pions", "Unfolded", 0.01, 0.1); +// Plot_ErrorGroup2D(p, eff, "Genie_InteractionModel", "Unfolded", 0.01, 0.1); +// Plot_ErrorGroup2D(p, eff, "NonResPi", "Unfolded", 0.0, 0.1); +// Plot_ErrorGroup2D(p, eff, "RPA", "Unfolded", 0.0, 0.02); +// Plot_ErrorGroup2D(p, eff, "Target", "Unfolded", 0.0, 0.1); +// Plot_ErrorGroup2D(p, eff, "Response", "Unfolded", 0.0, 0.24); +// Plot_ErrorGroup2D(p, eff, "Diffractive", "Unfolded", 0.0, 0.02); +// Plot_ErrorGroup2D(p, eff, "PhysicsModel", "Unfolded", 0.0, 0.02); +// Plot_ErrorGroup2D(p, eff, "Muon", "Unfolded", 0.0, 0.14); +} + +void Plot_CrossSection2D(EventSelectionPlotInfo2D p, MnvH2D* data, MnvH2D* mc, + std::string outdir = ".", double ymax = -1, + bool do_log_scale = false, + bool do_bin_width_norm = true) { + + int nxpads = 4; + int nypads = p.m_variable2D->NBinsY()/4; + if (p.m_variable2D->NBinsY() < 4){ + nxpads = p.m_variable2D->NBinsY(); + nypads = 1; + } + if (p.m_variable2D->NBinsY() > 4 && p.m_variable2D->NBinsY() < 8 ) + nypads = 2; + std::cout << "Plotting Cross Section " << p.m_variable2D->NameX() << " vs " << p.m_variable2D->NameY()<< std::endl; + PlotUtils::GridCanvas* GridPlot =new PlotUtils::GridCanvas(Form("2D_CrossSection_%s_vs_%s",p.m_variable2D->NameX().c_str(), p.m_variable2D->NameY().c_str()), nxpads, nypads, 1400, 600); + GridPlot->SetTitle("Cross Section"); + //GridPlot->SetInterpadSpace(0.0005); + // Make sure we remembered to load the source histos from the input file. + assert(data); + assert(mc); + +// TCanvas canvas("c1", "c1"); + + // Get Hists + PlotUtils::MnvH2D* xsec_data = (PlotUtils::MnvH2D*)data->Clone("xsec_data"); + PlotUtils::MnvH2D* xsec_mc = (PlotUtils::MnvH2D*)mc->Clone("xsec_mc"); + TH2D* xsec_data_w_tot_error = new TH2D(xsec_data->GetCVHistoWithError()); + TH2D* xsec_data_w_stat_error = new TH2D(xsec_data->GetCVHistoWithStatError()); + TH2D* xsec_mc_cv = + new TH2D(xsec_mc->GetCVHistoWithStatError()); + TH2D* xsec_mc_w_stat_error = + new TH2D(xsec_mc->GetCVHistoWithStatError()); + + xsec_data_w_tot_error->SetMarkerStyle(20); + xsec_data_w_tot_error->SetMarkerSize(0.8); + xsec_data_w_tot_error->SetMarkerColor(1); + xsec_data_w_tot_error->SetLineWidth(1); + xsec_data_w_tot_error->SetLineStyle(1); + xsec_data_w_tot_error->SetLineColor(1); + xsec_data_w_stat_error->SetMarkerStyle(20); + xsec_data_w_stat_error->SetMarkerSize(0.8); + xsec_data_w_stat_error->SetMarkerColor(1); + xsec_data_w_stat_error->SetLineWidth(1); + xsec_data_w_stat_error->SetLineStyle(1); + xsec_data_w_stat_error->SetLineColor(1); + xsec_mc_cv->SetFillColor(0); + xsec_mc_cv->SetLineColor(2); + xsec_mc_cv->SetLineStyle(1); + xsec_mc_cv->SetLineWidth(3); + + xsec_mc_w_stat_error->SetFillColor(kRed-10); + xsec_mc_w_stat_error->SetFillStyle(1001); + xsec_mc_w_stat_error->SetMarkerStyle(0); + + + // Log Scale +/* if (do_log_scale) { + canvas.SetLogy(); + p.m_mnv_plotter.axis_minimum = 1; + } +*/ + // Y-axis range +// if (ymax > 0) p.m_mnv_plotter.axis_maximum = ymax; + + // X label + p.SetXLabel(xsec_mc_w_stat_error); + p.SetXLabel(xsec_data_w_stat_error); + p.SetXLabel(xsec_mc_cv); + p.SetXLabel(xsec_mc_w_stat_error); + // Overall Normalization + double pot_scale = -99.; + if (p.m_do_cov_area_norm) { + pot_scale = 1.; + } else { + pot_scale = p.m_data_pot / p.m_mc_pot; + } + + // Bin Width Normalization + std::string yaxis = ""; + if (do_bin_width_norm) { + xsec_data_w_tot_error->Scale(1.e42, "width"); + xsec_data_w_stat_error->Scale(1.e42, "width"); + xsec_mc_w_stat_error->Scale(1.e42, "width"); + xsec_mc_cv->Scale(1.e42, "width"); + std::string div = Form("#frac{d^{2}#sigma}{d%sd%s}",p.m_variable2D->m_hists2D.m_xlabelX.c_str(), p.m_variable2D->m_hists2D.m_xlabelY.c_str()); + // Y label + yaxis = div + " (10^{-42} cm^{2}/" + p.m_variable2D->m_unitsY + "*" + + p.m_variable2D->m_unitsY + "/nucleon)"; + } + // Draw + double mx[p.m_variable2D->NBinsY()]; + std::vector mult = GetMultipliers(xsec_data_w_stat_error); + std::vector bins; + for (int i = 0; i < p.m_variable2D->NBinsY(); ++i){ + bins.push_back(i+1); + if (mult[i] > 1000) mx[i] = 1.; + else mx[i] = mult[i]; + } + bins.push_back(p.m_variable2D->NBinsY()+1); + + // std::vector bins = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; + + auto legend = new TLegend(0.88,0.65,0.98,0.78); + legend->SetFillStyle(0); + legend->SetLineColor(0); + legend->AddEntry(xsec_mc_cv, "MC", "l"); +//legend->AddEntry(tmp_bg, "BG", "f"); + legend->AddEntry(xsec_data_w_stat_error, "Data", "p"); + + GridPlot->SetRightMargin(0.12); + GridPlot->SetLeftMargin(0.07); + GridPlot->SetTopMargin(0.1); + GridPlot->SetInterpadSpace(0.008); + GridPlot->ResetPads(); + xsec_mc_w_stat_error->GetXaxis()->SetLabelSize(0.03); + // Draw + GridPlot->DrawOneHist( xsec_mc_w_stat_error, "SAME E2", false, bins, false, mx); + GridPlot->DrawOneHist( xsec_mc_cv, "SAME HIST", false, bins, false, mx); + GridPlot->DrawOneHist(xsec_data_w_tot_error, "SAME E1", false, bins, false, mx); + GridPlot->DrawBinRanges(xsec_data_w_tot_error, 2, bins, Form("%s (%s)",p.m_variable2D->m_hists2D.m_xlabelY.c_str(), p.m_variable2D->m_unitsY.c_str()), 0.03, ".2f", 2); + GridPlot->DrawMultipliers(sizeof(mx)/sizeof(double), mx); + GridPlot->SetXTitle(Form("%s (%s)",p.m_variable2D->m_hists2D.m_xlabelX.c_str(), p.m_variable2D->m_unitsX.c_str())); + p.SetTitle(Form("Cross Section %s vs %s", p.m_variable2D->m_hists2D.m_xlabelX.c_str(), + p.m_variable2D->m_hists2D.m_xlabelY.c_str())); + GridPlot->SetYTitle(yaxis.c_str()); + GridPlot->SetTitleSize(20); +// GridPlot->SetTitle(Form("Background Subtracted %s", GetSignalName(p.m_signal_definition).c_str())); +// GridPlot->ResetPads(); + GridPlot->Draw(); + legend->Draw(); + std::string logy_str = do_log_scale ? "_logscale" : ""; + + std::string bwn_str = do_bin_width_norm ? "_BWN" : ""; + + GridPlot->Print(Form("2D_CrossSection_%s_vs_%s_%s.png", + p.m_variable2D->NameX().c_str(), + p.m_variable2D->NameY().c_str(), + bwn_str.c_str())); + +} + +void PlotCrossSection_ErrorSummary2D(EventSelectionPlotInfo2D p) { + SetErrorGroups2D(p.m_mnv_plotter, false); + std::cout << "In errorSummary2D Cross Section \n"; + PlotUtils::MnvH2D* xsec = + (PlotUtils::MnvH2D*)p.m_variable2D->m_hists2D.m_cross_section->Clone(uniq()); + +// Plot_ErrorGroup2D(p, xsec, "LEGENDONLY", "Unfolded", 0.0); + Plot_ErrorGroup2D(p, xsec, "", "CrossSection", 0.0); + Plot_ErrorGroup2D(p, xsec, "Flux", "CrossSection", 0.0); + Plot_ErrorGroup2D(p, xsec, "Pion_Reconstruction", "CrossSection", 0.0); + Plot_ErrorGroup2D(p, xsec, "GENIE_FSI", "CrossSection", 0.0); + Plot_ErrorGroup2D(p, xsec, "Muon", "CrossSection", 0.0); + Plot_ErrorGroup2D(p, xsec, "Others", "CrossSection", 0.0); + + std::vector XsecModelsvec; + XsecModelsvec.push_back(AddingGroups(p.m_mnv_plotter, *xsec, "NonRESPi")); + XsecModelsvec.push_back(AddingGroups(p.m_mnv_plotter, *xsec, "RESPi")); + XsecModelsvec.push_back(AddingGroups(p.m_mnv_plotter, *xsec, "CCQE")); + XsecModelsvec.push_back(AddingGroups(p.m_mnv_plotter, *xsec, "Coherent-Diffractive")); + XsecModelsvec.push_back(AddingGroups(p.m_mnv_plotter, *xsec, "DIS-Hadronization")); + XsecModelsvec.push_back(AddingGroups(p.m_mnv_plotter, *xsec, "MnvTunes")); + XsecModelsvec.push_back(AddingGroups(p.m_mnv_plotter, *xsec, "Elastic")); + +// AddingGroups(p.m_mnv_plotter, *xsec, "NonRESPi"); +// AddingGroups(p.m_mnv_plotter, *xsec, "RESPi"); +// AddingGroups(p.m_mnv_plotter, *xsec, "CCQE"); +// AddingGroups(p.m_mnv_plotter, *xsec, "Coherent-Diffractive"); +// AddingGroups(p.m_mnv_plotter, *xsec, "DIS-Hadronization"); +// AddingGroups(p.m_mnv_plotter, *xsec, "MnvTunes"); +// AddingGroups(p.m_mnv_plotter, *xsec, "Elastic"); + + SetErrorGroups2D(p.m_mnv_plotter, true); + std::vector names{"NonRESPi", "RESPi", "CCQE", + "Coherent-Diffractive", "DIS-Hadronization", + "MnvTunes", "Elastic"}; +// Plot_ErrorGroup2D(p, xsec, "Cross_Section_Models", "CrossSection", 0.0); + NiceColors(p, XsecModelsvec, names); + + Plot2D(p, XsecModelsvec, names, "CrossSection_Cross_Section_Models", + "Fractional Uncertainty"); + Plot_ErrorGroup2D(p, xsec, "RESPi", "CrossSection", 0.0); + Plot_ErrorGroup2D(p, xsec, "NonRESPi", "CrossSection", 0.0); + Plot_ErrorGroup2D(p, xsec, "CCQE", "CrossSection", 0.0); + Plot_ErrorGroup2D(p, xsec, "Coherent-Diffractive", "CrossSection", 0.0); + Plot_ErrorGroup2D(p, xsec, "DIS-Hadronization", "CrossSection", 0.0); + Plot_ErrorGroup2D(p, xsec, "MnvTunes", "CrossSection", 0.0); + Plot_ErrorGroup2D(p, xsec, "Elastic", "CrossSection", 0.0); + +} +