{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "24f0fdfb",
   "metadata": {},
   "source": [
    "# df034_SaveGraph\n",
    "Basic SaveGraph usage.\n",
    "\n",
    "This tutorial shows how to use the SaveGraph action.\n",
    "SaveGraph inspects the sequence of RDataFrame actions.\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "**Author:** Ivan Kabadzhov (CERN)  \n",
    "<i><small>This notebook tutorial was automatically generated with <a href= \"https://github.com/root-project/root/blob/master/documentation/doxygen/converttonotebook.py\">ROOTBOOK-izer</a> from the macro found in the ROOT repository  on Tuesday, May 19, 2026 at 08:10 PM.</small></i>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "463c67b4",
   "metadata": {},
   "source": [
    "First, an RDataFrame computation graph is created with Defines, Filters and methods such as Mean, Count, etc.\n",
    "After that, SaveGraph can be called either on the root RDataFrame object or on a specific node of the computation\n",
    "graph: in the first case, the graph returned will span the full computation graph, in the second case it will show\n",
    "only the branch of the computation graph that the node belongs to.\n",
    "If a filename is passed as second argument, the graph is saved to that file, otherwise it is returned as a string."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "de190e0f",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:10:15.033215Z",
     "iopub.status.busy": "2026-05-19T20:10:15.033031Z",
     "iopub.status.idle": "2026-05-19T20:10:18.417742Z",
     "shell.execute_reply": "2026-05-19T20:10:18.417058Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "digraph {\n",
      "\t8 [label=\"Mean\", style=\"filled\", fillcolor=\"#e47c7e\", shape=\"box\"];\n",
      "\t6 [label=\"Filter_1_1\", style=\"filled\", fillcolor=\"#0f9d58\", shape=\"hexagon\"];\n",
      "\t7 [label=\"Define\\nBranch_1_1_def\", style=\"filled\", fillcolor=\"#4285f4\", shape=\"ellipse\"];\n",
      "\t3 [label=\"Filter_1\", style=\"filled\", fillcolor=\"#0f9d58\", shape=\"hexagon\"];\n",
      "\t4 [label=\"Define\\nBranch_1_def\", style=\"filled\", fillcolor=\"#4285f4\", shape=\"ellipse\"];\n",
      "\t5 [label=\"Define\\nRoot_def2\", style=\"filled\", fillcolor=\"#4285f4\", shape=\"ellipse\"];\n",
      "\t1 [label=\"Main_Filter\", style=\"filled\", fillcolor=\"#0f9d58\", shape=\"hexagon\"];\n",
      "\t2 [label=\"Define\\nRoot_def1\", style=\"filled\", fillcolor=\"#4285f4\", shape=\"ellipse\"];\n",
      "\t0 [label=\"Empty source\\nEntries: 2\", style=\"filled\", fillcolor=\"#f4b400\", shape=\"ellipse\"];\n",
      "\t6 -> 8;\n",
      "\t7 -> 6;\n",
      "\t3 -> 7;\n",
      "\t4 -> 3;\n",
      "\t5 -> 4;\n",
      "\t1 -> 5;\n",
      "\t2 -> 1;\n",
      "\t0 -> 2;\n",
      "}\n"
     ]
    }
   ],
   "source": [
    "import ROOT\n",
    "\n",
    "rd1 = ROOT.RDataFrame(2)\n",
    "\n",
    "rd2 = rd1.Define(\"Root_def1\", \"1\") \\\n",
    "         .Filter(\"Root_def1 < 2\", \"Main_Filter\") \\\n",
    "         .Define(\"Root_def2\", \"1\")\n",
    "\n",
    "branch1 = rd2.Define(\"Branch_1_def\", \"1\")\n",
    "branch2 = rd2.Define(\"Branch_2_def\", \"1\")\n",
    "\n",
    "branch1_1 = branch1.Filter(\"Branch_1_def < 2\", \"Filter_1\") \\\n",
    "                   .Define(\"Branch_1_1_def\", \"1\") \\\n",
    "                   .Filter(\"1 == Branch_1_1_def % 2\", \"Filter_1_1\") \\\n",
    "                   .Mean(\"Branch_1_1_def\");\n",
    "\n",
    "branch1_2 = branch1.Define(\"Branch_1_2_def\", \"1\") \\\n",
    "                   .Filter(\"Branch_1_2_def < 2\", \"Filter_1_2\") \\\n",
    "                   .Count()\n",
    "\n",
    "branch2_1 = branch2.Filter(\"Branch_2_def < 2\", \"Filter_2\") \\\n",
    "                   .Define(\"Branch_2_1_def\", \"1\") \\\n",
    "                   .Define(\"Branch_2_2_def\", \"1\") \\\n",
    "                   .Filter(\"1 == Branch_2_1_def % 2\", \"Filter_2_1\") \\\n",
    "                   .Max(\"Branch_2_1_def\")\n",
    "\n",
    "branch2_2 = branch2.Count()\n",
    "\n",
    "print(ROOT.RDF.SaveGraph(branch1_1))\n",
    "ROOT.RDF.SaveGraph(rd1, \"exampleGraph.dot\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
