KAHIBARO
Discord Login Register

12.2 Creating ROOT Files

Table of Contents

TFile

To create a ROOT file you always start with the class TFile. A TFile object represents an open .root file that can contain histograms, graphs, functions, TTrees, and even subdirectories. Once you understand how to create and control a TFile, saving and organizing analysis results becomes straightforward.

At the simplest level you create a file by constructing a TFile object with a filename and a mode string. The filename should usually end with .root, and can be either a relative path such as "results.root" or an absolute path such as "/home/user/analysis/results.root".

A minimal example in an interactive ROOT session looks like this:

cpp
TFile f("myoutput.root", "RECREATE");

When this line runs, ROOT opens (or creates) the file on disk and associates it with the variable f. As long as f is alive and the file is open, you can write objects into it using methods such as Write() on the objects you create, or f.Write() to write everything that is attached to the current file or its directories.

You can also create a file using the static function TFile::Open, which returns a pointer:

cpp
TFile *f = TFile::Open("myoutput.root", "RECREATE");

This form is common in macros and in larger analysis code, because you can later check whether the pointer is valid and whether the file was opened correctly.

A useful pattern when you want to immediately write something after creating the file is:

cpp
TFile *f = TFile::Open("histos.root", "RECREATE");
// create objects here (for example histograms) and write them
h1->Write();
h2->Write();
// close the file when done
f->Close();

Closing the file is important. When you call Close(), ROOT flushes all buffers and ensures the file is complete and readable later. If you forget to close a file in a macro, it will usually be closed automatically when the process exits, but it is good practice to close explicitly, especially when you write many files or when your program continues running after writing.

You can check if a TFile is open and good by using methods such as:

cpp
if (!f || f->IsZombie()) {
   // handle error: file could not be opened or created
}

This kind of check is useful if a filename may not be writable, or if you open remote files.

For writing analysis output it is common to create the file once at the beginning of your macro, then create all histograms and other objects, fill them during your event loop, and finally write and close the file at the end. The details of writing objects and the role of TDirectory are covered in later sections of this ROOT Files chapter.

Always ensure that each output TFile is explicitly closed with Close() once all objects have been written, to avoid incomplete or corrupted ROOT files.

File modes

The second argument to the TFile constructor or to TFile::Open is the file mode string. This short code tells ROOT whether to create a new file, overwrite an existing one, or open a file only for reading. Using the correct mode is essential to protect your data and to control how analysis output is updated.

The most common modes are summarized in the table below:

Mode stringMeaningTypical use
"READ"Open an existing file for reading onlyInspecting or analyzing existing data files
"UPDATE"Open an existing file for reading and writing, create if neededAdd objects to an existing file, or update them
"RECREATE"Create a new file, overwrite any existing file of same nameFresh output for a new analysis run
"NEW"Create a new file, fail if the file already existsProtect existing results from being overwritten

A file opened in "READ" mode does not allow writing. If you try to call Write() on objects or on the file itself, nothing will be saved. Use this mode when you are absolutely sure you will not modify the file and you want to avoid accidental changes.

In contrast, "UPDATE" opens a file for both reading and writing. If the file does not exist yet, ROOT will create it. This mode is useful if you want to add new histograms or TTrees to an existing result file. Be aware that using "UPDATE" repeatedly can gradually grow the file size because updated objects may be stored as new versions. Managing versions and file size is a more advanced topic, but it is worth knowing that "UPDATE" favors flexibility over strict reproducibility of the original file contents.

The "RECREATE" mode is very common in analysis macros. When you use:

cpp
TFile f("results.root", "RECREATE");

ROOT will create results.root if it does not exist, or overwrite it completely if it does. Any previous contents are lost. This is convenient during development because you can rerun your macro multiple times and always get a clean, fresh output file.

The "NEW" mode is similar to "RECREATE", but safer. With:

cpp
TFile *f = TFile::Open("results.root", "NEW");

ROOT will create results.root only if it does not already exist. If the file is already present, TFile::Open will fail and typically return a null pointer or a zombie file. This mode is useful when you want to ensure that you never overwrite previous output, for example in a production analysis or when running large batch jobs where each run must keep its own results.

Internally, file modes also control how ROOT handles directories inside the file, and how objects with identical names are replaced or versioned. For absolute beginners, the key ideas are simple:

Use "READ" when you only want to inspect data, "RECREATE" for clean new output that can overwrite old files, "NEW" to protect existing results from being overwritten, and "UPDATE" when you intentionally want to add or modify content in an existing ROOT file.

Be deliberate about which mode you choose, since it determines whether your previous analysis results are preserved or replaced.

Views: 11

Comments

Please login to add a comment.

Don't have an account? Register now!