/// <summary> /// Generate the generic plots /// </summary> /// <param name="source"></param> /// <param name="outd"></param> public static void GenericPlots(this IQueryable <LLPInfo.extrapTree> source, FutureTDirectory outd, string name) { source .Select(e => e.llp1_pt / 1000.0) .FuturePlot(JetPtPlotRaw, $"{name}_pt1", $"{name}_pt1") .Save(outd); source .Select(e => e.llp2_pt / 1000.0) .FuturePlot(JetPtPlotRaw, $"{name}_pt2", $"{name}_pt2") .Save(outd); source .Select(e => e.llp1_Lxy / 1000.0) .FuturePlot(JetLxyPlotRaw, $"{name}_lxy1", $"{name}_lxy1") .Save(outd); source .Select(e => e.llp2_Lxy / 1000.0) .FuturePlot(JetLxyPlotRaw, $"{name}_lxy2", $"{name}_lxy2") .Save(outd); source .Select(e => e.llp1_eta) .FuturePlot(JetEtaPlotRaw, $"{name}_eta1", $"{name}_eta1") .Save(outd); source .Select(e => e.llp2_eta) .FuturePlot(JetEtaPlotRaw, $"{name}_eta2", $"{name}_eta2") .Save(outd); }
/// <summary> /// Generate plots for a background. /// </summary> /// <param name="backgrounds"></param> public ABCDInfo ProcessBackground(FutureTDirectory output, IQueryable <T> backgrounds) { GenericPlots(output, backgrounds); // We have to calculate the correlation for this. var count = backgrounds.FutureCount(); var s1 = backgrounds.Select(v => _v1.ValueExpressionX.Invoke(v)).FutureAggregate(0.0, (ac, v) => ac + v); var s2 = backgrounds.Select(v => _v2.ValueExpressionX.Invoke(v)).FutureAggregate(0.0, (ac, v) => ac + v); var av1 = s1.Value / count.Value; var av2 = s2.Value / count.Value; var sdS1 = backgrounds.Select(v => _v1.ValueExpressionX.Invoke(v) - av1).Select(v => v * v).FutureAggregate(0.0, (ac, v) => ac + v); var sdS2 = backgrounds.Select(v => _v2.ValueExpressionX.Invoke(v) - av2).Select(v => v * v).FutureAggregate(0.0, (ac, v) => ac + v); var sdS12 = backgrounds.Select(v => (_v1.ValueExpressionX.Invoke(v) - av1) * (_v2.ValueExpressionX.Invoke(v) - av2)).FutureAggregate(0.0, (ac, v) => ac + v); var covar = Matrix <double> .Build.Dense(2, 2); covar[0, 0] = sdS1.Value / (count.Value - 1); covar[1, 1] = sdS2.Value / (count.Value - 1); covar[0, 1] = sdS12.Value / (count.Value - 1); covar[1, 0] = sdS12.Value / (count.Value - 1); Console.WriteLine(covar); // Done, return info. return(new ABCDInfo() { CoVar = covar }); }
/// <summary> /// Plot some basic jet values /// </summary> /// <param name="source"></param> /// <param name="name"></param> /// <param name="dir"></param> public static void PlotBasicValues(this IQueryable<recoTreeJets> source, string name, FutureTDirectory dir) { source .FuturePlot(JetPtPlot, name) .Save(dir); source .FuturePlot(JetEtaPlot, name) .Save(dir); source .FuturePlot(JetCalRPlot, name) .Save(dir); }
/// <summary> /// Make the generic plots of everything /// </summary> /// <param name="output"></param> /// <param name="backgrounds"></param> private void GenericPlots(FutureTDirectory output, IQueryable <T> source) { // Do the 1D plots of everything source .FuturePlot(_v1, "") .Save(output); source .FuturePlot(_v2, "") .Save(output); source .FuturePlot(_2DPlot, "") .Save(output); }
/// <summary> /// Make some basic plots for LLP's. /// </summary> /// <param name="source"></param> /// <param name="dir"></param> public static void PlotBasicLLPValues(this IQueryable<recoTreeLLPs> source, string name, FutureTDirectory dir) { source .FuturePlot(LLPPtPlot, name) .Save(dir); source .FuturePlot(LLPLxyPlot, name) .Save(dir); source .FuturePlot(LLPEtaPlot, name) .Save(dir); source .FuturePlot(LLPLzPlot, name) .Save(dir); source .FuturePlot(LLPLxyLzPlot, name) .Save(dir); }
/// <summary> /// Make some signal like plots /// </summary> /// <param name="output"></param> /// <param name="signal"></param> public void ProcessSignal(FutureTDirectory output, IQueryable <T> signal) { GenericPlots(output, signal); }
/// <summary> /// Do the cut /// </summary> /// <param name="effResults"></param> /// <param name="queryable1"></param> /// <param name="queryable2"></param> private static IFutureValue<double> CalcEff(FutureTDirectory effResults, Expression<Func<TrainingData,double>> selection, double threshold, IQueryable<TrainingData> background, IQueryable<TrainingData> signal) { background .Select(t => selection.Invoke(t)) .FuturePlot("b_weight", "Background weight", 50, -1.1, 1.1) .Save(effResults); signal .Select(t => selection.Invoke(t)) .FuturePlot("s_weight", "Signal weight", 50, -1.1, 1.1) .Save(effResults); var total_b = background.FutureCount(); var total_s = signal.FutureCount(); var selected_b = background.Where(t => selection.Invoke(t) > threshold).FutureCount(); var selected_s = signal.Where(t => selection.Invoke(t) > threshold).FutureCount(); var eff_b = from tb in total_b from ns in selected_b select (double) ns / (double) tb; var eff_s = from tb in total_s from ns in selected_s select (double) ns / (double) tb; //FutureWrite(from eb in eff_b from es in eff_s select $"Signal eff: {es}; Background eff: {eb}"); return eff_s; }
/// <summary> /// Make a series of plots for the LLP's. /// </summary> /// <param name="llp"></param> /// <param name="dir"></param> private static void ProcessSample(IQueryable<Files.MetaData> llp, FutureTDirectory dir) { // Dump basic plots with info for the LLPs. var llpStream = llp.SelectMany(l => l.Data.LLPs); llpStream .PlotBasicLLPValues("all", dir); // Next, for LLP's with a jet near them. var llpStreamWithJets = llp.SelectMany(ev => ev.Data.Jets) .Where(j => j.LLP.IsGoodIndex()); llpStreamWithJets .Select(j => j.LLP) .PlotBasicLLPValues("withJet", dir); var llpStreamWithGoodJets = llpStreamWithJets .Where(j => j.ET > 40.0 && Math.Abs(j.eta) < JetEtaLimit); llpStreamWithGoodJets .Select(j => j.LLP) .PlotBasicLLPValues("withGoodJet", dir); llpStreamWithGoodJets .Where(j => Math.Abs(j.eta) <= 1.7) .PlotBasicValues("withGoodJetBarrel", dir); llpStreamWithGoodJets .Where(j => Math.Abs(j.eta) > 1.7) .PlotBasicValues("withGoodJetEndCap", dir); // Look at the number of times sharing occurs (should never happen) var sharedJets = from ev in llp from j1 in ev.Data.Jets from j2 in ev.Data.Jets where j1.isGoodLLP && j2.isGoodLLP where j1.LLP.IsGoodIndex() && j2.LLP.IsGoodIndex() where j1 != j2 where j1.LLP == j2.LLP select Tuple.Create(j1, j2); var count = sharedJets.FutureCount(); FutureWriteLine(() => $" Number of jets that share an LLP: {count.Value}"); // Calculate how close things are for the LLP's var sharedLLPs = from ev in llp let l1 = ev.Data.LLPs.First() let l2 = ev.Data.LLPs.Skip(1).First() select Tuple.Create(l1, l2); sharedLLPs .Select(l => Sqrt(DeltaR2(l.Item1.eta, l.Item1.phi, l.Item2.eta, l.Item2.phi))) .FuturePlot("DeltaRLLP", "The DeltaR between the two LLPs in the event", 20, 0.0, 3.0) .Save(dir); sharedLLPs .Select(l => DeltaPhi(l.Item1.phi, l.Item2.phi)) .FuturePlot("DeltaPhiLLP", "The DeltaPhi between the two LLPs in the event", 60, 0.0, PI) .Save(dir); // How many LLPs are within 0.4 of a jet? Expression<Func<recoTreeJets, recoTreeLLPs, double>> DR2 = (l, j) => DeltaR2(l.eta, l.phi, j.eta, j.phi); #if false double openingAngle = 0.4; var llpsCloseToJets = from ev in llp select from j in ev.Data.Jets where j.isGoodLLP select from lp in ev.Data.LLPs let dr = DR2.Invoke(j, lp) let dphi = Abs(DeltaPhi(j.phi, lp.phi)) select Tuple.Create(j, lp, dr, dphi); llpsCloseToJets .SelectMany(jets => jets) .Select(llps => llps.Where(tup => tup.Item3 < openingAngle * openingAngle).Count()) .FuturePlot("nLLPsCloseToJet", $"Number of LLPs with DR < {openingAngle}", 5, 0.0, 5.0) .Save(dir); llpsCloseToJets .SelectMany(jets => jets) .FuturePlot("maxDRForLLPs", "Max DR between each Jet and all LLPs in event", 60, 0.0, 3.0, jets => Sqrt(jets.Max(v => v.Item3))) .Save(dir); llpsCloseToJets .SelectMany(jets => jets) .FuturePlot("maxDPhiForLLPs", "Max DPhi between each jet and all LLPs in event", 60, 0, PI, jets => jets.Max(v => v.Item4)) .Save(dir); llpsCloseToJets .SelectMany(jets => jets) .Where(j => j.First().Item1.logRatio > 1.2) .FuturePlot("maxDRForLLPsInCRJets", "Max DR between each CR Jet (logR>1.2) and all LLPs in event", 60, 0.0, 3.0, jets => Sqrt(jets.Max(v => v.Item3))) .Save(dir); llpsCloseToJets .SelectMany(jets => jets) .Where(j => j.First().Item1.logRatio > 1.2) .FuturePlot("maxDPhiForLLPsInCRJets", "Max DPhi between each CR Jet (logR>1.2) and all LLPs in event", 60, 0, PI, jets => jets.Max(v => v.Item4)) .Save(dir); llpsCloseToJets .SelectMany(jets => jets) .FuturePlot("maxDPhiForLLPsZoom", "Max DPhi between each jet and all LLPs in event", 60, 0, 0.4, jets => jets.Max(v => v.Item4)) .Save(dir); llpsCloseToJets .SelectMany(jets => jets) .Select(jets => jets.OrderByDescending(j => j.Item4).First()) .FuturePlot("maxDPhiVsDEtaZoom", "Max DPhi between each jet and all LLPs in event vs DEta; Delta Phi; Delta eta", 60, 0, 0.4, jet => jet.Item4, 60, -0.5, 0.5, jet => jet.Item1.eta - jet.Item2.eta) .Save(dir); #endif // Look at jets that pass the Run 1 cuts but don't have an associated LLP. // Once we have the good and bad jets, partner them up with the closest LLP we can. var jetsOnTheirOwn = from ev in llp from j in ev.Data.Jets where j.isGoodLLP where Abs(j.eta) < JetEtaLimit && j.pT > 40.0 where j.logRatio >= IsolationTrackPtCut where !j.LLP.IsGoodIndex() let closeLLP = ev.Data.LLPs.OrderBy(l => DR2.Invoke(j, l)).First() select Tuple.Create(j, closeLLP, Sqrt(DR2.Invoke(j, closeLLP)), ev.Data.eventNumber); var jetsWithPartner = from ev in llp from j in ev.Data.Jets where j.isGoodLLP where Abs(j.eta) < JetEtaLimit where j.logRatio >= IsolationTrackPtCut where j.LLP.IsGoodIndex() let closeLLP = ev.Data.LLPs.OrderBy(l => DR2.Invoke(j, l)).First() select Tuple.Create(j, closeLLP, Sqrt(DR2.Invoke(j, closeLLP))); jetsOnTheirOwn .Select(jinfo => jinfo.Item1) .PlotBasicValues("CalRNoLLPNear", dir); jetsWithPartner .Select(jinfo => jinfo.Item1) .PlotBasicValues("CalRLLPNear", dir); jetsOnTheirOwn .Select(jinfo => jinfo.Item3) .FuturePlot("DRNoLLPNear", "DR to nearest LLP for lonely CalR jets", 20, 0.0, 0.7) .Save(dir); jetsWithPartner .Select(jinfo => jinfo.Item3) .FuturePlot("DRLLPNear", "DR to nearest LLP for CalR jets with associated LLP", 20, 0.0, 0.7) .Save(dir); jetsOnTheirOwn .Select(jinfo => jinfo.Item2) .PlotBasicLLPValues("CalRNoLLPNear", dir); jetsWithPartner .Select(jinfo => jinfo.Item2) .PlotBasicLLPValues("CalRLLPNear", dir); jetsWithPartner .Where(jinfo => Math.Abs(jinfo.Item1.eta) <= 1.7) .Select(jinfo => jinfo.Item2) .PlotBasicLLPValues("CalRLLPNearBarrel", dir); jetsWithPartner .Where(jinfo => Math.Abs(jinfo.Item1.eta) > 1.7) .Select(jinfo => jinfo.Item2) .PlotBasicLLPValues("CalRLLPNearEndCap", dir); // Write out a small text file of the bad events so we can cross check. jetsOnTheirOwn .Select(i => new { EventNumber = i.Item4, DR = i.Item3, JetEta = i.Item1.eta, JetPhi = i.Item1.phi, JetPt = i.Item1.pT, LLPEta = i.Item2.eta, LLPPhi = i.Item2.phi, LLPPt = i.Item2.pT / 1000.0 }) .AsCSV(new FileInfo("lonlyevents.csv")); // And, finally, we need to count so we can have some efficiencies... var jetsWithPartnerCount = jetsWithPartner.FutureCount(); var jetsOnTheirOwnCount = jetsOnTheirOwn.FutureCount(); var fraction = from jOnOwn in jetsOnTheirOwnCount from jPartner in jetsWithPartnerCount select jOnOwn / ((double)jOnOwn + (double)jPartner); FutureConsole.FutureWriteLine(() => $" Fraction of unpartnered jets: {fraction.Value}."); #if false // Lets look at llp's matched to a jet next var matchedLLPs = from ev in llp where ev.Data.Jets.Count() >= 2 select from lp in ev.Data.LLPs let closeJet = (from j in ev.Data.Jets let dr = DR2.Invoke(j, lp) //where dr < 0.4*0.4 orderby dr ascending select j).FirstOrDefault() where closeJet != null select Tuple.Create(lp, closeJet); var eventsWithTwoMatchedJets = matchedLLPs .Where(linfo => linfo.Count() == 2) .Where(linfo => linfo.First().Item2 == linfo.Skip(1).First().Item2) .FutureCount(); FutureWriteLine(() => $" Number of events where two LLPs are closest to one jet: {eventsWithTwoMatchedJets.Value}"); matchedLLPs .SelectMany(linfo => linfo) .FuturePlot("DRLLPJet", "The DR between jet and LLP; DR", 100, 0.0, 1.6, linfo => DR2.Invoke(linfo.Item2, linfo.Item1)) .Save(dir); matchedLLPs .SelectMany(linfo => linfo) .Where(linfo => linfo.Item1.Lxy > 2000.0) .FuturePlot("DRLLPJetInCal", "The DR between jet and LLP for Lxy > 2.0 m; DR", 100, 0.0, 1.6, linfo => DR2.Invoke(linfo.Item2, linfo.Item1)) .Save(dir); matchedLLPs .SelectMany(linfo => linfo) .FuturePlot("DRvsCalRLLPJet", "The DR between jet and LLP; DR(jet,llp) ; CalRatio", 100, 0.0, 1.6, linfo => DR2.Invoke(linfo.Item2, linfo.Item1), 100, -2.0, 3.0, linfo => linfo.Item2.logRatio) .Save(dir); matchedLLPs .SelectMany(linfo => linfo) .Where(linfo => linfo.Item1.Lxy > 2000.0) .FuturePlot("DRvsCalRLLPJetInCal", "The DR between jet and LLP for Lxy > 2.0 m; DR(jet,llp) ; CalRatio", 100, 0.0, 1.6, linfo => DR2.Invoke(linfo.Item2, linfo.Item1), 100, -2.0, 3.0, linfo => linfo.Item2.logRatio) .Save(dir); // The following causes a crash b.c. we aren't properly doing optimization, I think, in LINQToTTree var jetsCloseToLLPs = from ev in llp select from lp in ev.Data.LLPs select from j in ev.Data.Jets let dr = DR2.Invoke(j, lp) select Tuple.Create(j, lp, dr); jetsCloseToLLPs .SelectMany(jets => jets) .FuturePlot("maxDRForJets", "Max DR between each LLP and all Jets in event", 60, 0.0, 3.0, jets => Sqrt(jets.Max(v => v.Item3))) .Save(dir); llpsCloseToJets .SelectMany(jets => jets) .Select(jets => jets.OrderByDescending(j => j.Item4).First()) .FuturePlot("maxDPhiVsDRZoom", "Max DPhi between each jet and all LLPs in event vs DR; Delta Phi; Delta R", 60, 0, 0.4, jet => jet.Item4, 60, -0.5, 0.5, jet => Sqrt(jet.Item3)) .Save(dir); #endif }
/// <summary> /// Calculate a set of plots over this list of events /// </summary> /// <param name="signal"></param> /// <param name="background"></param> /// <param name="jetSelectorFunc"></param> /// <param name="dir"></param> private static Tuple<IFutureValue<NTH1>, IFutureValue<NTH1>> CalcSignalToBackground(IQueryable<JetInfoExtra> signal, IQueryable<JetInfoExtra> background, IPlotSpec<JetInfoExtra> plotter, FutureTDirectory dir, string name) { GC.Collect(3, GCCollectionMode.Forced, true); // Some generic plots signal .FuturePlot(JetExtraPtPlot, $"{name}_sig") .Save(dir); background .FuturePlot(JetExtraPtPlot, $"{name}_back") .Save(dir); signal .FuturePlot(JetExtraEtaPlot, $"{name}_sig") .Save(dir); background .FuturePlot(JetExtraEtaPlot, $"{name}_back") .Save(dir); // get the histograms for the signal and background var sPlot = signal .FuturePlot(plotter, "eff_sig") .Rename($"{name}_sig") .Save(dir) .Normalize() .AsCumulative(startWithZeroEff: false) .Rename($"{name}_sigrtback_sig") .Save(dir); var bPlot = background .FuturePlot(plotter, "eff_back") .Rename($"{name}_back") .Save(dir) .Normalize() .AsCumulative() .Rename($"{name}_sigrtback_back") .Save(dir); var bPlotSqrt = bPlot .Sqrt(); // As a bonus, calc the effeciency graf. Get the x and y for that. // TODO: there doesn't seem to be a get accessor for Content on NTH1 - is that really right? //var r = from s in sPlot // let sContent = Enumerable.Range(1, s.NbinsX).Select(idx => s.GetBinContent(idx)).ToArray() // from b in bPlot // select new ROOTNET.NTGraph(s.NBinsX, sContent, sContent); var effCurve = from s in sPlot from b in bPlot select CalculateROC(s, b, $"{name}_roc",$"ROC for {name}"); effCurve .Save(dir); // Calc the S/sqrt(B) and return it. sPlot .DividedBy(bPlotSqrt) .Rename($"{name}_sigrtback") .Save(dir); return Tuple.Create(sPlot, bPlot); }
/// <summary> /// Generate a series of plots /// </summary> /// <param name="signal"></param> /// <param name="background"></param> /// <param name="plotter"></param> /// <param name="dir"></param> /// <param name="nameStub"></param> private static Tuple<IFutureValue<NTH1>, IFutureValue<NTH1>> CalcSignalToBackgroundSeries(IQueryable<JetInfoExtra> signal, IQueryable<JetInfoExtra> background, IPlotSpec<JetInfoExtra> plotter, FutureTDirectory dir, string nameStub) { // Do them all. CalcSignalToBackground(signal, background, plotter, dir, nameStub); // Do LLP that have LLPs // TODO: understand how the LLP association is made, and make sure it is good enough. CalcSignalToBackground(signal.Where(sj => sj.Jet.LLP.IsGoodIndex()), background, plotter, dir, $"{nameStub}LLPJ"); // Has an LLP in the calorimeter. // TODO: understand how the LLP association is made, and make sure it is good enough. // TODO: Understand what isCRJet is defined to be. return CalcSignalToBackground(signal.Where(sj => sj.Jet.LLP.IsGoodIndex() && Constants.InCalorimeter.Invoke(sj.Jet.LLP.Lxy/1000)), background, plotter, dir, $"{nameStub}LLPJCal"); }
/// <summary> /// Make plots of everything /// </summary> /// <param name="source"></param> /// <returns></returns> public static IQueryable<TrainingTree> PlotTrainingVariables (this IQueryable<TrainingTree> source, FutureTDirectory dir, string tag) { // Plots of all the items foreach (var p in _plotters) { source .Select(j => Tuple.Create(p.ValueGetter.Invoke(j), j.Weight)) .FuturePlot(p.Plotter.NameFormat, p.Plotter.TitleFormat, p.Plotter, tag) .Save(dir); source .Select(j => p.ValueGetter.Invoke(j)) .FuturePlot(p.Plotter, $"{tag}_unweighted") .Save(dir); } // Continue on... return source; }
/// <summary> /// Allow for studying multiple samples /// </summary> /// <param name="background"></param> /// <param name="signal"></param> /// <param name="outputHistograms"></param> /// <returns></returns> private static List<IFutureValue<string>> PerSampleStudies(IQueryable<recoTree> background, IQueryable<recoTree> signal, FutureTDirectory outputHistograms) { var backgroundJets = BuildSuperJetInfo(background); var signalJets = BuildSuperJetInfo(signal); backgroundJets .PlotBasicDataPlots(outputHistograms.mkdir("background"), "all"); var sigdir = outputHistograms.mkdir("signal"); signalJets .PlotBasicDataPlots(sigdir, "all"); signalJets .Where(j => j.Jet.LLP.IsGoodIndex()) .PlotBasicDataPlots(sigdir, "withLLP"); signalJets .Where(j => j.Jet.LLP.IsGoodIndex()) .Where(j => LLPInCalorimeter.Invoke(j.Jet.LLP)) .PlotBasicDataPlots(sigdir, "withLLPInCal"); // Some basic info about the LLP's // TODO: make sure this is part of the LLPInvestigations guy. // LLPBasicInfo(signal.SelectMany(s => s.LLPs), signal.SelectMany(s => s.Jets), outputHistograms.mkdir("signalLLP")); // Do the CalR and NTrk plots var result = new List<IFutureValue<string>>(); var rtot = CalSigAndBackgroundSeries(signalJets, backgroundJets, "all", outputHistograms.mkdir("sigrtback")); result.AddRange(result); // Next, as a function of pT foreach (var ptRegion in Constants.PtRegions) { var dir = outputHistograms.mkdir($"sigrtback_{ptRegion.Item1}_{ptRegion.Item2}"); var signalGoodJets = signalJets .Where(j => j.Jet.pT >= ptRegion.Item1 && j.Jet.pT < ptRegion.Item2); var backgroundGoodJets = backgroundJets .Where(j => j.Jet.pT >= ptRegion.Item1 && j.Jet.pT < ptRegion.Item2); var regionInfo = $"{ptRegion.Item1}-{ptRegion.Item2}"; var r = CalSigAndBackgroundSeries(signalGoodJets, backgroundGoodJets, regionInfo, dir); result.AddRange(r); } // Dump out the number of events so everyone can see. var status = from nB in background.FutureCount() from nS in signal.FutureCount() select string.Format("Signal events: {0} Background events: {1}", nS, nB); result.Add(status); return result; }
/// <summary> /// Look at a single set of stuff for the ABCD method /// </summary> /// <param name="explorer"></param> /// <param name="backgrounds"></param> /// <param name="output"></param> private static ABCDInfo DoABCDExploration(ABCDCutExplorer <EventType> explorer, IQueryable <EventType> backgrounds, FutureTDirectory output) { var info = explorer.ProcessBackground(output.mkdir("JnZ"), backgrounds); // And a few signals var signalList = SampleMetaData.AllSamplesWithTag("signal") .Select(i => Tuple.Create(i.NickName, Files.GetSampleAsMetaData(i))); foreach (var source in signalList) { // Do everything var asEvents = source.Item2 .AsEventStream(); explorer.ProcessSignal(output.mkdir(source.Item1), asEvents); // Now, look carefully at only "signal" jets var asCalSignalEvents = asEvents .Where(t => SampleUtils.IsGoodSignalJet.Invoke(t.Item1.Jet) && SampleUtils.IsGoodSignalJet.Invoke(t.Item2.Jet)); explorer.ProcessSignal(output.mkdir($"{source.Item1}-CalOnly"), asCalSignalEvents); } return(info); }
/// <summary> /// Make generic plots of pT, CalRatio, etc. for all jets /// </summary> /// <param name="jets">Source of jets</param> /// <param name="saveDir">Future directory where we will save these plots</param> /// <param name="nameAddition">Text to give to name and title of all plots we are making</param> public static IQueryable<JetInfoExtra> PlotBasicDataPlots (this IQueryable<JetInfoExtra> jets, FutureTDirectory saveDir, string nameAddition) { jets .FuturePlot(JetExtraPtPlot, nameAddition) .Save(saveDir); jets .FuturePlot(JetExtraEtaPlot, nameAddition) .Save(saveDir); jets .FuturePlot(JetExtraCalRPlot, nameAddition) .Save(saveDir); jets .FuturePlot(NTrackExtraPlot, nameAddition) .Save(saveDir); jets .FuturePlot(TrackPtExtraPlot, nameAddition) .Save(saveDir); jets .FuturePlot(JetWidthPlotExtra, nameAddition) .Save(saveDir); jets .FuturePlot(DeltaROfCloseTrackPlotExtra, nameAddition) .Save(saveDir); // TODO: Running this loop takes waaay too long. What are we doing // wrong (if anything)? jets .FuturePlot(SumTrackPtPlot, nameAddition) .Save(saveDir); jets .FuturePlot(MaxTrackPtPlot, nameAddition) .Save(saveDir); jets .FuturePlot(JetExtraCalRVsPtPlot, nameAddition) .Save(saveDir); jets .FuturePlot(JetExtraNTrackVsPtPlot, nameAddition) .Save(saveDir); jets .FuturePlot(JetExtraCalRVsNTrackPlot, nameAddition) .Save(saveDir); jets .FuturePlot(JetExtraCalRVsMaxPtPlot, nameAddition) .Save(saveDir); jets .FuturePlot(JetExtraCalRVsSumPtPlot, nameAddition) .Save(saveDir); jets .FuturePlot(JetSumPtVsPtPlot, nameAddition) .Save(saveDir); jets .FuturePlot(JetMaxPtVsPtPlot, nameAddition) .Save(saveDir); return jets; }
/// <summary> /// Generate plots for the signal /// </summary> /// <param name="queryable"></param> /// <param name="sampleD"></param> /// <param name="mvaValue"></param> private static void PlotMVAResult(IQueryable<JetStream> source, FutureTDirectory dir, Expression<Func<TrainingTree, double>> mvaValue) { // Plot the weights. This can be used to plot signal vs background, ROC curves, etc. var weights = source .Select(j => TrainingUtils.TrainingTreeConverter.Invoke(j)) .Select(j => Tuple.Create(mvaValue.Invoke(j), j.Weight)) .FuturePlot(TrainingEventWeightFine.NameFormat, TrainingEventWeightFine.TitleFormat, TrainingEventWeightFine, "All") .Save(dir); // Next, let plot lots of kinematic plots so we can see what they look like. var plotsFromJS = new IPlotSpec<JetStream>[] { JetPtPlotJetStream, JetETPlotJetStream, JetEtaPlotJetStream, JetLxyPlotJetStream, JetCalRPlotJetStream, JetStreamSumPt, JetStreamMaxPt, JetCalRPlotFineJetStream, }; var plots = plotsFromJS .Select(myp => myp.FromType<JetStream, Tuple<JetStream, double>>(jinfo => jinfo.Item1, weight: jinfo => jinfo.Item2 * jinfo.Item1.Weight)); // We want weighted and unweighted plots here. We first have to normalize the weighting to be from 0 to 1. // If there is only a single weight in the sample (which is just weird) then correctly make sure we are set to deal // with things. var firstNonZeroBinValue = weights.Value.FindNonZeroBinValue(); var lastNonZeroBinValue = weights.Value.FindNonZeroBinValue(HistogramUtils.BinSearchOrder.HighestBin); if (firstNonZeroBinValue == lastNonZeroBinValue) { Console.WriteLine($" Sample has events with all one weight ({firstNonZeroBinValue})."); } var scaleing = lastNonZeroBinValue == firstNonZeroBinValue ? 1.0 : 1.0 / (lastNonZeroBinValue - firstNonZeroBinValue); firstNonZeroBinValue = lastNonZeroBinValue == firstNonZeroBinValue ? firstNonZeroBinValue - 1.0 : firstNonZeroBinValue; var mvaWeithedJetStream = source .Select(j => Tuple.Create(j, j.Weight * (mvaValue.Invoke(TrainingUtils.TrainingTreeConverter.Invoke(j)) - firstNonZeroBinValue)*scaleing)); var weithedJetStream = source .Select(j => Tuple.Create(j, j.Weight)); // And run through each plot foreach (var p in plots) { mvaWeithedJetStream .FuturePlot(p, "MVA") .Save(dir); weithedJetStream .FuturePlot(p, "") .Save(dir); } }
/// <summary> /// For a set of signal and background nets, do the calc for ntrk, cal ratio, etc. /// </summary> /// <param name="dir"></param> /// <param name="signalGoodJets"></param> /// <param name="backgroundGoodJets"></param> /// <param name="regionInfo"></param> /// <returns></returns> private static List<IFutureValue<string>> CalSigAndBackgroundSeries(IQueryable<JetInfoExtra> signalGoodJets, IQueryable<JetInfoExtra> backgroundGoodJets, string regionInfo, FutureTDirectory dir) { var sigBackCalR = CalcSignalToBackgroundSeries( signalGoodJets, backgroundGoodJets, JetExtraCalRPlot, dir, "CalR"); var sigBackNtrk = CalcSignalToBackgroundSeries( signalGoodJets, backgroundGoodJets, NTrackExtraPlot, dir, "Ntrk"); var sigBackSumPt = CalcSignalToBackgroundSeries( signalGoodJets, backgroundGoodJets, SumTrackPtPlot, dir, "SumPt"); var sigBackMaxPt = CalcSignalToBackgroundSeries( signalGoodJets, backgroundGoodJets, MaxTrackPtPlot, dir, "MaxPt"); // Look to see what it would take to get constant efficiency var result = new List<IFutureValue<string>>(); #if false // This was interesting - but not yet sure how to use it. var backRejValues = new double[] { 0.999, 0.99, 0.95, 0.9 }; var sigValues = new double[] { 0.1, 0.2, 0.3, 0.4, 0.5 }; var requiredBackValues = from bv in backRejValues select from bHist in sigBackCalR.Item2 from sHist in sigBackCalR.Item1 let backCut = CalcEffValue(bHist, bv) let effValue = LookupEffAtCut(sHist, backCut) select $"{regionInfo}: Cut for Back Rejection of {bv} is {backCut} (sig eff is {effValue})"; result.AddRange(requiredBackValues); var requiredSigValues = from sv in sigValues select from bHist in sigBackCalR.Item2 from sHist in sigBackCalR.Item1 let sigCut = CalcEffValue(sHist, sv, false) let backRejection = LookupEffAtCut(bHist, sigCut) select $"{regionInfo}: Cut for Sig Eff of {sv} is {sigCut} (back rej is {backRejection})"; result.AddRange(requiredSigValues); #endif return result; }
/// <summary> /// Some very basic LLP plots. Good LLPs are < 1.7 in eta?? For forward it is 1.7 to 2.5. /// </summary> /// <param name="LLPsToPlot"></param> /// <param name="dir"></param> private static void LLPBasicInfo(IQueryable<recoTreeLLPs> LLPsToPlot, IQueryable<recoTreeJets> jets, FutureTDirectory dir) { // LLP's and LLP's associated with a jet LLPsToPlot .FuturePlot(LLPLxyPlot, "all") .Save(dir); LLPsToPlot .FuturePlot(LLPEtaPlot, "all") .Save(dir); var jetsWithLLPS = jets .Where(j => j.LLP.IsGoodIndex()); jetsWithLLPS .Select(j => j.LLP) .FuturePlot(LLPLxyPlot, "JetMatched") .Save(dir); jetsWithLLPS .Select(j => j.LLP) .FuturePlot(LLPEtaPlot, "JetMatched") .Save(dir); // And look at the EMF as a function of the jet decay length so we can see exactly where the Calorimeter is. jetsWithLLPS .FuturePlot(JetCalRVsLXYPlot, "JetsWithLLPs") .Save(dir); // Check out what things look like for our cut region. LLPsToPlot .Where(llp => Constants.InCalorimeter.Invoke(llp.Lxy/1000)) .FuturePlot(LLPLxyPlot, "In Cut CAL Range") .Save(dir); }
/// <summary> /// Determine the NN value for a pass value. Return it. /// </summary> /// <param name="source"></param> /// <param name="passFraction"></param> /// <param name="dir"></param> /// <returns></returns> public static double FindNNCut(this IQueryable<TrainingTree> source, double passFraction, FutureTDirectory dir, Method<TrainingTree> m) { if (passFraction < 0 || passFraction > 1.0) { throw new ArgumentException($"passFraction of {passFraction} is not between 0 and 1 - not legal!"); } // dump the MVA output into a large histogram that has lots of bins so we can calculate. var p = source .MakeNNPlot(m) .Save(dir); // Now, look through the plot, bin by bin, till we get past the total. var bin = from h in p select CalcBinWhereFractionIs(h, passFraction); // And the center of that bin var binCenter = from b in bin from h in p select h.GetBinCenter(b); return binCenter.Value; }
public static void GenericPlotsInSquare(this IQueryable <LLPInfo.extrapTree> source, double lxy_low, double lxy_high, FutureTDirectory outd, string namearg = "") { source .Where(e => e.llp1_Lxy > lxy_low && e.llp1_Lxy < lxy_high) .Where(e => e.llp2_Lxy > lxy_low && e.llp2_Lxy < lxy_high) .GenericPlots(outd, $"{namearg}lxy_{lxy_low}_{lxy_high}"); }