{ "cells": [ { "cell_type": "markdown", "id": "35603f05", "metadata": {}, "source": [ "# testUnfold3\n", "Simple Test program for the class TUnfoldDensity.\n", "\n", "1-dimensional unfolding with background subtraction\n", "\n", " the goal is to unfold the underlying \"true\" distribution of a variable Pt\n", "\n", " the reconstructed Pt is measured in 24 bins from 4 to 28\n", " the generator-level Pt is unfolded into 10 bins from 6 to 26\n", " - plus underflow bin from 0 to 6\n", " - plus overflow bin above 26\n", " there are two background sources bgr1 and bgr2\n", " the signal has a finite trigger efficiency at a threshold of 8 GeV\n", "\n", " one type of systematic error is studied, where the signal parameters are\n", " changed\n", "\n", " Finally, the unfolding is compared to a \"bin-by-bin\" correction method\n", "\n", "\n", " **Version 17.6, in parallel to changes in TUnfold**\n", "\n", "#### History:\n", " - Version 17.5, in parallel to changes in TUnfold\n", " - Version 17.4, in parallel to changes in TUnfold\n", " - Version 17.3, in parallel to changes in TUnfold\n", " - Version 17.2, in parallel to changes in TUnfold\n", " - Version 17.1, in parallel to changes in TUnfold\n", " - Version 17.0, change to use the class TUnfoldDensity\n", " - Version 16.1, parallel to changes in TUnfold\n", " - Version 16.0, parallel to changes in TUnfold\n", " - Version 15, simple example including background subtraction\n", "\n", " This file is part of TUnfold.\n", "\n", " TUnfold is free software: you can redistribute it and/or modify\n", " it under the terms of the GNU General Public License as published by\n", " the Free Software Foundation, either version 3 of the License, or\n", " (at your option) any later version.\n", "\n", " TUnfold is distributed in the hope that it will be useful,\n", " but WITHOUT ANY WARRANTY; without even the implied warranty of\n", " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n", " GNU General Public License for more details.\n", "\n", " You should have received a copy of the GNU General Public License\n", " along with TUnfold. If not, see .\n", "\n", "\n", "\n", "**Author:** Stefan Schmitt DESY, 14.10.2008 \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:11 PM." ] }, { "cell_type": "code", "execution_count": 1, "id": "ccf6cef0", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:23.116209Z", "iopub.status.busy": "2026-05-19T20:11:23.116063Z", "iopub.status.idle": "2026-05-19T20:11:23.123760Z", "shell.execute_reply": "2026-05-19T20:11:23.123437Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "#include \n", "#include \n", "#include \n", "#include \n", "#include \n", "#include \n", "#include \n", "\n", "#include \"TUnfoldDensity.h\"\n", "\n", "TRandom *rnd=nullptr;" ] }, { "cell_type": "markdown", "id": "60c89ef0", "metadata": {}, "source": [ " Definition of a helper function: " ] }, { "cell_type": "code", "execution_count": 2, "id": "5ff41282", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:23.136410Z", "iopub.status.busy": "2026-05-19T20:11:23.136277Z", "iopub.status.idle": "2026-05-19T20:11:23.143470Z", "shell.execute_reply": "2026-05-19T20:11:23.142535Z" } }, "outputs": [], "source": [ "%%cpp -d\n", "Double_t GenerateEvent(const Double_t *parm,\n", " const Double_t *triggerParm,\n", " Double_t *intLumi,\n", " Bool_t *triggerFlag,\n", " Double_t *ptGen,Int_t *iType)\n", "{\n", " // generate an event\n", " // input:\n", " // parameters for the event generator\n", " // return value:\n", " // reconstructed Pt\n", " // output to pointers:\n", " // integrated luminosity\n", " // several variables only accessible on generator level\n", " //\n", " // the parm array defines the physical parameters\n", " // parm[0]: background source 1 fraction\n", " // parm[1]: background source 2 fraction\n", " // parm[2]: lower limit of generated Pt distribution\n", " // parm[3]: upper limit of generated Pt distribution\n", " // parm[4]: exponent for Pt distribution signal\n", " // parm[5]: exponent for Pt distribution background 1\n", " // parm[6]: exponent for Pt distribution background 2\n", " // parm[7]: resolution parameter a goes with sqrt(Pt)\n", " // parm[8]: resolution parameter b goes with Pt\n", " // triggerParm[0]: trigger threshold turn-on position\n", " // triggerParm[1]: trigger threshold turn-on width\n", " // triggerParm[2]: trigger efficiency for high pt\n", " //\n", " // intLumi is advanced bu 1 for each *generated* event\n", " // for data, several events may be generated, until one passes the trigger\n", " //\n", " // some generator-level quantities are also returned:\n", " // triggerFlag: whether the event passed the trigger threshold\n", " // ptGen: the generated pt\n", " // iType: which type of process was simulated\n", " //\n", " // the \"triggerFlag\" also has another meaning:\n", " // if(triggerFlag==0) only triggered events are returned\n", " //\n", " // Usage to generate data events\n", " // ptObs=GenerateEvent(parm,triggerParm,0,0,0)\n", " //\n", " // Usage to generate MC events\n", " // ptGen=GenerateEvent(parm,triggerParm,&triggerFlag,&ptGen,&iType);\n", " //\n", " Double_t ptObs;\n", " Bool_t isTriggered=kFALSE;\n", " do {\n", " Int_t itype;\n", " Double_t ptgen;\n", " Double_t f=rnd->Rndm();\n", " // decide whether this is background or signal\n", " itype=0;\n", " if(fRndm();\n", " if(a1 == 0.0) {\n", " Double_t x0=TMath::Log(parm[2]);\n", " ptgen=TMath::Exp(t*(TMath::Log(parm[3])-x0)+x0);\n", " } else {\n", " Double_t x0=pow(parm[2],a1);\n", " ptgen=pow(t*(pow(parm[3],a1)-x0)+x0,1./a1);\n", " }\n", " if(iType) *iType=itype;\n", " if(ptGen) *ptGen=ptgen;\n", "\n", " // smearing in Pt with large asymmetric tail\n", " Double_t sigma=\n", " TMath::Sqrt(parm[7]*parm[7]*ptgen+parm[8]*parm[8]*ptgen*ptgen);\n", " ptObs=rnd->BreitWigner(ptgen,sigma);\n", "\n", " // decide whether event was triggered\n", " Double_t triggerProb =\n", " triggerParm[2]/(1.+TMath::Exp((triggerParm[0]-ptObs)/triggerParm[1]));\n", " isTriggered= rnd->Rndm()SetOptFit(1111);" ] }, { "cell_type": "markdown", "id": "2b19fe9e", "metadata": {}, "source": [ "random generator" ] }, { "cell_type": "code", "execution_count": 5, "id": "e6bcfd60", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:23.668381Z", "iopub.status.busy": "2026-05-19T20:11:23.668264Z", "iopub.status.idle": "2026-05-19T20:11:23.871797Z", "shell.execute_reply": "2026-05-19T20:11:23.871145Z" } }, "outputs": [], "source": [ " rnd=new TRandom3();" ] }, { "cell_type": "markdown", "id": "a61596bb", "metadata": {}, "source": [ "data and MC luminosities" ] }, { "cell_type": "code", "execution_count": 6, "id": "d50a5777", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:23.877560Z", "iopub.status.busy": "2026-05-19T20:11:23.877434Z", "iopub.status.idle": "2026-05-19T20:11:24.080921Z", "shell.execute_reply": "2026-05-19T20:11:24.080359Z" } }, "outputs": [], "source": [ " Double_t const lumiData= 30000;\n", " Double_t const lumiMC =1000000;" ] }, { "cell_type": "markdown", "id": "5ffe57d4", "metadata": {}, "source": [ "========================\n", "Step 1: define binning, book histograms" ] }, { "cell_type": "markdown", "id": "90d0e5e5", "metadata": {}, "source": [ "reconstructed pt (fine binning)" ] }, { "cell_type": "code", "execution_count": 7, "id": "b30c341f", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:24.083014Z", "iopub.status.busy": "2026-05-19T20:11:24.082894Z", "iopub.status.idle": "2026-05-19T20:11:24.286248Z", "shell.execute_reply": "2026-05-19T20:11:24.285737Z" } }, "outputs": [], "source": [ " Int_t const nDet=24;\n", " Double_t const xminDet=4.0;\n", " Double_t const xmaxDet=28.0;" ] }, { "cell_type": "markdown", "id": "cc50f9e7", "metadata": {}, "source": [ "generated pt (coarse binning)" ] }, { "cell_type": "code", "execution_count": 8, "id": "e3fdbbc2", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:24.288073Z", "iopub.status.busy": "2026-05-19T20:11:24.287942Z", "iopub.status.idle": "2026-05-19T20:11:24.491179Z", "shell.execute_reply": "2026-05-19T20:11:24.490709Z" } }, "outputs": [], "source": [ " Int_t const nGen=10;\n", " Double_t const xminGen= 6.0;\n", " Double_t const xmaxGen=26.0;" ] }, { "cell_type": "markdown", "id": "e86c92c0", "metadata": {}, "source": [ "==================================================================\n", "book histograms\n", "(1) unfolding input: binning scheme is fine for detector,coarse for gen\n", "histUnfoldInput : reconstructed data, binning for unfolding\n", "histUnfoldMatrix : generated vs reconstructed distribution\n", "histUnfoldBgr1 : background source1, as predicted by MC\n", "histUnfoldBgr2 : background source2, as predicted by MC\n", "for systematic studies\n", "histUnfoldMatrixSys : generated vs reconstructed with different signal\n", "\n", "(2) histograms required for bin-by-bin method\n", "histDetDATAbbb : reconstructed data for bin-by-bin\n", "histDetMCbbb : reconstructed MC for bin-by-bin\n", "histDetMCBgr1bbb : reconstructed MC bgr1 for bin-by-bin\n", "histDetMCBgr2bbb : reconstructed MC bgr2 for bin-by-bin\n", "histDetMCBgrPtbbb : reconstructed MC bgr from low/high pt for bin-by-bin\n", "histGenMCbbb : generated MC truth\n", "for systematic studies\n", "histDetMCSysbbb : reconstructed with changed trigger\n", "histGenMCSysbbb : generated MC truth\n", "\n", "(3) monitoring and control\n", "histGenData : data truth for bias tests\n", "histDetMC : MC prediction" ] }, { "cell_type": "markdown", "id": "595ead80", "metadata": {}, "source": [ "(1) create histograms required for unfolding" ] }, { "cell_type": "code", "execution_count": 9, "id": "d9bf00df", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:24.493351Z", "iopub.status.busy": "2026-05-19T20:11:24.493231Z", "iopub.status.idle": "2026-05-19T20:11:24.696501Z", "shell.execute_reply": "2026-05-19T20:11:24.696046Z" } }, "outputs": [], "source": [ " TH1D *histUnfoldInput=\n", " new TH1D(\"unfolding input rec\",\";ptrec\",nDet,xminDet,xmaxDet);\n", " TH2D *histUnfoldMatrix=\n", " new TH2D(\"unfolding matrix\",\";ptgen;ptrec\",\n", " nGen,xminGen,xmaxGen,nDet,xminDet,xmaxDet);\n", " TH1D *histUnfoldBgr1=\n", " new TH1D(\"unfolding bgr1 rec\",\";ptrec\",nDet,xminDet,xmaxDet);\n", " TH1D *histUnfoldBgr2=\n", " new TH1D(\"unfolding bgr2 rec\",\";ptrec\",nDet,xminDet,xmaxDet);\n", " TH2D *histUnfoldMatrixSys=\n", " new TH2D(\"unfolding matrix sys\",\";ptgen;ptrec\",\n", " nGen,xminGen,xmaxGen,nDet,xminDet,xmaxDet);" ] }, { "cell_type": "markdown", "id": "45ccba24", "metadata": {}, "source": [ "(2) histograms required for bin-by-bin" ] }, { "cell_type": "code", "execution_count": 10, "id": "a2c09801", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:24.698395Z", "iopub.status.busy": "2026-05-19T20:11:24.698278Z", "iopub.status.idle": "2026-05-19T20:11:24.901202Z", "shell.execute_reply": "2026-05-19T20:11:24.900534Z" } }, "outputs": [], "source": [ " TH1D *histBbbInput=\n", " new TH1D(\"bbb input rec\",\";ptrec\",nGen,xminGen,xmaxGen);\n", " TH1D *histBbbSignalRec=\n", " new TH1D(\"bbb signal rec\",\";ptrec\",nGen,xminGen,xmaxGen);\n", " TH1D *histBbbBgr1=\n", " new TH1D(\"bbb bgr1 rec\",\";ptrec\",nGen,xminGen,xmaxGen);\n", " TH1D *histBbbBgr2=\n", " new TH1D(\"bbb bgr2 rec\",\";ptrec\",nGen,xminGen,xmaxGen);\n", " TH1D *histBbbBgrPt=\n", " new TH1D(\"bbb bgrPt rec\",\";ptrec\",nGen,xminGen,xmaxGen);\n", " TH1D *histBbbSignalGen=\n", " new TH1D(\"bbb signal gen\",\";ptgen\",nGen,xminGen,xmaxGen);\n", " TH1D *histBbbSignalRecSys=\n", " new TH1D(\"bbb signal sys rec\",\";ptrec\",nGen,xminGen,xmaxGen);\n", " TH1D *histBbbBgrPtSys=\n", " new TH1D(\"bbb bgrPt sys rec\",\";ptrec\",nGen,xminGen,xmaxGen);\n", " TH1D *histBbbSignalGenSys=\n", " new TH1D(\"bbb signal sys gen\",\";ptgen\",nGen,xminGen,xmaxGen);" ] }, { "cell_type": "markdown", "id": "8eaca0f1", "metadata": {}, "source": [ "(3) control histograms" ] }, { "cell_type": "code", "execution_count": 11, "id": "843bb600", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:24.902974Z", "iopub.status.busy": "2026-05-19T20:11:24.902855Z", "iopub.status.idle": "2026-05-19T20:11:25.105542Z", "shell.execute_reply": "2026-05-19T20:11:25.105136Z" } }, "outputs": [], "source": [ " TH1D *histDataTruth=\n", " new TH1D(\"DATA truth gen\",\";ptgen\",nGen,xminGen,xmaxGen);\n", " TH1D *histDetMC=\n", " new TH1D(\"MC prediction rec\",\";ptrec\",nDet,xminDet,xmaxDet);" ] }, { "cell_type": "markdown", "id": "46522b92", "metadata": {}, "source": [ "==============================================================\n", "Step 2: generate data distributions\n", "\n", "data parameters: in real life these are unknown" ] }, { "cell_type": "code", "execution_count": 12, "id": "1a088246", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:25.108156Z", "iopub.status.busy": "2026-05-19T20:11:25.108023Z", "iopub.status.idle": "2026-05-19T20:11:25.310640Z", "shell.execute_reply": "2026-05-19T20:11:25.309733Z" } }, "outputs": [], "source": [ " static Double_t parm_DATA[]={\n", " 0.05, // fraction of background 1 (on generator level)\n", " 0.05, // fraction of background 2 (on generator level)\n", " 3.5, // lower Pt cut (generator level)\n", " 100.,// upper Pt cut (generator level)\n", " -3.0,// signal exponent\n", " 0.1, // background 1 exponent\n", " -0.5, // background 2 exponent\n", " 0.2, // energy resolution a term\n", " 0.01, // energy resolution b term\n", " };\n", " static Double_t triggerParm_DATA[]={8.0, // threshold is 8 GeV\n", " 4.0, // width is 4 GeV\n", " 0.95 // high Pt efficiency os 95%\n", " };\n", "\n", " Double_t intLumi=0.0;\n", " while(intLumiFill(ptObs);\n", "\n", " // (2) histogram for bin-by-bin\n", " histBbbInput->Fill(ptObs);\n", " }\n", " // (3) monitoring\n", " if(iTypeGen==0) histDataTruth->Fill(ptGen);\n", " }" ] }, { "cell_type": "markdown", "id": "e6a9452c", "metadata": {}, "source": [ "==============================================================\n", "Step 3: generate default MC distributions\n", "\n", "MC parameters\n", "default settings" ] }, { "cell_type": "code", "execution_count": 13, "id": "4bb6c3ad", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:25.312425Z", "iopub.status.busy": "2026-05-19T20:11:25.312290Z", "iopub.status.idle": "2026-05-19T20:11:25.514832Z", "shell.execute_reply": "2026-05-19T20:11:25.513749Z" } }, "outputs": [], "source": [ " static Double_t parm_MC[]={\n", " 0.05, // fraction of background 1 (on generator level)\n", " 0.05, // fraction of background 2 (on generator level)\n", " 3.5, // lower Pt cut (generator level)\n", " 100.,// upper Pt cut (generator level)\n", " -4.0,// signal exponent !!! steeper than in data\n", " // to illustrate bin-by-bin bias\n", " 0.1, // background 1 exponent\n", " -0.5, // background 2 exponent\n", " 0.2, // energy resolution a term\n", " 0.01, // energy resolution b term\n", " };\n", " static Double_t triggerParm_MC[]={8.0, // threshold is 8 GeV\n", " 4.0, // width is 4 GeV\n", " 0.95 // high Pt efficiency is 95%\n", " };" ] }, { "cell_type": "markdown", "id": "900ecbc2", "metadata": {}, "source": [ "weighting factor to accommodate for the different luminosity in data and MC" ] }, { "cell_type": "code", "execution_count": 14, "id": "10e6bf78", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:25.516624Z", "iopub.status.busy": "2026-05-19T20:11:25.516448Z", "iopub.status.idle": "2026-05-19T20:11:25.776705Z", "shell.execute_reply": "2026-05-19T20:11:25.775936Z" } }, "outputs": [], "source": [ " Double_t lumiWeight = lumiData/lumiMC;\n", " intLumi=0.0;\n", " while(intLumiFill(ptGen,ptObs,lumiWeight);\n", " } else if(iTypeGen==1) {\n", " histUnfoldBgr1->Fill(ptObs,lumiWeight);\n", " } else if(iTypeGen==2) {\n", " histUnfoldBgr2->Fill(ptObs,lumiWeight);\n", " }\n", "\n", " // (2) distributions for bbb\n", " if(iTypeGen==0) {\n", " if((ptGen>=xminGen)&&(ptGenFill(ptObs,lumiWeight);\n", " } else {\n", " histBbbBgrPt->Fill(ptObs,lumiWeight);\n", " }\n", " histBbbSignalGen->Fill(ptGen,lumiWeight);\n", " } else if(iTypeGen==1) {\n", " histBbbBgr1->Fill(ptObs,lumiWeight);\n", " } else if(iTypeGen==2) {\n", " histBbbBgr2->Fill(ptObs,lumiWeight);\n", " }\n", "\n", " // (3) control distribution\n", " histDetMC ->Fill(ptObs,lumiWeight);\n", " }" ] }, { "cell_type": "markdown", "id": "36fd6dbd", "metadata": {}, "source": [ "==============================================================\n", "Step 4: generate MC distributions for systematic study\n", "example: study dependence on initial signal shape\n", "-> BGR distributions do not change" ] }, { "cell_type": "code", "execution_count": 15, "id": "a89529ed", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:25.778351Z", "iopub.status.busy": "2026-05-19T20:11:25.778197Z", "iopub.status.idle": "2026-05-19T20:11:26.128310Z", "shell.execute_reply": "2026-05-19T20:11:26.127502Z" } }, "outputs": [], "source": [ " static Double_t parm_MC_SYS[]={\n", " 0.05, // fraction of background: unchanged\n", " 0.05, // fraction of background: unchanged\n", " 3.5, // lower Pt cut (generator level)\n", " 100.,// upper Pt cut (generator level)\n", " -2.0, // signal exponent changed\n", " 0.1, // background 1 exponent\n", " -0.5, // background 2 exponent\n", " 0.2, // energy resolution a term\n", " 0.01, // energy resolution b term\n", " };\n", "\n", " intLumi=0.0;\n", " while(intLumiFill(ptGen,ptObs);\n", " }\n", "\n", " // (2) for bin-by-bin\n", " if(iTypeGen==0) {\n", " if((ptGen>=xminGen)&&(ptGenFill(ptObs);\n", " } else {\n", " histBbbBgrPtSys->Fill(ptObs);\n", " }\n", " histBbbSignalGenSys->Fill(ptGen);\n", " }\n", " }" ] }, { "cell_type": "markdown", "id": "f1a3d493", "metadata": {}, "source": [ "this method is new in version 16 of TUnfold" ] }, { "cell_type": "code", "execution_count": 16, "id": "1d0f9104", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:26.129976Z", "iopub.status.busy": "2026-05-19T20:11:26.129852Z", "iopub.status.idle": "2026-05-19T20:11:26.333158Z", "shell.execute_reply": "2026-05-19T20:11:26.332523Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "TUnfold version is V17.9\n" ] } ], "source": [ " cout<<\"TUnfold version is \"<: fConstraint=1\n", "Info in : 24 input bins and 12 output bins (includes 2 underflow/overflow bins)\n", "Info in : regularizing xaxis regMode=3 densityMode=1 axisSteering=*[UOB]\n" ] } ], "source": [ " TUnfoldDensity unfold(histUnfoldMatrix,TUnfold::kHistMapOutputHoriz,\n", " regMode,constraintMode,densityFlags);" ] }, { "cell_type": "markdown", "id": "d3bfa6bb", "metadata": {}, "source": [ "define the input vector (the measured data distribution)" ] }, { "cell_type": "code", "execution_count": 21, "id": "8c861669", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:27.156728Z", "iopub.status.busy": "2026-05-19T20:11:27.156594Z", "iopub.status.idle": "2026-05-19T20:11:27.360084Z", "shell.execute_reply": "2026-05-19T20:11:27.359500Z" } }, "outputs": [], "source": [ " unfold.SetInput(histUnfoldInput);" ] }, { "cell_type": "markdown", "id": "a69f2cdd", "metadata": {}, "source": [ "subtract background, normalized to data luminosity\n", "with 10% scale error each" ] }, { "cell_type": "code", "execution_count": 22, "id": "73635bf7", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:27.361329Z", "iopub.status.busy": "2026-05-19T20:11:27.361214Z", "iopub.status.idle": "2026-05-19T20:11:27.564151Z", "shell.execute_reply": "2026-05-19T20:11:27.563579Z" } }, "outputs": [], "source": [ " Double_t scale_bgr=1.0;\n", " Double_t dscale_bgr=0.1;\n", " unfold.SubtractBackground(histUnfoldBgr1,\"background1\",scale_bgr,dscale_bgr);\n", " unfold.SubtractBackground(histUnfoldBgr2,\"background2\",scale_bgr,dscale_bgr);" ] }, { "cell_type": "markdown", "id": "138f645b", "metadata": {}, "source": [ "add systematic error" ] }, { "cell_type": "code", "execution_count": 23, "id": "76ffaf5c", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:27.565430Z", "iopub.status.busy": "2026-05-19T20:11:27.565318Z", "iopub.status.idle": "2026-05-19T20:11:27.768780Z", "shell.execute_reply": "2026-05-19T20:11:27.768226Z" } }, "outputs": [], "source": [ " unfold.AddSysError(histUnfoldMatrixSys,\"signalshape_SYS\",\n", " TUnfold::kHistMapOutputHoriz,\n", " TUnfoldSys::kSysErrModeMatrix);" ] }, { "cell_type": "markdown", "id": "448e4a9a", "metadata": {}, "source": [ "run the unfolding" ] }, { "cell_type": "code", "execution_count": 24, "id": "c2a1f319", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:27.769997Z", "iopub.status.busy": "2026-05-19T20:11:27.769886Z", "iopub.status.idle": "2026-05-19T20:11:27.973265Z", "shell.execute_reply": "2026-05-19T20:11:27.972737Z" } }, "outputs": [], "source": [ " Int_t nScan=30;\n", " TSpline *logTauX,*logTauY;\n", " TGraph *lCurve;" ] }, { "cell_type": "markdown", "id": "ee266cc4", "metadata": {}, "source": [ "this method scans the parameter tau and finds the kink in the L curve\n", "finally, the unfolding is done for the best choice of tau" ] }, { "cell_type": "code", "execution_count": 25, "id": "78112481", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:27.974533Z", "iopub.status.busy": "2026-05-19T20:11:27.974423Z", "iopub.status.idle": "2026-05-19T20:11:28.179058Z", "shell.execute_reply": "2026-05-19T20:11:28.178596Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "chi**2=25.3912+4.28619 / 11\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "Info in : logtau=-Infinity X=1.398300 Y=5.378547\n", "Info in : logtau=-1.914692 X=1.501461 Y=5.045396\n", "Info in : logtau=-2.414692 X=1.401645 Y=5.325900\n", "Info in : logtau=-2.164692 X=1.421959 Y=5.232814\n", "Info in : logtau=-2.039692 X=1.451597 Y=5.151192\n", "Info in : logtau=-1.977192 X=1.473934 Y=5.100968\n", "Info in : logtau=-2.289692 X=1.407586 Y=5.289508\n", "Info in : logtau=-2.102192 X=1.434441 Y=5.195244\n", "Info in : logtau=-1.945942 X=1.487070 Y=5.073781\n", "Info in : logtau=-2.227192 X=1.413316 Y=5.264065\n", "Info in : logtau=-2.008442 X=1.462104 Y=5.126812\n", "Info in : logtau=-2.070942 X=1.442393 Y=5.174021\n", "Info in : logtau=-2.133442 X=1.427663 Y=5.214839\n", "Info in : logtau=-2.352192 X=1.403921 Y=5.309858\n", "Info in : logtau=-2.195942 X=1.417216 Y=5.249204\n", "Info in : logtau=-1.930317 X=1.494113 Y=5.059728\n", "Info in : logtau=-1.961567 X=1.480342 Y=5.087534\n", "Info in : logtau=-1.992817 X=1.467854 Y=5.114066\n", "Info in : logtau=-2.024067 X=1.456686 Y=5.139191\n", "Info in : logtau=-2.258442 X=1.410143 Y=5.277471\n", "Info in : logtau=-2.055317 X=1.446834 Y=5.162805\n", "Info in : logtau=-2.086567 X=1.438265 Y=5.184835\n", "Info in : logtau=-2.117817 X=1.430912 Y=5.205245\n", "Info in : logtau=-2.320942 X=1.405542 Y=5.300271\n", "Info in : logtau=-2.149067 X=1.424684 Y=5.224027\n", "Info in : logtau=-2.180317 X=1.419475 Y=5.241204\n", "Info in : logtau=-2.383442 X=1.402644 Y=5.318368\n", "Info in : logtau=-1.922504 X=1.497750 Y=5.052595\n", "Info in : logtau=-1.938129 X=1.490553 Y=5.066790\n", "Info in : logtau=-2.211567 X=1.415168 Y=5.256821\n", "Info in : Result logtau=-2.336567 X=1.404684 Y=5.305205\n" ] } ], "source": [ " Int_t iBest=unfold.ScanLcurve(nScan,0.,0.,&lCurve,&logTauX,&logTauY);\n", "\n", " cout<<\"chi**2=\"<GetKnot(iBest,t[0],x[0]);\n", " logTauY->GetKnot(iBest,t[0],y[0]);\n", " TGraph *bestLcurve=new TGraph(1,x,y);\n", " TGraph *bestLogTauLogChi2=new TGraph(1,t,x);" ] }, { "cell_type": "markdown", "id": "0ff533a3", "metadata": {}, "source": [ "===========================\n", "Step 6: retrieve unfolding results" ] }, { "cell_type": "markdown", "id": "9505a3d0", "metadata": {}, "source": [ "get unfolding output\n", "includes the statistical and background errors\n", "but not the other systematic uncertainties" ] }, { "cell_type": "code", "execution_count": 27, "id": "8477af89", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:28.384897Z", "iopub.status.busy": "2026-05-19T20:11:28.384783Z", "iopub.status.idle": "2026-05-19T20:11:28.587628Z", "shell.execute_reply": "2026-05-19T20:11:28.587062Z" } }, "outputs": [], "source": [ " TH1 *histUnfoldOutput=unfold.GetOutput(\"PT(unfold,stat+bgrerr)\");" ] }, { "cell_type": "markdown", "id": "294c618c", "metadata": {}, "source": [ "retrieve error matrix of statistical errors" ] }, { "cell_type": "code", "execution_count": 28, "id": "93db06e2", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:28.588900Z", "iopub.status.busy": "2026-05-19T20:11:28.588788Z", "iopub.status.idle": "2026-05-19T20:11:28.791683Z", "shell.execute_reply": "2026-05-19T20:11:28.791106Z" } }, "outputs": [], "source": [ " TH2 *histEmatStat=unfold.GetEmatrixInput(\"unfolding stat error matrix\");" ] }, { "cell_type": "markdown", "id": "efd6e475", "metadata": {}, "source": [ "retrieve full error matrix\n", "This includes all systematic errors" ] }, { "cell_type": "code", "execution_count": 29, "id": "799905e5", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:28.792924Z", "iopub.status.busy": "2026-05-19T20:11:28.792810Z", "iopub.status.idle": "2026-05-19T20:11:28.995628Z", "shell.execute_reply": "2026-05-19T20:11:28.995103Z" } }, "outputs": [], "source": [ " TH2 *histEmatTotal=unfold.GetEmatrixTotal(\"unfolding total error matrix\");" ] }, { "cell_type": "markdown", "id": "1821b7f7", "metadata": {}, "source": [ "create two copies of the unfolded data, one with statistical errors\n", "the other with total errors" ] }, { "cell_type": "code", "execution_count": 30, "id": "e915cae6", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:28.996907Z", "iopub.status.busy": "2026-05-19T20:11:28.996793Z", "iopub.status.idle": "2026-05-19T20:11:29.210249Z", "shell.execute_reply": "2026-05-19T20:11:29.209669Z" } }, "outputs": [], "source": [ " TH1 *histUnfoldStat=new TH1D(\"PT(unfold,staterr)\",\";Pt(gen)\",\n", " nGen,xminGen,xmaxGen);\n", " TH1 *histUnfoldTotal=new TH1D(\"PT(unfold,totalerr)\",\";Pt(gen)\",\n", " nGen,xminGen,xmaxGen);\n", " for(Int_t i=0;iGetBinContent(i);\n", "\n", " // histogram with unfolded data and stat errors\n", " histUnfoldStat->SetBinContent(i,c);\n", " histUnfoldStat->SetBinError\n", " (i,TMath::Sqrt(histEmatStat->GetBinContent(i,i)));\n", "\n", " // histogram with unfolded data and total errors\n", " histUnfoldTotal->SetBinContent(i,c);\n", " histUnfoldTotal->SetBinError\n", " (i,TMath::Sqrt(histEmatTotal->GetBinContent(i,i)));\n", " }" ] }, { "cell_type": "markdown", "id": "93e3dbaf", "metadata": {}, "source": [ "create histogram with correlation matrix" ] }, { "cell_type": "code", "execution_count": 31, "id": "9c9df8c3", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:29.214174Z", "iopub.status.busy": "2026-05-19T20:11:29.214052Z", "iopub.status.idle": "2026-05-19T20:11:29.418891Z", "shell.execute_reply": "2026-05-19T20:11:29.417770Z" } }, "outputs": [], "source": [ " TH2D *histCorr=new TH2D(\"Corr(total)\",\";Pt(gen);Pt(gen)\",\n", " nGen,xminGen,xmaxGen,nGen,xminGen,xmaxGen);\n", " for(Int_t i=0;iGetBinContent(i,i));\n", " if(ei<=0.0) continue;\n", " for(Int_t j=0;jGetBinContent(j,j));\n", " if(ej<=0.0) continue;\n", " histCorr->SetBinContent(i,j,histEmatTotal->GetBinContent(i,j)/ei/ej);\n", " }\n", " }" ] }, { "cell_type": "markdown", "id": "d753a09b", "metadata": {}, "source": [ "retrieve bgr source 1" ] }, { "cell_type": "code", "execution_count": 32, "id": "d5f0d591", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:29.420195Z", "iopub.status.busy": "2026-05-19T20:11:29.420081Z", "iopub.status.idle": "2026-05-19T20:11:29.639301Z", "shell.execute_reply": "2026-05-19T20:11:29.638659Z" } }, "outputs": [], "source": [ " TH1 *histDetNormBgr1=unfold.GetBackground(\"bgr1 normalized\",\n", " \"background1\");\n", " TH1 *histDetNormBgrTotal=unfold.GetBackground(\"bgr total normalized\");" ] }, { "cell_type": "markdown", "id": "93fa6c09", "metadata": {}, "source": [ "========================\n", "Step 7: plots" ] }, { "cell_type": "code", "execution_count": 33, "id": "95379bb1", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:29.650233Z", "iopub.status.busy": "2026-05-19T20:11:29.650093Z", "iopub.status.idle": "2026-05-19T20:11:29.887021Z", "shell.execute_reply": "2026-05-19T20:11:29.882387Z" } }, "outputs": [], "source": [ " TCanvas output;\n", " output.Divide(3,2);\n", " output.cd(1);" ] }, { "cell_type": "markdown", "id": "433198b6", "metadata": {}, "source": [ "data, MC prediction, background" ] }, { "cell_type": "code", "execution_count": 34, "id": "f2791517", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:29.900937Z", "iopub.status.busy": "2026-05-19T20:11:29.900800Z", "iopub.status.idle": "2026-05-19T20:11:30.104599Z", "shell.execute_reply": "2026-05-19T20:11:30.103965Z" } }, "outputs": [], "source": [ " histUnfoldInput->SetMinimum(0.0);\n", " histUnfoldInput->Draw(\"E\");\n", " histDetMC->SetMinimum(0.0);\n", " histDetMC->SetLineColor(kBlue);\n", " histDetNormBgrTotal->SetLineColor(kRed);\n", " histDetNormBgr1->SetLineColor(kCyan);\n", " histDetMC->Draw(\"SAME HIST\");\n", " histDetNormBgr1->Draw(\"SAME HIST\");\n", " histDetNormBgrTotal->Draw(\"SAME HIST\");\n", "\n", " output.cd(2);" ] }, { "cell_type": "markdown", "id": "7a3633e1", "metadata": {}, "source": [ "unfolded data, data truth, MC truth" ] }, { "cell_type": "code", "execution_count": 35, "id": "6223a9a2", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:30.105942Z", "iopub.status.busy": "2026-05-19T20:11:30.105825Z", "iopub.status.idle": "2026-05-19T20:11:30.309418Z", "shell.execute_reply": "2026-05-19T20:11:30.308855Z" } }, "outputs": [], "source": [ " histUnfoldTotal->SetMinimum(0.0);\n", " histUnfoldTotal->SetMaximum(histUnfoldTotal->GetMaximum()*1.5);" ] }, { "cell_type": "markdown", "id": "53c9862f", "metadata": {}, "source": [ "outer error: total error" ] }, { "cell_type": "code", "execution_count": 36, "id": "3ba809bf", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:30.310788Z", "iopub.status.busy": "2026-05-19T20:11:30.310661Z", "iopub.status.idle": "2026-05-19T20:11:30.513566Z", "shell.execute_reply": "2026-05-19T20:11:30.513020Z" } }, "outputs": [], "source": [ " histUnfoldTotal->Draw(\"E\");" ] }, { "cell_type": "markdown", "id": "8ef3419d", "metadata": {}, "source": [ "middle error: stat+bgr" ] }, { "cell_type": "code", "execution_count": 37, "id": "4d34b4d6", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:30.514932Z", "iopub.status.busy": "2026-05-19T20:11:30.514820Z", "iopub.status.idle": "2026-05-19T20:11:30.723437Z", "shell.execute_reply": "2026-05-19T20:11:30.722725Z" } }, "outputs": [], "source": [ " histUnfoldOutput->Draw(\"SAME E1\");" ] }, { "cell_type": "markdown", "id": "c449ecd1", "metadata": {}, "source": [ "inner error: stat only" ] }, { "cell_type": "code", "execution_count": 38, "id": "6764d006", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:30.725385Z", "iopub.status.busy": "2026-05-19T20:11:30.725259Z", "iopub.status.idle": "2026-05-19T20:11:30.934790Z", "shell.execute_reply": "2026-05-19T20:11:30.934080Z" } }, "outputs": [], "source": [ " histUnfoldStat->Draw(\"SAME E1\");\n", " histDataTruth->Draw(\"SAME HIST\");\n", " histBbbSignalGen->SetLineColor(kBlue);\n", " histBbbSignalGen->Draw(\"SAME HIST\");\n", "\n", " output.cd(3);" ] }, { "cell_type": "markdown", "id": "14708b2f", "metadata": {}, "source": [ "unfolding matrix" ] }, { "cell_type": "code", "execution_count": 39, "id": "75630570", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:30.936714Z", "iopub.status.busy": "2026-05-19T20:11:30.936555Z", "iopub.status.idle": "2026-05-19T20:11:31.140287Z", "shell.execute_reply": "2026-05-19T20:11:31.139074Z" } }, "outputs": [], "source": [ " histUnfoldMatrix->SetLineColor(kBlue);\n", " histUnfoldMatrix->Draw(\"BOX\");" ] }, { "cell_type": "markdown", "id": "323a7982", "metadata": {}, "source": [ "show tau as a function of chi**2" ] }, { "cell_type": "code", "execution_count": 40, "id": "8b9244c4", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:31.142040Z", "iopub.status.busy": "2026-05-19T20:11:31.141899Z", "iopub.status.idle": "2026-05-19T20:11:31.345754Z", "shell.execute_reply": "2026-05-19T20:11:31.344629Z" } }, "outputs": [], "source": [ " output.cd(4);\n", " logTauX->Draw();\n", " bestLogTauLogChi2->SetMarkerColor(kRed);\n", " bestLogTauLogChi2->Draw(\"*\");" ] }, { "cell_type": "markdown", "id": "d1dc173c", "metadata": {}, "source": [ "show the L curve" ] }, { "cell_type": "code", "execution_count": 41, "id": "84eb261f", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:31.347286Z", "iopub.status.busy": "2026-05-19T20:11:31.347153Z", "iopub.status.idle": "2026-05-19T20:11:31.550575Z", "shell.execute_reply": "2026-05-19T20:11:31.549551Z" } }, "outputs": [], "source": [ " output.cd(5);\n", " lCurve->Draw(\"AL\");\n", " bestLcurve->SetMarkerColor(kRed);\n", " bestLcurve->Draw(\"*\");" ] }, { "cell_type": "markdown", "id": "91d2cbd0", "metadata": {}, "source": [ "show correlation matrix" ] }, { "cell_type": "code", "execution_count": 42, "id": "0d97996a", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:31.552030Z", "iopub.status.busy": "2026-05-19T20:11:31.551912Z", "iopub.status.idle": "2026-05-19T20:11:31.755837Z", "shell.execute_reply": "2026-05-19T20:11:31.754988Z" } }, "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 : ps file testUnfold3.ps has been created\n" ] } ], "source": [ " output.cd(6);\n", " histCorr->Draw(\"BOX\");\n", "\n", " output.SaveAs(\"testUnfold3.ps\");" ] }, { "cell_type": "markdown", "id": "ac136884", "metadata": {}, "source": [ "============================================================\n", "step 8: compare results to the so-called bin-by-bin \"correction\"" ] }, { "cell_type": "code", "execution_count": 43, "id": "578f128b", "metadata": { "collapsed": false, "execution": { "iopub.execute_input": "2026-05-19T20:11:31.757330Z", "iopub.status.busy": "2026-05-19T20:11:31.757198Z", "iopub.status.idle": "2026-05-19T20:11:31.961373Z", "shell.execute_reply": "2026-05-19T20:11:31.960578Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "bin truth result (stat) (bgr) (sys)\n", "===+=====+=========+========+========+=======\n", " 1 4002 4261.3 +/-137.0 +/- 8.9 +/-473.2 (unfolding)\n", " 4190.1 +/-128.7 +/-104.7 +/-266.3 (bin-by-bin)\n", "\n", " 2 1816 1775.1 +/- 82.0 +/- 7.3 +/- 25.2 (unfolding)\n", " 1714.1 +/- 61.0 +/- 17.0 +/- 70.8 (bin-by-bin)\n", "\n", " 3 1011 1020.9 +/- 60.1 +/- 6.7 +/- 24.8 (unfolding)\n", " 959.5 +/- 40.9 +/- 9.2 +/- 43.3 (bin-by-bin)\n", "\n", " 4 593 526.9 +/- 45.2 +/- 6.1 +/- 15.0 (unfolding)\n", " 506.2 +/- 27.9 +/- 6.6 +/- 45.2 (bin-by-bin)\n", "\n", " 5 379 371.6 +/- 38.6 +/- 6.5 +/- 19.8 (unfolding)\n", " 351.8 +/- 22.6 +/- 6.0 +/- 29.2 (bin-by-bin)\n", "\n", " 6 256 341.5 +/- 34.4 +/- 6.0 +/- 9.2 (unfolding)\n", " 282.5 +/- 19.2 +/- 5.2 +/- 46.6 (bin-by-bin)\n", "\n", " 7 193 182.0 +/- 30.1 +/- 5.7 +/- 7.5 (unfolding)\n", " 177.7 +/- 15.8 +/- 4.9 +/- 22.5 (bin-by-bin)\n", "\n", " 8 137 147.1 +/- 28.4 +/- 5.6 +/- 7.0 (unfolding)\n", " 133.6 +/- 13.9 +/- 4.5 +/- 20.5 (bin-by-bin)\n", "\n", " 9 123 109.6 +/- 26.3 +/- 5.4 +/- 10.4 (unfolding)\n", " 98.6 +/- 12.1 +/- 4.1 +/- 20.7 (bin-by-bin)\n", "\n", " 10 78 100.7 +/- 24.7 +/- 6.1 +/- 8.4 (unfolding)\n", " 89.7 +/- 13.2 +/- 5.0 +/- 17.1 (bin-by-bin)\n", "\n" ] } ], "source": [ " std::cout<<\"bin truth result (stat) (bgr) (sys)\\n\";\n", " std::cout<<\"===+=====+=========+========+========+=======\\n\";\n", " for(Int_t i=1;i<=nGen;i++) {\n", " // data contribution in this bin\n", " Double_t data=histBbbInput->GetBinContent(i);\n", " Double_t errData=histBbbInput->GetBinError(i);\n", "\n", " // subtract background contributions\n", " Double_t data_bgr=data\n", " - scale_bgr*(histBbbBgr1->GetBinContent(i)\n", " + histBbbBgr2->GetBinContent(i)\n", " + histBbbBgrPt->GetBinContent(i));\n", " Double_t errData_bgr=TMath::Sqrt\n", " (errData*errData+\n", " TMath::Power(dscale_bgr*histBbbBgr1->GetBinContent(i),2)+\n", " TMath::Power(scale_bgr*histBbbBgr1->GetBinError(i),2)+\n", " TMath::Power(dscale_bgr*histBbbBgr2->GetBinContent(i),2)+\n", " TMath::Power(scale_bgr*histBbbBgr2->GetBinError(i),2)+\n", " TMath::Power(dscale_bgr*histBbbBgrPt->GetBinContent(i),2)+\n", " TMath::Power(scale_bgr*histBbbBgrPt->GetBinError(i),2));\n", " // \"correct\" the data, using the Monte Carlo and neglecting off-diagonals\n", " Double_t fCorr=(histBbbSignalGen->GetBinContent(i)/\n", " histBbbSignalRec->GetBinContent(i));\n", " Double_t data_bbb= data_bgr *fCorr;\n", " // stat only error\n", " Double_t errData_stat_bbb = errData*fCorr;\n", " // stat plus background subtraction\n", " Double_t errData_statbgr_bbb = errData_bgr*fCorr;\n", "\n", " // estimate systematic error by repeating the exercise\n", " // using the MC with systematic shifts applied\n", " Double_t fCorr_sys=(histBbbSignalGenSys->GetBinContent(i)/\n", " histBbbSignalRecSys->GetBinContent(i));\n", " Double_t shift_sys= data_bgr*fCorr_sys - data_bbb;\n", "\n", " // add systematic shift quadratically and get total error\n", " Double_t errData_total_bbb=\n", " TMath::Sqrt(errData_statbgr_bbb*errData_statbgr_bbb\n", " +shift_sys*shift_sys);\n", "\n", " // get results from real unfolding\n", " Double_t data_unfold= histUnfoldStat->GetBinContent(i);\n", " Double_t errData_stat_unfold=histUnfoldStat->GetBinError(i);\n", " Double_t errData_statbgr_unfold=histUnfoldOutput->GetBinError(i);\n", " Double_t errData_total_unfold=histUnfoldTotal->GetBinError(i);\n", "\n", " // compare\n", "\n", " std::cout<GetBinContent(i),data_unfold,\n", " errData_stat_unfold,TMath::Sqrt(errData_statbgr_unfold*\n", " errData_statbgr_unfold-\n", " errData_stat_unfold*\n", " errData_stat_unfold),\n", " TMath::Sqrt(errData_total_unfold*\n", " errData_total_unfold-\n", " errData_statbgr_unfold*\n", " errData_statbgr_unfold))<<\"\\n\";\n", " std::cout<\n", "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "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 }