diff --git a/data/flux/ANL_1977_2horn_rescan.root b/data/flux/ANL_1977_2horn_rescan.root new file mode 100644 index 0000000..3524d3a Binary files /dev/null and b/data/flux/ANL_1977_2horn_rescan.root differ diff --git a/data/flux/BNL_NuInt02_rescan.root b/data/flux/BNL_NuInt02_rescan.root new file mode 100644 index 0000000..ed4604e Binary files /dev/null and b/data/flux/BNL_NuInt02_rescan.root differ diff --git a/parameters/config.xml b/parameters/config.xml index 834932e..6507c32 100644 --- a/parameters/config.xml +++ b/parameters/config.xml @@ -1,187 +1,192 @@ <nuisance> <!-- # ###################################################### --> <!-- # NUISANCE CONFIGURATION OPTIONS --> <!-- # This file is read in by default at runtime --> <!-- # If you want to override on a case by case bases use -q at runtime --> <!-- # ###################################################### --> <!-- # MAIN Configs --> <!-- # ###################################################### --> <!-- # Logger goes from --> <!-- # 1 Quiet --> <!-- # 2 Fitter --> <!-- # 3 Samples --> <!-- # 4 Reconfigure Loops --> <!-- # 5 Every Event print out (SHOUT) --> <!-- # -1 DEBUGGING --> <config verbosity='5'/> <config VERBOSITY='5'/> <!-- # ERROR goes from --> <!-- # 0 NONE --> <!-- # 1 FATAL --> <!-- # 2 WARN --> <config ERROR='2'/> <config TRACE='0'/> <config cores='2' /> <config spline_test_throws='50' /> <config spline_cores='6' /> <config spline_chunks='10' /> <config spline_procchunk='-1' /> <config Electron_NThetaBins='4' /> <config Electron_NEnergyBins='4' /> <config Electron_ThetaWidth='1.0' /> <config Electron_EnergyWidth='0.10' /> <config RemoveFSIParticles='0' /> <config RemoveUndefParticles='0' /> <config RemoveNuclearParticles='0'/> <config logging.JointFCN.cxx='4'/> <!-- # Input Configs --> <!-- # ###################################################### --> <!-- # Default Requirements file for the externalDataFitter Package --> <!-- # MAX Events : -1 is no cut. Events will be scaled automatically to give good xsec predictions. --> <config input.maxevents='-1'/> <config MAXEVENTS='-1'/> <config input.MAXEVENTS='-1'/> <config includeemptystackhists='0'/> <!-- # Turn on/off event manager --> <!-- # EventManager enables us to only loop number of events once for multiple projections of the same measurements --> <!-- # e.g. MiniBooNE CC1pi+ Q2 and MiniBooNE CC1pi+ Tmu would ordinarily require 2 reconfigures, but with this enabled it requires only one --> <config input.eventmanager='1'/> <config EventManager='1'/> <!-- # Event Directories --> <!-- # Can setup default directories and use @EVENT_DIR/path to link to it --> <config EVENT_DIR='/data2/stowell/NIWG/'/> <config NEUT_EVENT_DIR='/data2/stowell/NIWG/neut/fit_samples_neut5.3.3/'/> <config GENIE_EVENT_DIR='/data2/stowell/NIWG/genie/fit_samples_R.2.10.0/'/> <config NUWRO_EVENT_DIR='/data2/stowell/NIWG/nuwro/fit_samples/'/> <config GIBUU_EVENT_DIR='/data/GIBUU/DIR/'/> <config SaveNuWroExtra='0' /> <!-- # In PrepareGENIE the reconstructed splines can be saved into the file --> <config save_genie_splines='1'/> <!-- # In InputHandler the option to regenerate NuWro flux/xsec plots is available --> <!-- # Going to move this to its own app soon --> <config input.regen_nuwro_plots='0'/> <!-- # DEVEL CONFIG OPTION, don't touch! --> <config CacheSize='0'/> <!-- # ReWeighting Configuration Options --> <!-- # ###################################################### --> <!-- # Set absolute twkdial for parameters --> <config params.setabstwk='0'/> <!-- # Convert Dials in output statements using dial conversion card --> <config convert_dials='0'/> <!-- # Make RW Calculations be quiet --> <config params.silentweighting='0'/> <!-- # Vetos can be used to specify RW dials NOT to be loaded in --> <!-- # Useful if one specific one has an issue --> <config FitWeight.fNIWGRW_veto=''/> <config FitWeight.fNuwroRW_veto=''/> <config FitWeight.fNeutRW_veto=''/> <config FitWeight.fGenieRW_veto=''/> <!-- # Output Options --> <!-- # ###################################################### --> <!-- # Save Nominal prediction with all rw engines at default --> <config savenominal='0'/> <!-- # Save prefit with values at starting values --> <config saveprefit='0'/> <!-- # Here's the full list of drawing options --> <!-- # See src/FitBase/Measurement1D::Write for more info --> <!-- #config drawopts DATA/MC/EVT/FINE/RATIO/MODES/SHAPE/RESIDUAL/MATRIX/FLUX/MASK/MAP --> <!-- #config drawopts DATA/MC --> <config drawopts='DATA/MC/EVT/FINE/RATIO/MODES/SHAPE/FLUX/XSEC/MASK/COV/INCOV/DECOMP/CANVPDG/CANVMC/SETTINGS'/> <config InterpolateSigmaQ0Histogram='1' /> <config InterpolateSigmaQ0HistogramRes='100' /> <config InterpolateSigmaQ0HistogramThrow='1' /> <config InterpolateSigmaQ0HistogramNTHROWS='100000' /> <!-- # Save the shape scaling applied with option SHAPE into the main MC hist --> <config saveshapescaling='0'/> <config CorrectGENIEMECNorm='1'/> <!-- # Set style of 1D output histograms --> <config linecolour='1'/> <config linestyle='1'/> <config linewidth='1'/> <!-- # For GenericFlux --> <config isLiteMode='0'/> <!-- # Statistical Options --> <!-- # ###################################################### --> <!-- # Add MC Statistical error to likelihoods --> <config statutils.addmcerror='0'/> <!-- # NUISMIN Configurations --> <!-- # ###################################################### --> <config minimizer.maxcalls='1000000'/> <config minimizer.maxiterations='1000000'/> <config minimizer.tolerance='0.001'/> <!-- # Number of events required in low stats routines --> <config minimizer.lowstatevents='25000'/> <!-- # Error band generator configs --> <!-- # ###################################################### --> <!-- # For -f ErrorBands creates error bands for given measurements --> <!-- # How many throws do we want (The higher the better precision) --> <config error_throws='250'/> <!-- # Are we throwing uniform or according to Gaussian? --> <!-- # Only use uniform if wanting to study the limits of a dial. --> <config error_uniform='0'/> <config WriteSeperateStacks='1'/> <!-- # Other Individual Case Configs --> <!-- # ###################################################### --> <!-- # Covariance throw options for fake data studies with MiniBooNE data. --> <config thrown_covariance='FULL'/> <config throw_mc_stat='0.0'/> <config throw_diag_syst='0'/> <config throw_corr_syst='0'/> <config throw_mc_stat='0'/> <!-- # Apply a shift to the muon momentum before calculation of Q2 --> <config muon_momentum_shift='0.0'/> <config muon_momentum_throw='0'/> <!-- # MINERvA Specific Configs --> <config MINERvA_XSec_CCinc_2DEavq3_nu.hadron_cut='0'/> <config MINERvA_CCinc_XSec_2DEavq3_nu.useq3true='0'/> <config Modes.split_PN_NN='0'/> <config SignalReconfigures='0'/> <!-- # SciBooNE specific --> <config SciBarDensity='1.04'/> <config SciBarRecoDist='10.0'/> <config PenetratingMuonEnergy='1.4'/> <config NumRangeSteps='50'/> + +<config GENIEWeightEngine_CCRESMode="kModeMaMv"/> +<config GENIEInputHandler.SavePrimary="0" /> + </nuisance> + diff --git a/scripts/plotlimitdist.py b/scripts/plotlimitdist.py new file mode 100644 index 0000000..cbb6134 --- /dev/null +++ b/scripts/plotlimitdist.py @@ -0,0 +1,178 @@ +from ROOT import * +from array import array +import sys + +def GetUID(name): + return name.replace("_" + name.split("_")[-1],"") +def GetValue(name): + return float(name.split("_")[-1]) + + +colorlist = [kGreen,kRed, kBlue, kOrange] + +infile = TFile(sys.argv[1], "READ") +alllimitdir = infile.Get("Limits") + +# Make starting legend +leg = TLegend(0.1,0.1,0.9,0.9) +alluidstyles = {} +alllines = [] + +c1 = TCanvas("c1","c1",1000,600) + +for dirkey in alllimitdir.GetListOfKeys(): + if dirkey.GetName() == "nominal": + linedata = TLine(0.1,0.1,0.9,0.9) + linedata.SetLineColor(kBlack) + leg.AddEntry(linedata, "DATA", "l") + alllines.append(linedata) + + linemc = TLine(0.1,0.1,0.9,0.9) + linemc.SetLineColor(kGreen) + leg.AddEntry(linemc, "Nominal MC", "l") + alllines.append(linemc) + alluidstyles["nominal"] = kGreen + + else: + uid = GetUID(dirkey.GetName()) + if uid not in alluidstyles: + alluidstyles[uid] = colorlist[len(alluidstyles)] + line = TLine(0.1,0.1,0.9,0.9) + line.SetLineColor( alluidstyles[uid] ) + leg.AddEntry(line, uid, "l") + alllines.append(line) + +leg.Draw() +gPad.Update() +c1.SaveAs("limitplots.pdf(") +gStyle.SetOptTitle(1) +c1.Clear() +c1.Divide(3,1) + +# Get Nominal +nomdir = infile.Get("Limits/nominal") +for plotkey in nomdir.GetListOfKeys(): + + # Only get data + if (not plotkey.GetName().endswith("_data")): continue + + # Get Plots + data = nomdir.Get(plotkey.GetName()) + datashape = nomdir.Get(plotkey.GetName()).Clone() + mc = nomdir.Get(plotkey.GetName().replace("data","MC")) + mcshape = nomdir.Get(plotkey.GetName().replace("data","MC_SHAPE")) + + if not data or not mc: continue + + # Draw nominal and data + c1.cd(1) + data.GetYaxis().SetRangeUser(0.0, data.GetMaximum()*1.5) + data.SetLineColor(kBlack) + data.SetLineWidth(3) + data.Draw("E1") + mc.SetLineColor(kGreen) + mc.SetLineWidth(3) + mc.Draw("SAME HIST") + alllimitmc = [] + + c1.cd(2) + datashape.GetYaxis().SetRangeUser(0.0, data.GetMaximum()*1.5) + datashape.SetLineColor(kBlack) + datashape.SetLineWidth(3) + datashape.SetTitle(datashape.GetName() + "_SHAPE") + datashape.Draw("E1") + mcshape.SetLineWidth(3) + mcshape.SetLineColor(kGreen) + mcshape.Draw("SAME HIST") + + likelihoodvals = {} + maxlike = 0.0 + minlike = 1.E9 + + + + # Loop through and get limit plots + for dirkey in alllimitdir.GetListOfKeys(): + if dirkey.GetName() == "nominal": continue + limitdir = alllimitdir.Get(dirkey.GetName()) + limitmc = limitdir.Get(plotkey.GetName().replace("_data","_MC")).Clone() + limitmcshape = limitdir.Get(plotkey.GetName().replace("_data","_MC_SHAPE")).Clone() + + print "Getting from key:", limitdir, limitmc + uid = GetUID(dirkey.GetName()) + if uid not in likelihoodvals: + likelihoodvals[uid] = [] + + limitmc.SetLineColor( alluidstyles[uid] ) + limitmc.SetLineWidth(1) + + limitmcshape.SetLineColor( alluidstyles[uid] ) + limitmcshape.SetLineWidth(1) + + c1.cd(1) + limitmc.Draw("SAME HIST C") + alllimitmc.append(limitmc) + + c1.cd(2) + limitmcshape.Draw("SAME HIST C") + alllimitmc.append(limitmcshape) + + xval = float(GetValue(dirkey.GetName())) + yval = float(limitmc.GetTitle()) + likelihoodvals[uid].append([xval,yval]) + + maxlike = max([maxlike, (float(limitmc.GetTitle()))]) + minlike = min([minlike, (float(limitmc.GetTitle()))]) + + + + #likelihoodvals["nominal"] = [[-1000, minlike], +# [1000, minlike]] +# alluidstyles["nominal"] = kGreen +# likelihoodvals["nominal2"] = [[1000, minlike+1.00], +# [-1000, minlike+1.00]] +# alluidstyles["nominal2"] = kGreen +# likelihoodvals["nominal3"] = [[-1000, minlike+7.82], +# [1000, minlike+7.82]] +# alluidstyles["nominal3"] = kGreen + + # Make like hist + c1.cd(3) + dif = (maxlike - minlike)/10.0 + allgr = [] + for i, uid in enumerate(sorted(likelihoodvals)): + print i, uid + xvals = [] + yvals = [] + for valset in sorted(likelihoodvals[uid]): + xvals.append(valset[0]) + yvals.append(valset[1]) + + + gr = TGraph(len(xvals), array('f',xvals), array('f',yvals)) + gr.SetTitle("Likelihood Scan about Nominal") + gr.SetLineColor( alluidstyles[uid] ) + + if "nominal" in uid: + gr.SetMarkerStyle(20) + gr.SetMarkerColor(kGreen) + if i == 0: + gr.Draw("APL") + else: gr.Draw("SAME PL") + + gr.GetYaxis().SetRangeUser(minlike - dif, maxlike + dif) + allgr.append(gr) + + c1.Update() + c1.SaveAs("limitplots.pdf") + +c1.SaveAs("limitplots.pdf)") + + + + + + + + + diff --git a/scripts/plotnuiscomp.py b/scripts/plotnuiscomp.py new file mode 100644 index 0000000..13369a1 --- /dev/null +++ b/scripts/plotnuiscomp.py @@ -0,0 +1,175 @@ +from ROOT import * +import os +import sys + + +gColorList = [kRed, kGreen, kBlue, kYellow, kOrange, kBlack] + +def DrawDataMC(keyname, filelist): + + # Extract Data + data = None + for readfile in filelist: + print keyname + data = readfile[0].Get(keyname) + if not data: continue + break + + if not data: + print "Data not found for : ", keyname + sys.exit(-1) + + # Main Data Formatting + data.SetTitle(keyname) + data.SetLineColor(kBlack) + data.SetLineWidth(2) + + # Extract MC + singlemclist = [] + singledatalist = [] + for i, mcfile in enumerate(allfiles): + + print mcfile[0] + # Extract individual MC + mckey = keyname.replace("_data","_MC") + singlemc = mcfile[0].Get(mckey) + if singlemc: + + singlemc = singlemc.Clone(mcfile[1]+"_MC") + singlemc.SetLineColor( gColorList[i] ) + singlemc.SetLineWidth(2) + singlemc.SetTitle( mcfile[1] + " (" + str(singlemc.GetTitle().strip()) + ") " ) + + singlemclist.append(singlemc.Clone()) + del singlemc + + # Extra individual data (optional) + singledata = mcfile[0].Get(keyname) + if singledata: + + singledata = singledata.Clone(mcfile[1] + "_DATA") + singledata.SetLineColor( kBlack ) + singledata.SetLineWidth(2) + singledata.SetTitle( "^-> Saved Data" ) + + singledatalist.append(singledata.Clone()) + del singledata + + + # Assign Ranges + miny = 99999.9 + maxy = 0.0 + for i in range(data.GetNbinsX()): + miny = min([data.GetBinContent(i+1) - data.GetBinError(i+1),miny]) + maxy = max([data.GetBinContent(i+1) + data.GetBinError(i+1),maxy]) + for singlemc in singlemclist: + miny = min([singlemc.GetMinimum(),miny]) + maxy = max([singlemc.GetMaximum(),maxy]) + for singledata in singledatalist: + miny = min([singledata.GetMinimum(),miny]) + maxy = max([singledata.GetMaximum(),maxy]) + widthy = maxy - miny + + # Assign Ranges to data + if "1D" in keyname: data.GetYaxis().SetRangeUser( miny - 0.1*widthy, maxy + 0.3*widthy) + elif "2D" in keyname: data.GetZaxis().SetRangeUser( miny - 0.1*widthy, maxy + 0.3*widthy) + + # Draw Plots 1D + if "1D" in keyname: + data.Draw("E1") + for mc in singlemclist: + mc.Draw("SAME HIST") + + # Draw Plots 2D + elif "2D" in keyname: + data.Draw("E1") + for mc in singlemclist: + mc.Draw("SAME LEGO") + + # Build Legend + leg = gPad.BuildLegend(0.45,0.65,0.8,0.85) + leg.SetFillStyle(0) + leg.SetFillColorAlpha(0,0.0) + leg.SetBorderSize(0) + + gStyle.SetOptTitle(1) + gPad.SetGridx(0) + gPad.SetGridy(0) + gPad.Update() + + singlemclist.append(data) + return singlemclist + + +if __name__=="__main__": + c1 = TCanvas("c1","c1",210*4,297*4) + c1.cd() + + + # Make filelist + allfiles = [] + + for i in xrange(2, len(sys.argv)): + print "Reading ", i, sys.argv[i] + + # split by comma + splitname = sys.argv[i].split(",") + + # Get First + if (os.path.isfile(splitname[0])): + + # Get File + newfile = (TFile(splitname[0],"READ")) + if not newfile: + print "File is not a ROOT file : ", splitname[0] + sys.exit() + + # Set Name + name = splitname[0].replace(".root","") + if len(splitname) > 1: + name = splitname[1] + + allfiles.append([newfile, name]) + + + print allfiles + + # Parse Unique Keys + uniquekeys = [] + for readfile in allfiles: + for readkey in readfile[0].GetListOfKeys(): + if not (readkey.GetName().endswith("_data")): continue + if readkey.GetName() not in uniquekeys: uniquekeys.append(readkey.GetName()) + + print uniquekeys + + # Setup First Page + leg = TLegend(0.1,0.1,0.9,0.9) + for i, readfile in enumerate(allfiles): + hist = TH1D(readfile[1],readfile[1],1,0,1) + hist.SetLineColor(gColorList[i % len(gColorList)]) + hist.SetLineWidth(2) + + leg.AddEntry(hist, readfile[1], "l") + + leg.Draw() + gPad.Update() + + + outputfile = sys.argv[1] + c1.Print(outputfile + "(") + + + # Loop through unique keys + for readkey in uniquekeys: + + # Draw + datamclist = DrawDataMC(readkey, allfiles) + + # Save + c1.Print(outputfile) + + # Now save the legend again to close... + leg.Draw() + gPad.Update() + gPad.Print(outputfile + ")") diff --git a/scripts/plotnuismin.py b/scripts/plotnuismin.py new file mode 100644 index 0000000..1ef01c7 --- /dev/null +++ b/scripts/plotnuismin.py @@ -0,0 +1,273 @@ +from ROOT import * +import os +import sys + + +gColorList = [kRed, kGreen, kBlue, kYellow, kOrange, kBlack] + +def DrawDataMC(keyname, filelist): + + # Extract Data + data = None + for readfile in filelist: + print keyname + data = readfile[0].Get(keyname) + if not data: continue + break + + if not data: + print "Data not found for : ", keyname + sys.exit(-1) + + # Main Data Formatting + data.SetTitle(keyname) + data.SetLineColor(kBlack) + data.SetLineWidth(2) + + # Extract MC + singlemclist = [] + singledatalist = [] + for i, mcfile in enumerate(allfiles): + + print mcfile[0] + # Extract individual MC + mckey = keyname.replace("_data","_MC") + singlemc = mcfile[0].Get(mckey) + if singlemc: + + singlemc = singlemc.Clone(mcfile[1]+"_MC") + singlemc.SetLineColor( gColorList[i] ) + singlemc.SetLineWidth(2) + singlemc.SetTitle( mcfile[1] + " (" + str(singlemc.GetTitle().strip()) + ") " ) + + singlemclist.append(singlemc.Clone()) + del singlemc + + # Extra individual data (optional) + singledata = mcfile[0].Get(keyname) + if singledata: + + singledata = singledata.Clone(mcfile[1] + "_DATA") + singledata.SetLineColor( kBlack ) + singledata.SetLineWidth(2) + singledata.SetTitle( "^-> Saved Data" ) + + singledatalist.append(singledata.Clone()) + del singledata + + + # Assign Ranges + miny = 99999.9 + maxy = 0.0 + for i in range(data.GetNbinsX()): + miny = min([data.GetBinContent(i+1) - data.GetBinError(i+1),miny]) + maxy = max([data.GetBinContent(i+1) + data.GetBinError(i+1),maxy]) + for singlemc in singlemclist: + miny = min([singlemc.GetMinimum(),miny]) + maxy = max([singlemc.GetMaximum(),maxy]) + for singledata in singledatalist: + miny = min([singledata.GetMinimum(),miny]) + maxy = max([singledata.GetMaximum(),maxy]) + widthy = maxy - miny + + # Assign Ranges to data + if "1D" in keyname: data.GetYaxis().SetRangeUser( miny - 0.1*widthy, maxy + 0.3*widthy) + elif "2D" in keyname: data.GetZaxis().SetRangeUser( miny - 0.1*widthy, maxy + 0.3*widthy) + + # Draw Plots 1D + if "1D" in keyname: + data.Draw("E1") + for mc in singlemclist: + mc.Draw("SAME HIST") + + # Draw Plots 2D + elif "2D" in keyname: + data.Draw("E1") + for mc in singlemclist: + mc.Draw("SAME LEGO") + + # Build Legend + leg = gPad.BuildLegend(0.45,0.65,0.8,0.85) + leg.SetFillStyle(0) + leg.SetFillColorAlpha(0,0.0) + leg.SetBorderSize(0) + + gStyle.SetOptTitle(1) + gPad.SetGridx(0) + gPad.SetGridy(0) + gPad.Update() + + singlemclist.append(data) + return singlemclist + +def DrawFitDialsPlot(allfiles): + + singlemclist = [] + singlelimitlist = [] + for i, mcfile in enumerate(allfiles): + + singlemc = mcfile[0].Get("fit_dials") + if not singlemc: continue + + # Setup fit result + singlemc = singlemc.Clone(mcfile[1]+"_FIT") + singlemc.SetLineColor( gColorList[i] ) + singlemc.SetFillColorAlpha( gColorList[i], 0.3 ) + singlemc.SetLineWidth(2) + singlemc.SetTitle( mcfile[1] ) + + singlemclist.append(singlemc.Clone()) + del singlemc + + # Setup Limits + singlestart = mcfile[0].Get("start_dials") + singlemin = mcfile[0].Get("min_dials") + singlemax = mcfile[0].Get("max_dials") + + print singlestart, singlemin, singlemax + + singlestart.SetLineColor(gColorList[i]) + singlestart.SetLineWidth(1) + singlestart.SetLineStyle(7) + singlelimitlist.append(singlestart.Clone()) + + singlemin.SetLineColor(gColorList[i]) + singlemin.SetLineWidth(2) + singlemin.SetLineStyle(5) + singlelimitlist.append(singlemin.Clone()) + + singlemax.SetLineColor(gColorList[i]) + singlemax.SetLineWidth(2) + singlemax.SetLineStyle(5) + singlelimitlist.append(singlemax.Clone()) + + + # Assign Ranges + miny = 99999.9 + maxy = 0.0 + + for singlemc in singlemclist: + miny = min([singlemc.GetMinimum(),miny]) + maxy = max([singlemc.GetMaximum(),maxy]) + for singlelimit in singlelimitlist: + miny = min([singlelimit.GetMinimum(),miny]) + maxy = max([singlelimit.GetMaximum(),maxy]) + + widthy = maxy - miny + + # Assign Ranges to data + data = singlemclist[0] + data.GetYaxis().SetRangeUser( miny - 0.1*widthy, maxy + 0.3*widthy) + + # Draw our limits + for i, mc in enumerate(singlemclist): + if i == 0: mc.Draw("E2") + else: mc.Draw("SAME E2") + + leg = gPad.BuildLegend(0.7,0.8,1.0,1.0) + + + for limit in singlelimitlist: + limit.Draw("SAME HIST") + + for mc in singlemclist: + mc.Draw("SAME E2") + + startline = TLine(0.6,0.6,0.8,0.8) + limitline = TLine(0.6,0.6,0.8,0.8) + startline.SetLineStyle(7) + limitline.SetLineStyle(5) + leg.AddEntry(startline, "Start", "l") + leg.AddEntry(limitline, "Limits", "l") + + linehists = [] + for mc in singlemclist: + mcline = mc.Clone() + mcline.SetFillStyle(0) + mcline.Draw("SAME HIST") + linehists.append(mcline) + + leg.Draw("SAME") + gPad.Update() + + + return [singlemclist, singlelimitlist, linehists, leg] + + + + + +if __name__=="__main__": + c1 = TCanvas("c1","c1",800,600) + c1.cd() + + + # Make filelist + allfiles = [] + + for i in xrange(2, len(sys.argv)): + print "Reading ", i, sys.argv[i] + + # split by comma + splitname = sys.argv[i].split(",") + + # Get First + if (os.path.isfile(splitname[0])): + + # Get File + newfile = (TFile(splitname[0],"READ")) + if not newfile: + print "File is not a ROOT file : ", splitname[0] + sys.exit() + + # Set Name + name = splitname[0].replace(".root","") + if len(splitname) > 1: + name = splitname[1] + + allfiles.append([newfile, name]) + + + print allfiles + + # Parse Unique Keys + uniquekeys = [] + for readfile in allfiles: + for readkey in readfile[0].GetListOfKeys(): + if not (readkey.GetName().endswith("_data")): continue + if readkey.GetName() not in uniquekeys: uniquekeys.append(readkey.GetName()) + + print uniquekeys + + # Setup First Page + leg = TLegend(0.1,0.1,0.9,0.9) + for i, readfile in enumerate(allfiles): + hist = TH1D(readfile[1],readfile[1],1,0,1) + hist.SetLineColor(gColorList[i % len(gColorList)]) + hist.SetLineWidth(2) + + leg.AddEntry(hist, readfile[1], "l") + + leg.Draw() + gPad.Update() + + + outputfile = sys.argv[1] + c1.Print(outputfile + "(") + + plotlist = DrawFitDialsPlot(allfiles) + c1.Print(outputfile) + + # Loop through unique keys + for readkey in uniquekeys: + + # Draw + datamclist = DrawDataMC(readkey, allfiles) + + # Save + c1.Print(outputfile) + + # Now save the legend again to close... + leg.Draw() + gPad.Update() + gPad.Print(outputfile + ")") diff --git a/src/InputHandler/FitEvent.cxx b/src/InputHandler/FitEvent.cxx index cbdf359..0d8503a 100644 --- a/src/InputHandler/FitEvent.cxx +++ b/src/InputHandler/FitEvent.cxx @@ -1,445 +1,448 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is pddrt of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see <http://www.gnu.org/licenses/>. *******************************************************************************/ #include "FitEvent.h" #include <iostream> #include "TObjArray.h" FitEvent::FitEvent() { fGenInfo = NULL; kRemoveFSIParticles = true; kRemoveUndefParticles = true; AllocateParticleStack(400); }; void FitEvent::AddGeneratorInfo(GeneratorInfoBase* gen) { fGenInfo = gen; gen->AllocateParticleStack(kMaxParticles); } void FitEvent::AllocateParticleStack(int stacksize) { LOG(DEB) << "Allocating particle stack of size: " << stacksize << std::endl; kMaxParticles = stacksize; fParticleList = new FitParticle*[kMaxParticles]; fParticleMom = new double*[kMaxParticles]; fParticleState = new UInt_t[kMaxParticles]; fParticlePDG = new int[kMaxParticles]; fOrigParticleMom = new double*[kMaxParticles]; fOrigParticleState = new UInt_t[kMaxParticles]; fOrigParticlePDG = new int[kMaxParticles]; for (size_t i = 0; i < kMaxParticles; i++) { fParticleList[i] = NULL; fParticleMom[i] = new double[4]; fOrigParticleMom[i] = new double[4]; } if (fGenInfo) fGenInfo->AllocateParticleStack(kMaxParticles); } void FitEvent::ExpandParticleStack(int stacksize) { DeallocateParticleStack(); AllocateParticleStack(stacksize); } void FitEvent::DeallocateParticleStack() { for (size_t i = 0; i < kMaxParticles; i++) { if (fParticleList[i]) delete fParticleList[i]; delete fParticleMom[i]; delete fOrigParticleMom[i]; } delete fParticleMom; delete fOrigParticleMom; delete fParticleList; delete fParticleState; delete fParticlePDG; delete fOrigParticleState; delete fOrigParticlePDG; if (fGenInfo) fGenInfo -> DeallocateParticleStack(); kMaxParticles = 0; } void FitEvent::ClearFitParticles() { for (size_t i = 0; i < kMaxParticles; i++) { fParticleList[i] = NULL; } } void FitEvent::FreeFitParticles() { for (size_t i = 0; i < kMaxParticles; i++) { FitParticle* fp = fParticleList[i]; if (fp) delete fp; fParticleList[i] = NULL; } } void FitEvent::ResetParticleList() { for (unsigned int i = 0; i < kMaxParticles; i++) { FitParticle* fp = fParticleList[i]; if (fp) delete fp; fParticleList[i] = NULL; } } void FitEvent::HardReset() { for (unsigned int i = 0; i < kMaxParticles; i++) { fParticleList[i] = NULL; } } void FitEvent::ResetEvent() { fMode = 9999; Mode = 9999; fEventNo = -1; fTotCrs = -1.0; fTargetA = -1; fTargetZ = -1; fTargetH = -1; fBound = false; fNParticles = 0; if (fGenInfo) fGenInfo->Reset(); for (unsigned int i = 0; i < kMaxParticles; i++) { if (fParticleList[i]) delete fParticleList[i]; fParticleList[i] = NULL; continue; fParticlePDG[i] = 0; fParticleState[i] = kUndefinedState; fParticleMom[i][0] = 0.0; fParticleMom[i][1] = 0.0; fParticleMom[i][2] = 0.0; fParticleMom[i][3] = 0.0; fOrigParticlePDG[i] = 0; fOrigParticleState[i] = kUndefinedState; fOrigParticleMom[i][0] = 0.0; fOrigParticleMom[i][1] = 0.0; fOrigParticleMom[i][2] = 0.0; fOrigParticleMom[i][3] = 0.0; } } void FitEvent::OrderStack() { // Copy current stack int npart = fNParticles; for (int i = 0; i < npart; i++) { fOrigParticlePDG[i] = fParticlePDG[i]; fOrigParticleState[i] = fParticleState[i]; fOrigParticleMom[i][0] = fParticleMom[i][0]; fOrigParticleMom[i][1] = fParticleMom[i][1]; fOrigParticleMom[i][2] = fParticleMom[i][2]; fOrigParticleMom[i][3] = fParticleMom[i][3]; } // Now run loops for each particle fNParticles = 0; int stateorder[6] = {kInitialState, kFinalState, kFSIState, kNuclearInitial, kNuclearRemnant, kUndefinedState }; for (int s = 0; s < 6; s++) { for (int i = 0; i < npart; i++) { if ((UInt_t)fOrigParticleState[i] != (UInt_t)stateorder[s]) continue; fParticlePDG[fNParticles] = fOrigParticlePDG[i]; fParticleState[fNParticles] = fOrigParticleState[i]; fParticleMom[fNParticles][0] = fOrigParticleMom[i][0]; fParticleMom[fNParticles][1] = fOrigParticleMom[i][1]; fParticleMom[fNParticles][2] = fOrigParticleMom[i][2]; fParticleMom[fNParticles][3] = fOrigParticleMom[i][3]; fNParticles++; } } if (LOG_LEVEL(DEB)) { LOG(DEB) << "Ordered stack" << std::endl; for (int i = 0; i < fNParticles; i++) { LOG(DEB) << "Particle " << i << ". " << fParticlePDG[i] << " " << fParticleMom[i][0] << " " << fParticleMom[i][1] << " " << fParticleMom[i][2] << " " << fParticleMom[i][3] << " " << fParticleState[i] << std::endl; } } if (fNParticles != npart) { ERR(FTL) << "Dropped some particles when ordering the stack!" << std::endl; } return; } void FitEvent::Print() { if (LOG_LEVEL(EVT)) { LOG(EVT) << "EVTEvent print" << std::endl; LOG(EVT) << "Mode: " << fMode << std::endl; LOG(EVT) << "Particles: " << fNParticles << std::endl; LOG(EVT) << " -> Particle Stack " << std::endl; for (int i = 0; i < fNParticles; i++) { LOG(EVT) << " -> -> " << i << ". " << fParticlePDG[i] << " " << fParticleState[i] << " " << " Mom(" << fParticleMom[i][0] << ", " << fParticleMom[i][1] << ", " << fParticleMom[i][2] << ", " << fParticleMom[i][3] << ")." << std::endl; } } return; } /* Read/Write own event class */ void FitEvent::SetBranchAddress(TChain* tn) { tn->SetBranchAddress("Mode", &fMode); tn->SetBranchAddress("Mode", &Mode); tn->SetBranchAddress("EventNo", &fEventNo); tn->SetBranchAddress("TotCrs", &fTotCrs); tn->SetBranchAddress("TargetA", &fTargetA); tn->SetBranchAddress("TargetH", &fTargetH); tn->SetBranchAddress("Bound", &fBound); tn->SetBranchAddress("RWWeight", &SavedRWWeight); tn->SetBranchAddress("InputWeight", &InputWeight); - tn->SetBranchAddress("NParticles", &fNParticles); - tn->SetBranchAddress("ParticleState", fParticleState); - tn->SetBranchAddress("ParticlePDG", fParticlePDG); - tn->SetBranchAddress("ParticleMom", fParticleMom); + + + // This has to be setup by the handler now :( + // tn->SetBranchAddress("NParticles", &fNParticles); + // tn->SetBranchAddress("ParticleState", &fParticleState); + // tn->SetBranchAddress("ParticlePDG", &fParticlePDG); + // tn->SetBranchAddress("ParticleMom", &fParticleMom); } void FitEvent::AddBranchesToTree(TTree* tn) { tn->Branch("Mode", &Mode, "Mode/I"); tn->Branch("EventNo", &fEventNo, "EventNo/i"); tn->Branch("TotCrs", &fTotCrs, "TotCrs/D"); tn->Branch("TargetA", &fTargetA, "TargetA/I"); tn->Branch("TargetH", &fTargetH, "TargetH/I"); tn->Branch("Bound", &fBound, "Bound/O"); tn->Branch("RWWeight", &RWWeight, "RWWeight/D"); tn->Branch("InputWeight", &InputWeight, "InputWeight/D"); tn->Branch("NParticles", &fNParticles, "NParticles/I"); tn->Branch("ParticleState", fOrigParticleState, "ParticleState[NParticles]/i"); tn->Branch("ParticlePDG", fOrigParticlePDG, "ParticlePDG[NParticles]/I"); tn->Branch("ParticleMom", fOrigParticleMom, "ParticleMom[NParticles][4]/D"); } // ------- EVENT ACCESS FUNCTION --------- // TLorentzVector FitEvent::GetParticleP4 (int index) const { if (index == -1 or index >= fNParticles) return TLorentzVector(); return TLorentzVector( fParticleMom[index][0], fParticleMom[index][1], fParticleMom[index][2], fParticleMom[index][3] ); } TVector3 FitEvent::GetParticleP3 (int index) const { if (index == -1 or index >= fNParticles) return TVector3(); return TVector3( fParticleMom[index][0], fParticleMom[index][1], fParticleMom[index][2] ); } double FitEvent::GetParticleMom (int index) const { if (index == -1 or index >= fNParticles) return 0.0; return sqrt(fParticleMom[index][0] * fParticleMom[index][0] + fParticleMom[index][1] * fParticleMom[index][1] + fParticleMom[index][2] * fParticleMom[index][2]); } double FitEvent::GetParticleMom2 (int index) const { if (index == -1 or index >= fNParticles) return 0.0; return fabs((fParticleMom[index][0] * fParticleMom[index][0] + fParticleMom[index][1] * fParticleMom[index][1] + fParticleMom[index][2] * fParticleMom[index][2])); } double FitEvent::GetParticleE (int index) const { if (index == -1 or index >= fNParticles) return 0.0; return fParticleMom[index][3]; } int FitEvent::GetParticleState (int index) const { if (index == -1 or index >= fNParticles) return kUndefinedState; return (fParticleState[index]); } int FitEvent::GetParticlePDG (int index) const { if (index == -1 or index >= fNParticles) return 0; return (fParticlePDG[index]); } FitParticle* FitEvent::GetParticle (int const i) { // Check Valid Index if (i == -1){ return NULL; } // Check Valid if (i > fNParticles) { ERR(FTL) << "Requesting particle beyond stack!" << std::endl << "i = " << i << " N = " << fNParticles << std::endl << "Mode = " << fMode << std::endl; throw; } if (!fParticleList[i]) { fParticleList[i] = new FitParticle(fParticleMom[i][0], fParticleMom[i][1], fParticleMom[i][2], fParticleMom[i][3], fParticlePDG[i], fParticleState[i]); } else { fParticleList[i]->SetValues(fParticleMom[i][0], fParticleMom[i][1], fParticleMom[i][2], fParticleMom[i][3], fParticlePDG[i], fParticleState[i]); } return fParticleList[i]; } bool FitEvent::HasParticle(int const pdg, int const state) const { bool found = false; for (int i = 0; i < fNParticles; i++) { if (state != -1 && fParticleState[i] != (uint)state) continue; if (fParticlePDG[i] == pdg) found = true; } return found; } int FitEvent::NumParticle(int const pdg, int const state) const { int nfound = 0; for (int i = 0; i < fNParticles; i++) { if (state != -1 and fParticleState[i] != (uint)state) continue; if (pdg == 0 or fParticlePDG[i] == pdg) nfound += 1; } return nfound; } std::vector<int> FitEvent::GetAllParticleIndices (int const pdg, int const state) const { std::vector<int> indexlist; for (int i = 0; i < fNParticles; i++) { if (state != -1 and fParticleState[i] != (uint)state) continue; if (pdg == 0 or fParticlePDG[i] == pdg) { indexlist.push_back(i); } } return indexlist; } std::vector<FitParticle*> FitEvent::GetAllParticle(int const pdg, int const state) { std::vector<int> indexlist = GetAllParticleIndices(pdg, state); std::vector<FitParticle*> plist; for (std::vector<int>::iterator iter = indexlist.begin(); iter != indexlist.end(); iter++) { plist.push_back( GetParticle((*iter)) ); } return plist; } int FitEvent::GetHMParticleIndex (int const pdg, int const state) const { double maxmom2 = -9999999.9; int maxind = -1; for (int i = 0; i < fNParticles; i++) { if (state != -1 and fParticleState[i] != (uint)state) continue; if (pdg == 0 or fParticlePDG[i] == pdg) { double newmom2 = GetParticleMom2(i); if (newmom2 > maxmom2) { maxind = i; maxmom2 = newmom2; } } } return maxind; } int FitEvent::GetBeamNeutrinoIndex (void) const { for (int i = 0; i < fNParticles; i++){ if (fParticleState[i] != kInitialState) continue; int pdg = abs(fParticlePDG[i]); if (pdg == 12 or pdg == 14 or pdg == 16){ return i; } } return 0; } int FitEvent::GetBeamElectronIndex (void) const { return GetHMISParticleIndex( 11 ); } int FitEvent::GetBeamPionIndex (void) const { return GetHMISParticleIndex( PhysConst::pdg_pions ); } int FitEvent::NumFSMesons() { int nMesons = 0; for (int i = 0; i < fNParticles; i++) { if (fParticleState[i] != kFinalState) continue; if (abs(fParticlePDG[i]) >= 111 && abs(fParticlePDG[i]) <= 557) nMesons += 1; } return nMesons; } int FitEvent::NumFSLeptons(void) const{ int nLeptons = 0; for (int i = 0; i < fNParticles; i++) { if (fParticleState[i] != kFinalState) continue; if (abs(fParticlePDG[i]) == 11 || abs(fParticlePDG[i]) == 13 || abs(fParticlePDG[i]) == 15) nLeptons += 1; } return nLeptons; } diff --git a/src/InputHandler/FitEventInputHandler.cxx b/src/InputHandler/FitEventInputHandler.cxx index 7de683a..969c245 100644 --- a/src/InputHandler/FitEventInputHandler.cxx +++ b/src/InputHandler/FitEventInputHandler.cxx @@ -1,100 +1,130 @@ #include "FitEventInputHandler.h" FitEventInputHandler::FitEventInputHandler(std::string const& handle, std::string const& rawinputs) { LOG(SAM) << "Creating FitEventInputHandler : " << handle << std::endl; // Run a joint input handling fName = handle; fFitEventTree = new TChain("nuisance_events"); fCacheSize = FitPar::Config().GetParI("CacheSize"); std::vector<std::string> inputs = InputUtils::ParseInputFileList(rawinputs); for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) { // Open File for histogram access TFile* inp_file = new TFile(inputs[inp_it].c_str(), "READ"); if (!inp_file or inp_file->IsZombie()) { ERR(FTL) << "FitEvent File IsZombie() at " << inputs[inp_it] << std::endl; throw; } // Get Flux/Event hist TH1D* fluxhist = (TH1D*)inp_file->Get("nuisance_fluxhist"); TH1D* eventhist = (TH1D*)inp_file->Get("nuisance_eventhist"); if (!fluxhist or !eventhist) { ERR(FTL) << "FitEvent FILE doesn't contain flux/xsec info" << std::endl; throw; } // Get N Events TTree* eventtree = (TTree*)inp_file->Get("nuisance_events"); if (!eventtree) { ERR(FTL) << "nuisance_events not located in GENIE file! " << inputs[inp_it] << std::endl; throw; } int nevents = eventtree->GetEntries(); // Register input to form flux/event rate hists RegisterJointInput(inputs[inp_it], nevents, fluxhist, eventhist); // Add to TChain fFitEventTree->Add( inputs[inp_it].c_str() ); } // Registor all our file inputs SetupJointInputs(); // Assign to tree fEventType = kINPUTFITEVENT; // Create Fit Event fNUISANCEEvent = new FitEvent(); fNUISANCEEvent->HardReset(); fNUISANCEEvent->SetBranchAddress(fFitEventTree); - + + fFitEventTree->SetBranchAddress("NParticles", &fReadNParticles); + fFitEventTree->SetBranchAddress("ParticleState", &fReadParticleState); + fFitEventTree->SetBranchAddress("ParticlePDG", &fReadParticlePDG); + fFitEventTree->SetBranchAddress("ParticleMom", &fReadParticleMom); + + + fFitEventTree->Show(0); + fNUISANCEEvent = GetNuisanceEvent(0); + std::cout << "NParticles = " << fNUISANCEEvent->Npart() << std::endl; + std::cout << "Event Info " << fNUISANCEEvent->PartInfo(0)->fPID << std::endl; + } FitEventInputHandler::~FitEventInputHandler(){ if (fFitEventTree) delete fFitEventTree; } void FitEventInputHandler::CreateCache() { - fFitEventTree->SetCacheEntryRange(0, fNEvents); - fFitEventTree->AddBranchToCache("*", 1); - fFitEventTree->SetCacheSize(fCacheSize); + // fFitEventTree->SetCacheEntryRange(0, fNEvents); + // fFitEventTree->AddBranchToCache("*", 1); + // fFitEventTree->SetCacheSize(fCacheSize); } void FitEventInputHandler::RemoveCache() { - fFitEventTree->SetCacheEntryRange(0, fNEvents); - fFitEventTree->AddBranchToCache("*", 0); - fFitEventTree->SetCacheSize(0); + //fFitEventTree->SetCacheEntryRange(0, fNEvents); + // fFitEventTree->AddBranchToCache("*", 0); + // fFitEventTree->SetCacheSize(0); } FitEvent* FitEventInputHandler::GetNuisanceEvent(const UInt_t entry, const bool lightweight) { // Return NULL if out of bounds if (entry >= (UInt_t)fNEvents) return NULL; // Reset all variables before tree read fNUISANCEEvent->ResetEvent(); // Read NUISANCE Tree fFitEventTree->GetEntry(entry); + // Fill Stack + fNUISANCEEvent->fNParticles = 0; + for (size_t i = 0; i < fReadNParticles; i++){ + size_t curpart = fNUISANCEEvent->fNParticles; + fNUISANCEEvent->fParticleState[curpart] = fReadParticleState[i]; + + // Mom + fNUISANCEEvent->fParticleMom[curpart][0] = fReadParticleMom[i][0]; + fNUISANCEEvent->fParticleMom[curpart][1] = fReadParticleMom[i][1]; + fNUISANCEEvent->fParticleMom[curpart][2] = fReadParticleMom[i][2]; + fNUISANCEEvent->fParticleMom[curpart][3] = fReadParticleMom[i][3]; + + // PDG + fNUISANCEEvent->fParticlePDG[curpart] = fReadParticlePDG[i]; + + // Add to N particle count + fNUISANCEEvent->fNParticles++; + } + // Setup Input scaling for joint inputs fNUISANCEEvent->InputWeight = GetInputWeight(entry); return fNUISANCEEvent; } double FitEventInputHandler::GetInputWeight(int entry) { double w = InputHandlerBase::GetInputWeight(entry); return w * fNUISANCEEvent->SavedRWWeight; } void FitEventInputHandler::Print() { } diff --git a/src/InputHandler/FitEventInputHandler.h b/src/InputHandler/FitEventInputHandler.h index 45eb979..5bdc84c 100644 --- a/src/InputHandler/FitEventInputHandler.h +++ b/src/InputHandler/FitEventInputHandler.h @@ -1,37 +1,43 @@ #ifndef FITEVENT_INPUTHANDLER_H #define FITEVENT_INPUTHANDLER_H /*! * \addtogroup InputHandler * @{ */ #include "InputHandler.h" #include "FitEvent.h" #include "PlotUtils.h" /// Class to read in NUISANCE FitEvents that have been saved to tree class FitEventInputHandler : public InputHandlerBase { public: /// Standard constructor given name and inputs FitEventInputHandler(std::string const& handle, std::string const& rawinputs); virtual ~FitEventInputHandler(); /// Create a TTree Cache to speed up file read void CreateCache(); /// Remove TTree Cache to save memory void RemoveCache(); /// Returns NUISANCE FitEvent from the TTree. If lightweight does nothing. FitEvent* GetNuisanceEvent(const UInt_t entry, const bool lightweight=false); /// Alongside InputWeight also returns any saved RWWeights double GetInputWeight(int entry); /// Print out event information void Print(); TChain* fFitEventTree; ///< TTree from FitEvent file. + + int fReadNParticles; + double fReadParticleMom[400][4]; + UInt_t fReadParticleState[400]; + int fReadParticlePDG[400]; + }; /*! @} */ #endif diff --git a/src/InputHandler/InputHandler.cxx b/src/InputHandler/InputHandler.cxx index b11a028..c21c968 100644 --- a/src/InputHandler/InputHandler.cxx +++ b/src/InputHandler/InputHandler.cxx @@ -1,263 +1,263 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see <http://www.gnu.org/licenses/>. *******************************************************************************/ #include "InputHandler.h" InputHandlerBase::InputHandlerBase() { fName = ""; fFluxHist = NULL; fEventHist = NULL; fNEvents = 0; fNUISANCEEvent = NULL; fBaseEvent = NULL; kRemoveUndefParticles = FitPar::Config().GetParB("RemoveUndefParticles"); kRemoveFSIParticles = FitPar::Config().GetParB("RemoveFSIParticles"); kRemoveNuclearParticles = FitPar::Config().GetParB("RemoveNuclearParticles"); fMaxEvents = FitPar::Config().GetParI("MAXEVENTS"); fTTreePerformance = NULL; }; InputHandlerBase::~InputHandlerBase() { if (fFluxHist) delete fFluxHist; if (fEventHist) delete fEventHist; - if (fXSecHist) delete fXSecHist; - if (fNUISANCEEvent) delete fNUISANCEEvent; + // if (fXSecHist) delete fXSecHist; + // if (fNUISANCEEvent) delete fNUISANCEEvent; jointfluxinputs.clear(); jointeventinputs.clear(); jointindexlow.clear(); jointindexhigh.clear(); jointindexallowed.clear(); jointindexscale.clear(); - if (fTTreePerformance) { - fTTreePerformance->SaveAs(("ttreeperfstats_" + fName + ".root").c_str()); - } + // if (fTTreePerformance) { + // fTTreePerformance->SaveAs(("ttreeperfstats_" + fName + ".root").c_str()); + // } } void InputHandlerBase::Print() { }; TH1D* InputHandlerBase::GetXSecHistogram(void) { fXSecHist = (TH1D*)fFluxHist->Clone(); fXSecHist->Divide(fEventHist); return fXSecHist; }; double InputHandlerBase::PredictedEventRate(double low, double high, std::string intOpt) { int minBin = fFluxHist->GetXaxis()->FindBin(low); int maxBin = fFluxHist->GetXaxis()->FindBin(high); return fEventHist->Integral(minBin, maxBin + 1, intOpt.c_str()); }; double InputHandlerBase::TotalIntegratedFlux(double low, double high, std::string intOpt) { Int_t minBin = fFluxHist->GetXaxis()->FindFixBin(low); Int_t maxBin = fFluxHist->GetXaxis()->FindFixBin(high); if ((fFluxHist->IsBinOverflow(minBin) && (low != -9999.9))) { minBin = 1; } if ((fFluxHist->IsBinOverflow(maxBin) && (high != -9999.9))) { maxBin = fFluxHist->GetXaxis()->GetNbins() + 1; } // If we are within a single bin if (minBin == maxBin) { // Get the contained fraction of the single bin's width return ((high - low) / fFluxHist->GetXaxis()->GetBinWidth(minBin)) * fFluxHist->Integral(minBin, minBin, intOpt.c_str()); } double lowBinUpEdge = fFluxHist->GetXaxis()->GetBinUpEdge(minBin); double highBinLowEdge = fFluxHist->GetXaxis()->GetBinLowEdge(maxBin); double lowBinfracIntegral = ((lowBinUpEdge - low) / fFluxHist->GetXaxis()->GetBinWidth(minBin)) * fFluxHist->Integral(minBin, minBin, intOpt.c_str()); double highBinfracIntegral = ((high - highBinLowEdge) / fFluxHist->GetXaxis()->GetBinWidth(maxBin)) * fFluxHist->Integral(maxBin, maxBin, intOpt.c_str()); // If they are neighbouring bins if ((minBin + 1) == maxBin) { std::cout << "Get lowfrac + highfrac" << std::endl; // Get the contained fraction of the two bin's width return lowBinfracIntegral + highBinfracIntegral; } // If there are filled bins between them return lowBinfracIntegral + highBinfracIntegral + fFluxHist->Integral(minBin + 1, maxBin - 1, intOpt.c_str()); // return fFluxHist->Integral(minBin + 1, maxBin - 1, intOpt.c_str()); } std::vector<TH1*> InputHandlerBase::GetFluxList(void) { return std::vector<TH1*>(1, fFluxHist); }; std::vector<TH1*> InputHandlerBase::GetEventList(void) { return std::vector<TH1*>(1, fEventHist); }; std::vector<TH1*> InputHandlerBase::GetXSecList(void) { return std::vector<TH1*>(1, GetXSecHistogram()); }; FitEvent* InputHandlerBase::FirstNuisanceEvent() { fCurrentIndex = 0; return GetNuisanceEvent(fCurrentIndex); }; FitEvent* InputHandlerBase::NextNuisanceEvent() { fCurrentIndex++; return GetNuisanceEvent(fCurrentIndex); }; BaseFitEvt* InputHandlerBase::FirstBaseEvent() { fCurrentIndex = 0; return GetBaseEvent(fCurrentIndex); }; BaseFitEvt* InputHandlerBase::NextBaseEvent() { fCurrentIndex++; if (jointinput and fMaxEvents != -1) { while ( fCurrentIndex < jointindexlow[jointindexswitch] || fCurrentIndex >= jointindexhigh[jointindexswitch] ) { jointindexswitch++; // Loop Around if (jointindexswitch == jointindexlow.size()) { jointindexswitch = 0; } } if (fCurrentIndex > jointindexlow[jointindexswitch] + jointindexallowed[jointindexswitch]) { fCurrentIndex = jointindexlow[jointindexswitch]; } } return GetBaseEvent(fCurrentIndex); }; void InputHandlerBase::RegisterJointInput(std::string input, int n, TH1D* f, TH1D* e) { if (jointfluxinputs.size() == 0) { jointindexswitch = 0; fNEvents = 0; } // Push into individual input vectors jointfluxinputs.push_back( (TH1D*) f->Clone() ); jointeventinputs.push_back( (TH1D*) e->Clone() ); jointindexlow.push_back(fNEvents); jointindexhigh.push_back(fNEvents + n); fNEvents += n; // Add to the total flux/event hist if (!fFluxHist) fFluxHist = (TH1D*) f->Clone(); else fFluxHist->Add(f); if (!fEventHist) fEventHist = (TH1D*) e->Clone(); else fEventHist->Add(e); } void InputHandlerBase::SetupJointInputs() { if (jointeventinputs.size() <= 1) { jointinput = false; } else if (jointeventinputs.size() > 1) { jointinput = true; jointindexswitch = 0; } fMaxEvents = FitPar::Config().GetParI("MAXEVENTS"); if (fMaxEvents != -1 and jointeventinputs.size() > 1){ THROW("Can only handle joint inputs when config MAXEVENTS = -1!"); } for (size_t i = 0; i < jointeventinputs.size(); i++) { TH1D* eventhist = (TH1D*) jointeventinputs.at(i)->Clone(); double scale = double(fNEvents) / fEventHist->Integral("width"); scale *= eventhist->Integral("width"); scale /= double(jointindexhigh[i] - jointindexlow[i]); jointindexscale .push_back(scale); } fEventHist->SetNameTitle((fName + "_EVT").c_str(), (fName + "_EVT").c_str()); fFluxHist->SetNameTitle((fName + "_FLUX").c_str(), (fName + "_FLUX").c_str()); // Setup Max Events if (fMaxEvents > 1 && fMaxEvents < fNEvents) { if (LOG_LEVEL(SAM)) { std::cout << "\t\t|-> Read Max Entries : " << fMaxEvents << std::endl; } fNEvents = fMaxEvents; } // Print out Status if (LOG_LEVEL(SAM)) { std::cout << "\t\t|-> Total Entries : " << fNEvents << std::endl << "\t\t|-> Event Integral : " << fEventHist->Integral("width") * 1.E-38 << " events/nucleon" << std::endl << "\t\t|-> Flux Integral : " << fFluxHist->Integral("width") << " /cm2" << std::endl << "\t\t|-> Event/Flux : " << fEventHist->Integral("width") * 1.E-38 / fFluxHist->Integral("width") << " cm2/nucleon" << std::endl; } } BaseFitEvt* InputHandlerBase::GetBaseEvent(const UInt_t entry) { return static_cast<BaseFitEvt*>(GetNuisanceEvent(entry, true)); } double InputHandlerBase::GetInputWeight(int entry) { if (!jointinput) return 1.0; // Find Switch Scale while ( entry < jointindexlow[jointindexswitch] || entry >= jointindexhigh[jointindexswitch] ) { jointindexswitch++; // Loop Around if (jointindexswitch >= jointindexlow.size()) { jointindexswitch = 0; } } return jointindexscale[jointindexswitch]; }; diff --git a/src/InputHandler/NEUTInputHandler.cxx b/src/InputHandler/NEUTInputHandler.cxx index fb46488..8883c8e 100644 --- a/src/InputHandler/NEUTInputHandler.cxx +++ b/src/InputHandler/NEUTInputHandler.cxx @@ -1,436 +1,436 @@ #ifdef __NEUT_ENABLED__ #include "NEUTInputHandler.h" NEUTGeneratorInfo::~NEUTGeneratorInfo() { DeallocateParticleStack(); } void NEUTGeneratorInfo::AddBranchesToTree(TTree * tn) { tn->Branch("NEUTParticleN", fNEUTParticleN, "NEUTParticleN/I"); tn->Branch("NEUTParticleStatusCode", fNEUTParticleStatusCode, "NEUTParticleStatusCode[NEUTParticleN]/I"); tn->Branch("NEUTParticleAliveCode", fNEUTParticleAliveCode, "NEUTParticleAliveCode[NEUTParticleN]/I"); } void NEUTGeneratorInfo::SetBranchesFromTree(TTree* tn) { tn->SetBranchAddress("NEUTParticleN", &fNEUTParticleN ); tn->SetBranchAddress("NEUTParticleStatusCode", &fNEUTParticleStatusCode ); tn->SetBranchAddress("NEUTParticleAliveCode", &fNEUTParticleAliveCode ); } void NEUTGeneratorInfo::AllocateParticleStack(int stacksize) { fNEUTParticleN = 0; fNEUTParticleStatusCode = new int[stacksize]; fNEUTParticleStatusCode = new int[stacksize]; } void NEUTGeneratorInfo::DeallocateParticleStack() { delete fNEUTParticleStatusCode; delete fNEUTParticleAliveCode; } void NEUTGeneratorInfo::FillGeneratorInfo(NeutVect* nevent) { Reset(); for (int i = 0; i < nevent->Npart(); i++) { fNEUTParticleStatusCode[i] = nevent->PartInfo(i)->fStatus; fNEUTParticleAliveCode[i] = nevent->PartInfo(i)->fIsAlive; fNEUTParticleN++; } } void NEUTGeneratorInfo::Reset() { for (int i = 0; i < fNEUTParticleN; i++) { fNEUTParticleStatusCode[i] = -1; fNEUTParticleAliveCode[i] = 9; } fNEUTParticleN = 0; } NEUTInputHandler::NEUTInputHandler(std::string const& handle, std::string const& rawinputs) { LOG(SAM) << "Creating NEUTInputHandler : " << handle << std::endl; // Run a joint input handling fName = handle; // Setup the TChain fNEUTTree = new TChain("neuttree"); fSaveExtra = FitPar::Config().GetParB("SaveExtraNEUT"); fCacheSize = FitPar::Config().GetParI("CacheSize"); fMaxEvents = FitPar::Config().GetParI("MAXEVENTS"); // Loop over all inputs and grab flux, eventhist, and nevents std::vector<std::string> inputs = InputUtils::ParseInputFileList(rawinputs); for (size_t inp_it = 0; inp_it < inputs.size(); ++inp_it) { // Open File for histogram access TFile* inp_file = new TFile(inputs[inp_it].c_str(), "READ"); if (!inp_file or inp_file->IsZombie()) { THROW( "NEUT File IsZombie() at : '" << inputs[inp_it] << "'" << std::endl << "Check that your file paths are correct and the file exists!" << std::endl << "$ ls -lh " << inputs[inp_it] ); } // Get Flux/Event hist TH1D* fluxhist = (TH1D*)inp_file->Get( (PlotUtils::GetObjectWithName(inp_file, "flux")).c_str()); TH1D* eventhist = (TH1D*)inp_file->Get( (PlotUtils::GetObjectWithName(inp_file, "evt")).c_str()); if (!fluxhist or !eventhist) { ERROR(FTL, "Input File Contents: " << inputs[inp_it] ); inp_file->ls(); THROW( "NEUT FILE doesn't contain flux/xsec info. You may have to regenerate your MC!" ); } // Get N Events TTree* neuttree = (TTree*)inp_file->Get("neuttree"); if (!neuttree) { ERROR(FTL, "neuttree not located in NEUT file: " << inputs[inp_it]); THROW("Check your inputs, they may need to be completely regenerated!"); throw; } int nevents = neuttree->GetEntries(); if (nevents <= 0) { THROW("Trying to a TTree with " << nevents << " to TChain from : " << inputs[inp_it]); } // Register input to form flux/event rate hists RegisterJointInput(inputs[inp_it], nevents, fluxhist, eventhist); // Add To TChain fNEUTTree->AddFile( inputs[inp_it].c_str() ); } // Registor all our file inputs SetupJointInputs(); // Assign to tree fEventType = kNEUT; fNeutVect = NULL; fNEUTTree->SetBranchAddress("vectorbranch", &fNeutVect); fNEUTTree->GetEntry(0); // Create Fit Event fNUISANCEEvent = new FitEvent(); fNUISANCEEvent->SetNeutVect(fNeutVect); if (fSaveExtra) { fNeutInfo = new NEUTGeneratorInfo(); fNUISANCEEvent->AddGeneratorInfo(fNeutInfo); } fNUISANCEEvent->HardReset(); }; NEUTInputHandler::~NEUTInputHandler() { - if (fNEUTTree) delete fNEUTTree; - if (fNeutVect) delete fNeutVect; - if (fNeutInfo) delete fNeutInfo; + // if (fNEUTTree) delete fNEUTTree; + // if (fNeutVect) delete fNeutVect; + // if (fNeutInfo) delete fNeutInfo; }; void NEUTInputHandler::CreateCache() { if (fCacheSize > 0) { // fNEUTTree->SetCacheEntryRange(0, fNEvents); fNEUTTree->AddBranchToCache("vectorbranch", 1); fNEUTTree->SetCacheSize(fCacheSize); } } void NEUTInputHandler::RemoveCache() { // fNEUTTree->SetCacheEntryRange(0, fNEvents); fNEUTTree->AddBranchToCache("vectorbranch", 0); fNEUTTree->SetCacheSize(0); } FitEvent* NEUTInputHandler::GetNuisanceEvent(const UInt_t entry, const bool lightweight) { // Catch too large entries if (entry >= (UInt_t)fNEvents) return NULL; // Read Entry from TTree to fill NEUT Vect in BaseFitEvt; fNEUTTree->GetEntry(entry); // Setup Input scaling for joint inputs fNUISANCEEvent->InputWeight = GetInputWeight(entry); // Run NUISANCE Vector Filler if (!lightweight) { CalcNUISANCEKinematics(); } // Return event pointer return fNUISANCEEvent; } int NEUTInputHandler::GetNeutParticleStatus(NeutPart * part) { // State int state = kUndefinedState; // fStatus == -1 means initial state if (part->fIsAlive == false && part->fStatus == -1) { state = kInitialState; // NEUT has a bit of a strange convention for fIsAlive and fStatus // combinations // for NC and neutrino particle isAlive true/false and status 2 means // final state particle // for other particles in NC status 2 means it's an FSI particle // for CC it means it was an FSI particle } else if (part->fStatus == 2) { // NC case is a little strange... The outgoing neutrino might be alive or // not alive. Remaining particles with status 2 are FSI particles that // reinteracted if (abs(fNeutVect->Mode) > 30 && (abs(part->fPID) == 14 || abs(part->fPID) == 12)) { state = kFinalState; // The usual CC case } else if (part->fIsAlive == true) { state = kFSIState; } } else if (part->fIsAlive == true && part->fStatus == 2 && (abs(part->fPID) == 14 || abs(part->fPID) == 12)) { state = kFinalState; } else if (part->fIsAlive == true && part->fStatus == 0) { state = kFinalState; } else if (part->fIsAlive == true) { ERR(WRN) << "Undefined NEUT state " << " Alive: " << part->fIsAlive << " Status: " << part->fStatus << " PDG: " << part->fPID << std::endl; throw; } return state; } void NEUTInputHandler::CalcNUISANCEKinematics() { // Reset all variables fNUISANCEEvent->ResetEvent(); // Fill Globals fNUISANCEEvent->fMode = fNeutVect->Mode; fNUISANCEEvent->Mode = fNeutVect->Mode; fNUISANCEEvent->fEventNo = fNeutVect->EventNo; fNUISANCEEvent->fTargetA = fNeutVect->TargetA; fNUISANCEEvent->fTargetZ = fNeutVect->TargetZ; fNUISANCEEvent->fTargetH = fNeutVect->TargetH; fNUISANCEEvent->fBound = bool(fNeutVect->Ibound); if (fNUISANCEEvent->fBound) { fNUISANCEEvent->fTargetPDG = TargetUtils::GetTargetPDGFromZA(fNUISANCEEvent->fTargetZ, fNUISANCEEvent->fTargetA); } else { fNUISANCEEvent->fTargetPDG = 1000010010; } // Check Particle Stack UInt_t npart = fNeutVect->Npart(); UInt_t kmax = fNUISANCEEvent->kMaxParticles; if (npart > kmax) { ERR(FTL) << "NEUT has too many particles. Expanding stack." << std::endl; fNUISANCEEvent->ExpandParticleStack(npart); throw; } // Fill Particle Stack for (size_t i = 0; i < npart; i++) { // Get Current Count int curpart = fNUISANCEEvent->fNParticles; // Get NEUT Particle NeutPart* part = fNeutVect->PartInfo(i); // State int state = GetNeutParticleStatus(part); // Remove Undefined if (kRemoveUndefParticles && state == kUndefinedState) continue; // Remove FSI if (kRemoveFSIParticles && state == kFSIState) continue; // Remove Nuclear if (kRemoveNuclearParticles && (state == kNuclearInitial || state == kNuclearRemnant)) continue; // State fNUISANCEEvent->fParticleState[curpart] = state; // Mom fNUISANCEEvent->fParticleMom[curpart][0] = part->fP.X(); fNUISANCEEvent->fParticleMom[curpart][1] = part->fP.Y(); fNUISANCEEvent->fParticleMom[curpart][2] = part->fP.Z(); fNUISANCEEvent->fParticleMom[curpart][3] = part->fP.T(); // PDG fNUISANCEEvent->fParticlePDG[curpart] = part->fPID; // Add up particle count fNUISANCEEvent->fNParticles++; } // Save Extra Generator Info if (fSaveExtra) { fNeutInfo->FillGeneratorInfo(fNeutVect); } // Run Initial, FSI, Final, Other ordering. fNUISANCEEvent-> OrderStack(); return; } void NEUTUtils::FillNeutCommons(NeutVect* nvect) { // WARNING: This has only been implemented for a neuttree and not GENIE // This should be kept in sync with T2KNIWGUtils::GetNIWGEvent(TTree) //NEUT version info. Can't get it to compile properly with this yet //neutversion_.corev = nvect->COREVer; //neutversion_.nucev = nvect->NUCEVer; //neutversion_.nuccv = nvect->NUCCVer; // Documentation: See nework.h nework_.modene = nvect->Mode; nework_.numne = nvect->Npart(); nemdls_.mdlqeaf = nvect->QEVForm; nemdls_.mdlqe = nvect->QEModel; nemdls_.mdlspi = nvect->SPIModel; nemdls_.mdldis = nvect->DISModel; nemdls_.mdlcoh = nvect->COHModel; neutcoh_.necohepi = nvect->COHModel; nemdls_.xmaqe = nvect->QEMA; nemdls_.xmvqe = nvect->QEMV; nemdls_.kapp = nvect->KAPPA; //nemdls_.sccfv = SCCFVdef; //nemdls_.sccfa = SCCFAdef; //nemdls_.fpqe = FPQEdef; nemdls_.xmaspi = nvect->SPIMA; nemdls_.xmvspi = nvect->SPIMV; nemdls_.xmares = nvect->RESMA; nemdls_.xmvres = nvect->RESMV; neut1pi_.xmanffres = nvect->SPIMA; neut1pi_.xmvnffres = nvect->SPIMV; neut1pi_.xmarsres = nvect->RESMA; neut1pi_.xmvrsres = nvect->RESMV; neut1pi_.neiff = nvect->SPIForm; neut1pi_.nenrtype = nvect->SPINRType; neut1pi_.rneca5i = nvect->SPICA5I; neut1pi_.rnebgscl = nvect->SPIBGScale; nemdls_.xmacoh = nvect->COHMA; nemdls_.rad0nu = nvect->COHR0; //nemdls_.fa1coh = nvect->COHA1err; //nemdls_.fb1coh = nvect->COHb1err; //neutdis_.nepdf = NEPDFdef; //neutdis_.nebodek = NEBODEKdef; neutcard_.nefrmflg = nvect->FrmFlg; neutcard_.nepauflg = nvect->PauFlg; neutcard_.nenefo16 = nvect->NefO16; neutcard_.nemodflg = nvect->ModFlg; //neutcard_.nenefmodl = 1; //neutcard_.nenefmodh = 1; //neutcard_.nenefkinh = 1; //neutpiabs_.neabspiemit = 1; nenupr_.iformlen = nvect->FormLen; neutpiless_.ipilessdcy = nvect->IPilessDcy; neutpiless_.rpilessdcy = nvect->RPilessDcy; neutpiless_.ipilessdcy = nvect->IPilessDcy; neutpiless_.rpilessdcy = nvect->RPilessDcy; neffpr_.fefqe = nvect->NuceffFactorPIQE; neffpr_.fefqeh = nvect->NuceffFactorPIQEH; neffpr_.fefinel = nvect->NuceffFactorPIInel; neffpr_.fefabs = nvect->NuceffFactorPIAbs; neffpr_.fefcx = nvect->NuceffFactorPICX; neffpr_.fefcxh = nvect->NuceffFactorPICXH; neffpr_.fefcoh = nvect->NuceffFactorPICoh; neffpr_.fefqehf = nvect->NuceffFactorPIQEHKin; neffpr_.fefcxhf = nvect->NuceffFactorPICXKin; neffpr_.fefcohf = nvect->NuceffFactorPIQELKin; for ( int i = 0; i < nework_.numne; i++ ) { nework_.ipne[i] = nvect->PartInfo(i)->fPID; nework_.pne[i][0] = (float)nvect->PartInfo(i)->fP.X() / 1000; // VC(NE)WORK in M(G)eV nework_.pne[i][1] = (float)nvect->PartInfo(i)->fP.Y() / 1000; // VC(NE)WORK in M(G)eV nework_.pne[i][2] = (float)nvect->PartInfo(i)->fP.Z() / 1000; // VC(NE)WORK in M(G)eV } // fsihist.h // neutroot fills a dummy object for events with no FSI to prevent memory leak when // reading the TTree, so check for it here if ( (int)nvect->NfsiVert() == 1 ) { // An event with FSI must have at least two vertices // if (nvect->NfsiPart()!=1 || nvect->Fsiprob!=-1) // ERR(WRN) << "T2KNeutUtils::fill_neut_commons(TTree) NfsiPart!=1 or Fsiprob!=-1 when NfsiVert==1" << std::endl; fsihist_.nvert = 0; fsihist_.nvcvert = 0; fsihist_.fsiprob = 1; } else { // Real FSI event fsihist_.nvert = (int)nvect->NfsiVert(); for (int ivert = 0; ivert < fsihist_.nvert; ivert++) { fsihist_.iflgvert[ivert] = nvect->FsiVertInfo(ivert)->fVertID; fsihist_.posvert[ivert][0] = (float)nvect->FsiVertInfo(ivert)->fPos.X(); fsihist_.posvert[ivert][1] = (float)nvect->FsiVertInfo(ivert)->fPos.Y(); fsihist_.posvert[ivert][2] = (float)nvect->FsiVertInfo(ivert)->fPos.Z(); } fsihist_.nvcvert = nvect->NfsiPart(); for (int ip = 0; ip < fsihist_.nvcvert; ip++) { fsihist_.abspvert[ip] = (float)nvect->FsiPartInfo(ip)->fMomLab; fsihist_.abstpvert[ip] = (float)nvect->FsiPartInfo(ip)->fMomNuc; fsihist_.ipvert[ip] = nvect->FsiPartInfo(ip)->fPID; fsihist_.iverti[ip] = nvect->FsiPartInfo(ip)->fVertStart; fsihist_.ivertf[ip] = nvect->FsiPartInfo(ip)->fVertEnd; fsihist_.dirvert[ip][0] = (float)nvect->FsiPartInfo(ip)->fDir.X(); fsihist_.dirvert[ip][1] = (float)nvect->FsiPartInfo(ip)->fDir.Y(); fsihist_.dirvert[ip][2] = (float)nvect->FsiPartInfo(ip)->fDir.Z(); } fsihist_.fsiprob = nvect->Fsiprob; } neutcrscom_.crsx = nvect->Crsx; neutcrscom_.crsy = nvect->Crsy; neutcrscom_.crsz = nvect->Crsz; neutcrscom_.crsphi = nvect->Crsphi; neutcrscom_.crsq2 = nvect->Crsq2; neuttarget_.numbndn = nvect->TargetA - nvect->TargetZ; neuttarget_.numbndp = nvect->TargetZ; neuttarget_.numfrep = nvect->TargetH; neuttarget_.numatom = nvect->TargetA; posinnuc_.ibound = nvect->Ibound; // put empty nucleon FSI history (since it is not saved in the NeutVect format) //Comment out as NEUT does not have the necessary proton FSI information yet // nucleonfsihist_.nfnvert = 0; // nucleonfsihist_.nfnstep = 0; } #endif diff --git a/src/MINERvA/CMakeLists.txt b/src/MINERvA/CMakeLists.txt index c8b8028..f74a9e9 100644 --- a/src/MINERvA/CMakeLists.txt +++ b/src/MINERvA/CMakeLists.txt @@ -1,131 +1,133 @@ # Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret ################################################################################ # This file is part of NUISANCE. # # NUISANCE is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # NUISANCE is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with NUISANCE. If not, see <http://www.gnu.org/licenses/>. ################################################################################ set(IMPLFILES MINERvA_CCQE_XSec_1DQ2_antinu.cxx MINERvA_CCQE_XSec_1DQ2_joint.cxx MINERvA_CCQE_XSec_1DQ2_nu.cxx MINERvA_CC0pi_XSec_1DEe_nue.cxx MINERvA_CC0pi_XSec_1DQ2_nue.cxx MINERvA_CC0pi_XSec_1DQ2_nu_proton.cxx MINERvA_CC0pi_XSec_1DThetae_nue.cxx MINERvA_CC1pi0_XSec_1DEnu_antinu.cxx MINERvA_CC1pi0_XSec_1DQ2_antinu.cxx MINERvA_CC1pi0_XSec_1Dpmu_antinu.cxx MINERvA_CC1pi0_XSec_1Dppi0_antinu.cxx MINERvA_CC1pi0_XSec_1DTpi0_antinu.cxx MINERvA_CC1pi0_XSec_1Dth_antinu.cxx MINERvA_CC1pi0_XSec_1Dthmu_antinu.cxx MINERvA_CC1pip_XSec_1DTpi_20deg_nu.cxx MINERvA_CC1pip_XSec_1DTpi_nu.cxx MINERvA_CC1pip_XSec_1Dth_20deg_nu.cxx MINERvA_CC1pip_XSec_1Dth_nu.cxx MINERvA_CCNpip_XSec_1DEnu_nu.cxx MINERvA_CCNpip_XSec_1DQ2_nu.cxx MINERvA_CCNpip_XSec_1DTpi_nu.cxx MINERvA_CCNpip_XSec_1Dpmu_nu.cxx MINERvA_CCNpip_XSec_1Dth_nu.cxx MINERvA_CCNpip_XSec_1Dthmu_nu.cxx MINERvA_CCinc_XSec_2DEavq3_nu.cxx MINERvA_CCinc_XSec_1Dx_ratio.cxx MINERvA_CCinc_XSec_1DEnu_ratio.cxx MINERvA_CCinc_XSec_1Dx_nu.cxx MINERvA_CCinc_XSec_1DEnu_nu.cxx MINERvA_CC0pi_XSec_1DQ2_Tgt_nu.cxx MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu.cxx +MINERvAUtils.cxx MINERvA_SignalDef.cxx ) set(HEADERFILES MINERvA_CCQE_XSec_1DQ2_antinu.h MINERvA_CCQE_XSec_1DQ2_joint.h MINERvA_CCQE_XSec_1DQ2_nu.h MINERvA_CC0pi_XSec_1DEe_nue.h MINERvA_CC0pi_XSec_1DQ2_nue.h MINERvA_CC0pi_XSec_1DQ2_nu_proton.h MINERvA_CC0pi_XSec_1DThetae_nue.h MINERvA_CC1pi0_XSec_1DEnu_antinu.h MINERvA_CC1pi0_XSec_1DQ2_antinu.h MINERvA_CC1pi0_XSec_1Dpmu_antinu.h MINERvA_CC1pi0_XSec_1Dppi0_antinu.h MINERvA_CC1pi0_XSec_1DTpi0_antinu.h MINERvA_CC1pi0_XSec_1Dth_antinu.h MINERvA_CC1pi0_XSec_1Dthmu_antinu.h MINERvA_CC1pip_XSec_1DTpi_20deg_nu.h MINERvA_CC1pip_XSec_1DTpi_nu.h MINERvA_CC1pip_XSec_1Dth_20deg_nu.h MINERvA_CC1pip_XSec_1Dth_nu.h MINERvA_CCNpip_XSec_1DEnu_nu.h MINERvA_CCNpip_XSec_1DQ2_nu.h MINERvA_CCNpip_XSec_1DTpi_nu.h MINERvA_CCNpip_XSec_1Dpmu_nu.h MINERvA_CCNpip_XSec_1Dth_nu.h MINERvA_CCNpip_XSec_1Dthmu_nu.h MINERvA_CCinc_XSec_2DEavq3_nu.h MINERvA_CCinc_XSec_1Dx_ratio.h MINERvA_CCinc_XSec_1DEnu_ratio.h MINERvA_CCinc_XSec_1Dx_nu.h MINERvA_CCinc_XSec_1DEnu_nu.h MINERvA_CC0pi_XSec_1DQ2_Tgt_nu.h MINERvA_CC0pi_XSec_1DQ2_TgtRatio_nu.h +MINERvAUtils.h MINERvA_SignalDef.h ) set(LIBNAME expMINERvA) if(CMAKE_BUILD_TYPE MATCHES DEBUG) add_library(${LIBNAME} STATIC ${IMPLFILES}) else(CMAKE_BUILD_TYPE MATCHES RELEASE) add_library(${LIBNAME} SHARED ${IMPLFILES}) endif() include_directories(${RWENGINE_INCLUDE_DIRECTORIES}) include_directories(${CMAKE_SOURCE_DIR}/src/FitBase) include_directories(${CMAKE_SOURCE_DIR}/src/InputHandler) include_directories(${CMAKE_SOURCE_DIR}/src/Genie) include_directories(${CMAKE_SOURCE_DIR}/src/Utils) include_directories(${CMAKE_SOURCE_DIR}/src/Reweight) include_directories(${CMAKE_SOURCE_DIR}/src/Splines) set_target_properties(${LIBNAME} PROPERTIES VERSION "${ExtFit_VERSION_MAJOR}.${ExtFit_VERSION_MINOR}.${ExtFit_VERSION_REVISION}") set_target_properties(${LIBNAME} PROPERTIES LINK_FLAGS ${ROOT_LD_FLAGS}) if(DEFINED PROJECTWIDE_EXTRA_DEPENDENCIES) add_dependencies(${LIBNAME} ${PROJECTWIDE_EXTRA_DEPENDENCIES}) endif() install(TARGETS ${LIBNAME} DESTINATION lib) #Can uncomment this to install the headers... but is it really neccessary? #install(FILES ${HEADERFILES} DESTINATION include) set(MODULETargets ${MODULETargets} ${LIBNAME} PARENT_SCOPE) diff --git a/src/MINERvA/MINERvAUtils.cxx b/src/MINERvA/MINERvAUtils.cxx new file mode 100644 index 0000000..7670f45 --- /dev/null +++ b/src/MINERvA/MINERvAUtils.cxx @@ -0,0 +1,232 @@ +// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +/******************************************************************************* +* This file is part of NUISANCE. +* +* NUISANCE is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* NUISANCE is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NUISANCE. If not, see <http://www.gnu.org/licenses/>. +*******************************************************************************/ + +#include "MINERvAUtils.h" +#include "FitParameters.h" +#include "FitUtils.h" + +namespace FitPar{ + double SciBarDensity = FitPar::Config().GetParD("SciBarDensity"); + double SciBarRecoDist = FitPar::Config().GetParD("SciBarRecoDist"); + double PenetratingMuonE = FitPar::Config().GetParD("PenetratingMuonEnergy"); + double NumRangeSteps = FitPar::Config().GetParI("NumRangeSteps"); +} + +double MINERvAUtils::StoppedEfficiency(TH2D *effHist, FitParticle *nu, FitParticle *muon){ + + double eff = 0.; + + if (!effHist) return eff; + eff = effHist->GetBinContent(effHist->FindBin(FitUtils::p(muon), FitUtils::th(nu, muon)/TMath::Pi()*180.)); + + return eff; +} + +double MINERvAUtils::PenetratedEfficiency(FitParticle *nu, FitParticle *muon){ + + double eff = 0.; + + if (FitUtils::th(nu, muon)/TMath::Pi()*180. > 50) eff = 0.; + if (FitUtils::p(muon) < 1.4) eff = 0.; + + return eff; +} + +double MINERvAUtils::BetheBlochCH(double E, double mass){ + + double beta2 = 1 - mass*mass/E/E; + double gamma = 1./sqrt(1-beta2); + double mass_ratio = PhysConst::mass_electron*1000./mass; + // Argh, have to remember to convert to MeV or you'll hate yourself! + double I2 = 68.7e-6*68.7e-6; + + double w_max = 2*PhysConst::mass_electron*1000.*beta2*gamma*gamma; + w_max /= 1 + 2*gamma*mass_ratio + mass_ratio*mass_ratio; + + + // Values taken from the PDG for K = 0.307075 MeV mol-1 cm2, mean ionization energy I = 68.7 eV (Polystyrene) + // <Z/A> = 0.53768 (pdg.lbl.gov/AtomicNuclearProperties) + double log_term = log(2*PhysConst::mass_electron*1000.*beta2*gamma*gamma*w_max/I2); + double dedx = 0.307075*0.53768/beta2*(0.5*log_term - beta2); + + return dedx; +} + + +// This function returns an estimate of the range of the particle in scintillator. +// It uses crude integration and Bethe-Bloch to approximate the range. +double MINERvAUtils::RangeInScintillator(FitParticle* particle, int nsteps){ + + // The particle energy + double E = particle->fP.E(); + double M = particle->fP.M(); + double Ek = E - M; + + double step_size = Ek/float(nsteps+1); + double range = 0; + + // Add an offset to make the integral a touch more accurate + Ek -= step_size/2.; + for (int i = 0; i < nsteps; ++i){ + + double dEdx = MINERvAUtils::BetheBlochCH(Ek+M, M); + + Ek -= step_size; + // dEdx is -ve + range -= step_size/dEdx; + } + + // Account for density of polystyrene + range /= FitPar::SciBarDensity; + + // Range estimate is in cm + return range; +} + + +// Function to calculate the distance the particle travels in scintillator +bool MINERvAUtils::PassesDistanceCut(FitParticle* beam, FitParticle* particle){ + + double dist = MINERvAUtils::RangeInScintillator(particle, FitPar::NumRangeSteps); + double zdist = dist*cos(FitUtils::th(beam, particle)); + + if (abs(zdist) < FitPar::SciBarRecoDist) return false; + return true; +} + + +// Function to return the MainTrk +int MINERvAUtils::GetMainTrack(FitEvent *event, TH2D *effHist, FitParticle*& mainTrk, double& weight, bool penetrated){ + + FitParticle *nu = event->GetNeutrinoIn(); + double highestMom = 0; + int index = 0; + mainTrk = NULL; + + // Loop over particles + for (uint j = 2; j < event->Npart(); ++j){ + + // Final state only! + if (!(event->PartInfo(j))->fIsAlive) continue; + if (event->PartInfo(j)->fNEUTStatusCode != 0) continue; + + int PID = event->PartInfo(j)->fPID; + + // Only consider pions, muons for now + if (abs(PID) != 211 && abs(PID) != 13) continue; + + // Ignore if higher momentum tracks available + if (FitUtils::p(event->PartInfo(j)) < highestMom) continue; + + // Okay, now this is highest momentum + highestMom = FitUtils::p(event->PartInfo(j)); + weight *= MINERvAUtils::StoppedEfficiency(effHist, nu, event->PartInfo(j)); + index = j; + mainTrk = event->PartInfo(j); + } // end loop over particle stack + + return index; +} + + +void MINERvAUtils::GetOtherTrackInfo(FitEvent *event, int mainIndex, int& nProtons, int& nPiMus, int& nVertex, FitParticle*& secondTrk){ + + // Reset everything + nPiMus = 0; + nProtons = 0; + nVertex = 0; + secondTrk = NULL; + + double highestMom = 0.; + + // Loop over particles + for (uint j = 2; j < event->Npart(); ++j){ + + // Don't re-count the main track + if (j == (uint)mainIndex) continue; + + // Final state only! + if (!(event->PartInfo(j))->fIsAlive) continue; + if (event->PartInfo(j)->fNEUTStatusCode != 0) continue; + + int PID = event->PartInfo(j)->fPID; + + // Only consider pions, muons, protons + if (abs(PID) != 211 && PID != 2212 && abs(PID) != 13) continue; + + // Must be reconstructed as a track in SciBooNE + if (MINERvAUtils::PassesDistanceCut(event->PartInfo(0), event->PartInfo(j))){ + + // Keep track of the second highest momentum track + if (FitUtils::p(event->PartInfo(j)) > highestMom){ + highestMom = FitUtils::p(event->PartInfo(j)); + secondTrk = event->PartInfo(j); + } + + if (PID == 2212) nProtons += 1; + else nPiMus += 1; + } else nVertex += 1; + + } // end loop over particle stack + + return; +} + + +// NOTE: need to adapt this to allow for penetrating events... +// Simpler, but gives the same results as in Hirade-san's thesis +double MINERvAUtils::CalcThetaPr(FitEvent *event, FitParticle *main, FitParticle *second, bool penetrated){ + + FitParticle *nu = event->GetNeutrinoIn(); + + if (!main || !nu || !second) return -999; + + // Construct the vector p_pr = (-p_mux, -p_muy, Enurec - pmucosthetamu) + // where p_mux, p_muy are the projections of the candidate muon momentum onto the x and y dimension respectively + double pmu = main->fP.Vect().Mag(); + double pmu_x = main->fP.Vect().X(); + double pmu_y = main->fP.Vect().Y(); + + if (penetrated){ + pmu = 1400.; + double ratio = 1.4/main->fP.Vect().Mag(); + TVector3 mod_mu = main->fP.Vect()*ratio; + pmu_x = mod_mu.X(); + pmu_y = mod_mu.Y(); + } + + double Enuqe = FitUtils::EnuQErec(pmu/1000.,cos(FitUtils::th(nu, main)), 27., true)*1000.; + double p_pr_z = Enuqe - pmu*cos(FitUtils::th(nu, main)); + + TVector3 p_pr = TVector3(-pmu_x, -pmu_y, p_pr_z); + double thetapr = p_pr.Angle(second->fP.Vect())/TMath::Pi()*180.; + + return thetapr; +} + +double MINERvAUtils::CalcThetaPi(FitEvent *event, FitParticle *second){ + + FitParticle *nu = event->GetNeutrinoIn(); + + if (!second || !nu) return -999; + + double thetapi = FitUtils::th(nu, second)/TMath::Pi()*180.; + return thetapi; +} + diff --git a/src/MINERvA/MINERvAUtils.h b/src/MINERvA/MINERvAUtils.h new file mode 100644 index 0000000..ed1976f --- /dev/null +++ b/src/MINERvA/MINERvAUtils.h @@ -0,0 +1,71 @@ +// Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret + +/******************************************************************************* +* This file is part of NUISANCE. +* +* NUISANCE is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* NUISANCE is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with NUISANCE. If not, see <http://www.gnu.org/licenses/>. +*******************************************************************************/ + +#ifndef MINERvAUtils_H_SEEN +#define MINERvAUtils_H_SEEN + +#include <math.h> +#include <stdlib.h> +#include <unistd.h> +#include <cstring> +#include <fstream> +#include <iostream> +#include <iostream> +#include <numeric> +#include <limits> +#include <sstream> +#include <string> +#include <vector> +#include <TLorentzVector.h> +#include <TH2D.h> + +#include "FitParticle.h" +#include "FitEvent.h" +#include "FitLogger.h" +#include "StandardStacks.h" + +/*! + * \addtogroup Utils + * @{ + */ + +namespace FitPar { + extern double SciBarDensity; + extern double SciBarRecoDist; + extern double PenetratingMuonE; + extern double NumRangeSteps; +} + +namespace MINERvAUtils { + + double StoppedEfficiency(TH2D *effHist, FitParticle *nu, FitParticle *muon); + double PenetratedEfficiency(FitParticle *nu, FitParticle *muon); + double BetheBlochCH(double beta, double mass); + double RangeInScintillator(FitParticle* particle, int nsteps=50); + + bool PassesDistanceCut(FitParticle* beam, FitParticle* particle); + + int GetMainTrack(FitEvent *event, TH2D *effHist, FitParticle*& mainTrk, double& weight, bool penetrated=false); + void GetOtherTrackInfo(FitEvent *event, int mainIndex, int& nProtons, int& nPiMus, int& nVertex, FitParticle*& secondTrk); + + double CalcThetaPr(FitEvent *event, FitParticle *main, FitParticle *second, bool penetrated=false); + double CalcThetaPi(FitEvent *event, FitParticle *second); + +} +#endif diff --git a/src/Reweight/GENIEWeightEngine.cxx b/src/Reweight/GENIEWeightEngine.cxx index 3eef0e4..7483959 100644 --- a/src/Reweight/GENIEWeightEngine.cxx +++ b/src/Reweight/GENIEWeightEngine.cxx @@ -1,232 +1,237 @@ #include "GENIEWeightEngine.h" GENIEWeightEngine::GENIEWeightEngine(std::string name) { #ifdef __GENIE_ENABLED__ // Setup the NEUT Reweight engien fCalcName = name; LOG(FIT) << "Setting up GENIE RW : " << fCalcName << std::endl; // Create RW Engine suppressing cout StopTalking(); fGenieRW = new genie::rew::GReWeight(); // Get List of Vetos (Just for debugging) std::string rw_engine_list = FitPar::Config().GetParS("FitWeight.fGenieRW_veto"); bool xsec_ncel = rw_engine_list.find("xsec_ncel") == std::string::npos; bool xsec_ccqe = rw_engine_list.find("xsec_ccqe") == std::string::npos; bool xsec_coh = rw_engine_list.find("xsec_coh") == std::string::npos; bool xsec_nnres = rw_engine_list.find("xsec_nonresbkg") == std::string::npos; bool xsec_nudis = rw_engine_list.find("nuclear_dis") == std::string::npos; bool xsec_resdec = rw_engine_list.find("hadro_res_decay") == std::string::npos; bool xsec_fzone = rw_engine_list.find("hadro_intranuke") == std::string::npos; bool xsec_intra = rw_engine_list.find("hadro_fzone") == std::string::npos; bool xsec_agky = rw_engine_list.find("hadro_agky") == std::string::npos; bool xsec_qevec = rw_engine_list.find("xsec_ccqe_vec") == std::string::npos; bool xsec_dis = rw_engine_list.find("xsec_dis") == std::string::npos; bool xsec_nc = rw_engine_list.find("xsec_nc") == std::string::npos; bool xsec_ccres = rw_engine_list.find("xsec_ccres") == std::string::npos; bool xsec_ncres = rw_engine_list.find("xsec_ncres") == std::string::npos; bool xsec_nucqe = rw_engine_list.find("nuclear_qe") == std::string::npos; bool xsec_qeaxial = rw_engine_list.find("xsec_ccqe_axial") == std::string::npos; // Now actually add the RW Calcs if (xsec_ncel) fGenieRW->AdoptWghtCalc("xsec_ncel", new genie::rew::GReWeightNuXSecNCEL); if (xsec_ccqe) fGenieRW->AdoptWghtCalc("xsec_ccqe", new genie::rew::GReWeightNuXSecCCQE); if (xsec_coh) fGenieRW->AdoptWghtCalc("xsec_coh", new genie::rew::GReWeightNuXSecCOH); if (xsec_nnres) fGenieRW->AdoptWghtCalc("xsec_nonresbkg", new genie::rew::GReWeightNonResonanceBkg); if (xsec_nudis) fGenieRW->AdoptWghtCalc("nuclear_dis", new genie::rew::GReWeightDISNuclMod); if (xsec_resdec) fGenieRW->AdoptWghtCalc("hadro_res_decay", new genie::rew::GReWeightResonanceDecay); if (xsec_fzone) fGenieRW->AdoptWghtCalc("hadro_fzone", new genie::rew::GReWeightFZone); if (xsec_intra) fGenieRW->AdoptWghtCalc("hadro_intranuke", new genie::rew::GReWeightINuke); if (xsec_agky) fGenieRW->AdoptWghtCalc("hadro_agky", new genie::rew::GReWeightAGKY); if (xsec_qevec) fGenieRW->AdoptWghtCalc("xsec_ccqe_vec", new genie::rew::GReWeightNuXSecCCQEvec); #if __GENIE_VERSION__ >= 212 if (xsec_qeaxial) fGenieRW->AdoptWghtCalc("xsec_ccqe_axial", new genie::rew::GReWeightNuXSecCCQEaxial); #endif if (xsec_dis) fGenieRW->AdoptWghtCalc("xsec_dis", new genie::rew::GReWeightNuXSecDIS); if (xsec_nc) fGenieRW->AdoptWghtCalc("xsec_nc", new genie::rew::GReWeightNuXSecNC); if (xsec_ccres) fGenieRW->AdoptWghtCalc("xsec_ccres", new genie::rew::GReWeightNuXSecCCRES); if (xsec_ncres) fGenieRW->AdoptWghtCalc("xsec_ncres", new genie::rew::GReWeightNuXSecNCRES); if (xsec_nucqe) fGenieRW->AdoptWghtCalc("nuclear_qe", new genie::rew::GReWeightFGM); GReWeightNuXSecCCQE * rwccqe = dynamic_cast<GReWeightNuXSecCCQE *> (fGenieRW->WghtCalc("xsec_ccqe")); rwccqe->SetMode(GReWeightNuXSecCCQE::kModeMa); // Default to include shape and normalization changes for CCRES (can be changed downstream if desired) GReWeightNuXSecCCRES * rwccres = dynamic_cast<GReWeightNuXSecCCRES *> (fGenieRW->WghtCalc("xsec_ccres")); - rwccres->SetMode(GReWeightNuXSecCCRES::kModeMaMv); + std::string marestype = FitPar::Config().GetParS("GENIEWeightEngine_CCRESMode"); + if (!marestype.compare("kModeNormAndMaMvShape")){ rwccres->SetMode(GReWeightNuXSecCCRES::kModeNormAndMaMvShape); } + else if (!marestype.compare("kModeMaMv")){ rwccres->SetMode(GReWeightNuXSecCCRES::kModeMaMv); } + else { + THROW("Unkown MARES Mode in GENIE Weight Engine : " << marestype ); + } // Default to include shape and normalization changes for NCRES (can be changed downstream if desired) GReWeightNuXSecNCRES * rwncres = dynamic_cast<GReWeightNuXSecNCRES *> (fGenieRW->WghtCalc("xsec_ncres")); rwncres->SetMode(GReWeightNuXSecNCRES::kModeMaMv); // Default to include shape and normalization changes for DIS (can be changed downstream if desired) GReWeightNuXSecDIS * rwdis = dynamic_cast<GReWeightNuXSecDIS *> (fGenieRW->WghtCalc("xsec_dis")); rwdis->SetMode(GReWeightNuXSecDIS::kModeABCV12u); // Final Reconfigure fGenieRW->Reconfigure(); // Set Abs Twk Config fIsAbsTwk = (FitPar::Config().GetParB("setabstwk")); // allow cout again StartTalking(); #else ERR(FTL) << "GENIE RW NOT ENABLED" << std::endl; #endif }; void GENIEWeightEngine::IncludeDial(std::string name, double startval) { #ifdef __GENIE_ENABLED__ // Get First enum int nuisenum = Reweight::ConvDial(name, kGENIE); // Setup Maps fEnumIndex[nuisenum];// = std::vector<size_t>(0); fNameIndex[name]; // = std::vector<size_t>(0); // Split by commas std::vector<std::string> allnames = GeneralUtils::ParseToStr(name, ","); for (uint i = 0; i < allnames.size(); i++) { std::string singlename = allnames[i]; // Get RW genie::rew::GSyst_t rwsyst = GSyst::FromString(singlename); // Fill Maps int index = fValues.size(); fValues.push_back(0.0); fGENIESysts.push_back(rwsyst); // Initialize dial std::cout << "Registering " << singlename << " from " << name << std::endl; fGenieRW->Systematics().Init( fGENIESysts[index] ); // If Absolute if (fIsAbsTwk) { GSystUncertainty::Instance()->SetUncertainty( rwsyst, 1.0, 1.0 ); } // Setup index fEnumIndex[nuisenum].push_back(index); fNameIndex[name].push_back(index); } // Set Value if given if (startval != -999.9) { SetDialValue(nuisenum, startval); } #endif }; void GENIEWeightEngine::SetDialValue(int nuisenum, double val) { #ifdef __GENIE_ENABLED__ std::vector<size_t> indices = fEnumIndex[nuisenum]; for (uint i = 0; i < indices.size(); i++) { fValues[indices[i]] = val; std::cout << "Setting GENIE Dial Value " << i << " " << indices[i] << " " << fGENIESysts[indices[i]] << std::endl; fGenieRW->Systematics().Set( fGENIESysts[indices[i]], val); } #endif } void GENIEWeightEngine::SetDialValue(std::string name, double val) { #ifdef __GENIE_ENABLED__ std::vector<size_t> indices = fNameIndex[name]; for (uint i = 0; i < indices.size(); i++) { fValues[indices[i]] = val; fGenieRW->Systematics().Set(fGENIESysts[indices[i]], val); } #endif } void GENIEWeightEngine::Reconfigure(bool silent) { #ifdef __GENIE_ENABLED__ // Hush now... if (silent) StopTalking(); // Reconf fGenieRW->Reconfigure(); fGenieRW->Print(); // Shout again if (silent) StartTalking(); #endif } double GENIEWeightEngine::CalcWeight(BaseFitEvt* evt) { double rw_weight = 1.0; #ifdef __GENIE_ENABLED__ // Skip Non GENIE if (evt->fType != kGENIE) return 1.0; // Make nom weight if (!evt) { THROW("evt not found : " << evt); } if (!(evt->genie_event)) { THROW("evt->genie_event not found!" << evt->genie_event); } if (!(evt->genie_event->event)) { THROW("evt->genie_event->event GHepRecord not found!" << (evt->genie_event->event)); } if (!fGenieRW) { THROW("GENIE RW Not Found!" << fGenieRW); } rw_weight = fGenieRW->CalcWeight(*(evt->genie_event->event)); // std::cout << "Returning GENIE Weight for electron scattering = " << rw_weight << std::endl; #endif // Return rw_weight return rw_weight; } diff --git a/src/Reweight/NUISANCESyst.cxx b/src/Reweight/NUISANCESyst.cxx index c279f67..44366e1 100644 --- a/src/Reweight/NUISANCESyst.cxx +++ b/src/Reweight/NUISANCESyst.cxx @@ -1,51 +1,52 @@ #include "NUISANCESyst.h" int Reweight::ConvertNUISANCEDial(std::string type) { for (int i = kUnkownNUISANCEDial + 1; i < kNUISANCEDial_LAST; i++) { if (!type.compare(ConvNUISANCEDial(i).c_str())) { return i; } } return kUnkownNUISANCEDial; }; std::string Reweight::ConvNUISANCEDial(int type) { switch (type) { case kGaussianCorr_CCQE_norm: { return "GaussianCorr_CCQE_norm"; } case kGaussianCorr_CCQE_tilt: { return "GaussianCorr_CCQE_tilt"; } case kGaussianCorr_CCQE_Pq0: { return "GaussianCorr_CCQE_Pq0"; } case kGaussianCorr_CCQE_Wq0: { return "GaussianCorr_CCQE_Wq0"; } case kGaussianCorr_CCQE_Pq3: { return "GaussianCorr_CCQE_Pq3"; } case kGaussianCorr_CCQE_Wq3: { return "GaussianCorr_CCQE_Wq3"; } case kGaussianCorr_2p2h_norm: { return "GaussianCorr_2p2h_norm"; } case kGaussianCorr_2p2h_tilt: { return "GaussianCorr_2p2h_tilt"; } case kGaussianCorr_2p2h_Pq0: { return "GaussianCorr_2p2h_Pq0"; } case kGaussianCorr_2p2h_Wq0: { return "GaussianCorr_2p2h_Wq0"; } case kGaussianCorr_2p2h_Pq3: { return "GaussianCorr_2p2h_Pq3"; } case kGaussianCorr_2p2h_Wq3: { return "GaussianCorr_2p2h_Wq3"; } case kGaussianCorr_2p2h_PPandNN_norm: { return "GaussianCorr_2p2h_PPandNN_norm"; } case kGaussianCorr_2p2h_PPandNN_tilt: { return "GaussianCorr_2p2h_PPandNN_tilt"; } case kGaussianCorr_2p2h_PPandNN_Pq0: { return "GaussianCorr_2p2h_PPandNN_Pq0"; } case kGaussianCorr_2p2h_PPandNN_Wq0: { return "GaussianCorr_2p2h_PPandNN_Wq0"; } case kGaussianCorr_2p2h_PPandNN_Pq3: { return "GaussianCorr_2p2h_PPandNN_Pq3"; } case kGaussianCorr_2p2h_PPandNN_Wq3: { return "GaussianCorr_2p2h_PPandNN_Wq3"; } case kGaussianCorr_2p2h_NP_norm: { return "GaussianCorr_2p2h_NP_norm"; } case kGaussianCorr_2p2h_NP_tilt: { return "GaussianCorr_2p2h_NP_tilt"; } case kGaussianCorr_2p2h_NP_Pq0: { return "GaussianCorr_2p2h_NP_Pq0"; } case kGaussianCorr_2p2h_NP_Wq0: { return "GaussianCorr_2p2h_NP_Wq0"; } case kGaussianCorr_2p2h_NP_Pq3: { return "GaussianCorr_2p2h_NP_Pq3"; } case kGaussianCorr_2p2h_NP_Wq3: { return "GaussianCorr_2p2h_NP_Wq3"; } case kGaussianCorr_CC1pi_norm: { return "GaussianCorr_CC1pi_norm"; } case kGaussianCorr_CC1pi_tilt: { return "GaussianCorr_CC1pi_tilt"; } case kGaussianCorr_CC1pi_Pq0: { return "GaussianCorr_CC1pi_Pq0"; } case kGaussianCorr_CC1pi_Wq0: { return "GaussianCorr_CC1pi_Wq0"; } case kGaussianCorr_CC1pi_Pq3: { return "GaussianCorr_CC1pi_Pq3"; } case kGaussianCorr_CC1pi_Wq3: { return "GaussianCorr_CC1pi_Wq3"; } case kGaussianCorr_AllowSuppression: { return "GaussianCorr_AllowSuppression"; } + case kModeNorm_NormRES: { return "NormRES"; } default: return "unknown_nuisance_dial"; } }; diff --git a/src/Reweight/NUISANCESyst.h b/src/Reweight/NUISANCESyst.h index 6315e23..296c956 100644 --- a/src/Reweight/NUISANCESyst.h +++ b/src/Reweight/NUISANCESyst.h @@ -1,48 +1,50 @@ #ifndef NUISANCESyst_H #define NUISANCESyst_H #include "GeneralUtils.h" namespace Reweight { enum NUISANCESyst { kUnkownNUISANCEDial = 0, kGaussianCorr_CCQE_norm, kGaussianCorr_CCQE_tilt, kGaussianCorr_CCQE_Pq0, kGaussianCorr_CCQE_Wq0, kGaussianCorr_CCQE_Pq3, kGaussianCorr_CCQE_Wq3, kGaussianCorr_2p2h_norm, kGaussianCorr_2p2h_tilt, kGaussianCorr_2p2h_Pq0, kGaussianCorr_2p2h_Wq0, kGaussianCorr_2p2h_Pq3, kGaussianCorr_2p2h_Wq3, kGaussianCorr_2p2h_PPandNN_norm, kGaussianCorr_2p2h_PPandNN_tilt, kGaussianCorr_2p2h_PPandNN_Pq0, kGaussianCorr_2p2h_PPandNN_Wq0, kGaussianCorr_2p2h_PPandNN_Pq3, kGaussianCorr_2p2h_PPandNN_Wq3, kGaussianCorr_2p2h_NP_norm, kGaussianCorr_2p2h_NP_tilt, kGaussianCorr_2p2h_NP_Pq0, kGaussianCorr_2p2h_NP_Wq0, kGaussianCorr_2p2h_NP_Pq3, kGaussianCorr_2p2h_NP_Wq3, kGaussianCorr_CC1pi_norm, kGaussianCorr_CC1pi_tilt, kGaussianCorr_CC1pi_Pq0, kGaussianCorr_CC1pi_Wq0, kGaussianCorr_CC1pi_Pq3, kGaussianCorr_CC1pi_Wq3, kGaussianCorr_AllowSuppression, + kModeNorm_NormRES, + kNUISANCEDial_LAST }; int ConvertNUISANCEDial(std::string type); std::string ConvNUISANCEDial(int type); }; #endif diff --git a/src/Reweight/NUISANCEWeightCalcs.cxx b/src/Reweight/NUISANCEWeightCalcs.cxx index d3f36e9..1f3ddf2 100644 --- a/src/Reweight/NUISANCEWeightCalcs.cxx +++ b/src/Reweight/NUISANCEWeightCalcs.cxx @@ -1,276 +1,329 @@ #include "NUISANCEWeightCalcs.h" +ModeNormCalc::ModeNormCalc(){ + fNormRES = 1.0; +} + +double ModeNormCalc::CalcWeight(BaseFitEvt* evt) { + FitEvent* fevt = static_cast<FitEvent*>(evt); + int mode = abs(fevt->Mode); + double w = 1.0; + + if (mode == 11 or mode == 12 or mode == 13){ + w *= fNormRES; + } + + return w; +} + +void ModeNormCalc::SetDialValue(std::string name, double val) { + SetDialValue(Reweight::ConvDial(name, kCUSTOM), val); +} + +void ModeNormCalc::SetDialValue(int rwenum, double val) { + + int curenum = rwenum % 1000; + + // Check Handled + if (!IsHandled(curenum)) return; + if (curenum == kModeNorm_NormRES) fNormRES = val; +} + +bool ModeNormCalc::IsHandled(int rwenum) { + + int curenum = rwenum % 1000; + switch (curenum) { + case kModeNorm_NormRES: return true; + default: return false; + } +} + + + + + + + GaussianModeCorr::GaussianModeCorr() { // Init fApply_CCQE = false; fGausVal_CCQE[kPosNorm] = 0.0; fGausVal_CCQE[kPosTilt] = 0.0; fGausVal_CCQE[kPosPq0] = 1.0; fGausVal_CCQE[kPosWq0] = 1.0; fGausVal_CCQE[kPosPq3] = 1.0; fGausVal_CCQE[kPosWq3] = 1.0; fApply_2p2h = false; fGausVal_2p2h[kPosNorm] = 0.0; fGausVal_2p2h[kPosTilt] = 0.0; fGausVal_2p2h[kPosPq0] = 1.0; fGausVal_2p2h[kPosWq0] = 1.0; fGausVal_2p2h[kPosPq3] = 1.0; fGausVal_2p2h[kPosWq3] = 1.0; fApply_2p2h_PPandNN = false; fGausVal_2p2h_PPandNN[kPosNorm] = 0.0; fGausVal_2p2h_PPandNN[kPosTilt] = 0.0; fGausVal_2p2h_PPandNN[kPosPq0] = 1.0; fGausVal_2p2h_PPandNN[kPosWq0] = 1.0; fGausVal_2p2h_PPandNN[kPosPq3] = 1.0; fGausVal_2p2h_PPandNN[kPosWq3] = 1.0; fApply_2p2h_NP = false; fGausVal_2p2h_NP[kPosNorm] = 0.0; fGausVal_2p2h_NP[kPosTilt] = 0.0; fGausVal_2p2h_NP[kPosPq0] = 1.0; fGausVal_2p2h_NP[kPosWq0] = 1.0; fGausVal_2p2h_NP[kPosPq3] = 1.0; fGausVal_2p2h_NP[kPosWq3] = 1.0; fApply_CC1pi = false; fGausVal_CC1pi[kPosNorm] = 0.0; fGausVal_CC1pi[kPosTilt] = 0.0; fGausVal_CC1pi[kPosPq0] = 1.0; fGausVal_CC1pi[kPosWq0] = 1.0; fGausVal_CC1pi[kPosPq3] = 1.0; fGausVal_CC1pi[kPosWq3] = 1.0; fDebugStatements = FitPar::Config().GetParB("GaussianModeCorr_DEBUG"); } double GaussianModeCorr::CalcWeight(BaseFitEvt* evt) { FitEvent* fevt = static_cast<FitEvent*>(evt); double rw_weight = 1.0; // Get Neutrino + if (!fevt->Npart()){ + THROW("NO particles found in stack!"); + } FitParticle* pnu = fevt->PartInfo(0); + if (!pnu){ + THROW("NO Starting particle found in stack!"); + } int pdgnu = pnu->fPID; FitParticle* plep = fevt->GetHMFSParticle(abs(pdgnu) - 1); if (!plep) return 1.0; TLorentzVector q = pnu->fP - plep->fP; // Extra q0,q3 double q0 = fabs(q.E()) / 1.E3; double q3 = fabs(q.Vect().Mag()) / 1.E3; int initialstate = -1; // Undef if (abs(fevt->Mode) == 2) { int npr = 0; int nne = 0; for (UInt_t j = 0; j < fevt->Npart(); j++) { if ((fevt->PartInfo(j))->fIsAlive) continue; if (fevt->PartInfo(j)->fPID == 2212) npr++; else if (fevt->PartInfo(j)->fPID == 2112) nne++; } // std::cout << "PN State = " << npr << " " << nne << std::endl; if (fevt->Mode == 2 and npr == 1 and nne == 1) { initialstate = 2; } else if (fevt->Mode == 2 and ((npr == 0 and nne == 2) or (npr == 2 and nne == 0))) { initialstate = 1; } } // std::cout << "Got q0 q3 = " << q0 << " " << q3 << std::endl; // Apply weighting if (fApply_CCQE and abs(fevt->Mode) == 1) { if (fDebugStatements) std::cout << "Getting CCQE Weight" << std::endl; - rw_weight *= GetGausWeight(q0, q3, fGausVal_CCQE); + double g = GetGausWeight(q0, q3, fGausVal_CCQE); + if (g < 1.0) g = 1.0; + rw_weight *= g; } if (fApply_2p2h and abs(fevt->Mode) == 2) { if (fDebugStatements) std::cout << "Getting 2p2h Weight" << std::endl; rw_weight *= GetGausWeight(q0, q3, fGausVal_2p2h); } if (fApply_2p2h_PPandNN and abs(fevt->Mode) == 2 and initialstate == 1) { if (fDebugStatements) std::cout << "Getting 2p2h PPandNN Weight" << std::endl; rw_weight *= GetGausWeight(q0, q3, fGausVal_2p2h_PPandNN); } if (fApply_2p2h_NP and abs(fevt->Mode) == 2 and initialstate == 2) { if (fDebugStatements) std::cout << "Getting 2p2h NP Weight" << std::endl; rw_weight *= GetGausWeight(q0, q3, fGausVal_2p2h_NP); } if (fApply_CC1pi and abs(fevt->Mode) >= 11 and abs(fevt->Mode) <= 13) { if (fDebugStatements) std::cout << "Getting CC1pi Weight" << std::endl; rw_weight *= GetGausWeight(q0, q3, fGausVal_CC1pi); } // if (fDebugStatements) std::cout << "Returning Weight " << rw_weight << std::endl; return rw_weight; } double GaussianModeCorr::GetGausWeight(double q0, double q3, double vals[]) { // // CCQE Without Suppression // double Norm = 4.82788679036; // double Tilt = 2.3501416116; // double Pq0 = 0.363964889702; // double Wq0 = 0.133976806938; // double Pq3 = 0.431769740224; // double Wq3 = 0.207666663434; // // Also add for CCQE at the end // return (w > 1.0) ? w : 1.0; // // 2p2h with suppression // double Norm = 15.967; // double Tilt = -0.455655; // double Pq0 = 0.214598; // double Wq0 = 0.0291061; // double Pq3 = 0.480194; // double Wq3 = 0.134588; + double Norm = vals[kPosNorm]; double Tilt = vals[kPosTilt]; double Pq0 = vals[kPosPq0]; double Wq0 = vals[kPosWq0]; double Pq3 = vals[kPosPq3]; double Wq3 = vals[kPosWq3]; double a = cos(Tilt) * cos(Tilt) / (2 * Wq0 * Wq0); a += sin(Tilt) * sin(Tilt) / (2 * Wq3 * Wq3); double b = - sin(2 * Tilt) / (4 * Wq0 * Wq0); b += sin(2 * Tilt) / (4 * Wq3 * Wq3); double c = sin(Tilt) * sin(Tilt) / (2 * Wq0 * Wq0); c += cos(Tilt) * cos(Tilt) / (2 * Wq3 * Wq3); double w = Norm; w *= exp(-a * (q0 - Pq0) * (q0 - Pq0)); w *= exp(+2.0 * b * (q0 - Pq0) * (q3 - Pq3)); w *= exp(-c * (q3 - Pq3) * (q3 - Pq3)); if (fDebugStatements) { std::cout << "Applied Tilt " << Tilt << " " << cos(Tilt) << " " << sin(Tilt) << std::endl; std::cout << "abc = " << a << " " << b << " " << c << std::endl; std::cout << "Returning " << Norm << " " << Pq0 << " " << Wq0 << " " << Pq3 << " " << Wq3 << " " << w << std::endl; } return w; } void GaussianModeCorr::SetDialValue(std::string name, double val) { SetDialValue(Reweight::ConvDial(name, kCUSTOM), val); } void GaussianModeCorr::SetDialValue(int rwenum, double val) { int curenum = rwenum % 1000; // Check Handled if (!IsHandled(curenum)) return; // CCQE Setting for (int i = kGaussianCorr_CCQE_norm; i <= kGaussianCorr_CCQE_Wq3; i++) { if (i == curenum) { int index = i - kGaussianCorr_CCQE_norm; fGausVal_CCQE[index] = val; fApply_CCQE = true; } } // 2p2h Setting for (int i = kGaussianCorr_2p2h_norm; i <= kGaussianCorr_2p2h_Wq3; i++) { if (i == curenum) { int index = i - kGaussianCorr_2p2h_norm; fGausVal_2p2h[index] = val; fApply_2p2h = true; } } // 2p2h_PPandNN Setting for (int i = kGaussianCorr_2p2h_PPandNN_norm; i <= kGaussianCorr_2p2h_PPandNN_Wq3; i++) { if (i == curenum) { int index = i - kGaussianCorr_2p2h_PPandNN_norm; fGausVal_2p2h_PPandNN[index] = val; fApply_2p2h_PPandNN = true; } } // 2p2h_NP Setting for (int i = kGaussianCorr_2p2h_NP_norm; i <= kGaussianCorr_2p2h_NP_Wq3; i++) { if (i == curenum) { int index = i - kGaussianCorr_2p2h_NP_norm; fGausVal_2p2h_NP[index] = val; fApply_2p2h_NP = true; } } // CC1pi Setting for (int i = kGaussianCorr_CC1pi_norm; i <= kGaussianCorr_CC1pi_Wq3; i++) { if (i == curenum) { int index = i - kGaussianCorr_CC1pi_norm; fGausVal_CC1pi[index] = val; fApply_CC1pi = true; } } } bool GaussianModeCorr::IsHandled(int rwenum) { int curenum = rwenum % 1000; switch (curenum) { case kGaussianCorr_CCQE_norm: case kGaussianCorr_CCQE_tilt: case kGaussianCorr_CCQE_Pq0: case kGaussianCorr_CCQE_Wq0: case kGaussianCorr_CCQE_Pq3: case kGaussianCorr_CCQE_Wq3: case kGaussianCorr_2p2h_norm: case kGaussianCorr_2p2h_tilt: case kGaussianCorr_2p2h_Pq0: case kGaussianCorr_2p2h_Wq0: case kGaussianCorr_2p2h_Pq3: case kGaussianCorr_2p2h_Wq3: case kGaussianCorr_2p2h_PPandNN_norm: case kGaussianCorr_2p2h_PPandNN_tilt: case kGaussianCorr_2p2h_PPandNN_Pq0: case kGaussianCorr_2p2h_PPandNN_Wq0: case kGaussianCorr_2p2h_PPandNN_Pq3: case kGaussianCorr_2p2h_PPandNN_Wq3: case kGaussianCorr_2p2h_NP_norm: case kGaussianCorr_2p2h_NP_tilt: case kGaussianCorr_2p2h_NP_Pq0: case kGaussianCorr_2p2h_NP_Wq0: case kGaussianCorr_2p2h_NP_Pq3: case kGaussianCorr_2p2h_NP_Wq3: case kGaussianCorr_CC1pi_norm: case kGaussianCorr_CC1pi_tilt: case kGaussianCorr_CC1pi_Pq0: case kGaussianCorr_CC1pi_Wq0: case kGaussianCorr_CC1pi_Pq3: case kGaussianCorr_CC1pi_Wq3: return true; default: return false; } } diff --git a/src/Reweight/NUISANCEWeightCalcs.h b/src/Reweight/NUISANCEWeightCalcs.h index 4d66e4a..95fa64b 100644 --- a/src/Reweight/NUISANCEWeightCalcs.h +++ b/src/Reweight/NUISANCEWeightCalcs.h @@ -1,85 +1,100 @@ #ifndef NUISANCE_WEIGHT_CALCS #define NUISANCE_WEIGHT_CALCS #include "FitEvent.h" #include "GeneralUtils.h" #include "BaseFitEvt.h" #include "WeightUtils.h" #include "NUISANCESyst.h" #include "FitParameters.h" using namespace Reweight; + class NUISANCEWeightCalc { public: NUISANCEWeightCalc() {}; virtual ~NUISANCEWeightCalc() {}; virtual double CalcWeight(BaseFitEvt* evt){return 1.0;}; virtual void SetDialValue(std::string name, double val){}; virtual void SetDialValue(int rwenum, double val){}; virtual bool IsHandled(int rwenum){return false;}; virtual void Print(){}; std::map<std::string, int> fDialNameIndex; std::map<int, int> fDialEnumIndex; std::vector<double> fDialValues; std::string fName; }; +class ModeNormCalc : public NUISANCEWeightCalc { + public: + ModeNormCalc(); + ~ModeNormCalc(){}; + + double CalcWeight(BaseFitEvt* evt); + void SetDialValue(std::string name, double val); + void SetDialValue(int rwenum, double val); + bool IsHandled(int rwenum); + + double fNormRES; + }; + + class GaussianModeCorr : public NUISANCEWeightCalc { public: GaussianModeCorr(); ~GaussianModeCorr(){}; double CalcWeight(BaseFitEvt* evt); void SetDialValue(std::string name, double val); void SetDialValue(int rwenum, double val); bool IsHandled(int rwenum); double GetGausWeight(double q0, double q3, double vals[]); // 5 pars describe the Gaussain // 0 norm. // 1 q0 pos // 2 q0 width // 3 q3 pos // 4 q3 width static const int kPosNorm = 0; static const int kPosTilt = 1; static const int kPosPq0 = 2; static const int kPosWq0 = 3; static const int kPosPq3 = 4; static const int kPosWq3 = 5; bool fApply_CCQE; double fGausVal_CCQE[6]; bool fApply_2p2h; double fGausVal_2p2h[6]; bool fApply_2p2h_PPandNN; double fGausVal_2p2h_PPandNN[6]; bool fApply_2p2h_NP; double fGausVal_2p2h_NP[6]; bool fApply_CC1pi; double fGausVal_CC1pi[6]; bool fAllowSuppression; bool fDebugStatements; }; #endif diff --git a/src/Reweight/NUISANCEWeightEngine.cxx b/src/Reweight/NUISANCEWeightEngine.cxx index 44b301a..e7344ca 100644 --- a/src/Reweight/NUISANCEWeightEngine.cxx +++ b/src/Reweight/NUISANCEWeightEngine.cxx @@ -1,129 +1,129 @@ #include "NUISANCEWeightEngine.h" #include "NUISANCEWeightCalcs.h" NUISANCEWeightEngine::NUISANCEWeightEngine(std::string name) { // Setup the NUISANCE Reweight engine fCalcName = name; LOG(FIT) << "Setting up NUISANCE Custom RW : " << fCalcName << std::endl; // Load in all Weight Calculations fWeightCalculators.push_back( new GaussianModeCorr() ); - + fWeightCalculators.push_back( new ModeNormCalc() ); // Set Abs Twk Config fIsAbsTwk = true; }; void NUISANCEWeightEngine::IncludeDial(std::string name, double startval) { // Get First enum int nuisenum = Reweight::ConvDial(name, kCUSTOM); // Setup Maps fEnumIndex[nuisenum];// = std::vector<size_t>(0); fNameIndex[name]; // = std::vector<size_t>(0); // Split by commas std::vector<std::string> allnames = GeneralUtils::ParseToStr(name, ","); for (uint i = 0; i < allnames.size(); i++) { std::string singlename = allnames[i]; // Get RW int singleenum = Reweight::ConvDial(singlename, kCUSTOM); // Fill Maps int index = fValues.size(); fValues.push_back(0.0); fNUISANCEEnums.push_back(singleenum); // Initialize dial std::cout << "Registering " << singlename << " from " << name << std::endl; // Setup index fEnumIndex[nuisenum].push_back(index); fNameIndex[name].push_back(index); } // Set Value if given if (startval != -999.9) { SetDialValue(nuisenum, startval); } }; void NUISANCEWeightEngine::SetDialValue(int nuisenum, double val) { std::vector<size_t> indices = fEnumIndex[nuisenum]; for (uint i = 0; i < indices.size(); i++) { fValues[indices[i]] = val; } } void NUISANCEWeightEngine::SetDialValue(std::string name, double val) { std::vector<size_t> indices = fNameIndex[name]; for (uint i = 0; i < indices.size(); i++) { fValues[indices[i]] = val; } } void NUISANCEWeightEngine::Reconfigure(bool silent) { for (size_t i = 0; i < fNUISANCEEnums.size(); i++) { for (std::vector<NUISANCEWeightCalc*>::iterator calciter = fWeightCalculators.begin(); calciter != fWeightCalculators.end(); calciter++) { NUISANCEWeightCalc* nuiscalc = static_cast<NUISANCEWeightCalc*>(*calciter); if (nuiscalc->IsHandled(fNUISANCEEnums[i])) { nuiscalc->SetDialValue(fNUISANCEEnums[i], fValues[i]); } } } } double NUISANCEWeightEngine::CalcWeight(BaseFitEvt * evt) { double rw_weight = 1.0; // Cast as usable class for (std::vector<NUISANCEWeightCalc*>::iterator iter = fWeightCalculators.begin(); iter != fWeightCalculators.end(); iter++) { NUISANCEWeightCalc* nuiscalc = static_cast<NUISANCEWeightCalc*>(*iter); rw_weight *= nuiscalc->CalcWeight(evt); } // Return rw_weight return rw_weight; } diff --git a/src/Routines/SplineRoutines.cxx b/src/Routines/SplineRoutines.cxx index 4cbe86a..8a24297 100755 --- a/src/Routines/SplineRoutines.cxx +++ b/src/Routines/SplineRoutines.cxx @@ -1,2593 +1,2593 @@ // Copyright 2016 L. Pickering, P Stowell, R. Terri, C. Wilkinson, C. Wret /******************************************************************************* * This file is part of NUISANCE. * * NUISANCE is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * NUISANCE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with NUISANCE. If not, see <http://www.gnu.org/licenses/>. *******************************************************************************/ #include "SplineRoutines.h" void SplineRoutines::Init() { fStrategy = "SaveEvents"; fRoutines.clear(); fCardFile = ""; fSampleFCN = NULL; fRW = NULL; fAllowedRoutines = ("SaveEvents,TestEvents,SaveSplineEvents"); }; SplineRoutines::~SplineRoutines() { }; SplineRoutines::SplineRoutines(int argc, char* argv[]) { // Initialise Defaults Init(); nuisconfig configuration = Config::Get(); // Default containers std::string cardfile = ""; std::string maxevents = "-1"; int errorcount = 0; int verbocount = 0; std::vector<std::string> xmlcmds; std::vector<std::string> configargs; // Make easier to handle arguments. std::vector<std::string> args = GeneralUtils::LoadCharToVectStr(argc, argv); ParserUtils::ParseArgument(args, "-c", fCardFile, true); ParserUtils::ParseArgument(args, "-o", fOutputFile, false, false); ParserUtils::ParseArgument(args, "-n", maxevents, false, false); ParserUtils::ParseArgument(args, "-f", fStrategy, false, false); ParserUtils::ParseArgument(args, "-i", xmlcmds); ParserUtils::ParseArgument(args, "-q", configargs); ParserUtils::ParseCounter(args, "e", errorcount); ParserUtils::ParseCounter(args, "v", verbocount); ParserUtils::CheckBadArguments(args); // Add extra defaults if none given if (fCardFile.empty() and xmlcmds.empty()) { ERR(FTL) << "No input supplied!" << std::endl; throw; } if (fOutputFile.empty() and !fCardFile.empty()) { fOutputFile = fCardFile + ".root"; ERR(WRN) << "No output supplied so saving it to: " << fOutputFile << std::endl; } else if (fOutputFile.empty()) { ERR(FTL) << "No output file or cardfile supplied!" << std::endl; throw; } // Configuration Setup ============================= // Check no comp key is available nuiskey fCompKey; if (Config::Get().GetNodes("nuiscomp").empty()) { fCompKey = Config::Get().CreateNode("nuiscomp"); } else { fCompKey = Config::Get().GetNodes("nuiscomp")[0]; } if (!fCardFile.empty()) fCompKey.AddS("cardfile", fCardFile); fCompKey.AddS("outputfile", fOutputFile); if (!fStrategy.empty()) fCompKey.AddS("strategy", fStrategy); // Load XML Cardfile configuration.LoadConfig( fCompKey.GetS("cardfile"), ""); // Add CMD XML Structs for (size_t i = 0; i < xmlcmds.size(); i++) { configuration.AddXMLLine(xmlcmds[i]); } // Add Config Args for (size_t i = 0; i < configargs.size(); i++) { configuration.OverrideConfig(configargs[i]); } if (maxevents.compare("-1")) { std::cout << "[ NUISANCE ] : Overriding " << "MAXEVENTS=" + maxevents << std::endl; configuration.OverrideConfig("MAXEVENTS=" + maxevents); } // Finish configuration XML configuration.FinaliseConfig(fCompKey.GetS("outputfile") + ".xml"); // Add Error Verbo Lines verbocount += Config::Get().GetParI("VERBOSITY"); errorcount += Config::Get().GetParI("ERROR"); std::cout << "[ NUISANCE ]: Setting VERBOSITY=" << verbocount << std::endl; std::cout << "[ NUISANCE ]: Setting ERROR=" << errorcount << std::endl; // FitPar::log_verb = verbocount; SETVERBOSITY(verbocount); // ERR_VERB(errorcount); // Starting Setup // --------------------------- SetupRWEngine(); return; }; /* Setup Functions */ //************************************* void SplineRoutines::SetupRWEngine() { //************************************* fRW = new FitWeight("splineweight"); // std::vector<nuiskey> splinekeys = Config::QueryKeys("spline"); std::vector<nuiskey> parameterkeys = Config::QueryKeys("parameter"); // Add Parameters for (size_t i = 0; i < parameterkeys.size(); i++) { nuiskey key = parameterkeys[i]; std::string parname = key.GetS("name"); std::string partype = key.GetS("type"); double nom = key.GetD("nominal"); fRW->IncludeDial( key.GetS("name"), FitBase::ConvDialType(key.GetS("type")), nom); fRW->SetDialValue( key.GetS("name"), key.GetD("nominal") ); } fRW->Reconfigure(); return; } /* Fitting Functions */ //************************************* void SplineRoutines::UpdateRWEngine(std::map<std::string, double>& updateVals) { //************************************* for (UInt_t i = 0; i < fParams.size(); i++) { std::string name = fParams[i]; if (updateVals.find(name) == updateVals.end()) continue; fRW->SetDialValue(name, updateVals.at(name)); } fRW->Reconfigure(); return; } //************************************* void SplineRoutines::Run() { //************************************* std::cout << "Running " << std::endl; // Parse given routines fRoutines = GeneralUtils::ParseToStr(fStrategy, ","); if (fRoutines.empty()) { ERR(FTL) << "Trying to run ComparisonRoutines with no routines given!" << std::endl; throw; } for (size_t i = 0; i < fRoutines.size(); i++) { LOG(FIT) << "Running Routine: " << fRoutines[i] << std::endl; std::string rout = fRoutines[i]; if (!rout.compare("SaveEvents")) SaveEvents(); else if (!rout.compare("TestEvents")) TestEvents(); else if (!rout.compare("GenerateEventSplines")) { GenerateEventWeights(); BuildEventSplines(); } else if (!rout.compare("GenerateEventWeights")) { GenerateEventWeights(); } else if (!rout.compare("GenerateEventWeightChunks")){ GenerateEventWeightChunks(FitPar::Config().GetParI("spline_procchunk")); } else if (!rout.compare("BuildEventSplines")) { BuildEventSplines(); } else if (!rout.compare("TestSplines_1DEventScan")) TestSplines_1DEventScan(); else if (!rout.compare("TestSplines_NDEventThrow")) TestSplines_NDEventThrow(); else if (!rout.compare("SaveSplinePlots")) SaveSplinePlots(); else if (!rout.compare("TestSplines_1DLikelihoodScan")) TestSplines_1DLikelihoodScan(); else if (!rout.compare("TestSplines_NDLikelihoodThrow")) TestSplines_NDLikelihoodThrow(); else if (!rout.compare("BuildEventSplinesChunks")) { int chunk = FitPar::Config().GetParI("spline_procchunk"); BuildEventSplines(chunk); } else if (!rout.compare("MergeEventSplinesChunks")) { MergeEventSplinesChunks(); } } } //************************************* void SplineRoutines::SaveEvents() { //************************************* if (fRW) delete fRW; SetupRWEngine(); fRW->Reconfigure(); fRW->Print(); // Generate a set of nominal events // Method, Loop over inputs, create input handler, then create a ttree std::vector<nuiskey> eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } // Make new outputfile TFile* outputfile = new TFile(outputfilename.c_str(), "RECREATE"); outputfile->cd(); // Make a new input handler std::vector<std::string> file_descriptor = GeneralUtils::ParseToStr(inputfilename, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfilename << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inptype = InputUtils::ParseInputType(file_descriptor[0]); InputHandlerBase* input = InputUtils::CreateInputHandler("eventsaver", inptype, file_descriptor[1]); // Get info from inputhandler int nevents = input->GetNEvents(); int countwidth = (nevents / 10); FitEvent* nuisevent = input->FirstNuisanceEvent(); // Setup a TTree to save the event outputfile->cd(); TTree* eventtree = new TTree("nuisance_events", "nuisance_events"); nuisevent->AddBranchesToTree(eventtree); // Loop over all events and fill the TTree int icount = 0; // int countwidth = nevents / 5; while (nuisevent) { // Get Event Weight nuisevent->RWWeight = fRW->CalcWeight(nuisevent); // if (nuisevent->RWWeight != 1.0){ // std::cout << "Weight = " << nuisevent->RWWeight << std::endl; // } // Save everything eventtree->Fill(); // Logging if (icount % countwidth == 0) { LOG(REC) << "Saved " << icount << "/" << nevents << " nuisance events. [M, W] = [" << nuisevent->Mode << ", " << nuisevent->RWWeight << "]" << std::endl; } // iterate nuisevent = input->NextNuisanceEvent(); - i++; + icount++; } // Save flux and close file outputfile->cd(); eventtree->Write(); input->GetFluxHistogram()->Write("nuisance_fluxhist"); input->GetEventHistogram()->Write("nuisance_eventhist"); // Close Output outputfile->Close(); // Delete Inputs delete input; } // remove Keys eventkeys.clear(); // Finished LOG(FIT) << "Finished processing all nuisance events." << std::endl; } //************************************* void SplineRoutines::TestEvents() { //************************************* LOG(FIT) << "Testing events." << std::endl; // Create a new file for the test samples if (!fOutputRootFile) { fOutputRootFile = new TFile(fCompKey.GetS("outputfile").c_str(), "RECREATE"); } // Loop over all tests int count = 0; std::vector<nuiskey> testkeys = Config::QueryKeys("sampletest"); for (std::vector<nuiskey>::iterator iter = testkeys.begin(); iter != testkeys.end(); iter++) { nuiskey key = (*iter); // 0. Create new measurement list std::list<MeasurementBase*> samplelist; // 1. Build Sample From Events std::string samplename = key.GetS("name"); std::string eventsid = key.GetS("inputid"); nuiskey eventskey = Config::QueryLastKey("events", "id=" + eventsid); std::string rawfile = eventskey.GetS("input"); LOG(FIT) << "Creating sample " << samplename << std::endl; MeasurementBase* rawsample = SampleUtils::CreateSample(samplename, rawfile, "", "", FitBase::GetRW()); // 2. Build Sample From Nuisance Events std::string eventsfile = eventskey.GetS("output"); LOG(FIT) << "Creating Fit Eevnt Sample " << samplename << " " << eventsfile << std::endl; MeasurementBase* nuissample = SampleUtils::CreateSample(samplename, "FEVENT:" + eventsfile, "", "", FitBase::GetRW()); // 3. Make some folders to save stuff TDirectory* sampledir = (TDirectory*) fOutputRootFile->mkdir(Form((samplename + "_test_%d").c_str(), count)); TDirectory* rawdir = (TDirectory*) sampledir->mkdir("raw"); TDirectory* nuisancedir = (TDirectory*) sampledir->mkdir("nuisance"); TDirectory* difdir = (TDirectory*) sampledir->mkdir("difference"); // 4. Reconfigure both rawdir->cd(); rawsample->Reconfigure(); rawsample->Write(); nuisancedir->cd(); nuissample->Reconfigure(); nuissample->Write(); // 4. Compare Raw to Nuisance Events // Loop over all keyse TIter next(rawdir->GetListOfKeys()); TKey *dirkey; while ((dirkey = (TKey*)next())) { // If not a 1D/2D histogram skip TClass *cl = gROOT->GetClass(dirkey->GetClassName()); if (!cl->InheritsFrom("TH1D") and !cl->InheritsFrom("TH2D")) continue; // Get TH1* from both dir TH1 *rawplot = (TH1*)rawdir->Get(dirkey->GetName()); TH1 *nuisanceplot = (TH1*)nuisancedir->Get(dirkey->GetName()); // Take Difference nuisanceplot->Add(rawplot, -1.0); // Save to dif folder difdir->cd(); nuisanceplot->Write(); } // 5. Tidy Up samplelist.clear(); // Iterator count++; } } void SplineRoutines::GenerateEventWeightChunks(int procchunk) { if (fRW) delete fRW; SetupRWEngine(); // Setup the spline reader SplineWriter* splwrite = new SplineWriter(fRW); std::vector<nuiskey> splinekeys = Config::QueryKeys("spline"); // Add splines to splinewriter for (std::vector<nuiskey>::iterator iter = splinekeys.begin(); iter != splinekeys.end(); iter++) { nuiskey splkey = (*iter); // Add Spline Info To Reader splwrite->AddSpline(splkey); } splwrite->SetupSplineSet(); // Event Loop // Loop over all events and calculate weights for each parameter set. // Generate a set of nominal events // Method, Loop over inputs, create input handler, then create a ttree std::vector<nuiskey> eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } outputfilename += ".weights.root"; // Make new outputfile TFile* outputfile = new TFile(outputfilename.c_str(), "RECREATE"); outputfile->cd(); // Make a new input handler std::vector<std::string> file_descriptor = GeneralUtils::ParseToStr(inputfilename, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfilename << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inptype = InputUtils::ParseInputType(file_descriptor[0]); InputHandlerBase* input = InputUtils::CreateInputHandler("eventsaver", inptype, file_descriptor[1]); // Get info from inputhandler int nevents = input->GetNEvents(); // int countwidth = (nevents / 1000); FitEvent* nuisevent = input->FirstNuisanceEvent(); // Setup a TTree to save the event outputfile->cd(); TTree* eventtree = new TTree("nuisance_events", "nuisance_events"); // Add a flag that allows just splines to be saved. nuisevent->AddBranchesToTree(eventtree); // Save the spline reader splwrite->Write("spline_reader"); // Setup the spline TTree TTree* weighttree = new TTree("weight_tree", "weight_tree"); splwrite->AddWeightsToTree(weighttree); // Make container for all weights int nweights = splwrite->GetNWeights(); // int npar = splwrite->GetNPars(); // double* weightcont = new double[nweights]; int lasttime = time(NULL); // Load N Chunks of the Weights into Memory // Split into N processing chunks int nchunks = FitPar::Config().GetParI("spline_chunks"); if (nchunks <= 0) nchunks = 1; if (nchunks >= nevents / 2) nchunks = nevents / 2; std::cout << "Starting NChunks " << nchunks << std::endl; for (int ichunk = 0; ichunk < nchunks; ichunk++) { // Skip to only do one processing chunk if (procchunk != -1 and procchunk != ichunk) continue; LOG(FIT) << "On Processing Chunk " << ichunk << std::endl; int neventsinchunk = nevents / nchunks; int loweventinchunk = neventsinchunk * ichunk; // int higheventinchunk = neventsinchunk * (ichunk + 1); double** allweightcont = new double*[neventsinchunk]; for (int k = 0; k < neventsinchunk; k++){ allweightcont[k] = new double[nweights]; } // Start Set Processing Here. for (int iset = 0; iset < nweights; iset++) { splwrite->ReconfigureSet(iset); // Could reorder this to save the weightconts in order instead of reconfiguring per event. // Loop over all events and fill the TTree for (int i = 0; i < neventsinchunk; i++){ nuisevent = input->GetNuisanceEvent(i+loweventinchunk); double w = splwrite->GetWeightForThisSet(nuisevent); if (iset == 0){ allweightcont[i][0] = w; } else { allweightcont[i][iset] = w/allweightcont[i][0]; } // Save everything if (iset == 0) { eventtree->Fill(); } } std::ostringstream timestring; int timeelapsed = time(NULL) - lasttime; if (timeelapsed) { lasttime = time(NULL); int setsleft = (nweights-iset-1) + (nweights * (nchunks - ichunk - 1)); float proj = (float(setsleft) *timeelapsed) / 60 / 60; timestring << setsleft << " sets remaining. Last one took " << timeelapsed << ". " << proj << " hours remaining."; } LOG(REC) << "Processed Set " << iset << "/" << nweights <<" in chunk " << ichunk << "/" << nchunks << " " << timestring.str() << std::endl; } // Fill weights for this chunk into the TTree for (int k = 0; k < neventsinchunk; k++){ splwrite->SetWeights(allweightcont[k]); weighttree->Fill(); } } // at end of the chunk, when all sets have been done // loop over the container and fill weights to ttree outputfile->cd(); eventtree->Write(); weighttree->Write(); input->GetFluxHistogram()->Write("nuisance_fluxhist"); input->GetEventHistogram()->Write("nuisance_eventhist"); splwrite->Write("spline_reader"); outputfile->Close(); // Close Output outputfile->Close(); // Delete Inputs delete input; } // remove Keys eventkeys.clear(); } //************************************* void SplineRoutines::GenerateEventWeights() { //************************************* if (fRW) delete fRW; SetupRWEngine(); // Setup the spline reader SplineWriter* splwrite = new SplineWriter(fRW); std::vector<nuiskey> splinekeys = Config::QueryKeys("spline"); // Add splines to splinewriter for (std::vector<nuiskey>::iterator iter = splinekeys.begin(); iter != splinekeys.end(); iter++) { nuiskey splkey = (*iter); // Add Spline Info To Reader splwrite->AddSpline(splkey); } splwrite->SetupSplineSet(); // Event Loop // Loop over all events and calculate weights for each parameter set. // Generate a set of nominal events // Method, Loop over inputs, create input handler, then create a ttree std::vector<nuiskey> eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } outputfilename += ".weights.root"; // Make new outputfile TFile* outputfile = new TFile(outputfilename.c_str(), "RECREATE"); outputfile->cd(); // Make a new input handler std::vector<std::string> file_descriptor = GeneralUtils::ParseToStr(inputfilename, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfilename << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inptype = InputUtils::ParseInputType(file_descriptor[0]); InputHandlerBase* input = InputUtils::CreateInputHandler("eventsaver", inptype, file_descriptor[1]); // Get info from inputhandler int nevents = input->GetNEvents(); int countwidth = (nevents / 1000); FitEvent* nuisevent = input->FirstNuisanceEvent(); // Setup a TTree to save the event outputfile->cd(); TTree* eventtree = new TTree("nuisance_events", "nuisance_events"); // Add a flag that allows just splines to be saved. nuisevent->AddBranchesToTree(eventtree); // Save the spline reader splwrite->Write("spline_reader"); // Setup the spline TTree TTree* weighttree = new TTree("weight_tree", "weight_tree"); splwrite->AddWeightsToTree(weighttree); // Make container for all weights int nweights = splwrite->GetNWeights(); // int npar = splwrite->GetNPars(); double* weightcont = new double[nweights]; int lasttime = time(NULL); // Could reorder this to save the weightconts in order instead of reconfiguring per event. // Loop over all events and fill the TTree while (nuisevent) { // Calculate the weights for each parameter set splwrite->GetWeightsForEvent(nuisevent, weightcont); // Save everything eventtree->Fill(); weighttree->Fill(); // Logging if (i % countwidth == 0) { std::ostringstream timestring; int timeelapsed = time(NULL) - lasttime; if (i != 0 and timeelapsed) { lasttime = time(NULL); int eventsleft = nevents - i; float speed = float(countwidth) / float(timeelapsed); float proj = (float(eventsleft) / float(speed)) / 60 / 60; timestring << proj << " hours remaining."; } LOG(REC) << "Saved " << i << "/" << nevents << " nuisance spline weights. " << timestring.str() << std::endl; } // Iterate i++; nuisevent = input->NextNuisanceEvent(); } // at end of the chunk, when all sets have been done // loop over the container and fill weights to ttree outputfile->cd(); eventtree->Write(); weighttree->Write(); input->GetFluxHistogram()->Write("nuisance_fluxhist"); input->GetEventHistogram()->Write("nuisance_eventhist"); splwrite->Write("spline_reader"); outputfile->Close(); // Close Output outputfile->Close(); // Delete Inputs delete input; } // remove Keys eventkeys.clear(); } //************************************* void SplineRoutines::GenerateEventSplines() { //************************************* if (fRW) delete fRW; SetupRWEngine(); // Setup the spline reader SplineWriter* splwrite = new SplineWriter(fRW); std::vector<nuiskey> splinekeys = Config::QueryKeys("spline"); // Add splines to splinewriter for (std::vector<nuiskey>::iterator iter = splinekeys.begin(); iter != splinekeys.end(); iter++) { nuiskey splkey = (*iter); // Add Spline Info To Reader splwrite->AddSpline(splkey); } splwrite->SetupSplineSet(); // Make an ugly list for N cores int ncores = FitPar::Config().GetParI("NCORES");//omp_get_max_threads(); std::vector<SplineWriter*> splwriterlist; for (int i = 0; i < ncores; i++) { SplineWriter* tmpwriter = new SplineWriter(fRW); for (std::vector<nuiskey>::iterator iter = splinekeys.begin(); iter != splinekeys.end(); iter++) { nuiskey splkey = (*iter); // Add Spline Info To Reader tmpwriter->AddSpline(splkey); } tmpwriter->SetupSplineSet(); splwriterlist.push_back(tmpwriter); } // Event Loop // Loop over all events and calculate weights for each parameter set. // Generate a set of nominal events // Method, Loop over inputs, create input handler, then create a ttree std::vector<nuiskey> eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } // Make new outputfile TFile* outputfile = new TFile(outputfilename.c_str(), "RECREATE"); outputfile->cd(); // Make a new input handler std::vector<std::string> file_descriptor = GeneralUtils::ParseToStr(inputfilename, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfilename << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inptype = InputUtils::ParseInputType(file_descriptor[0]); InputHandlerBase* input = InputUtils::CreateInputHandler("eventsaver", inptype, file_descriptor[1]); // Get info from inputhandler int nevents = input->GetNEvents(); int countwidth = (nevents / 1000); FitEvent* nuisevent = input->FirstNuisanceEvent(); // Setup a TTree to save the event outputfile->cd(); TTree* eventtree = new TTree("nuisance_events", "nuisance_events"); // Add a flag that allows just splines to be saved. nuisevent->AddBranchesToTree(eventtree); // Save the spline reader splwrite->Write("spline_reader"); // Setup the spline TTree TTree* weighttree = new TTree("weight_tree", "weight_tree"); splwrite->AddWeightsToTree(weighttree); // Make container for all weights int nweights = splwrite->GetNWeights(); double** weightcont = new double*[nevents]; for (int k = 0; k < nevents; k++) { weightcont[k] = new double[nweights]; } int npar = splwrite->GetNPars(); int lasttime = time(NULL); // Could reorder this to save the weightconts in order instead of reconfiguring per event. // Loop over all events and fill the TTree while (nuisevent) { // std::cout << "Fitting event " << i << std::endl; // Calculate the weights for each parameter set // splwrite->FitSplinesForEvent(nuisevent); splwrite->GetWeightsForEvent(nuisevent, weightcont[i]); bool hasresponse = false; for (int j = 0; j < nweights; j++) { if (weightcont[i][j] != 1.0) { // std::cout << "Non Zero Weight at " << i << " " << j << std::endl; hasresponse = true; } else { // std::cout << "Empty Weight at " << i << " " << j << std::endl; } } if (!hasresponse) { // std::cout << "Deleting flat response " << nuisevent->Mode << std::endl; delete weightcont[i]; weightcont[i] = NULL; } // Save everything eventtree->Fill(); weighttree->Fill(); // splinetree->Fill(); // nuisevent->Print(); // std::cout << "Done with event " << i << std::endl; // Push weight sets into a the array // sleep(4); // Logging if (i % countwidth == 0) { std::ostringstream timestring; int timeelapsed = time(NULL) - lasttime; if (i != 0 and timeelapsed) { lasttime = time(NULL); int eventsleft = nevents - i; float speed = float(countwidth) / float(timeelapsed); float proj = (float(eventsleft) / float(speed)) / 60 / 60; timestring << proj << " hours remaining."; } LOG(REC) << "Saved " << i << "/" << nevents << " nuisance spline weights. " << timestring.str() << std::endl; } // Iterate i++; nuisevent = input->NextNuisanceEvent(); } outputfile->cd(); eventtree->Write(); weighttree->Write(); input->GetFluxHistogram()->Write("nuisance_fluxhist"); input->GetEventHistogram()->Write("nuisance_eventhist"); outputfile->Close(); outputfile = new TFile(outputfilename.c_str(), "UPDATE"); outputfile->cd(); weighttree = (TTree*) outputfile->Get("weight_tree"); // splwrite->ReadWeightsFromTree(weighttree); // Divide weights container into Ncores. // Parrallelise this loop checking for what core we are on. // for (int i = 0; i < nevents; i++){ // splwriterlist[int(i / (nevents/4))]->FitSplinesForEvent(coeff); // } // // Now loop over weights tree // for (int i = 0; i < weighttree->GetEntries(); i++) { // weighttree->GetEntry(i); // splwrite->FitSplinesForEvent(); // splinetree->Fill(); // if (i % countwidth == 0) { // std::ostringstream timestring; // int timeelapsed = time(NULL) - lasttime; // if (i != 0 and timeelapsed) { // lasttime = time(NULL); // int eventsleft = nevents - i; // float speed = float(countwidth) / float(timeelapsed); // float proj = (float(eventsleft) / float(speed)) / 60 / 60; // timestring << proj << " hours remaining."; // } // LOG(REC) << "Built " << i << "/" << nevents << " nuisance spline events. " << timestring.str() << std::endl; // } // } // Get Splines float** allcoeff = new float*[nevents]; for (int k = 0; k < nevents; k++) { allcoeff[k] = new float[npar]; } // #pragma omp parallel for num_threads(ncores) for (int i = 0; i < nevents; i++) { //#pragma omp atomic // printf("Using Thread %d to build event %d \n", int(omp_get_thread_num()), (int)i ); // std::cout<< " -> Writer = " << splwriterlist[ i / (nevents/ncores) ] << std::endl; // #pragma omp atomic if (weightcont[i]) { splwriterlist[ int(omp_get_thread_num()) ]->FitSplinesForEvent(weightcont[i], allcoeff[i]); } else { for (int j = 0; j < npar; j++) { allcoeff[i][j] = float(0.0); } } // splwrite->FitSplinesForEvent(weightcont[i], allcoeff[i]); if (i % 500 == 0) { if (LOG_LEVEL(REC)) { printf("Using Thread %d to build event %d \n", int(omp_get_thread_num()), (int)i ); } } /* std::ostringstream timestring; int timeelapsed = time(NULL) - lasttime; if (i != 0 and timeelapsed) { lasttime = time(NULL); int eventsleft = nevents - i; float speed = float(countwidth) / float(timeelapsed); float proj = (float(eventsleft) / float(speed)) / 60 / 60; timestring << proj << " hours remaining."; timestring << " Using Writer at " << i / (nevents/ncores) << " = " << splwriterlist[ i / (nevents/ncores) ] << std::endl; } LOG(REC) << "Built " << i << "/" << nevents << " nuisance spline events. " << timestring.str() << std::endl; } */ } // Save Splines into TTree float* coeff = new float[npar]; outputfile->cd(); TTree* splinetree = new TTree("spline_tree", "spline_tree"); splinetree->Branch("SplineCoeff", coeff, Form("SplineCoeff[%d]/F", npar)); std::cout << "Saving to the allcoeff" << std::endl; for (int k = 0; k < nevents; k++) { for (int l = 0; l < npar; l++) { coeff[l] = allcoeff[k][l]; } std::cout << "Coeff 0, 1, 2 = " << coeff[0] << " " << coeff[1] << " " << coeff[2] << std::endl; splinetree->Fill(); } // Save flux and close file outputfile->cd(); splinetree->Write(); // Delete the container. for (int k = 0; k < nevents; k++) { delete weightcont[k]; } delete weightcont; delete coeff; // Close Output outputfile->Close(); // Delete Inputs delete input; } // remove Keys eventkeys.clear(); } //************************************* void SplineRoutines::BuildEventSplines(int procchunk) { //************************************* if (fRW) delete fRW; SetupRWEngine(); // Setup the spline reader SplineWriter* splwrite = new SplineWriter(fRW); std::vector<nuiskey> splinekeys = Config::QueryKeys("spline"); // Add splines to splinewriter for (std::vector<nuiskey>::iterator iter = splinekeys.begin(); iter != splinekeys.end(); iter++) { nuiskey splkey = (*iter); // Add Spline Info To Reader splwrite->AddSpline(splkey); } splwrite->SetupSplineSet(); // Make an ugly list for N cores int ncores = FitPar::Config().GetParI("spline_cores");//omp_get_max_threads(); if (ncores > omp_get_max_threads()) ncores = omp_get_max_threads(); if (ncores <= 0) ncores = 1; std::vector<SplineWriter*> splwriterlist; for (int i = 0; i < ncores; i++) { SplineWriter* tmpwriter = new SplineWriter(fRW); for (std::vector<nuiskey>::iterator iter = splinekeys.begin(); iter != splinekeys.end(); iter++) { nuiskey splkey = (*iter); // Add Spline Info To Reader tmpwriter->AddSpline(splkey); } tmpwriter->SetupSplineSet(); splwriterlist.push_back(tmpwriter); } // Event Loop // Loop over all events and calculate weights for each parameter set. // Generate a set of nominal events // Method, Loop over inputs, create input handler, then create a ttree std::vector<nuiskey> eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } // Make new outputfile TFile* outputfile; if (procchunk == -1) outputfile = new TFile(outputfilename.c_str(), "RECREATE"); else outputfile = new TFile((outputfilename + std::string(Form(".coeffchunk_%d.root", procchunk))).c_str(), "RECREATE"); outputfile->cd(); // Get Weights File TFile* weightsfile = new TFile((outputfilename + ".weights.root").c_str(), "READ"); TTree* weighttree = (TTree*) weightsfile->Get("weight_tree"); // Get SPLWRite Info //splwrite->ReadWeightsFromTree(weighttree); int nevents = weighttree->GetEntries(); // int countwidth = (nevents / 1000); int nweights = splwrite->GetNWeights(); int npar = splwrite->GetNPars(); // Access Weights double* eventweights = new double[nweights]; weighttree->SetBranchAddress("SplineWeights", eventweights); // Make counter // int lasttime = time(NULL); // Setup Splines To Be Saved into TTree outputfile->cd(); TTree* splinetree = new TTree("spline_tree", "spline_tree"); float* coeff = new float[npar]; splinetree->Branch("SplineCoeff", coeff, Form("SplineCoeff[%d]/F", npar)); // Load N Chunks of the Weights into Memory // Split into N processing chunks int nchunks = FitPar::Config().GetParI("spline_chunks"); if (nchunks <= 0) nchunks = 1; if (nchunks >= nevents / 2) nchunks = nevents / 2; std::cout << "Starting NChunks " << nchunks << std::endl; sleep(1); for (int ichunk = 0; ichunk < nchunks; ichunk++) { // Skip to only do one processing chunk if (procchunk != -1 and procchunk != ichunk) continue; LOG(FIT) << "On Processing Chunk " << ichunk << std::endl; int neventsinchunk = nevents / nchunks; int loweventinchunk = neventsinchunk * ichunk; // int higheventinchunk = neventsinchunk * (ichunk + 1); // Build Chunk Containers for Event Weights double** weightcont = new double*[nevents]; float** allcoeff = new float*[nevents]; // Load Chunks into Containers for (int k = 0; k < neventsinchunk; k++) { weighttree->GetEntry(loweventinchunk + k); weightcont[k] = new double[nweights]; allcoeff[k] = new float[npar]; bool hasresponse = false; for (int j = 0; j < nweights; j++) { weightcont[k][j] = eventweights[j]; if (eventweights[j] != 1.0) hasresponse = true; } if (!hasresponse) delete weightcont[k]; } // Loop over ncores and process chunks // #pragma omp parallel for num_threads(ncores) for (int k = 0; k < neventsinchunk; k++) { if (weightcont[k]) { splwriterlist[ int(omp_get_thread_num()) ]->FitSplinesForEvent(weightcont[k], allcoeff[k]); } else { for (int j = 0; j < npar; j++) { allcoeff[k][j] = float(0.0); } } if (k + loweventinchunk % 500 == 0) { if (LOG_LEVEL(REC)) { printf("Using Thread %d to build event %d in chunk %d \n", int(omp_get_thread_num()), (int) loweventinchunk + k, ichunk ); } } } // Save Coeff To Tree std::cout << "Saving coeffs to Tree in Chunk " << ichunk << std::endl; for (int k = 0; k < neventsinchunk; k++) { for (int l = 0; l < npar; l++) { coeff[l] = allcoeff[k][l]; } // std::cout << "Coeff 0, 1, 2 = " << coeff[0] << " " << coeff[1] << " " << coeff[2] << std::endl; splinetree->Fill(); } // Delete the container. for (int k = 0; k < neventsinchunk; k++) { if (weightcont[k]) delete weightcont[k]; if (allcoeff[k]) delete allcoeff[k]; } delete allcoeff; delete weightcont; } // Save flux and close file outputfile->cd(); splinetree->Write(); if (procchunk == -1 or procchunk == 0) { outputfile->cd(); splwrite->Write("spline_reader"); TTree* nuisanceevents = (TTree*) weightsfile->Get("nuisance_events"); nuisanceevents->CloneTree()->Write(); weighttree->CloneTree()->Write(); TH1D* nuisance_fluxhist = (TH1D*) weightsfile->Get("nuisance_fluxhist"); TH1D* nuisance_eventhist = (TH1D*) weightsfile->Get("nuisance_eventhist"); nuisance_fluxhist->Write("nuisance_fluxhist"); nuisance_eventhist->Write("nuisance_eventhist"); } weightsfile->Close(); // Add option to build seperate chunks // Close Output outputfile->Close(); } // remove Keys eventkeys.clear(); } void SplineRoutines::MergeEventSplinesChunks() { if (fRW) delete fRW; SetupRWEngine(); // Setup the spline reader SplineWriter* splwrite = new SplineWriter(fRW); std::vector<nuiskey> splinekeys = Config::QueryKeys("spline"); // Add splines to splinewriter for (std::vector<nuiskey>::iterator iter = splinekeys.begin(); iter != splinekeys.end(); iter++) { nuiskey splkey = (*iter); // Add Spline Info To Reader splwrite->AddSpline(splkey); } splwrite->SetupSplineSet(); std::vector<nuiskey> eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } // Make new outputfile TFile* outputfile = new TFile(outputfilename.c_str(), "RECREATE"); outputfile->cd(); // Get Weights File TFile* weightsfile = new TFile((outputfilename + ".weights.root").c_str(), "READ"); TTree* weighttree = (TTree*) weightsfile->Get("weight_tree"); // Get SPLWRite Info //splwrite->ReadWeightsFromTree(weighttree); int nevents = weighttree->GetEntries(); // int countwidth = (nevents / 1000); // int nweights = splwrite->GetNWeights(); int npar = splwrite->GetNPars(); // Make counter // int lasttime = time(NULL); // Setup Splines To Be Saved into TTree outputfile->cd(); TTree* splinetree = new TTree("spline_tree", "spline_tree"); float* coeff = new float[npar]; splinetree->Branch("SplineCoeff", coeff, Form("SplineCoeff[%d]/F", npar)); // Load N Chunks of the Weights into Memory // Split into N processing chunks int nchunks = FitPar::Config().GetParI("spline_chunks"); if (nchunks <= 0) nchunks = 1; if (nchunks >= nevents / 2) nchunks = nevents / 2; int neventsinchunk = nevents / nchunks; for (int ichunk = 0; ichunk < nchunks; ichunk++) { // Get Output File TFile* chunkfile = new TFile( (outputfilename + std::string(Form(".coeffchunk_%d.root", ichunk))).c_str() ); // Get TTree for spline coeffchunk TTree* splinetreechunk = (TTree*) chunkfile->Get("spline_tree"); // Set Branch Address to coeffchunk float* coeffchunk = new float[npar]; splinetreechunk->SetBranchAddress("SplineCoeff", coeffchunk); // Loop over nevents in chunk for (int k = 0; k < neventsinchunk; k++) { splinetreechunk->GetEntry(k); for (int j = 0; j < npar; j++) { coeff[j] = coeffchunk[j]; } splinetree->Fill(); } // Close up chunkfile->Close(); delete coeffchunk; std::cout << "Merged chunk " << ichunk << std::endl; } // Save flux and close file outputfile->cd(); splinetree->Write(); outputfile->cd(); splwrite->Write("spline_reader"); TTree* nuisanceevents = (TTree*) weightsfile->Get("nuisance_events"); nuisanceevents->CloneTree()->Write(); weighttree->CloneTree()->Write(); TH1D* nuisance_fluxhist = (TH1D*) weightsfile->Get("nuisance_fluxhist"); TH1D* nuisance_eventhist = (TH1D*) weightsfile->Get("nuisance_eventhist"); nuisance_fluxhist->Write("nuisance_fluxhist"); nuisance_eventhist->Write("nuisance_eventhist"); weightsfile->Close(); // Add option to build seperate chunks // Close Output outputfile->Close(); } // remove Keys eventkeys.clear(); } // void SplineRoutines::BuildSplineChunk(){ //} // void SplineRoutines::MergeSplineChunks(){ //} //************************************* void SplineRoutines::MergeSplines() { //************************************* // Loop over all 'splinemerge' keys. // Add them to the Merger. // Call setup splines. // Get the key with eventinput // - remaining keys should have splineinput // - Loop over number of entries. // - FillEntry in merger. // - Fill NUISANCEEvent into a new TTree. SplineMerger* splmerge = new SplineMerger(); std::vector<nuiskey> splinekeys = Config::QueryKeys("splinemerge"); for (std::vector<nuiskey>::iterator iter = splinekeys.begin(); iter != splinekeys.end(); iter++) { nuiskey splkey = (*iter); TFile* infile = new TFile(splkey.GetS("input").c_str(), "READ"); splmerge->AddSplineSetFromFile(infile); } splmerge->SetupSplineSet(); // Now get Event File std::vector<nuiskey> eventkeys = Config::QueryKeys("eventmerge"); nuiskey key = eventkeys[0]; std::string inputfilename = key.GetS("input"); // Make a new input handler std::vector<std::string> file_descriptor = GeneralUtils::ParseToStr(inputfilename, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfilename << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inptype = InputUtils::ParseInputType(file_descriptor[0]); InputHandlerBase* input = InputUtils::CreateInputHandler("eventsaver", inptype, file_descriptor[1]); std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } // Make new outputfile TFile* outputfile = new TFile(outputfilename.c_str(), "RECREATE"); outputfile->cd(); // Get info from inputhandler int nevents = input->GetNEvents(); int countwidth = (nevents / 1000); FitEvent* nuisevent = input->FirstNuisanceEvent(); // Setup a TTree to save the event outputfile->cd(); TTree* eventtree = new TTree("nuisance_events", "nuisance_events"); // Add a flag that allows just splines to be saved. nuisevent->AddBranchesToTree(eventtree); // Save the spline reader splmerge->Write("spline_reader"); // Setup the spline TTree TTree* splinetree = new TTree("spline_tree", "spline_tree"); splmerge->AddCoefficientsToTree(splinetree); int lasttime = time(NULL); int i = 0; // Loop over all events and fill the TTree while (nuisevent) { // Calculate the weights for each parameter set splmerge->FillMergedSplines(i); // Save everything eventtree->Fill(); splinetree->Fill(); // Logging if (i % countwidth == 0) { std::ostringstream timestring; int timeelapsed = time(NULL) - lasttime; if (i != 0 and timeelapsed) { lasttime = time(NULL); int eventsleft = nevents - i; float speed = float(countwidth) / float(timeelapsed); float proj = (float(eventsleft) / float(speed)) / 60 / 60; timestring << proj << " hours remaining."; } LOG(REC) << "Saved " << i << "/" << nevents << " nuisance spline events. " << timestring.str() << std::endl; } // Iterate i++; nuisevent = input->NextNuisanceEvent(); } // Save flux and close file outputfile->cd(); eventtree->Write(); splinetree->Write(); input->GetFluxHistogram()->Write("nuisance_fluxhist"); input->GetEventHistogram()->Write("nuisance_eventhist"); // Close Output outputfile->Close(); // Delete Inputs delete input; } //************************************* void SplineRoutines::TestSplines_1DEventScan() { //************************************* // Setup RW Engine if (fRW) delete fRW; SetupRWEngine(); // Make a spline RW Engine too. FitWeight* splweight = new FitWeight("splinerwaweight"); // std::vector<nuiskey> splinekeys = Config::QueryKeys("spline"); std::vector<nuiskey> parameterkeys = Config::QueryKeys("parameter"); TH1D* parhisttemplate = new TH1D("parhist", "parhist", parameterkeys.size(), 0.0, float(parameterkeys.size())); // Add Parameters for (size_t i = 0; i < parameterkeys.size(); i++) { nuiskey key = parameterkeys[i]; std::string parname = key.GetS("name"); std::string partype = key.GetS("type"); double nom = key.GetD("nominal"); parhisttemplate->SetBinContent(i + 1, nom); parhisttemplate->GetXaxis()->SetBinLabel(i + 1, parname.c_str()); splweight->IncludeDial( key.GetS("name"), kSPLINEPARAMETER, nom); splweight->SetDialValue( key.GetS("name"), key.GetD("nominal") ); } splweight->Reconfigure(); // Make a high resolution spline set. std::vector<double> nomvals = fRW->GetDialValues(); // int testres = FitPar::Config().GetParI("spline_test_resolution"); std::vector< std::vector<double> > scanparset_vals; std::vector< TH1D* > scanparset_hists; // Loop over all params // Add Parameters for (size_t i = 0; i < parameterkeys.size(); i++) { nuiskey key = parameterkeys[i]; // Get Par Name std::string name = key.GetS("name"); if (!key.Has("low") or !key.Has("high") or !key.Has("step")) { continue; } // Push Back Scan double low = key.GetD("low"); double high = key.GetD("high"); double cur = low; double step = key.GetD("step"); while (cur <= high) { // Make new set std::vector<double> newvals = nomvals; newvals[i] = cur; // Add to vects scanparset_vals.push_back(newvals); TH1D* parhist = (TH1D*)parhisttemplate->Clone(); for (size_t j = 0; j < newvals.size(); j++) { parhist->SetBinContent(j + 1, newvals[j]); } scanparset_hists.push_back(parhist); // Move to next one cur += step; } } // Print out the parameter set to test for (uint i = 0; i < scanparset_vals.size(); i++) { std::cout << "Parset " << i; for (uint j = 0 ; j < scanparset_vals[i].size(); j++) { std::cout << " " << scanparset_vals[i][j]; } std::cout << std::endl; } // Weight holders double* rawweights = new double[scanparset_vals.size()]; double* splweights = new double[scanparset_vals.size()]; double* difweights = new double[scanparset_vals.size()]; int nweights = scanparset_vals.size(); // int NParSets = scanparset_vals.size(); // Loop over all event I/O std::vector<nuiskey> eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } // Make a new input handler std::vector<std::string> file_descriptor = GeneralUtils::ParseToStr(inputfilename, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfilename << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inptype = InputUtils::ParseInputType(file_descriptor[0]); // Make handlers for input and output InputHandlerBase* input = InputUtils::CreateInputHandler("rawevents", inptype, file_descriptor[1]); InputHandlerBase* output = InputUtils::CreateInputHandler("splineevents", InputUtils::kEVSPLN_Input, outputfilename); // Get Base Events for each case. FitEvent* rawevent = input->FirstNuisanceEvent(); FitEvent* splevent = output->FirstNuisanceEvent(); // Setup outputfile std::string outputtest = outputfilename + ".splinetest.1DEventScan.root"; TFile* outputtestfile = new TFile(outputtest.c_str(), "RECREATE"); outputtestfile->cd(); // Save Parameter Sets for (size_t i = 0; i < scanparset_hists.size(); i++) { scanparset_hists[i]->Write(Form("Paramater_Set_%i", (int)i)); } // Save a TTree of weights and differences. TTree* weighttree = new TTree("weightscan", "weightscan"); // Make a branch for each weight set for (size_t i = 0; i < scanparset_hists.size(); i++) { weighttree->Branch(Form("RawWeights_Set_%i", (int)i), &rawweights[i], Form("RawWeights_Set_%i/D", (int)i) ); weighttree->Branch(Form("SplineWeights_Set_%i", (int)i), &splweights[i], Form("SplineWeights_Set_%i/D", (int)i) ); weighttree->Branch(Form("DifWeights_Set_%i", (int)i), &difweights[i], Form("DifWeights_Set_%i/D", (int)i) ); } // Count // int i = 0; int nevents = input->GetNEvents(); int lasttime = time(NULL); // Load N Chunks of the Weights into Memory // Split into N processing chunks int nchunks = FitPar::Config().GetParI("spline_chunks"); if (nchunks <= 0) nchunks = 1; if (nchunks >= nevents / 2) nchunks = nevents / 2; std::cout << "Starting NChunks " << nchunks << std::endl; for (int ichunk = 0; ichunk < nchunks; ichunk++) { // Skip to only do one processing chunk // if (procchunk != -1 and procchunk != ichunk) continue; LOG(FIT) << "On Processing Chunk " << ichunk << std::endl; int neventsinchunk = nevents / nchunks; int loweventinchunk = neventsinchunk * ichunk; // int higheventinchunk = neventsinchunk * (ichunk + 1); double** allrawweights = new double*[neventsinchunk]; double** allsplweights = new double*[neventsinchunk]; double** alldifweights = new double*[neventsinchunk]; for (int k = 0; k < neventsinchunk; k++){ allrawweights[k] = new double[nweights]; allsplweights[k] = new double[nweights]; alldifweights[k] = new double[nweights]; } // Start Set Processing Here. for (int iset = 0; iset < nweights; iset++) { // Reconfigure fRW->SetAllDials(&scanparset_vals[iset][0], scanparset_vals[iset].size()); fRW->Reconfigure(); // Reconfigure spline RW splweight->SetAllDials(&scanparset_vals[iset][0], scanparset_vals[iset].size()); splweight->Reconfigure(); splevent->fSplineRead->SetNeedsReconfigure(true); // Could reorder this to save the weightconts in order instead of reconfiguring per event. // Loop over all events and fill the TTree for (int i = 0; i < neventsinchunk; i++){ rawevent = input->GetNuisanceEvent(i+loweventinchunk); splevent = output->GetNuisanceEvent(i+loweventinchunk); allrawweights[i][iset] = fRW->CalcWeight(rawevent); allsplweights[i][iset] = splweight->CalcWeight(splevent); alldifweights[i][iset] = allsplweights[i][iset] - allrawweights[i][iset]; } std::ostringstream timestring; int timeelapsed = time(NULL) - lasttime; if (timeelapsed) { lasttime = time(NULL); int setsleft = (nweights-iset-1) + (nweights * (nchunks - ichunk - 1)); float proj = (float(setsleft) *timeelapsed) / 60 / 60; timestring << setsleft << " sets remaining. Last one took " << timeelapsed << ". " << proj << " hours remaining."; } LOG(REC) << "Processed Set " << iset << "/" << nweights <<" in chunk " << ichunk << "/" << nchunks << " " << timestring.str() << std::endl; } // Fill weights for this chunk into the TTree for (int k = 0; k < neventsinchunk; k++){ for (int l = 0; l < nweights; l++){ rawweights[l] = allrawweights[k][l]; splweights[l] = allsplweights[k][l]; difweights[l] = alldifweights[k][l]; } weighttree->Fill(); } } // Loop over nchunks // Loop over parameter sets // Set All Dials and reconfigure // Loop over events in chunk // Fill Chunkweightcontainers // Once all dials are done, fill the weight tree // Iterator to next chunk outputtestfile->cd(); weighttree->Write(); outputtestfile->Close(); } } /* // Make a high resolution spline set. std::vector<double> nomvals = fRW->GetDialValues(); int testres = FitPar::Config().GetParI("spline_test_resolution"); std::vector< std::vector<double> > scanparset_vals; std::vector< TH1D* > scanparset_hists; // Loop over all params // Add Parameters for (size_t i = 0; i < parameterkeys.size(); i++) { nuiskey key = parameterkeys[i]; // Get Par Name std::string name = key.GetS("name"); if (!key.Has("low") or !key.Has("high") or !key.Has("step")) { continue; } // Push Back Scan double low = key.GetD("low"); double high = key.GetD("high"); double cur = low; double step = key.GetD("step"); while (cur <= high) { // Make new set std::vector<double> newvals = nomvals; newvals[i] = cur; // Add to vects scanparset_vals.push_back(newvals); TH1D* parhist = (TH1D*)parhisttemplate->Clone(); for (size_t j = 0; j < newvals.size(); j++) { parhist->SetBinContent(j + 1, newvals[j]); } scanparset_hists.push_back(parhist); // Move to next one cur += step; } } // Print out the parameter set to test for (int i = 0; i < scanparset_vals.size(); i++) { std::cout << "Parset " << i; for (int j = 0 ; j < scanparset_vals[i].size(); j++) { std::cout << " " << scanparset_vals[i][j]; } std::cout << std::endl; } // Weight holders double* rawweights = new double[scanparset_vals.size()]; double* splweights = new double[scanparset_vals.size()]; double* difweights = new double[scanparset_vals.size()]; int NParSets = scanparset_vals.size(); // Loop over all event I/O std::vector<nuiskey> eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } // Make a new input handler std::vector<std::string> file_descriptor = GeneralUtils::ParseToStr(inputfilename, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfilename << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inptype = InputUtils::ParseInputType(file_descriptor[0]); // Make handlers for input and output InputHandlerBase* input = InputUtils::CreateInputHandler("rawevents", inptype, file_descriptor[1]); InputHandlerBase* output = InputUtils::CreateInputHandler("splineevents", InputUtils::kEVSPLN_Input, outputfilename); // Get Base Events for each case. FitEvent* rawevent = input->FirstNuisanceEvent(); FitEvent* splevent = output->FirstNuisanceEvent(); // Setup outputfile std::string outputtest = outputfilename + ".splinetest.1DEventScan.root"; TFile* outputtestfile = new TFile(outputtest.c_str(), "RECREATE"); outputtestfile->cd(); // Save Parameter Sets for (size_t i = 0; i < scanparset_hists.size(); i++) { scanparset_hists[i]->Write(Form("Paramater_Set_%i", (int)i)); } // Save a TTree of weights and differences. TTree* weighttree = new TTree("weightscan", "weightscan"); // Make a branch for each weight set for (size_t i = 0; i < scanparset_hists.size(); i++) { weighttree->Branch(Form("RawWeights_Set_%i", (int)i), &rawweights[i], Form("RawWeights_Set_%i/D", (int)i) ); weighttree->Branch(Form("SplineWeights_Set_%i", (int)i), &splweights[i], Form("SplineWeights_Set_%i/D", (int)i) ); weighttree->Branch(Form("DifWeights_Set_%i", (int)i), &difweights[i], Form("DifWeights_Set_%i/D", (int)i) ); } // Count int i = 0; int nevents = input->GetNEvents(); while (rawevent and splevent) { // Loop over 1D parameter sets. for (size_t j = 0; j < scanparset_vals.size(); j++) { // Reconfigure fRW->SetAllDials(&scanparset_vals[j][0], scanparset_vals[j].size()); fRW->Reconfigure(); // Reconfigure spline RW splweight->SetAllDials(&scanparset_vals[j][0], scanparset_vals[j].size()); splweight->Reconfigure(); splevent->fSplineRead->SetNeedsReconfigure(true); // Calc weight for both events rawweights[j] = fRW->CalcWeight(rawevent); splweights[j] = splweight->CalcWeight(splevent); difweights[j] = splweights[j] - rawweights[j]; } if (i % 1000 == 0) { LOG(FIT) << "Processed " << i << "/" << nevents << std::endl; } // Fill Array weighttree->Fill(); // Iterate to next event. i++; rawevent = input->NextNuisanceEvent(); splevent = output->NextNuisanceEvent(); } outputtestfile->cd(); weighttree->Write(); outputtestfile->Close(); } } */ //************************************* void SplineRoutines::TestSplines_NDEventThrow() { //************************************* // Setup RW Engine if (fRW) delete fRW; SetupRWEngine(); // Make a spline RW Engine too. FitWeight* splweight = new FitWeight("splinerwaweight"); std::vector<nuiskey> parameterkeys = Config::QueryKeys("parameter"); TH1D* parhisttemplate = new TH1D("parhist", "parhist", parameterkeys.size(), 0.0, float(parameterkeys.size())); // Add Parameters for (size_t i = 0; i < parameterkeys.size(); i++) { nuiskey key = parameterkeys[i]; std::string parname = key.GetS("name"); std::string partype = key.GetS("type"); double nom = key.GetD("nominal"); parhisttemplate->SetBinContent(i + 1, nom); parhisttemplate->GetXaxis()->SetBinLabel(i + 1, parname.c_str()); splweight->IncludeDial( key.GetS("name"), kSPLINEPARAMETER, nom); splweight->SetDialValue( key.GetS("name"), key.GetD("nominal") ); } splweight->Reconfigure(); // Make a high resolution spline set. std::vector<double> nomvals = fRW->GetDialValues(); // int testres = FitPar::Config().GetParI("spline_test_resolution"); std::vector< std::string > scanparset_names; std::vector< std::vector<double> > scanparset_vals; std::vector< TH1D* > scanparset_hists; // Loop over all params // Add Parameters int nthrows = FitPar::Config().GetParI("spline_test_throws"); for (int i = 0; i < nthrows; i++) { std::vector<double> newvals = nomvals; for (size_t j = 0; j < parameterkeys.size(); j++) { nuiskey key = parameterkeys[j]; if (!key.Has("low") or !key.Has("high") or !key.Has("step")) { continue; } // Push Back Scan double low = key.GetD("low"); double high = key.GetD("high"); newvals[j] = gRandom->Uniform(low, high); } // Add to vects scanparset_vals.push_back(newvals); TH1D* parhist = (TH1D*)parhisttemplate->Clone(); for (size_t j = 0; j < newvals.size(); j++) { parhist->SetBinContent(j + 1, newvals[j]); } scanparset_hists.push_back(parhist); } // Print out the parameter set to test for (uint i = 0; i < scanparset_vals.size(); i++) { std::cout << "Parset " << i; for (uint j = 0 ; j < scanparset_vals[i].size(); j++) { std::cout << " " << scanparset_vals[i][j]; } std::cout << std::endl; } // Weight holders double* rawweights = new double[scanparset_vals.size()]; double* splweights = new double[scanparset_vals.size()]; double* difweights = new double[scanparset_vals.size()]; int nweights = scanparset_vals.size(); // int NParSets = scanparset_vals.size(); // Loop over all event I/O std::vector<nuiskey> eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } // Make a new input handler std::vector<std::string> file_descriptor = GeneralUtils::ParseToStr(inputfilename, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfilename << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inptype = InputUtils::ParseInputType(file_descriptor[0]); // Make handlers for input and output InputHandlerBase* input = InputUtils::CreateInputHandler("rawevents", inptype, file_descriptor[1]); InputHandlerBase* output = InputUtils::CreateInputHandler("splineevents", InputUtils::kEVSPLN_Input, outputfilename); // Get Base Events for each case. FitEvent* rawevent = input->FirstNuisanceEvent(); FitEvent* splevent = output->FirstNuisanceEvent(); // Setup outputfile std::string outputtest = outputfilename + ".splinetest.NDEventThrow.root"; TFile* outputtestfile = new TFile(outputtest.c_str(), "RECREATE"); outputtestfile->cd(); // Save Parameter Sets for (size_t i = 0; i < scanparset_hists.size(); i++) { scanparset_hists[i]->Write(Form("Paramater_Set_%i", (int)i)); } // Save a TTree of weights and differences. TTree* weighttree = new TTree("weightscan", "weightscan"); // Make a branch for each weight set for (size_t i = 0; i < scanparset_hists.size(); i++) { weighttree->Branch(Form("RawWeights_Set_%i", (int)i), &rawweights[i], Form("RawWeights_Set_%i/D", (int)i) ); weighttree->Branch(Form("SplineWeights_Set_%i", (int)i), &splweights[i], Form("SplineWeights_Set_%i/D", (int)i) ); weighttree->Branch(Form("DifWeights_Set_%i", (int)i), &difweights[i], Form("DifWeights_Set_%i/D", (int)i) ); } // Count // int i = 0; int nevents = input->GetNEvents(); int lasttime = time(NULL); // Load N Chunks of the Weights into Memory // Split into N processing chunks int nchunks = FitPar::Config().GetParI("spline_chunks"); if (nchunks <= 0) nchunks = 1; if (nchunks >= nevents / 2) nchunks = nevents / 2; std::cout << "Starting NChunks " << nchunks << std::endl; for (int ichunk = 0; ichunk < nchunks; ichunk++) { // Skip to only do one processing chunk // if (procchunk != -1 and procchunk != ichunk) continue; LOG(FIT) << "On Processing Chunk " << ichunk << std::endl; int neventsinchunk = nevents / nchunks; int loweventinchunk = neventsinchunk * ichunk; // int higheventinchunk = neventsinchunk * (ichunk + 1); double** allrawweights = new double*[neventsinchunk]; double** allsplweights = new double*[neventsinchunk]; double** alldifweights = new double*[neventsinchunk]; for (int k = 0; k < neventsinchunk; k++){ allrawweights[k] = new double[nweights]; allsplweights[k] = new double[nweights]; alldifweights[k] = new double[nweights]; } // Start Set Processing Here. for (int iset = 0; iset < nweights; iset++) { // Reconfigure fRW->SetAllDials(&scanparset_vals[iset][0], scanparset_vals[iset].size()); fRW->Reconfigure(); // Reconfigure spline RW splweight->SetAllDials(&scanparset_vals[iset][0], scanparset_vals[iset].size()); splweight->Reconfigure(); splevent->fSplineRead->SetNeedsReconfigure(true); // Could reorder this to save the weightconts in order instead of reconfiguring per event. // Loop over all events and fill the TTree for (int i = 0; i < neventsinchunk; i++){ rawevent = input->GetNuisanceEvent(i+loweventinchunk); splevent = output->GetNuisanceEvent(i+loweventinchunk); allrawweights[i][iset] = fRW->CalcWeight(rawevent); allsplweights[i][iset] = splweight->CalcWeight(splevent); alldifweights[i][iset] = allsplweights[i][iset] - allrawweights[i][iset]; } std::ostringstream timestring; int timeelapsed = time(NULL) - lasttime; if (timeelapsed) { lasttime = time(NULL); int setsleft = (nweights-iset-1) + (nweights * (nchunks - ichunk - 1)); float proj = (float(setsleft) *timeelapsed) / 60 / 60; timestring << setsleft << " sets remaining. Last one took " << timeelapsed << ". " << proj << " hours remaining."; } LOG(REC) << "Processed Set " << iset << "/" << nweights <<" in chunk " << ichunk << "/" << nchunks << " " << timestring.str() << std::endl; } // Fill weights for this chunk into the TTree for (int k = 0; k < neventsinchunk; k++){ for (int l = 0; l < nweights; l++){ rawweights[l] = allrawweights[k][l]; splweights[l] = allsplweights[k][l]; difweights[l] = alldifweights[k][l]; } weighttree->Fill(); } } // Loop over nchunks // Loop over parameter sets // Set All Dials and reconfigure // Loop over events in chunk // Fill Chunkweightcontainers // Once all dials are done, fill the weight tree // Iterator to next chunk outputtestfile->cd(); weighttree->Write(); outputtestfile->Close(); } } void SplineRoutines::SaveSplinePlots() { if (fRW) delete fRW; SetupRWEngine(); // Setup the spline reader SplineWriter* splwrite = new SplineWriter(fRW); std::vector<nuiskey> splinekeys = Config::QueryKeys("spline"); // Add splines to splinewriter for (std::vector<nuiskey>::iterator iter = splinekeys.begin(); iter != splinekeys.end(); iter++) { nuiskey splkey = (*iter); // Add Spline Info To Reader splwrite->AddSpline(splkey); } splwrite->SetupSplineSet(); // Event Loop // Loop over all events and calculate weights for each parameter set. // Generate a set of nominal events // Method, Loop over inputs, create input handler, then create a ttree std::vector<nuiskey> eventkeys = Config::QueryKeys("events"); for (size_t i = 0; i < eventkeys.size(); i++) { nuiskey key = eventkeys.at(i); // Get I/O std::string inputfilename = key.GetS("input"); if (inputfilename.empty()) { ERR(FTL) << "No input given for set of input events!" << std::endl; throw; } std::string outputfilename = key.GetS("output"); if (outputfilename.empty()) { outputfilename = inputfilename + ".nuisance.root"; ERR(FTL) << "No output give for set of output events! Saving to " << outputfilename << std::endl; } // Make new outputfile outputfilename += ".SplinePlots.root"; TFile* outputfile = new TFile(outputfilename.c_str(), "RECREATE"); outputfile->cd(); // Make a new input handler std::vector<std::string> file_descriptor = GeneralUtils::ParseToStr(inputfilename, ":"); if (file_descriptor.size() != 2) { ERR(FTL) << "File descriptor had no filetype declaration: \"" << inputfilename << "\". expected \"FILETYPE:file.root\"" << std::endl; throw; } InputUtils::InputType inptype = InputUtils::ParseInputType(file_descriptor[0]); InputHandlerBase* input = InputUtils::CreateInputHandler("eventsaver", inptype, file_descriptor[1]); // Get info from inputhandler int nevents = input->GetNEvents(); int countwidth = (nevents / 1000); FitEvent* nuisevent = input->FirstNuisanceEvent(); outputfile->cd(); // int lasttime = time(NULL); TCanvas* fitcanvas = NULL; // Loop over all events and fill the TTree while (nuisevent) { // std::cout << "Fitting event " << i << std::endl; // Calculate the weights for each parameter set splwrite->GetWeightsForEvent(nuisevent); splwrite->FitSplinesForEvent(fitcanvas, true); if (fitcanvas) { outputfile->cd(); fitcanvas->Write(Form("Event_SplineCanvas_%i", (int)i)); } // Logging if (i % countwidth == 0) { LOG(REC) << "Saved " << i << "/" << nevents << " nuisance spline plots. " << std::endl; } // Iterate i++; nuisevent = input->NextNuisanceEvent(); } // Save flux and close file outputfile->cd(); // Close Output outputfile->Close(); // Delete Inputs delete input; } // remove Keys eventkeys.clear(); } void SplineRoutines::TestSplines_NDLikelihoodThrow() { // Setup RW Engine if (fRW) delete fRW; SetupRWEngine(); // Make a spline RW Engine too. FitWeight* splweight = new FitWeight("splinerwaweight"); std::vector<nuiskey> parameterkeys = Config::QueryKeys("parameter"); TH1D* parhisttemplate = new TH1D("parhist", "parhist", parameterkeys.size(), 0.0, float(parameterkeys.size())); // Add Parameters for (size_t i = 0; i < parameterkeys.size(); i++) { nuiskey key = parameterkeys[i]; std::string parname = key.GetS("name"); std::string partype = key.GetS("type"); double nom = key.GetD("nominal"); parhisttemplate->SetBinContent(i + 1, nom); parhisttemplate->GetXaxis()->SetBinLabel(i + 1, parname.c_str()); splweight->IncludeDial( key.GetS("name"), kSPLINEPARAMETER, nom); splweight->SetDialValue( key.GetS("name"), key.GetD("nominal") ); } splweight->Reconfigure(); // Make a high resolution spline set. std::vector<double> nomvals = fRW->GetDialValues(); // int testres = FitPar::Config().GetParI("spline_test_resolution"); std::vector< std::string > scanparset_names; std::vector< std::vector<double> > scanparset_vals; std::vector< TH1D* > scanparset_hists; // Loop over all params // Add Parameters int nthrows = FitPar::Config().GetParI("spline_test_throws"); for (int i = 0; i < nthrows; i++) { std::vector<double> newvals = nomvals; for (size_t j = 0; j < parameterkeys.size(); j++) { nuiskey key = parameterkeys[j]; if (!key.Has("low") or !key.Has("high") or !key.Has("step")) { continue; } // Push Back Scan double low = key.GetD("low"); double high = key.GetD("high"); newvals[j] = gRandom->Uniform(low, high); } // Add to vects scanparset_vals.push_back(newvals); TH1D* parhist = (TH1D*)parhisttemplate->Clone(); for (size_t j = 0; j < newvals.size(); j++) { parhist->SetBinContent(j + 1, newvals[j]); } scanparset_hists.push_back(parhist); } // Print out the parameter set to test for (uint i = 0; i < scanparset_vals.size(); i++) { std::cout << "Parset " << i; for (uint j = 0 ; j < scanparset_vals[i].size(); j++) { std::cout << " " << scanparset_vals[i][j]; } std::cout << std::endl; } // Make a new set of Raw/Spline Sample Keys std::vector<nuiskey> eventkeys = Config::QueryKeys("events"); std::vector<nuiskey> testkeys = Config::QueryKeys("sampletest"); std::vector<nuiskey> rawkeys; std::vector<nuiskey> splkeys; for (std::vector<nuiskey>::iterator iter = testkeys.begin(); iter != testkeys.end(); iter++) { nuiskey key = (*iter); std::string samplename = key.GetS("name"); std::string eventsid = key.GetS("inputid"); nuiskey eventskey = Config::QueryLastKey("events", "id=" + eventsid); std::string rawfile = eventskey.GetS("input"); std::string splfile = eventskey.GetS("output"); nuiskey rawkeytemp = Config::CreateKey("sample"); rawkeytemp.SetS("name", samplename); rawkeytemp.SetS("input", rawfile); nuiskey splkeytemp = Config::CreateKey("sample"); splkeytemp.SetS("name", samplename); splkeytemp.SetS("input", "EVSPLN:" + splfile); rawkeys.push_back(rawkeytemp); splkeys.push_back(splkeytemp); } if (fOutputRootFile) delete fOutputRootFile; fOutputRootFile = new TFile(fOutputFile.c_str(), "RECREATE"); fOutputRootFile->ls(); // Make two new JointFCN JointFCN* rawfcn = new JointFCN(rawkeys, fOutputRootFile); JointFCN* splfcn = new JointFCN(splkeys, fOutputRootFile); // Create iteration tree in output file fOutputRootFile->cd(); rawfcn->CreateIterationTree("raw_iterations", fRW); splfcn->CreateIterationTree("spl_iterations", splweight); // Loop over parameter sets. for (size_t j = 0; j < scanparset_vals.size(); j++) { FitBase::SetRW(fRW); double rawtotal = rawfcn->DoEval(&scanparset_vals[j][0]); FitBase::SetRW(splweight); double spltotal = splfcn->DoEval(&scanparset_vals[j][0]); LOG(FIT) << "RAW SPLINE DIF = " << rawtotal << " " << spltotal << " " << spltotal - rawtotal << std::endl; } fOutputRootFile->cd(); rawfcn->WriteIterationTree(); splfcn->WriteIterationTree(); } void SplineRoutines::TestSplines_1DLikelihoodScan() { // Setup RW Engine. if (fRW) delete fRW; SetupRWEngine(); // Setup Parameter Set. // Make a spline RW Engine too. FitWeight* splweight = new FitWeight("splinerwaweight"); // std::vector<nuiskey> splinekeys = Config::QueryKeys("spline"); std::vector<nuiskey> parameterkeys = Config::QueryKeys("parameter"); TH1D* parhisttemplate = new TH1D("parhist", "parhist", parameterkeys.size(), 0.0, float(parameterkeys.size())); // Add Parameters for (size_t i = 0; i < parameterkeys.size(); i++) { nuiskey key = parameterkeys[i]; std::string parname = key.GetS("name"); std::string partype = key.GetS("type"); double nom = key.GetD("nominal"); parhisttemplate->SetBinContent(i + 1, nom); parhisttemplate->GetXaxis()->SetBinLabel(i + 1, parname.c_str()); splweight->IncludeDial( key.GetS("name"), kSPLINEPARAMETER, nom); splweight->SetDialValue( key.GetS("name"), key.GetD("nominal") ); } splweight->Reconfigure(); // Make a high resolution spline set. std::vector<double> nomvals = fRW->GetDialValues(); // int testres = FitPar::Config().GetParI("spline_test_resolution"); std::vector< std::vector<double> > scanparset_vals; std::vector< TH1D* > scanparset_hists; // Loop over all params // Add Parameters for (size_t i = 0; i < parameterkeys.size(); i++) { nuiskey key = parameterkeys[i]; // Get Par Name std::string name = key.GetS("name"); if (!key.Has("low") or !key.Has("high") or !key.Has("step")) { continue; } // Push Back Scan double low = key.GetD("low"); double high = key.GetD("high"); double cur = low; double step = key.GetD("step"); while (cur <= high) { // Make new set std::vector<double> newvals = nomvals; newvals[i] = cur; // Add to vects scanparset_vals.push_back(newvals); TH1D* parhist = (TH1D*)parhisttemplate->Clone(); for (size_t j = 0; j < newvals.size(); j++) { parhist->SetBinContent(j + 1, newvals[j]); } scanparset_hists.push_back(parhist); // Move to next one cur += step; } } // Print out the parameter set to test for (uint i = 0; i < scanparset_vals.size(); i++) { std::cout << "Parset " << i; for (uint j = 0 ; j < scanparset_vals[i].size(); j++) { std::cout << " " << scanparset_vals[i][j]; } std::cout << std::endl; } // Make a new set of Raw/Spline Sample Keys std::vector<nuiskey> eventkeys = Config::QueryKeys("events"); std::vector<nuiskey> testkeys = Config::QueryKeys("sampletest"); std::vector<nuiskey> rawkeys; std::vector<nuiskey> splkeys; for (std::vector<nuiskey>::iterator iter = testkeys.begin(); iter != testkeys.end(); iter++) { nuiskey key = (*iter); std::string samplename = key.GetS("name"); std::string eventsid = key.GetS("inputid"); nuiskey eventskey = Config::QueryLastKey("events", "id=" + eventsid); std::string rawfile = eventskey.GetS("input"); std::string splfile = eventskey.GetS("output"); nuiskey rawkeytemp = Config::CreateKey("sample"); rawkeytemp.SetS("name", samplename); rawkeytemp.SetS("input", rawfile); nuiskey splkeytemp = Config::CreateKey("sample"); splkeytemp.SetS("name", samplename); splkeytemp.SetS("input", "EVSPLN:" + splfile); rawkeys.push_back(rawkeytemp); splkeys.push_back(splkeytemp); } if (fOutputRootFile) delete fOutputRootFile; fOutputRootFile = new TFile(fOutputFile.c_str(), "RECREATE"); fOutputRootFile->ls(); // Make two new JointFCN JointFCN* rawfcn = new JointFCN(rawkeys, fOutputRootFile); JointFCN* splfcn = new JointFCN(splkeys, fOutputRootFile); // Create iteration tree in output file fOutputRootFile->cd(); rawfcn->CreateIterationTree("raw_iterations", fRW); splfcn->CreateIterationTree("spl_iterations", splweight); // Loop over parameter sets. for (size_t j = 0; j < scanparset_vals.size(); j++) { FitBase::SetRW(fRW); double rawtotal = rawfcn->DoEval(&scanparset_vals[j][0]); FitBase::SetRW(splweight); double spltotal = splfcn->DoEval(&scanparset_vals[j][0]); LOG(FIT) << "RAW SPLINE DIF = " << rawtotal << " " << spltotal << " " << spltotal - rawtotal << std::endl; } fOutputRootFile->cd(); rawfcn->WriteIterationTree(); splfcn->WriteIterationTree(); } /* MISC Functions */ //************************************* int SplineRoutines::GetStatus() { //************************************* return 0; }