From 6b517cf6bcc285cb41178694ae00f9c2b7a20b27 Mon Sep 17 00:00:00 2001 From: Whitney Armstrong <warmstrong@anl.gov> Date: Tue, 2 Feb 2021 15:57:39 -0600 Subject: [PATCH] Rebased dis_test modified: dvmp/analysis/util.h new file: dvmp/analysis/vm_invar.cxx modified: dvmp/analysis/vm_mass.cxx modified: dvmp/dvmp.sh --- benchmarks/dvmp/analysis/vm_mass.cxx | 2 + benchmarks/dvmp/dvmp.sh | 1 + dvmp/analysis/vm_invar.cxx | 268 +++++++++++++++++++++++++++ 3 files changed, 271 insertions(+) create mode 100644 dvmp/analysis/vm_invar.cxx diff --git a/benchmarks/dvmp/analysis/vm_mass.cxx b/benchmarks/dvmp/analysis/vm_mass.cxx index 82abba6f..a3973729 100644 --- a/benchmarks/dvmp/analysis/vm_mass.cxx +++ b/benchmarks/dvmp/analysis/vm_mass.cxx @@ -113,6 +113,7 @@ int vm_mass(const std::string& config_name) auto h_eta_rec = d_im.Histo1D({"h_eta_rec", ";#eta_{ll'};#", 1000, -5., 5.}, "eta_rec"); auto h_eta_sim = d_im.Histo1D({"h_eta_sim", ";#eta_{ll'};#", 1000, -5., 5.}, "eta_sim"); + // Plot our histograms. // TODO: to start I'm explicitly plotting the histograms, but want to // factorize out the plotting code moving forward. @@ -240,6 +241,7 @@ int vm_mass(const std::string& config_name) t4->Draw(); c.Print(fmt::format("{}vm_mass_pt_phi_rapidity.png", output_prefix).c_str()); + } // TODO we're not actually doing an IM fit yet, so for now just return an diff --git a/benchmarks/dvmp/dvmp.sh b/benchmarks/dvmp/dvmp.sh index 1746a860..4f42e235 100755 --- a/benchmarks/dvmp/dvmp.sh +++ b/benchmarks/dvmp/dvmp.sh @@ -151,6 +151,7 @@ fi mv ${REC_LOG} ${RESULTS_PATH} + ## cleanup output files #rm -f ${REC_FILE} ${SIM_FILE} ## --> not needed for CI diff --git a/dvmp/analysis/vm_invar.cxx b/dvmp/analysis/vm_invar.cxx new file mode 100644 index 00000000..ab25f56f --- /dev/null +++ b/dvmp/analysis/vm_invar.cxx @@ -0,0 +1,268 @@ +#include "benchmark.hh" +#include "mt.h" +#include "plot.h" +#include "util.h" + +#include <ROOT/RDataFrame.hxx> +#include <cmath> +#include <fmt/color.h> +#include <fmt/core.h> +#include <fstream> +#include <iostream> +#include <nlohmann/json.hpp> +#include <string> +#include <vector> + +// Run VM invariant-mass-based benchmarks on an input reconstruction file for +// a desired vector meson (e.g. jpsi) and a desired decay particle (e.g. muon) +// Output figures are written to our output prefix (which includes the output +// file prefix), and labeled with our detector name. +// TODO: I think it would be better to pass small json configuration file to +// the test, instead of this ever-expanding list of function arguments. +// FIXME: MC does not trace back into particle history. Need to fix that +int vm_invar(const std::string& config_name) { + // read our configuration + std::ifstream config_file{config_name}; + nlohmann::json config; + config_file >> config; + + const std::string rec_file = config["rec_file"]; + const std::string vm_name = config["vm_name"]; + const std::string decay_name = config["decay"]; + const std::string detector = config["detector"]; + std::string output_prefix = config["output_prefix"]; + const std::string test_tag = config["test_tag"]; + + fmt::print(fmt::emphasis::bold | fg(fmt::color::forest_green), + "Running VM invariant mass analysis...\n"); + fmt::print(" - Vector meson: {}\n", vm_name); + fmt::print(" - Decay particle: {}\n", decay_name); + fmt::print(" - Detector package: {}\n", detector); + fmt::print(" - output prefix: {}\n", output_prefix); + + // create our test definition + // test_tag + eic::util::Test vm_mass_resolution_test{ + {{"name", + fmt::format("{}_{}_{}_mass_resolution", test_tag, vm_name, decay_name)}, + {"title", + fmt::format("{} -> {} Invariant Mass Resolution", vm_name, decay_name)}, + {"description", "Invariant Mass Resolution calculated from raw " + "tracking data using a Gaussian fit."}, + {"quantity", "resolution"}, + {"target", ".1"}}}; + + // Run this in multi-threaded mode if desired + ROOT::EnableImplicitMT(kNumThreads); + + // The particles we are looking for. E.g. J/psi decaying into e+e- + const double vm_mass = util::get_pdg_mass(vm_name); + const double decay_mass = util::get_pdg_mass(decay_name); + + // Ensure our output prefix always ends on a dot, a slash or a dash + if (output_prefix.back() != '.' && output_prefix.back() != '/' && + output_prefix.back() != '-') { + output_prefix += "-"; + } + + // Open our input file file as a dataframe + ROOT::RDataFrame d{"events", rec_file}; + + // utility lambda functions to bind the vector meson and decay particle + // types + auto momenta_from_tracking = + [decay_mass](const std::vector<eic::TrackParametersData>& tracks) { + return util::momenta_from_tracking(tracks, decay_mass); + }; + auto calc_inv_quant_rec = + [vm_mass](const std::vector<ROOT::Math::PxPyPzMVector>& parts) { + return util::calc_inv_quant_rec(parts, vm_mass); + }; + + //==================================================================== + + // Define analysis flow + auto d_im = + d.Define("p_rec", momenta_from_tracking, {"outputTrackParameters"}) + .Define("N", "p_rec.size()") + .Define("p_sim", util::momenta_from_simulation, {"mcparticles2"}) + //================================================================ + .Define("invariant_quantities_rec", calc_inv_quant_rec, {"p_rec"}) + .Define("invariant_quantities_sim", util::calc_inv_quant_simu, {"p_sim"}) + .Define("nu_rec" , util::get_nu, {"invariant_quantities_rec"}) + .Define("Q2_rec" , util::get_Q2, {"invariant_quantities_rec"}) + .Define("x_rec" , util::get_x, {"invariant_quantities_rec"}) + .Define("t_rec", util::get_t, {"invariant_quantities_rec"}) + .Define("nu_sim" , util::get_nu, {"invariant_quantities_sim"}) + .Define("Q2_sim" , util::get_Q2, {"invariant_quantities_sim"}) + .Define("x_sim" , util::get_x, {"invariant_quantities_sim"}) + .Define("t_sim", util::get_t, {"invariant_quantities_sim"}); + //================================================================ + + // Define output histograms + + auto h_nu_rec = d_im.Histo1D( + {"h_nu_rec", ";#nu/1000;#", 100, 0., 2.}, "nu_rec"); + auto h_Q2_rec = d_im.Histo1D( + {"h_Q2_rec", ";Q^{2};#", 100, 0., 15.}, "Q2_rec"); + auto h_x_rec = d_im.Histo1D( + {"h_x_rec", ";x;#", 100, 0., 0.1}, "x_rec"); + auto h_t_rec = d_im.Histo1D( + {"h_t_rec", ";t;#", 100, -1., 0.}, "t_rec"); + + + auto h_nu_sim = d_im.Histo1D( + {"h_nu_sim", ";#nu/1000;#", 100, 0., 2.}, "nu_sim"); + auto h_Q2_sim = d_im.Histo1D( + {"h_Q2_sim", ";Q^{2};#", 100, 0., 15.}, "Q2_sim"); + auto h_x_sim = d_im.Histo1D( + {"h_x_sim", ";x;#", 100, 0., 0.1}, "x_sim"); + auto h_t_sim = d_im.Histo1D( + {"h_t_sim", ";t;#", 100, -1., 0.}, "t_sim"); + + + // Plot our histograms. + // TODO: to start I'm explicitly plotting the histograms, but want to + // factorize out the plotting code moving forward. + { + + // Print canvas to output file + + TCanvas c{"canvas2", "canvas2", 1200, 1200}; + c.Divide(2, 2, 0.0001, 0.0001); + //pad 1 nu + c.cd(1); + //gPad->SetLogx(false); + //gPad->SetLogy(false); + auto& hnu_rec = *h_nu_rec; + auto& hnu_sim = *h_nu_sim; + // histogram style + hnu_rec.SetLineColor(plot::kMpOrange); + hnu_rec.SetLineWidth(2); + hnu_sim.SetLineColor(plot::kMpBlue); + hnu_sim.SetLineWidth(2); + // axes + hnu_rec.GetXaxis()->CenterTitle(); + //hnu.GetXaxis()->SetTitle("#times1000"); + // draw everything + hnu_sim.DrawClone("hist"); + hnu_rec.DrawClone("hist same"); + // FIXME hardcoded beam configuration + plot::draw_label(10, 100, detector, vm_name, "#nu"); + TText* tptr1; + auto t1 = new TPaveText(.6, .8417, .9, .925, "NB NDC"); + t1->SetFillColorAlpha(kWhite, 0); + t1->SetTextFont(43); + t1->SetTextSize(25); + tptr1 = t1->AddText("simulated"); + tptr1->SetTextColor(plot::kMpBlue); + tptr1 = t1->AddText("reconstructed"); + tptr1->SetTextColor(plot::kMpOrange); + t1->Draw(); + + //pad 2 Q2 + c.cd(2); + //gPad->SetLogx(false); + //gPad->SetLogy(false); + auto& hQ2_rec = *h_Q2_rec; + auto& hQ2_sim = *h_Q2_sim; + // histogram style + hQ2_rec.SetLineColor(plot::kMpOrange); + hQ2_rec.SetLineWidth(2); + hQ2_sim.SetLineColor(plot::kMpBlue); + hQ2_sim.SetLineWidth(2); + // axes + hQ2_rec.GetXaxis()->CenterTitle(); + //hnu.GetXaxis()->SetTitle("#times1000"); + // draw everything + hQ2_sim.DrawClone("hist"); + hQ2_rec.DrawClone("hist same"); + // FIXME hardcoded beam configuration + plot::draw_label(10, 100, detector, vm_name, "Q^{2}"); + TText* tptr2; + auto t2 = new TPaveText(.6, .8417, .9, .925, "NB NDC"); + t2->SetFillColorAlpha(kWhite, 0); + t2->SetTextFont(43); + t2->SetTextSize(25); + tptr2 = t2->AddText("simulated"); + tptr2->SetTextColor(plot::kMpBlue); + tptr2 = t2->AddText("reconstructed"); + tptr2->SetTextColor(plot::kMpOrange); + t2->Draw(); + + + //pad 3 x + c.cd(3); + //gPad->SetLogx(false); + //gPad->SetLogy(false); + auto& hx_rec = *h_x_rec; + auto& hx_sim = *h_x_sim; + // histogram style + hx_rec.SetLineColor(plot::kMpOrange); + hx_rec.SetLineWidth(2); + hx_sim.SetLineColor(plot::kMpBlue); + hx_sim.SetLineWidth(2); + // axes + hx_rec.GetXaxis()->CenterTitle(); + //hnu.GetXaxis()->SetTitle("#times1000"); + // draw everything + hx_sim.DrawClone("hist"); + hx_rec.DrawClone("hist same"); + // FIXME hardcoded beam configuration + plot::draw_label(10, 100, detector, vm_name, "x"); + TText* tptr3; + auto t3 = new TPaveText(.6, .8417, .9, .925, "NB NDC"); + t3->SetFillColorAlpha(kWhite, 0); + t3->SetTextFont(43); + t3->SetTextSize(25); + tptr3 = t3->AddText("simulated"); + tptr3->SetTextColor(plot::kMpBlue); + tptr3 = t3->AddText("reconstructed"); + tptr3->SetTextColor(plot::kMpOrange); + t3->Draw(); + + //pad 4 t + c.cd(4); + //gPad->SetLogx(false); + //gPad->SetLogy(false); + auto& ht_rec = *h_t_rec; + auto& ht_sim = *h_t_sim; + // histogram style + ht_rec.SetLineColor(plot::kMpOrange); + ht_rec.SetLineWidth(2); + ht_sim.SetLineColor(plot::kMpBlue); + ht_sim.SetLineWidth(2); + // axes + ht_rec.GetXaxis()->CenterTitle(); + //hnu.GetXaxis()->SetTitle("#times1000"); + // draw everything + ht_sim.DrawClone("hist"); + ht_rec.DrawClone("hist same"); + // FIXME hardcoded beam configuration + plot::draw_label(10, 100, detector, vm_name, "t"); + TText* tptr4; + auto t4 = new TPaveText(.6, .8417, .9, .925, "NB NDC"); + t4->SetFillColorAlpha(kWhite, 0); + t4->SetTextFont(43); + t4->SetTextSize(25); + tptr4 = t4->AddText("simulated"); + tptr4->SetTextColor(plot::kMpBlue); + tptr4 = t4->AddText("reconstructed"); + tptr4->SetTextColor(plot::kMpOrange); + t4->Draw(); + + + c.Print(fmt::format("{}InvariantQuantities.png", output_prefix).c_str()); + } + + // TODO we're not actually doing an IM fit yet, so for now just return an + // error for the test result + vm_mass_resolution_test.error(-1); + + // write out our test data + eic::util::write_test(vm_mass_resolution_test, + fmt::format("{}vm_invar.json", output_prefix)); + + // That's all! + return 0; +} -- GitLab