ROOT version 6.26/00 was released on March 03, 2022.
For more information, see:
The following people have contributed to this new version:
Sitong An, CERN/SFT,
Simone Azeglio, CERN/SFT,
Rahul Balasubramanian, NIKHEF/ATLAS,
Bertrand Bellenot, CERN/SFT,
Josh Bendavid, CERN/CMS,
Jakob Blomer, CERN/SFT,
Patrick Bos, Netherlands eScience Center,
Rene Brun, CERN/SFT,
Carsten D. Burgard, DESY/ATLAS,
Will Buttinger, STFC/ATLAS,
Philippe Canal, FNAL,
Olivier Couet, CERN/SFT,
Mattias Ellert, Uppsala University,
Gerri Ganis, CERN/SFT,
Andrei Gheata, CERN/SFT,
Enrico Guiraud, CERN/SFT,
Stephan Hageboeck, CERN/IT,
Jonas Hahnfeld, CERN/SFT,
Ahmat Hamdan, GSOC,
Fernando Hueso-González, University of Valencia,
Ivan Kabadzhov, CERN/SFT,
Shamrock Lee (@ShamrockLee),
Sergey Linev, GSI,
Javier Lopez-Gomez, CERN/SFT,
Pere Mato, CERN/SFT,
Emmanouil Michalainas, CERN/SFT,
Lorenzo Moneta, CERN/SFT,
Nicolas Morange, CNRS/IJCLab,
Axel Naumann, CERN/SFT,
Vincenzo Eduardo Padulano, CERN/SFT and UPV,
Max Orok, U Ottawa,
Alexander Penev, University of Plovdiv,
Danilo Piparo, CERN/SFT,
Fons Rademakers, CERN/SFT,
Jonas Rembser, CERN/SFT,
Enric Tejedor Saavedra, CERN/SFT,
Aaradhya Saxena, GSOC,
Oksana Shadura, UNL/CMS,
Sanjiban Sengupta, GSOC,
Harshal Shende, GSOC,
Federico Sossai, CERN/SFT,
Matevz Tadel, UCSD/CMS,
Vassil Vassilev, Princeton/CMS,
Wouter Verkerke, NIKHEF/ATLAS,
Zef Wolffs, NIKHEF/ATLAS,
Stefan Wunsch, CERN/SFT
The “Virtual MonteCarlo” facility VMC (montecarlo/vmc
)
has been removed from ROOT. The development of this package has moved to
a separate project. ROOT’s
copy of VMC was deprecated since v6.18. The previously deprecated
packages memstat, memcheck have been removed. Please use for instance
valgrind
or memory sanitizers instead. ROOT’s “alien”
package has been deprecated and will be removed in 6.28. Please contact
ALICE software support if you still rely on it.
TTree.AsMatrix
has been removed, after being deprecated
in 6.24. Instead, please use RDataFrame.AsNumpy
from now on
as a way to read and process data in ROOT files and store it in NumPy
arrays (a tutorial can be found here).
TTreeProcessorMT::SetMaxTasksPerFilePerWorker
has been
removed. TTreeProcessorMT::SetTasksPerWorkerHint
is a
superior alternative. TTree::GetEntry()
and
TTree::GetEvent()
no longer have 0 as the default value for
the first parameter entry
. We are not aware of correct uses
of this function without providing an entry number. If you have one,
please simply pass 0
from now on.
TBufferMerger
is now production ready and not experimental
anymore: ROOT::Experimental::TBufferMerger
is deprecated,
please use ROOT::TBufferMerger
instead.
RooFit container classes marked as deprecated with this release:
RooHashTable
, RooNameSet
,
RooSetPair
, and RooList
. These classes are
still available in this release, but will be removed in the next one.
Please migrate to STL container classes, such as
std::unordered_map
, std::set
, and
std::vector
. The
RooFit::FitOptions(const char*)
command to steer RooAbsPdf::fitTo()
with an option string in now deprecated and will be removed in ROOT
v6.28. Please migrate to the RooCmdArg-based fit configuration. The
former character flags map to RooFit command arguments as follows:
'h'
: RooFit::Hesse()'m'
: RooFit::Minos()'o'
: RooFit::Optimize(1)'r'
: RooFit::Save()'t'
: RooFit::Timer()'v'
: RooFit::Verbose()'0'
: RooFit::Strategy(0)Subsequently, the RooMinimizer::fit(const char*)
function and the RooMCStudy
constructor that takes an option string is deprecated as well.
As of v6.26, cling diagnostic messages can be redirected to the ROOT
error handler. Users may enable/disable this via
TCling::ReportDiagnosticsToErrorHandler()
, e.g.
[1] gInterpreter->ReportDiagnosticsToErrorHandler();
root [2] int f() { return; }
root <cling>: ROOT_prompt_2:1:11: non-void function 'f' should return a value [-Wreturn-type]
Error in int f() { return; }
^
More details at PR #8737.
Continuation of input lines using backslash \
is
supported in ROOT’s prompt, e.g.
root [0] std::cout \
root (cont'ed, cancel with .@) [1]<< "ROOT\n";
ROOT now interprets code with optimization (-O1
) by
default, with proper inlining optimization and alike. This accelerates
especially “modern” code (C++ stdlib, RDataFrame, etc) significantly.
According to our measurements the increased time for just-in-time
compiling code is reasonable given the runtime speed-up. Optimization
can be switched with .O 0
, .O 1
, etc; the
current optimization level is shown by .O
. The CPP macro
NDEBUG
is now set unconditionally for interpreted code.
Note that symbols that have been emitted with a given optimization level
will not get re-emitted once the optimization level changes.
Unless ROOT is used with an interactive prompt
(root [0]
), ROOT does not inject the pointer checks
anymore, accelerating code execution at the cost of not diagnosing the
dereferencing of nullptr
or uninitialized pointers.
Several internal optimizations of cling reduce the amount of symbols cling emits, and improve the just-in-time compilation time.
TDirectory::WriteObject
now always saves the object’s
title to the file if it is derived from TObject
(PR #8394).rootls
now follows the same logic of
TFile::ls()
to print the key cycle number and its tag when
listing contents of a file with the -l
option (PR #7878):$: rootls -l https://root.cern/files/ttree_read_imt.root
TTree Mar 13 17:17 2019 TreeIMT;2 "TTree for IMT test" [current cycle]
TTree Mar 13 17:17 2019 TreeIMT;1 "TTree for IMT test" [backup cycle]
root
will now error on receiving unrecognized options,
similarly to other command line tools (PR #8868):$: root --random -z --nonexistingoption
root: unrecognized option '--random'
root: unrecognized option '-z'
root: unrecognized option '--nonexistingoption'
Try 'root --help' for more information.
TTreeReader::GetEntryStatus
now always reports
kEntryBeyondEnd
after an event loop correctly completes. In
previous versions, it could sometime return kEntryNotFound
even for well-behaved event loops.TEntryList::AddSubList
to specifically add a
sub-list to the main list of entries. Consequently, add also a new
option "sync"
in TChain::SetEntryList
to
connect the sub-trees of the chain to the sub-lists of the entry list in
lockstep (PR #8660).TEntryList::EnterRange
to add all entries in a
certain range [start, end)
to the entry list (PR #8740).ROOT’s experimental successor of TTree has been upgraded to the version 1 of the binary format specification. Compared to the v0 format, the header is ~40% smaller and the footer ~100% smaller (after zstd compression). More details in PR #8897. RNTuple is still experimental and is scheduled to become production grade in 2024. Thus, we appreciate feedback and suggestions for improvement.
If you have been trying RNTuple for a while, these are the other important changes that you will notice:
RNTupleReader::OpenFriends()
function.RNTupleWriteOptions
now refer
to their target size in bytes (as opposed to the number of entries).
Defaults are 64 kB for the page size and 50 MB for the cluster size (PR
#8703).TClass
now
also includes members inherited from all the base classes (PR #8552).Redefine
to the RDataFrame
interface, which allows to overwrite the
value of an existing column.Describe
to the RDataFrame
interface, which allows to get useful
information, e.g. the columns and their types.DescribeDataset
to the RDataFrame
interface, which allows to get
information about the dataset (subset of the output of Describe()).DefinePerSample
,
a method which makes it possible to define columns based on the sample
and entry range being processed. It is also a useful way to register
callbacks that should only be called when the input dataset/TTree
changes.HistoND
action that fills a N-dimensional histogram.Book
now supports just-in-time compilation, i.e. it can
be called without passing the column types as template parameters (with
some performance penalty, as usual).RDataSource
implementations with which
collection sizes can be retrieved more efficiently than the full
collection, #var
can now be used as a short-hand notation
for column name R_rdf_sizeof_var
.RDataFrame
to RooFit datasets. See the “RooFit Libraries” section below for more
details, or see the
tutorial.Vary
method and the VariationsFor
helper
function. As a major feature with important performance and usability
benefits, we want to get this right: for now VariationsFor
is kept in the ROOT::RDF::Experimental
namespace to signal
that we might make slight changes to the programming model in the future
as we gather more user feedback. More information on working with
systematic variations with RDataFrame are available in the RDF
user guide.Alias
, it is now possible to register homonymous
aliases (alternative column names) in different branches of the
computation graph, in line with the behavior of Define
(until now, aliases were required to be unique in the whole computation
graph).Histo*D
methods now support the combination of
scalar values and vector-like weight values. For each entry, the
histogram is filled once for each weight, always with the same scalar
value.Histo*D
methods do not work on columns of type
std::string
anymore. They used to fill the histogram with
the integer value corresponding to each of the characters in the string.
Please use Fill
with a custom class to recover the old
behavior if that was what was desired.Filter
s or Define
s has been
greatly improved, see also this
talk for more detailsDisplay
has been significantly
improved.Fill
method now correctly supports user-defined
classes with arbitrary Fill
signatures (see #9428)The distributed RDataFrame module has been improved. Now it supports sending RDataFrame tasks to a Dask scheduler. Through Dask, RDataFrame can be also scaled to a cluster of machines managed through a batch system like HTCondor or Slurm. Here is an example:
import ROOT
from dask.distributed import Client
= ROOT.RDF.Experimental.Distributed.Dask.RDataFrame
RDataFrame
# In a Python script the Dask client needs to be initalized in a context
# Jupyter notebooks / Python session don't need this
if __name__ == "__main__":
= Client("SCHEDULER_ADDRESS")
client = RDataFrame("mytree","myfile.root", daskclient=client)
df # Proceed as usual
"x","someoperation").Histo1D("x") df.Define(
Other notable additions and improvements include:
RunGraphs
. This also allows sending both Spark and Dask
jobs at the same time through a single function call.DefinePerSample
HistoND
Redefine
npartitions
parameter to a
distributed RDataFrame constructor always takes precedence over the
value computed by default.Implement the SetStats
method for
TGraph
to turn ON or OFF the statistics box display for an
individual TGraph
.
Use INT_MAX in TH classes instead of an arbitrary big number.
Implement option AXIS
, to draw only axis, for
TH2Poly.
The logic to Paint fit parameters for TGraph was not following the one implemented for histograms. The v field described here was not working the same way. They are now implemented the same way.
Implement the option X+ and Y+ for reverse axis on TGraph.
TGLAxisPainter silently modified the histogram’s Z axis parameters.
Call automatically Deflate
at drawing time of
alphanumeric labels. It makes sense as nobody wants to see extra blank
labels.
The Confidence interval colors set by SetConfidenceIntervalColors (TRatioPlot) were inverted.
Add GetZaxis for THStack.
Fix Graph Errorbar Offsets for the new Marker Styles and thick markers.
When the palette width is bigger than the palette height, the palette is automatically drawn horizontally.
THStack::GetXaxis->SetRange did not auto-zoom Yaxis range.
The Paint method of THStack always redrew the histograms in the sub-pads defined by the THStack drawing option “pads”. Like the “pad dividing” the “histograms’ drawing” should be done only the first time the THStack is painted otherwise any additional graphics objects added in one of the pads (created by the “pads” option) will be removed.
Improve TRatioPlot axes drawing.
RVec
has been heavily re-engineered in order to add a
small buffer optimization and to streamline its internals. The change
should provide a small performance boost to applications that make heavy
use of RVec
s and should otherwise be user-transparent.
Please report any issues you should encounter.RVec
objects has been optimized. As a
side-effect, RVec
s can now be read back as
std::vector
s and vice-versa.ROOT::VecOps::Drop
, an operation that removes
RVec
elements at the specified indices.ROOT::RVecI
, ROOT::RVecD
,
ROOT::RVecF
, …, have been introduced as short-hands for
RVec<int>
, RVec<double>
,
RVec<float>
, …VecOps::StableArgsort
and
VecOps::StableSort
operationsBatchMode
RooFit’s BatchMode
has been around since
ROOT 6.20. It was further improved
in ROOT 6.24 to use vector extensions of modern CPUs without
recompiling ROOT, introducing the new RooBatchCompute
library as a backend that is compiled multiple times for different
instruction sets. With this release, RooBatchCompute
is
also compiled with the Nvidia CUDA compiler to support the computation
on GPUs if supported by the RooFit object. You can use the CUDA mode by
passing "cuda"
to the BatchMode()
command
argument:
.fitTo(data); // not using the batch mode
model.fitTo(data, RooFit::BatchMode(true)); // using the BatchMode on CPU (RooFit::BatchMode("cpu") is equivalent)
model.fitTo(data, RooFit::BatchMode("cuda")); // using the new CUDA backend model
The RooBatchCompute
backend now also supports ROOT’s
implicit multithreading (similar to RDataFrame), which can be enabled as
follows:
::EnableImplicitMT(nThreads); ROOT
For more information, please have a look at this contribution to the ACAT 2021 conference or consult the RooBatchComupte README. The README also describes how to enable BatchMode support for your own PDFs.
This release features two new optional RooFit libraries:
RooFit::MultiProcess
and
RooFit::TestStatistics
. To activate both, build with
-Droofit_multiprocess=ON
.
The RooFit::TestStatistics
namespace contains a major
refactoring of the
RooAbsTestStatistic
-RooAbsOptTestStatistic
-RooNLLVar
inheritance tree into:
The main selling point of using RooFit::TestStatistics
from a performance point of view is the implementation of the
RooFit::MultiProcess
based
LikelihoodGradientJob
calculator class. To use it to
perform a “migrad” fit (using Minuit2), one should create a
RooMinimizer
using a new constructor with a
RooAbsL
likelihood parameter as follows:
using RooFit::TestStatistics::RooAbsL;
using RooFit::TestStatistics::buildLikelihood;
* pdf = ...; // build a pdf
RooAbsPdf* data = ...; // get some data
RooAbsData
std::shared_ptr<RooAbsL> likelihood = buildLikelihood(pdf, data, [OPTIONAL ARGUMENTS]);
(likelihood);
RooMinimizer m.migrad(); m
The RooMinimizer
object behaves as usual, except that
behind the scenes it will now calculate each partial derivative on a
separate process, ideally running on a separate CPU core. This can be
used to speed up fits with many parameters (at least as many as there
are cores to parallelize over), since every parameter corresponds to a
partial derivative. The resulting fit parameters will be identical to
those obtained with the non-parallelized gradients minimizer in most
cases (see the usage notes linked below for exceptions).
In upcoming releases, further developments are planned:
RooAbsPdf::fitTo
interface around these new
classesRooNLLVar
functionality, e.g. ranges are not yet supported.For more details, consult the usage notes in the TestStatistics README.md. For benchmarking results on the prototype version of the parallelized gradient calculator, see the corresponding CHEP19 proceedings paper.
Various new pythonizations are introduced to streamline your RooFit code in Python.
For a complete list of all pythonized classes and functions, please see the RooFit pythonizations page in the reference guide. All RooFit Python tutorials have been updated to profit from all available pythonizations.
Some notable highlights are listed in the following.
All functions that take RooFit command arguments as parameters now accept equivalent Python keyword arguments, for example simplifying calls to RooAbsPdf::fitTo() such as:
"left,right"), ROOT.RooFit.Save()) model.fitTo(data, ROOT.RooFit.Range(
which becomes:
="left,right", Save=True) model.fitTo(data, Range
Many functions that take an enum as a parameter now accept also a string with the enum label.
Take for example this expression:
data.plotOn(frame, ROOT.RooFit.DataError(ROOT.RooAbsData.SumW2)
Combining the enum pythonization with the keyword argument pythonization explained before, this becomes:
="SumW2") data.plotOn(frame, DataError
This pythonization is also useful for your calls to RooFit::LineColor() or RooFit::LineStyle, to give some more common examples.
You can now benefit from implicit conversion from Python lists to RooArgLists, and from Python sets to RooArgSets.
For example, you can call RooAbsPdf::generate() with a Python set to specify the observables:
10000) pdf.generate({x, y, cut},
Or, you can create a RooPolynomial from a Python list of coefficients:
"p", "p", x, [0.01, -0.01, 0.0004]) ROOT.RooPolynomial(
Note that here we benefit from another new feature: the implicit call to RooFit::RooConst() when passing raw numbers to the RooFit collection constructors.
Some RooFit functions take STL map-like types such as
std::map
as parameters, for example the RooCategory
constructor. In the past, you had to create the correct C++ class in
Python, but now you can usually pass a Python dictionary instead. For
example, a RooCategory can be created like this:
= ROOT.RooCategory("sample", "sample", {"Sample1": 1, "Sample2": 2, "Sample3": 3}) sample
In Python, you can now get objects stored in a RooWorkspace with the item retrieval operator, and the return value is also always downcasted to the correct type. That means in Python you don’t have to use RooWorkspace::var() to access variables or RooWorkspace::pdf() to access pdfs, but you can always get any object using square brackets. For example:
# w is a RooWorkspace instance that contains the variables `x`, `y`, and `z` for which we want to generate toy data:
"x"], w["y"], w["z"]}, 1000) model.generate({w[
New member functions of RooFit classes were introduced exclusively to PyROOT for better interoperability between RooFit and Numpy and Pandas:
RooDataSet.from_numpy
: Import a RooDataSet from a
dictionary of numpy arrays (static method)RooDataSet.to_numpy
: Export a RooDataSet to a
dictionary of numpy arraysRooDataSet.from_pandas
: Import a RooDataSet from a
Pandas dataframe (static method)RooDataSet.to_pandas
: Export a RooDataSet to a Pandas
dataframeRooDataHist.from_numpy
: Import a RooDataHist from numpy
arrays with histogram counts and bin edges (static method)RooDataHist.to_numpy
: Export a RooDataHist to numpy
arrays with histogram counts and bin edgesRooRealVar.bins
: Get bin boundaries for a
RooRealVar
as a NumPy arrayFor more details, consult the tutorial rf409_NumPyPandasToRooFit.py.
The RooLagrangianMorphFunc class is a new RooFit class for modeling a continuous distribution of an observable as a function of the parameters of an effective field theory given the distribution sampled at some points in the parameter space. Two new classes to help to provide this functionality:
For example usage of the RooLagrangianMorphFunc class, please consult the tutorials for a single parameter case (rf711_lagrangianmorph.C / .py) and for a multi-parameter case (rf712_lagrangianmorphfit.C / .py).
A RooLagrangianMorphFunc
can also be created with the
RooWorkspace::factory
interface, showcased in rf512_wsfactory_oper.C
/ .py.
RooWorkspace
to and from JSON and YMLThe new component RooFitHS3
implements serialization and
deserialization of RooWorkspace
objects to and from JSON
and YML. The main class providing this functionality is RooJSONFactoryWSTool.
For now, this functionality is not feature complete with respect to all
available functions and pdfs available in RooFit
, but
provides an interface that is easily extensible by users, which is
documented in the corresponding README.
It is hoped that, though user contributions, a sufficiently
comprehensive library of serializers and deserializers will emerge over
time.
For more details, consult the tutorial rf515_hfJSON.
RooFit now contains two RDataFrame action helpers,
RooDataSetHelper
and RooDataHistHelper
, which
allow for creating RooFit datasets by booking an action:
("x", "x", -5., 5.);
RooRealVar x("y", "y", -50., 50.);
RooRealVar yauto myDataSet = rdataframe.Book<double, double>(
{"dataset", // Name (directly forwarded to RooDataSet::RooDataSet())
RooDataSetHelper"Title of dataset", // Title ( ~ '' ~ )
(x, y) }, // Variables to create in dataset
RooArgSet{"x", "y"} // Column names from RDataFrame
);
For more details, consult the tutorial rf408_RDataFrameToRooFit.
RooFit groups model variables into observables and parameters, depending on if their values are stored in the dataset. For fits with parameter constraints, there is a third kind of variables, called global observables. These represent the results of auxiliary measurements that constrain the nuisance parameters. In the RooFit implementation, a likelihood is generally the sum of two terms:
RooNLLVar
)RooConstraintSum
)Before this release, the global observable values were always taken
from the model/pdf. With this release, a mechanism is added to store a
snapshot of global observables in any RooDataSet
or
RooDataHist
. For toy studies where the global observables
assume a different values for each toy, the bookkeeping of the set of
global observables and in particular their values is much easier with
this change.
Usage example for a model with global observables g1
and
g2
:
auto data = model.generate(x, 1000); // data has only the single observables x
->setGlobalObservables(g1, g2); // now, data also stores a snapshot of g1 and g2
data
// If you fit the model to the data, the global observables and their values
// are taken from the dataset:
.fitTo(*data);
model
// You can still define the set of global observables yourself, but the values
// will be takes from the dataset if available:
.fitTo(*data, GlobalObservables(g1, g2));
model
// To force `fitTo` to take the global observable values from the model even
// though they are in the dataset, you can use the new `GlobalObservablesSource`
// command argument:
.fitTo(*data, GlobalObservables(g1, g2), GlobalObservablesSource("model"));
model// The only other allowed value for `GlobalObservablesSource` is "data", which
// corresponds to the new default behavior explained above.
In case you create a RooFit dataset directly by calling its
constructor, you can also pass the global observables in a command
argument instead of calling setGlobalObservables()
later:
{"dataset", "dataset", x, RooFit::GlobalObservables(g1, g2)}; RooDataSet data
To access the set of global observables stored in a
RooAbsData
, call
RooAbsData::getGlobalObservables()
. It returns a
nullptr
if no global observable snapshots are stored in the
dataset.
For more information of global observables and how to attach them to the toy datasets, please take a look at the new rf613_global_observables.C / .py tutorial.
RooAbsPdf::fitTo
behaviour for multi-range fitsThe RooAbsPdf::fitTo
and
RooAbsPdf::createNLL
functions accept a command argument to
specify the fit range. One can also fit in multiple ranges
simultaneously. The definition of such multi-range likelihoods for
non-extended fits changes in this release. Previously, the individual
likelihoods were normalized separately in each range, which meant that
the relative number of events in each sub-range was not used to estimate
the PDF parameters. From now on, the likelihoods are normalized by the
sum of integrals in each range. This implies that the likelihood takes
into account all inter-range and intra-range information.
RooMinuit
classThe RooMinuit
class was the old interface between RooFit
and minuit. With ROOT version 5.24, the more general
RooMinimizer
adapter was introduced, which became the
default with ROOT 6.08.
Before 6.26, it was possible to still use the RooMinuit
by passing the Minimizer("OldMinuit", "minimizer")
command
argument to RooAbsPdf::fitTo()
. This option is now
removed.
RooAbsArg
class versionThe class version of RooAbsArg
was incremented from 7 to
8 in this release. In some circumstances, this can cause warnings in
TStreamerInfo
for classes inheriting from
RooAbsArg
when reading older RooFit models from a file.
These warnings are harmless and can be avoided by incrementing also the
class version of the inheriting class.
RooCmdArg
s from
stringsThe implicit RooCmdArg
constructor from const char*
was removed to avoid the
accidental construction of meaningless RooCmdArgs that only have a name
but no payload. This causes new compiler errors in your code if you pass
a string instead of a RooCmdArg to various RooFit functions, such as RooAbsPdf::fitTo().
If this happens, please consult the documentation of fitTo()
to check which of the free functions in
the RooFit
namespace you need to use to achieve the
desired configuration.
Example of an error that is now caught at compile time: confusing the RooAbsPdf::fitTo() function signature with the one of TH1::Fit() and passing the fit range name as a string literal:
.fitTo(*data, "r"); // ERROR!
pdf// Will not compile anymore, as `"r"` is not a recognized command and will be ignored!
// Instead, to restrict to a range called "r", use:
.fitTo(*data, RooFit::Range("r")); pdf
ROOT/TMVA SOFIE (“System for Optimized Fast Inference code Emit”) is a new package introduced in this release that generates C++ functions easily invokable for the fast inference of trained neural network models. It takes ONNX model files as inputs and produces C++ header files that can be included and utilized in a “plug-and-go” style. This is a new development and it is currently still in experimental stage.
From ROOT command line, or in a ROOT macro you can use this code for parsing a model in ONNX file format and generate C++ code that can be used to evaluate the model:
using namespace TMVA::Experimental;
SOFIE::RModelParser_ONNX parser;
SOFIE::RModel model = parser.Parse(“./example_model.onnx”);
model.Generate();
model.OutputGenerated(“./example_output.hxx”);
And an C++ header file will be generated. In addition also a text
file, example_output.dat
will be also generated. This file
will contain the model weight values that will be used to initialize the
model. A full example for parsing an ONNX input file is given by the
tutorial TMVA_SOFIE_ONNX.C
.
To use the generated inference code, you need to create a
Session
class and call the function
Session::inder(float *)
:
#include "example_output.hxx"
float input[INPUT_SIZE] = {.....}; // input data
TMVA_SOFIE_example_model::Session s("example_output.dat");
std::vector<float> out = s.infer(input);
For using the ONNX parser you need to build ROOT with the configure
option tmva-sofie=ON
, which will be enabled when a Google
Protocol Buffer library (protobuf
, see
https://developers.google.com/protocol-buffers) is found in your
system.
If you don’t have protobuf
and you don’t want to install
you can still use SOFIE, although with some more limited operator
support parsing directly Keras .h5
input files or PyTorch
.pt
files. In tis case you can convert directly the model
to a RModel
representation which can be used as above to
generate the header and the weight file.
For parsing a Keras input file you need to do:
SOFIE::RModel model = SOFIE::PyKeras::Parse("KerasModel.h5");
See the tutorial TMVA_SOFIE_Keras.C
.
For parsing a PyTorch input file :
SOFIE::RModel model = SOFIE::PyTorch::Parse("PyTorchModel.pt",inputShapes);
where inputShapes
is a
std::vector<std::vector<size_t>>
defining the
inputs shape tensors. This information is required by PyTorch since it
is not stored in the model. A full example for parsing a PyTorch file is
in the TMVA_SOFIE_PyTorch.C
tutorial.
For using the Keras and/or the PyTorch parser you need to have
installed Keras and/or PyTorch in your Python system and in addition
build root with the support for pymva
, obtained when
configuring with -Dtmva-pymva=On
.
For using the Keras and/or the PyTorch parser you need to have
installed Keras and/or PyTorch in your Python system and in addition
build root with the support for pymva
, obtained when
configuring with -Dtmva-pymva=On
.
Note that the created SOFIE::RModel
class after parsing
can be stored also in a ROOT file, using standard ROOT I/O
functionality:
SOFIE::RModel model = SOFIE::PyKeras::Parse("KerasModel.h5");
TFile file("model.root","NEW");
model.Write();
file.Close();
Implement the option X+
and Y+
for
reverse axis on TGraph.
Offsets for axis titles with absolute-sized fonts (size%10 == 3) are now relative only to the font size (i.e. no longer relative to pad dimensions).
In TPaletteAxis
when the palette width is bigger
than the palette height, the palette in automatically drawn
horizontally.
The .tex
file produced when saving canvas as
.tex
, needed to be included in an existing LateX document
to be visualized. The new Standalone
option allows to
generate a .tex
file which can be directly processed by
LateX (for example with the pdflatex
command) in order to
visualise it. This is done via the command:
canvas->Print(".tex", "Standalone");
The generated .tex
file has the form:
\usepackage{tikz}
\usetikzlibrary{patterns,plotmarks}
\begin{document}
<----- here the graphics output
\end{document}
Implement ChangeLabel
in case
SetMoreLogLabels
is set. Implement it also for alphanumeric
labels.
Some extra lines were drawn when histograms have negative content.
TMathText did not display with high value coordinates.
When a TCanvas contains TGraph with a huge number of points, the auto-placement of TLegend took ages. It may even look like an infinite loop.
Fix title offsetting when using absolute-size fonts and multiple pads.
The function TLatex::DrawLatex() only copied the Text-Attributes, but not the Line-Attributes to the newly created TLatex-Object.
SaveAs png failed in batch mode with two canvases, one divided.
The text size computed in TLatex::FirstParse was not correct in case the text precision was 3.
Return pointer to the ABC object in DrawABC methods. This was not uniform.
On Mac, with Cocoa, the pattern selector did not work anymore and the fit panel range did not work.
Fix in Cocoa. XSGui crashed on Mac M1.
--web=server
mode, which only printout window
URLs instead of starting real web browser. Dedicated for the case when
ROOT should be running as server application, providing different
RWebWindow instances for connection.@pythonization
is now provided to
inject extra behaviour in user C++ classes that are used from Python.
The aim here is to make C++ classes more “pythonic” or easier to use
from Python. The way it works is the following: the user defines a
function - the pythonizor - that is decorated with
@pythonization
; the decorator arguments specify the target
C++ class or classes, and the pythonizor is responsible for injecting
the new behaviour if those classes are actually used from the
application. For a more complete description of the
@pythonization
decorator, please refer to this entry
of the ROOT manual and this tutorial.ROOT
Python module is now properly serializable so
that it is automatically available in the Python environment if a
function or ROOT object needs to be serialized. See issue #6764 for a
concrete usecase.The tutorial games.C was not working properly
Improve tutorial ErrorIntegral.C
Schrödinger’s Hydrogen Atom example.
Tutorial demonstrating how the changing of the range can zoom into the histogram.
Tutorial demonstrating how a Histogram can be read from a ROOT File.
histMax.C: a tutorial demoing how the hist->GetMaximumBin() can be used.
Images for ROOT7 tutorials can be generated, in json format,
using the directive using \macro_image (json)
in the macro
header.
Clarify THStack drawing options.
Add missing documentation to TH1 functions.
Restructure the the math reference guide.
Make the web gui documentation visible in the reference guide
Make clear THtml is legacy code. Add deprecated flag on PROOF and TGeoTrack.
Improve many classes documentation: TContext, TTreePlayer, THistPainter, TGraph, TSelector, integrator, GUI, TH1, TH2, TH3, TColor classes …
Make the TFile layout doc visible in Reference Guide.
Update the external links of the reference guide main page
Reformat TMVA mathcore Unuran Roostats documentation .
For users building from source the latest-stable
branch
and passing -Droottest=ON
to the CMake command line, the
corresponding revision of roottest pointed to by
latest-stable
will be downloaded as required.
ROOT now requires CMake version 3.16 or later. ROOT cannot be built with C++11 anymore; the supported standards are currently C++14 and C++17. ROOT’s experimental features (RNTuple, RHist, etc) now require C++17.
;
is expected after
int a,b
TPyMultiGenFunction
from
ROOT
runtime_cxxmodules=ON
CPyCppyy::CPPMethod::Destroy_
RPadUserAxisBase
RAxisAttr
root-config --has-feature
should complain if
feature
is not a ROOT featurecmake -Droottest=On
tests wrong ROOT build!root -memstat
should not be
available-Dtesting=ON
was
specifiedRPageSink
RPage{Sink,Source}
base classDisplay
gets confused by friend columns, prints them
twiceRBrowser
and similar commands in “server
mode”rootbench-benchJohnson
fills log with “use
fixCoefNormalization!”TIter &TIter::operator=(TIterator *it)
signature.root
extension
with IMT ontokenise()
function for splitting
strings to core/foundation
Redefine()
ing a Defined()
column causes
segmentation violationfAutoFlush == 0
TDirectory::RegisterGDirectory
is MT unsaferoot
command ignores unknown options - it should complain
instead\
RNTupleWriter::Recreate()
does not overwrite
data in DAOS containerclear
yields wrong resultsconst
-qualified members of a user-defined struct
do not worktmva/sofie/inc/TMVA/ROperator_Conv.hxx
-DNDEBUG
to the compilation flags
besides -O1
Describe
output does not display correctly in Jupyter
notebooksstd.vector['char']
is brokenTClonesArray
branchesRooAbsReal::getValues
is brokenPublished on April 12, 2022
Published on June 7, 2022
plotOn
issueTViewPubDataMembers
uses deprecated
std::iterator
RooSimultaneous
does not contain a pdf
for each value of the index categoryruntime_cxxmodules
fails to build with GCC12Published on July 28, 2022
REveBox.cxx
while building root 6.26.04root-config
fails if spaces are part of
ROOTSYS
pathTEntryList
RooDataSetHelper
doesn’t respect
RooRealVar
rangePreprocessFunction::PrintXML()
needs to
escape special characters to produce valid XMLRooAddPdf
in 6.26/04Published on Oct 18, 2022
Alias
and TTree
sub-branchesFloat16_t
branchTTreeReaderArray
does not support
Double32_t
TMetaUtils::ReSubstTemplateArg
with
gcc12 headersREAD_WITHOUT_GLOBALREGISTRATION
has no effect on remote
fileskNotDeleted
mechanism is broken on some
platformsTH1::Merge
does not extend axes properly for certain
histograms with labelsTHnSparse::Add()
does not preserve weightsdepsAreCond
in Conditional when
creating a RooProdPdf
Range
with
begin+strideDisplay
does not respect parameters if another operation is
booked before printingSetClusterPrefetch(true)
breaks BulkIO with more than one
basketPublished on November 16, 2022
TBrowser
does not show TGeo
volume namesTInterpreter::Calc
with no output stack in
seemingly random distributed rdf test executionPublished on November 28, 2023
This release also addresses a security issue. More details will follow.
Published on March 20, 2024
The latest Apple operating sytstem supported is Monterey (macOS version 12).
These changes will be part of a future 6.26/18.