{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "b5a45475",
   "metadata": {},
   "source": [
    "# tfile_context_manager\n",
    "This tutorial demonstrates the usage of the TFile class as a Python context\n",
    "manager.\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "**Author:** Vincenzo Eduardo Padulano CERN/UPV  \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:16 PM.</small></i>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "a2ccddce",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:16:46.787810Z",
     "iopub.status.busy": "2026-05-19T20:16:46.787684Z",
     "iopub.status.idle": "2026-05-19T20:16:47.773688Z",
     "shell.execute_reply": "2026-05-19T20:16:47.773022Z"
    }
   },
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "import ROOT\n",
    "from ROOT import TFile, gROOT"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "56e4f738",
   "metadata": {},
   "source": [
    "By default, in ROOT 6, objects of some ROOT types such as `TH1` and its derived types\n",
    "are automatically attached to a ROOT.TDirectory when they are created.\n",
    "Objects are attached to the current directory denoted by ROOT.gDirectory.\n",
    "For ROOT 7, the default will be *not* to attach objects to ROOT.gDirectory, except for\n",
    "cases where the documentation states it explicitly, such as TTree.\n",
    "In ROOT 6, this mode can be tested by setting ROOT.Experimental.DisableObjectAutoRegistration()."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "36b1fe69",
   "metadata": {},
   "source": [
    "The next line will print 'PyROOT' as the name of the current directory.\n",
    "That is the global directory created when using ROOT from Python, which is\n",
    "the ROOT.gROOT object."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "4f87d0a9",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:16:47.775858Z",
     "iopub.status.busy": "2026-05-19T20:16:47.775723Z",
     "iopub.status.idle": "2026-05-19T20:16:47.898820Z",
     "shell.execute_reply": "2026-05-19T20:16:47.898123Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Current directory: 'PyROOT'.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(\"Current directory: '{}'.\\n\".format(ROOT.gDirectory.GetName()))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2761e32e",
   "metadata": {},
   "source": [
    "We can check to which directory a newly created histogram is attached."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "e2242432",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:16:47.900253Z",
     "iopub.status.busy": "2026-05-19T20:16:47.900119Z",
     "iopub.status.idle": "2026-05-19T20:16:48.025458Z",
     "shell.execute_reply": "2026-05-19T20:16:48.024686Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Histogram 'histo_1' is attached to: 'PyROOT'.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "histo_1 = ROOT.TH1F(\"histo_1\", \"histo_1\", 10, 0, 10)\n",
    "print(\n",
    "    \"Histogram '{}' is attached to: '{}'.\\n\".format(\n",
    "        histo_1.GetName(), \"Nothing\" if not histo_1.GetDirectory() else histo_1.GetDirectory().GetName()\n",
    "    )\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dc8b65da",
   "metadata": {},
   "source": [
    "For quick saving and forgetting of objects into ROOT files, it is possible to\n",
    "open a TFile as a Python context manager. In the context, objects can be\n",
    "created, modified and finally written to the file. At the end of the context,\n",
    "the file will be automatically closed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "d26135fd",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:16:48.026917Z",
     "iopub.status.busy": "2026-05-19T20:16:48.026795Z",
     "iopub.status.idle": "2026-05-19T20:16:48.172704Z",
     "shell.execute_reply": "2026-05-19T20:16:48.171997Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Current directory: '/github/home/ROOT-CI/build/tutorials/io/tfile_1.root'.\n",
      "\n",
      "Histogram 'histo_2' is attached to: '/github/home/ROOT-CI/build/tutorials/io/tfile_1.root'.\n",
      "\n",
      "After setting the directory, histogram 'histo_2' is attached to: '/github/home/ROOT-CI/build/tutorials/io/tfile_1.root'.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "path = str(gROOT.GetTutorialDir()) + '/io/'\n",
    "filename = path+\"tfile_1.root\"\n",
    "with TFile.Open(filename, \"recreate\") as f:\n",
    "    histo_2 = ROOT.TH1F(\"histo_2\", \"histo_2\", 10, 0, 10)\n",
    "    # Inside the context, the current directory is the open file\n",
    "    print(\"Current directory: '{}'.\\n\".format(ROOT.gDirectory.GetName()))\n",
    "    # In ROOT 6, the created histogram is automatically attached to the file\n",
    "    print(\n",
    "        \"Histogram '{}' is attached to: '{}'.\\n\".format(\n",
    "            histo_2.GetName(), histo_2.GetDirectory().GetName() if histo_2.GetDirectory() else \"Nothing\"\n",
    "        )\n",
    "    )\n",
    "    # When auto registration is off, this can be done explicitly:\n",
    "    histo_2.SetDirectory(f)\n",
    "    print(\n",
    "        \"After setting the directory, histogram '{}' is attached to: '{}'.\\n\".format(\n",
    "            histo_2.GetName(), histo_2.GetDirectory().GetName()\n",
    "        )\n",
    "    )\n",
    "    # Before exiting the context, objects can be written to the file\n",
    "    f.WriteObject(histo_2, \"my_histogram\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c89bcf7b",
   "metadata": {},
   "source": [
    "When the TFile.Close method is called, the current directory is automatically\n",
    "set again to ROOT.gROOT. Objects that were attached to the file inside the\n",
    "context are automatically deleted, so they can't be accessed anymore after\n",
    "the file is closed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "8c6595e1",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:16:48.174696Z",
     "iopub.status.busy": "2026-05-19T20:16:48.174554Z",
     "iopub.status.idle": "2026-05-19T20:16:48.277711Z",
     "shell.execute_reply": "2026-05-19T20:16:48.277144Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Status after the first TFile context manager:\n",
      " Current directory: 'PyROOT'.\n"
     ]
    }
   ],
   "source": [
    "print(\"Status after the first TFile context manager:\")\n",
    "print(\" Current directory: '{}'.\".format(ROOT.gDirectory.GetName()))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a8dc5e90",
   "metadata": {},
   "source": [
    "print(histo_2) # the object is deleted at this point, so don't use it anymore!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f9d6d89c",
   "metadata": {},
   "source": [
    "Also reading data from a TFile can be done in a context manager. Information\n",
    "stored in the objects of the file can be queried and used inside the context.\n",
    "After the context, the objects are not usable anymore because the file is\n",
    "automatically closed. This means you should use this pattern as a quick way\n",
    "to get information or modify objects from a certain file, without needing to\n",
    "keep the histograms alive afterwards."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "34911443",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:16:48.279534Z",
     "iopub.status.busy": "2026-05-19T20:16:48.279379Z",
     "iopub.status.idle": "2026-05-19T20:16:48.398032Z",
     "shell.execute_reply": "2026-05-19T20:16:48.397442Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Retrieved 'histo_2' histogram from file '/github/home/ROOT-CI/build/tutorials/io/tfile_1.root'.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "with TFile.Open(filename, \"read\") as f:\n",
    "    # Retrieve histogram using the name given to f.WriteObject in the previous\n",
    "    # with statement\n",
    "    histo_2_fromfile = f[\"my_histogram\"]\n",
    "    print(\"Retrieved '{}' histogram from file '{}'.\\n\".format(histo_2_fromfile.GetName(), f.GetName()))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1ed6190e",
   "metadata": {},
   "source": [
    "Cleanup the file created for this tutorial"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "43fb48d1",
   "metadata": {
    "collapsed": false,
    "execution": {
     "iopub.execute_input": "2026-05-19T20:16:48.399593Z",
     "iopub.status.busy": "2026-05-19T20:16:48.399471Z",
     "iopub.status.idle": "2026-05-19T20:16:48.502725Z",
     "shell.execute_reply": "2026-05-19T20:16:48.502263Z"
    }
   },
   "outputs": [],
   "source": [
    "os.remove(filename)"
   ]
  }
 ],
 "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
}
