ROOT Version 6.38 Release Notes

2025-11

Introduction

For more information, see:

http://root.cern

The following people have contributed to this new version:

Bertrand Bellenot, CERN/EP-SFT,
Jakob Blomer, CERN/EP-SFT,
Lukas Breitwieser, CERN/EP-SFT,
Philippe Canal, FNAL,
Olivier Couet, CERN/EP-SFT,
Marta Czurylo, CERN/EP-SFT,
Florine de Geus, CERN/EP-SFT and University of Twente,
Edward Finkelstein, UCI and SDSU,
Jonas Hahnfeld, CERN/EP-SFT and Goethe University Frankfurt,
Fernando Hueso Gonzalez, IFIC (CSIC-University of Valencia),
Stephan Hageboeck, CERN/EP-SFT,
Petr Jacka, Czech Technical University in Prague,
Aaron Jomy, CERN/EP-SFT,
Sergey Linev, GSI Darmstadt,
Lorenzo Moneta, CERN/EP-SFT,
Vincenzo Eduardo Padulano, CERN/EP-SFT,
Giacomo Parolini, CERN/EP-SFT,
Danilo Piparo, CERN/EP-SFT,
Jonas Rembser, CERN/EP-SFT,
Sanjiban Sengupta, CERN/EP-SFT and Manchester University,
Silia Taider, CERN/EP-SFT,
Florian Uhlig, GSI,
Devajith Valaparambil Sreeramaswamy, CERN/EP-SFT,
Vassil Vassilev, Princeton,
Sandro Wenzel, CERN/ALICE,

Deprecation and Removal

Build System

Core Libraries

export ROOT_LDSYSPATH=$(LD_DEBUG=libs LD_PRELOAD=DOESNOTEXIST ls /tmp/DOESNOTEXIST 2>&1 | grep -m 1 "system search path" | sed 's/.*=//g' | awk '//{print $1}')
export CLING_LDSYSPATH=ROOT_LDSYSPATH
export CLING_CPPSYSINCL=$(LC_ALL=C c++ -xc++ -E -v /dev/null 2>&1 | sed -n '/^.include/,${/^ \/.*++/{p}}' | tr '\n' ':' | tr ' ' ':')

This caching reduces sub-process creation during initialization and can be useful when multiple ROOT instances or binaries linked to ROOT are executed (less system-calls, cleaner debugging). * It is now possible to read a user configuration file (in jeargon, a “rootrc file”) at startup in a custom path instead of the one in the home directory, by specifying its full path with the ROOTENV_USER_PATH environment variable. * ROOT reacts to the environment variable ROOT_MAX_THREADS. This can be used to select the number of worker threads when implicit multithreading is enabled. It is supported since 2021, but better documentation was added in the context of the RDataFrame documentation. * ROOT now determines std::hardware_destructive_interference_size at configure time, and defines the macro R__HARDWARE_INTERFERENCE_SIZE in RConfigure.h. Not keeping it fixed could lead to ABI breakages when code is interpreted on a machine that is different from the machine where ROOT was compiled.

I/O

TTree

RNTuple

Math

-Dexperimental_adaptivecpp=ON -Dexperimental_genvectorx=ON

Minimizer interface

Minuit2

RooFit

Error out when setting out-of-range variable value instead of silent clipping

In previous versions, if you set the value of a variable with RooRealVar::setVal(), the value was silently clippend when it was outside the variable range. This silent mutation of data can be dangerous. With ROOT 6.38, an exception will be thrown instead. If you know what you are doing and want to restore the old clipping behavior, you can do so with RooRealVar::enableSilentClipping(), but this is not recommended.

Changed return type of RooAbsData::split()

The return type of RooAbsData::split() was changed. So far, it returned a TList*, which is changed to std::vector<std::unique_ptr<RooAbsData>> in this release. The reason for this breaking change was memory safety. The returned TList as well as the RooAbsData objects it contains had to be deleted by the caller, which is usually forgotten in user frameworks and even RooFit itself. The new return type enforces memory safety.

Furthermore, the RooAbsData::split() method is not virtual anymore, as it’s not meant the be overridden by inheriting classes.

The names of the datasets in the return object still correspond to the channel names from the category that was used to split the dataset. It is quite common to look up the data for a given channel from the data splits, which could previously done with TList::FindObject().

TList *splits{data->split(*category)};
std::string channelName = "channel_a";
RooAbsData* channelData = static_cast<RooAbsData*>(splits->FindObject(channelName.c_str()));
// ... do something with channelData ...
splits->Delete();
delete splits;

With the new return type, one has to use algorithms from the standard library to do the lookups:

std::vector<std::unique_ptr<RooAbsData>> splits{data->split(*category)};
std::string channelName = "channel_a";
auto found = std::find_if(splits.begin(), splits.end(), [&](auto const &item) {
  return nameIdx.first == item->GetName();
});
RooAbsData *dataForChan = found != splits.end() ? found->get() : nullptr;
// ... do something with channelData ...

If you want to keep using TList* return values, you can write a small adapter function as described in the documentation of RooAbsData::split().

RooCrystalBall alternative

RDataFrame

Snapshot

Distributed RDataFrame

Python Interface

ROOT dropped support for Python 3.8, meaning ROOT now requires at least Python 3.9.

Deprecation of the TObject equality pythonization

TObject.__eq__ is deprecated and will be removed in ROOT 6.40.

It forwards to TObject::Equals(), which uses pointer comparison if not overridden in derived classes. This may be confusing, because people expect value comparisons. Use Pythons is for pointer comparison, or request an implementation of operator== on the C++ side if you need value-based equality checks for a given class.

Deprecate the attribute pythonization of TDirectory in favor of item-getting syntax

Since ROOT 6.32, the recommended way to get objects from a TFile or any TDirectory in general is via __getitem__:

tree = my_file["my_tree"] # instead of my_file.my_tree, which gave you a deprecation warning since ROOT 6.32

The deprecated pythonization with the __getattr__ syntax is now removed. It was originally schedeuled for removal in 6.34 according to the 6.32 release notes, but since it was still used quite a bit, the deprecation period was extended.

Enhancements to the RDataFrame Pythonic API

Support for C++ free functions in .Define and .Filter

Extended Numba support for C++ containers and ROOT classes

Further Unified Histogram Interface (UHI) integration and histogram pythonizations

ROOT executable

Command-line utilities

JavaScript ROOT

Experimental features

RFile

Optimization of ROOT header files

More unused includes were removed from ROOT header files. For instance, #include "TMathBase.h" was removed from TString.h. This change may cause errors during compilation of ROOT-based code. To fix it, provide missing the includes where they are really required. This improves compile times and reduces code inter-dependency; see https://github.com/include-what-you-use/include-what-you-use/blob/master/docs/WhyIWYU.md for a good overview of the motivation.

Versions of built-in packages

Items addressed for this release

More than 240 items were addressed for this release: