{ "cells": [ { "cell_type": "markdown", "id": "8984a3dd", "metadata": {}, "source": [ "# rf711_lagrangianmorph\n", "Morphing effective field theory distributions with RooLagrangianMorphFunc\n", "A morphing function as a function of one coefficient is setup and can be used\n", "to obtain the distribution for any value of the coefficient.\n", "\n", "\n", "\n", "\n", "**Author:** Rahul Balasubramanian \n", "This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Tuesday, May 19, 2026 at 08:35 PM." ] }, { "cell_type": "code", "execution_count": 1, "id": "20041379", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:35:07.209952Z", "iopub.status.busy": "2026-05-19T20:35:07.209814Z", "iopub.status.idle": "2026-05-19T20:35:07.225513Z", "shell.execute_reply": "2026-05-19T20:35:07.225020Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "#include \n", "#include \n", "#include \n", "#include \n", "#include \n", "#include \n", "\n", "#include \n", "#include \n", "#include \n", "#include \n", "#include \n", "#include \n", "#include \n", "\n", "using namespace RooFit;" ] }, { "cell_type": "markdown", "id": "f526666c", "metadata": {}, "source": [ "Create variables for\n", "morphing function\n", "---------------------------------------------" ] }, { "cell_type": "code", "execution_count": 2, "id": "ad044615", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:35:07.227183Z", "iopub.status.busy": "2026-05-19T20:35:07.227068Z", "iopub.status.idle": "2026-05-19T20:35:07.547598Z", "shell.execute_reply": "2026-05-19T20:35:07.546891Z" } }, "outputs": [], "source": [ "std::string observablename = \"pTV\";" ] }, { "cell_type": "markdown", "id": "af147524", "metadata": {}, "source": [ "Setup observable that is morphed" ] }, { "cell_type": "code", "execution_count": 3, "id": "351ffbc9", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:35:07.549689Z", "iopub.status.busy": "2026-05-19T20:35:07.549551Z", "iopub.status.idle": "2026-05-19T20:35:07.758900Z", "shell.execute_reply": "2026-05-19T20:35:07.758114Z" } }, "outputs": [], "source": [ "RooRealVar obsvar(observablename.c_str(), \"p_{T}^{V}\", 10, 600);" ] }, { "cell_type": "markdown", "id": "24152a9b", "metadata": {}, "source": [ "Setup two couplings that enters the morphing function\n", "kSM -> SM coupling set to constant (1)\n", "cHq3 -> EFT parameter with NewPhysics attribute set to true" ] }, { "cell_type": "code", "execution_count": 4, "id": "c6b6080d", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:35:07.760623Z", "iopub.status.busy": "2026-05-19T20:35:07.760486Z", "iopub.status.idle": "2026-05-19T20:35:07.970152Z", "shell.execute_reply": "2026-05-19T20:35:07.969281Z" } }, "outputs": [], "source": [ "RooRealVar kSM(\"kSM\", \"sm modifier\", 1.0);\n", "RooRealVar cHq3(\"cHq3\", \"EFT modifier\", 0.0, 1.0);\n", "cHq3.setAttribute(\"NewPhysics\", true);" ] }, { "cell_type": "markdown", "id": "3416c101", "metadata": {}, "source": [ "Inputs needed for config\n", "---------------------------------------------" ] }, { "cell_type": "code", "execution_count": 5, "id": "ec575e2c", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:35:07.972246Z", "iopub.status.busy": "2026-05-19T20:35:07.972116Z", "iopub.status.idle": "2026-05-19T20:35:08.178384Z", "shell.execute_reply": "2026-05-19T20:35:08.177640Z" } }, "outputs": [], "source": [ "std::string infilename = std::string(gROOT->GetTutorialDir()) + \"/roofit/roofit/input_histos_rf_lagrangianmorph.root\";\n", "std::vector samplelist = {\"SM_NPsq0\", \"cHq3_NPsq1\", \"cHq3_NPsq2\"};" ] }, { "cell_type": "markdown", "id": "5f47cce8", "metadata": {}, "source": [ "Setup Config\n", "---------------------------------------------" ] }, { "cell_type": "code", "execution_count": 6, "id": "d688d765", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:35:08.180365Z", "iopub.status.busy": "2026-05-19T20:35:08.180242Z", "iopub.status.idle": "2026-05-19T20:35:08.510330Z", "shell.execute_reply": "2026-05-19T20:35:08.509741Z" } }, "outputs": [], "source": [ "RooLagrangianMorphFunc::Config config;\n", "config.fileName = infilename;\n", "config.observableName = observablename;\n", "config.folderNames = samplelist;\n", "config.couplings.add(cHq3);\n", "config.couplings.add(kSM);" ] }, { "cell_type": "markdown", "id": "4f324cca", "metadata": {}, "source": [ "Create morphing function\n", "---------------------------------------------" ] }, { "cell_type": "code", "execution_count": 7, "id": "e47e1ca2", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:35:08.512353Z", "iopub.status.busy": "2026-05-19T20:35:08.512231Z", "iopub.status.idle": "2026-05-19T20:35:08.721819Z", "shell.execute_reply": "2026-05-19T20:35:08.721137Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[#0] PROGRESS:InputArguments -- initializing physics inputs from file /github/home/ROOT-CI/build/tutorials/roofit/roofit/input_histos_rf_lagrangianmorph.root with object name(s) 'pTV'\n" ] } ], "source": [ "RooLagrangianMorphFunc morphfunc(\"morphfunc\", \"morphed dist. of pTV\", config);" ] }, { "cell_type": "markdown", "id": "aa96149c", "metadata": {}, "source": [ "Get morphed distribution for\n", "different cHq3\n", "---------------------------------------------" ] }, { "cell_type": "code", "execution_count": 8, "id": "ba90476f", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:35:08.723345Z", "iopub.status.busy": "2026-05-19T20:35:08.723224Z", "iopub.status.idle": "2026-05-19T20:35:08.932641Z", "shell.execute_reply": "2026-05-19T20:35:08.932136Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[#0] PROGRESS:Caching -- creating cache from getCache function for 0x7f0cc4333000\n", "[#0] PROGRESS:Caching -- current storage has size 3\n", "[#0] PROGRESS:ObjectHandling -- observable: pTV\n", "[#0] PROGRESS:ObjectHandling -- binWidth: binWidth_pTV\n", "[#1] INFO:DataHandling -- RooDataHist::adjustBinning(morph_dh_cHq3=0.01): fit range of variable pTV expanded to nearest bin boundaries: [10,600] --> [0,600]\n" ] } ], "source": [ "morphfunc.setParameter(\"cHq3\", 0.01);\n", "auto morph_hist_0p01 = morphfunc.createTH1(\"morph_cHq3=0.01\");\n", "morphfunc.setParameter(\"cHq3\", 0.25);\n", "auto morph_hist_0p25 = morphfunc.createTH1(\"morph_cHq3=0.25\");\n", "morphfunc.setParameter(\"cHq3\", 0.5);\n", "auto morph_hist_0p5 = morphfunc.createTH1(\"morph_cHq3=0.5\");\n", "RooDataHist morph_datahist_0p01(\"morph_dh_cHq3=0.01\", \"\", {obsvar}, morph_hist_0p01);\n", "RooDataHist morph_datahist_0p25(\"morph_dh_cHq3=0.25\", \"\", {obsvar}, morph_hist_0p25);\n", "RooDataHist morph_datahist_0p5(\"morph_dh_cHq3=0.5\", \"\", {obsvar}, morph_hist_0p5);" ] }, { "cell_type": "markdown", "id": "a88b2e3c", "metadata": {}, "source": [ "Extract input templates\n", "for plotting\n", "---------------------------------------------" ] }, { "cell_type": "code", "execution_count": 9, "id": "c80aac1e", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:35:08.934358Z", "iopub.status.busy": "2026-05-19T20:35:08.934235Z", "iopub.status.idle": "2026-05-19T20:35:09.143731Z", "shell.execute_reply": "2026-05-19T20:35:09.143363Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[#1] INFO:InputArguments -- RooAbsData::plotOn(SM_NPsq0) INFO: dataset has non-integer weights, auto-selecting SumW2 errors instead of Poisson errors\n", "[#1] INFO:InputArguments -- RooAbsData::plotOn(cHq3_NPsq1) INFO: dataset has non-integer weights, auto-selecting SumW2 errors instead of Poisson errors\n", "[#1] INFO:Plotting -- RooPlot::updateFitRangeNorm: New event count of 24931.9 will supersede previous event count of 10852.3 for normalization of PDF projections\n", "[#1] INFO:InputArguments -- RooAbsData::plotOn(cHq3_NPsq2) INFO: dataset has non-integer weights, auto-selecting SumW2 errors instead of Poisson errors\n", "[#1] INFO:Plotting -- RooPlot::updateFitRangeNorm: New event count of 29789.2 will supersede previous event count of 24931.9 for normalization of PDF projections\n" ] } ], "source": [ "TFile *file = new TFile(infilename.c_str(), \"READ\");\n", "TFolder *folder = 0;\n", "file->GetObject(samplelist[0].c_str(), folder);\n", "TH1 *input_hist0 = dynamic_cast(folder->FindObject(observablename.c_str()));\n", "input_hist0->SetDirectory(NULL);\n", "file->GetObject(samplelist[1].c_str(), folder);\n", "TH1 *input_hist1 = dynamic_cast(folder->FindObject(observablename.c_str()));\n", "input_hist1->SetDirectory(NULL);\n", "file->GetObject(samplelist[2].c_str(), folder);\n", "TH1 *input_hist2 = dynamic_cast(folder->FindObject(observablename.c_str()));\n", "input_hist2->SetDirectory(NULL);\n", "file->Close();\n", "\n", "RooDataHist input_dh0(samplelist[0], \"\", {obsvar}, input_hist0);\n", "RooDataHist input_dh1(samplelist[1], \"\", {obsvar}, input_hist1);\n", "RooDataHist input_dh2(samplelist[2], \"\", {obsvar}, input_hist2);\n", "\n", "auto frame0 = obsvar.frame(Title(\"Input templates for p_{T}^{V}\"));\n", "input_dh0.plotOn(frame0, Name(samplelist[0].c_str()), LineColor(kBlack), MarkerColor(kBlack), MarkerSize(1));\n", "input_dh1.plotOn(frame0, Name(samplelist[1].c_str()), LineColor(kRed), MarkerColor(kRed), MarkerSize(1));\n", "input_dh2.plotOn(frame0, Name(samplelist[2].c_str()), LineColor(kBlue), MarkerColor(kBlue), MarkerSize(1));" ] }, { "cell_type": "markdown", "id": "6dbb9610", "metadata": {}, "source": [ "Plot morphed distribution for\n", "different cHq3\n", "---------------------------------------------" ] }, { "cell_type": "code", "execution_count": 10, "id": "b884605b", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:35:09.146861Z", "iopub.status.busy": "2026-05-19T20:35:09.146730Z", "iopub.status.idle": "2026-05-19T20:35:09.356218Z", "shell.execute_reply": "2026-05-19T20:35:09.355549Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[#1] INFO:Plotting -- RooPlot::updateFitRangeNorm: New event count of 18947.1 will supersede previous event count of 11104.6 for normalization of PDF projections\n", "[#1] INFO:Plotting -- RooPlot::updateFitRangeNorm: New event count of 30765.5 will supersede previous event count of 18947.1 for normalization of PDF projections\n" ] } ], "source": [ "auto frame1 = obsvar.frame(Title(\"Morphed templates for selected values\"));\n", "morph_datahist_0p01.plotOn(frame1, Name(\"morph_dh_cHq3=0.01\"), DrawOption(\"C\"), LineColor(kGreen),\n", " DataError(RooAbsData::None), XErrorSize(0));\n", "morph_datahist_0p25.plotOn(frame1, Name(\"morph_dh_cHq3=0.25\"), DrawOption(\"C\"), LineColor(kGreen + 1),\n", " DataError(RooAbsData::None), XErrorSize(0));\n", "morph_datahist_0p5.plotOn(frame1, Name(\"morph_dh_cHq3=0.5\"), DrawOption(\"C\"), LineColor(kGreen + 2),\n", " DataError(RooAbsData::None), XErrorSize(0));" ] }, { "cell_type": "markdown", "id": "af82d88c", "metadata": {}, "source": [ "Create wrapped pdf togenerate\n", "2D d a t a s e t o f c H q 3 a s a f u n c t i o n o f\n", "observable\n", "---------------------------------------------" ] }, { "cell_type": "code", "execution_count": 11, "id": "319f8ae7", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:35:09.357662Z", "iopub.status.busy": "2026-05-19T20:35:09.357528Z", "iopub.status.idle": "2026-05-19T20:35:11.291924Z", "shell.execute_reply": "2026-05-19T20:35:11.291446Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[#0] PROGRESS:Caching -- creating cache from getCache function for 0x7f0c75c65e10\n", "[#0] PROGRESS:Caching -- current storage has size 3\n", "[#0] PROGRESS:ObjectHandling -- observable: pTV\n", "[#0] PROGRESS:ObjectHandling -- binWidth: binWidth_pTV\n", "\n", "[#1] INFO:NumericIntegration -- RooRealIntegral::init(w_SM_NPsq0_morphfunc_Int[cHq3]) using numeric integrator RooIntegrator1D to calculate Int(cHq3)\n", "[#1] INFO:NumericIntegration -- RooRealIntegral::init(w_cHq3_NPsq1_morphfunc_Int[cHq3]) using numeric integrator RooIntegrator1D to calculate Int(cHq3)\n", "[#1] INFO:NumericIntegration -- RooRealIntegral::init(w_cHq3_NPsq2_morphfunc_Int[cHq3]) using numeric integrator RooIntegrator1D to calculate Int(cHq3)\n", "[#0] PROGRESS:Caching -- creating cache from getCache function for 0x7f0c760db540\n", "[#0] PROGRESS:Caching -- current storage has size 3\n", "[#0] PROGRESS:ObjectHandling -- observable: pTV\n", "[#0] PROGRESS:ObjectHandling -- binWidth: binWidth_pTV\n", "\n", "[#1] INFO:NumericIntegration -- RooRealIntegral::init(w_SM_NPsq0_morphfunc_Int[cHq3]) using numeric integrator RooIntegrator1D to calculate Int(cHq3)\n", "[#1] INFO:NumericIntegration -- RooRealIntegral::init(w_cHq3_NPsq1_morphfunc_Int[cHq3]) using numeric integrator RooIntegrator1D to calculate Int(cHq3)\n", "[#1] INFO:NumericIntegration -- RooRealIntegral::init(w_cHq3_NPsq2_morphfunc_Int[cHq3]) using numeric integrator RooIntegrator1D to calculate Int(cHq3)\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "input_line_70:3:1: warning: 'data' shadows a declaration with the same name in the 'std' namespace; use '::data' to reference this declaration\n", "std::unique_ptr data{model.generate({cHq3, obsvar}, 1000000)};\n", "^\n" ] } ], "source": [ "RooWrapperPdf model(\"wrap_pdf\", \"wrap_pdf\", morphfunc);\n", "std::unique_ptr data{model.generate({cHq3, obsvar}, 1000000)};\n", "TH1 *hh_data = data->createHistogram(\"pTV vs cHq3\", obsvar, Binning(20), YVar(cHq3, Binning(50)));\n", "hh_data->SetTitle(\"Morphing prediction\");" ] }, { "cell_type": "markdown", "id": "7dbe3838", "metadata": {}, "source": [ "Draw plots on canvas\n", "---------------------------------------------" ] }, { "cell_type": "code", "execution_count": 12, "id": "b6c008a8", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:35:11.293339Z", "iopub.status.busy": "2026-05-19T20:35:11.293185Z", "iopub.status.idle": "2026-05-19T20:35:11.610874Z", "shell.execute_reply": "2026-05-19T20:35:11.610294Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "
\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stderr", "output_type": "stream", "text": [ "Info in : png file rf711_lagrangianmorph.png has been created\n" ] } ], "source": [ "TCanvas *c1 = new TCanvas(\"fig3\", \"fig3\", 1200, 400);\n", "c1->Divide(3, 1);\n", "\n", "c1->cd(1);\n", "gPad->SetLeftMargin(0.15);\n", "gPad->SetRightMargin(0.05);\n", "\n", "frame0->Draw();\n", "TLegend *leg1 = new TLegend(0.55, 0.65, 0.94, 0.87);\n", "leg1->SetTextSize(0.04);\n", "leg1->SetFillColor(kWhite);\n", "leg1->SetLineColor(kWhite);\n", "leg1->AddEntry(\"SM_NPsq0\", \"SM\", \"LP\");\n", "leg1->AddEntry((TObject *)0, \"\", \"\");\n", "leg1->AddEntry(\"cHq3_NPsq1\", \"c_{Hq^(3)}=1.0 at #Lambda^{-2}\", \"LP\");\n", "leg1->AddEntry((TObject *)0, \"\", \"\");\n", "leg1->AddEntry(\"cHq3_NPsq2\", \"c_{Hq^(3)}=1.0 at #Lambda^{-4}\", \"LP\");\n", "leg1->Draw();\n", "\n", "c1->cd(2);\n", "gPad->SetLeftMargin(0.15);\n", "gPad->SetRightMargin(0.05);\n", "\n", "frame1->Draw();\n", "\n", "TLegend *leg2 = new TLegend(0.60, 0.65, 0.94, 0.87);\n", "leg2->SetTextSize(0.04);\n", "leg2->SetFillColor(kWhite);\n", "leg2->SetLineColor(kWhite);\n", "leg2->AddEntry(\"morph_dh_cHq3=0.01\", \"c_{Hq^{(3)}}=0.01\", \"L\");\n", "leg2->AddEntry((TObject *)0, \"\", \"\");\n", "leg2->AddEntry(\"morph_dh_cHq3=0.25\", \"c_{Hq^{(3)}}=0.25\", \"L\");\n", "leg2->AddEntry((TObject *)0, \"\", \"\");\n", "leg2->AddEntry(\"morph_dh_cHq3=0.5\", \"c_{Hq^{(3)}}=0.5\", \"L\");\n", "leg2->AddEntry((TObject *)0, \"\", \"\");\n", "leg2->Draw();\n", "\n", "c1->cd(3);\n", "gPad->SetLeftMargin(0.12);\n", "gPad->SetRightMargin(0.18);\n", "gStyle->SetNumberContours(255);\n", "gStyle->SetPalette(kGreyScale);\n", "gStyle->SetOptStat(0);\n", "TColor::InvertPalette();\n", "gPad->SetLogz();\n", "hh_data->GetYaxis()->SetTitle(\"c_{Hq^{(3)}}\");\n", "hh_data->GetYaxis()->SetRangeUser(0, 0.5);\n", "hh_data->GetZaxis()->SetTitleOffset(1.8);\n", "hh_data->Draw(\"COLZ\");\n", "c1->SaveAs(\"rf711_lagrangianmorph.png\");" ] }, { "cell_type": "markdown", "id": "e6facdfd", "metadata": {}, "source": [ "Draw all canvases " ] }, { "cell_type": "code", "execution_count": 13, "id": "f8fea886", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:35:11.612179Z", "iopub.status.busy": "2026-05-19T20:35:11.612060Z", "iopub.status.idle": "2026-05-19T20:35:11.827455Z", "shell.execute_reply": "2026-05-19T20:35:11.826832Z" } }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "
\n", "
\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%jsroot on\n", "gROOT->GetListOfCanvases()->Draw()" ] } ], "metadata": { "kernelspec": { "display_name": "ROOT C++", "language": "c++", "name": "root" }, "language_info": { "codemirror_mode": "text/x-c++src", "file_extension": ".C", "mimetype": " text/x-c++src", "name": "c++" } }, "nbformat": 4, "nbformat_minor": 5 }