6.34 is a short term support cycle not meant to be used for data taking. It will be superseded by the 6.36 cycle, which is foreseen to start with 6.36.00 in the second quarter of 2025. Patch releases of the 6.36 cycle will be provided until June 30th 2025.
Introduction
The development ROOT version 6.34.00 is scheduled for release at the end of November 2024.
The following people have contributed to this new version:
Guilherme Amadio, CERN/IT,
Bertrand Bellenot, CERN/EP-SFT,
Jakob Blomer, CERN/EP-SFT,
Patrick Bos, Netherlands eScience Center,
Rene Brun,
Carsten Burgard, DESY
Will Buttinger, RAL,
Philippe Canal, FNAL,
Jolly Chen, CERN/EP-SFT,
Olivier Couet, CERN/EP-SFT,
Marta Czurylo, CERN/EP-SFT,
Monica Dessole, CERN/EP-SFT,
Adrian Duesselberg, TU Munchen,
Mattias Ellert, Uppsala University,
Gerri Ganis, CERN/EP-SFT,
Florine de Geus, CERN/University of Twente,
Andrei Gheata, CERN/EP-SFT,
Enrico Guiraud,
Stephan Hageboeck, CERN/EP-SFT,
Jonas Hahnfeld, CERN/Goethe University Frankfurt,
Fernando Hueso Gonzalez, University of Valencia,
Attila Krasznahorkay, CERN/EP-ADP-OS,
Wim Lavrijsen, LBL,
Aaron Jomy, CERN/EP-SFT,
Ida Kaspary, Imperial College,
Valerii Kholoimov, National University of Kyiv/IRIS-HEP,
Sergey Linev, GSI,
Javier Lopez-Gomez,
Pere Mato, CERN/EP-SFT,
Andrea Maria Ola Mejicanos, Berea College,
Alaettin Serhan Mete, Argonne,
Thomas Madlener, DESY,
Vedant Mehra, GSOC,
Lorenzo Moneta, CERN/EP-SFT,
Alja Mrak Tadel, UCSD/CMS,
Axel Naumann, CERN/EP-SFT,
Ianna Osborne, Princeton University,
Vincenzo Eduardo Padulano, CERN/EP-SFT,
Giacomo Parolini, CERN/EP-SFT,
Danilo Piparo, CERN/EP-SFT,
Kristupas Pranckietis, Vilnius University,
Fons Rademakers, CERN/IT,
Jonas Rembser, CERN/EP-SFT,
Andrea Rizzi, University of Pisa,
Andre Sailer, CERN/EP-SFT,
Nopphakorn Subsa-Ard, KMUTT,
Pavlo Svirin, National Technical University of Ukraine,
Robin Syring, Leibniz University Hannover, CERN/EP-SFT,
Maciej Szymanski, Argonne,
Christian Tacke, Darmstadt University,
Matevz Tadel, UCSD/CMS,
Alvaro Tolosa Delgado, CERN/RCS-PRJ-FC,
Devajith Valaparambil Sreeramaswamy, CERN/EP-SFT,
Peter Van Gemmeren, Argonne,
Vassil Vassilev, Princeton/CMS,
Wouter Verkerke, NIKHEF/ATLAS,
Stefan Wunsch
Removal and Deprecation
The following interfaces have been removed:
The RooAbsReal::plotSliceOn() function that was deprecated since at least ROOT 6 was removed. Use plotOn(frame,Slice(...)) instead.
Multiple overloads of internal Minuit 2 constructors and functions have been removed. If your code fails to compile, you can easily change to another overload that takes a MnUserParameterState, which is a change backwards compatible with older ROOT versions.
The following interfaces are deprecated and will be removed in future releases:
The RooTemplateProxy constructors that take a proxyOwnsArg parameter to manually pass ownership are deprecated and replaced by a new constructor that takes ownership via std::unique_ptr<T>. They will be removed in ROOT 6.36.
Several RooFit legacy functions are deprecated and will be removed in ROOT 6.36 (see section “RooFit libraries”)
The int ROOT::CompressionSettings(ROOT::ECompressionAlgorithm algorithm, int compressionLevel) function is deprecated and will be removed in ROOT 6.36. Please use int CompressionSettings(RCompressionSetting::EAlgorithm::EValues algorithm, int compressionLevel) instead.
The void R__zip(int cxlevel, int *srcsize, char *src, int *tgtsize, char *tgt, int *irep) function is deprecated and will be removed in ROOT 6.36. Please use void R__zipMultipleAlgorithm(int cxlevel, int *srcsize, char *src, int *tgtsize, char *tgt, int *irep, ROOT::RCompressionSetting::EAlgorithm::EValues algorithm) instead.
The Bool_t TGeoShape::AreOverlapping(const TGeoBBox *box1, const TGeoMatrix *mat1, const TGeoBBox *box2, const TGeoMatrix *mat2) function is deprecated and will be removed in ROOT 6.36.
The TPython::Eval() function is deprecated and scheduled for removal in ROOT 6.36.
Core Libraries
The Cling C++ interpreter now relies on LLVM version 18.
The rootcling invocation corresponding to a genreflex invocation can be obtained with the new genreflex command line argument --print-rootcling-invocation. This can be useful when migrating from genreflex to rootcling.
The rootcling utility now fully supports selection xml files and not only LinkDef files.
I/O Libraries
RNTuple Libraries
The first version of the RNTuple on-disk binary format is finalized. Future versions of ROOT will be able to read back RNTuple data written as of this release. Please note that this version breaks compatibility with experimental RNTuple data written with releases up to v6.34. Please also note that the RNTuple API is not yet moving out of ROOT::Experimental.
Support for low-precision on-disk floating point representation. This can be enabled through RField<float|double>::SetTruncated() (truncated mantissa) and RField<float|double>::SetQuantized() (scaled integer representation).
Link RNTuple self-description to the common ROOT streamer infrastructure. As a result, TFile::MakeProject() properly creates header files for classes used in RNTuple data.
First version of the new RNTupleProcessor class. The RNTupleProcessor will support iteration of composed RNTuple data sets (comparable to and improving upon TTree friends and chains). This release supports chained (vertically composed) RNTuples. Other types of concatenations will be added in subsequent releases.
Support for cluster staging in the RNTupleParallelWriter. Cluster staging enables users to enforce a certain logical cluster ordering in the presence of parallel cluster writing.
Support for Direct I/O for writing. This gives access to the peak performance of modern NVMe drives.
Support for a “streamer field” that can wrap classic ROOT I/O serialized data for RNTuple in cases where native RNTuple support is not possible (e.g., recursive data structures). Use of the streamer field can be enforced through the LinkDef option rntupleStreamerMode(true). This features is similar to the unsplit/level-0-split branch in TTree.
Naming rules have been established for the strings representing the name of an RNTuple and the name of a field. The allowed character set is restricted to Unicode characters encoded as UTF-8, with the following exceptions: control codes, full stop, space, backslash, slash. See a full description in the RNTuple specification. The naming rules are also enforced when creating a new RNTuple or field for writing.
Many fixes to RNTuple merging, both through hadd and when using the RNTupleMerger class directly. Most notable of these fixes is the proper handling of projected fields.
Many additional bug fixes and improvements.
TTree Libraries
TTreeReader can now detect whether there is a mismatched number of entries between the main trees and the friend tree and act accordingly in two distinct scenarios. In the first scenario, at least one of the friend trees is shorter than the main tree, i.e. it has less entries. When the reader is trying to load an entry from the main tree which is beyond the last entry of the shorter friend, this will result in an error and stop execution. In the second scenario, at least one friend is longer than the main tree, i.e. it has more entries. Once the reader arrives at the end of the main tree, it will issue a warning informing the user that there are still entries to be read from the longer friend.
TTreeReader can now detect whether a branch, which was previously expected to exist in the dataset, has disappeared due to e.g. a branch missing when switching to the next file in a chain of files.
TTreeReader can now detect whether an entry being read is incomplete due to one of the following scenarios:
When switching to a new tree in the chain, a branch that was expected to be found is not available.
When doing event matching with TTreeIndex, one or more of the friend trees did not match the index value for the current entry.
RDataFrame
The GetColumnNames function to retrieve the number of available column names in the RDataFrame object is now also usable from a node of a distributed computation graph. This makes the generation of said computation graph slightly less lazy than before. Notably, it used to be the case that a distributed computation graph could be defined with code that was not yet available on the user’s local application, but that would only become available in the distributed worker. Now a call such as df.Define("mycol", "return run_my_fun();") needs to be at least declarable to the interpreter also locally so that the column can be properly tracked.
The order of execution of operations within the same branch of the computation graph is now guaranteed to be top to bottom. For example, the following code: ~{.cpp} ROOT::RDataFrame df{1}; auto df1 = df.Define(“x”, []{ return 11; }); auto df2 = df1.Define(“y”, []{ return 22; }); auto graph = df2.Graph<int, int>(“x”,“y”);~ will first execute the operation Define of the column x, then the one of the column y, when filling the graph.
The DefinePerSample operation now works also in the case when a TTree is stored in a subdirectory of a TFile.
The memory usage of distributed RDataFrame was drastically reduced by better managing caches of the computation graph artifacts. Large applications which previously had issues with killed executors due to being out of memory now show a minimal memory footprint. See https://github.com/root-project/root/pull/16094#issuecomment-2252273470 for more details.
RDataFrame can now read TTree branches of type std::array on disk explicitly as std::array values in memory.
New parts of the API were added to allow dealing with missing data in a TTree-based dataset:
DefaultValueFor(colname, defaultval): lets the user provide one default value for the current entry of the input column, in case the value is missing.
FilterAvailable(colname): works in the same way as the traditional Filter operation, where the “expression” is “is the value available?”. If so, the entry is kept, if not, it is discarded.
FilterMissing(colname): works in the same way as the traditional Filter operation, where the “expression” is “is the value missing?”. If so, the entry is kept, if not, it is discarded. The tutorials df036_missingBranches and df037_TTreeEventMatching show example usage of the new functionalities.
The automatic conversion of std::vector to ROOT::RVec which happens in memory within a JIT-ted RDataFrame computation graph meant that the result of a Snapshot operation would implicitly change the type of the input branch. A new option available as the data member fVector2RVec of the RSnapshotOptions struct can be used to prevent RDataFrame from making this implicit conversion.
RDataFrame does not take a lock anymore to check reading of supported types when there is a mismatch, see https://github.com/root-project/root/pull/16528.
Complexity of lookups during internal checks for type matching has been made constant on average, see the discussions at https://github.com/root-project/root/pull/16559 and https://github.com/root-project/root/pull/16559.
Major improvements have been brought to the experimental feature that allows lazily loading ROOT data into batches for machine learning model training pipelines. For a full description, see the presentation at CHEP 2024 https://indico.cern.ch/event/1338689/contributions/6015940/.
Histogram Libraries
THStack:GetMinimum() was not correct in case of negative contents.
Upgrade TUnfold to version 17.9
The TUnfold package inside ROOT is upgraded from version 17.6 to version 17.9.
Math Libraries
Minuit2
Usage of std::span<const double>in the interface: To avoid forcing the user to do manual memory allocations via std::vector, the interfaces of Minuit 2 function adapter classes like ROOT::Minuit2::FCNBase or ROOT::Minuit2::FCNGradientBase were changed to accept std::span<const double> arguments instead of std::vector<double> const&. This should have minimal impact on users, since one should usual use Minuit 2 via the ROOT::Math::Minimizer interface, which is unchanged.
Initial error/covariance matrix values for Hessian matrix: Initial error/covariance matrix values can be passed for initializating the Hessian matrix to be used in minimization algorithms by attaching the covariance matrix to the ROOT::Minuit2::MnUserParameterState instance used for seeding via the method AddCovariance(const MnUserCovariance &);.
RooFit Libraries
Error handling in MultiProcess-enabled fits
The MultiProcess-based fitting stack now handles errors during fits. Error signaling in (legacy) RooFit happens through two mechanisms: logEvalError calls and RooNaNPacker-enhanced NaN doubles. Both are now implemented and working for MultiProcess-based fits as well. See this PR for more details. This enables the latest ATLAS Higgs combination fits to complete successfully, and also other fits that encounter NaN values or other expected errors.
Miscellaneous
Setting useHashMapForFind(true) is not supported for RooArgLists anymore, since hash-assisted finding by name hash can be ambiguous: a RooArgList is allowed to have different elements with the same name. If you want to do fast lookups by name, convert your RooArgList to a RooArgSet.
The function RooFit::bindFunction() now supports arbitrary many input variables when binding a Python function.
The ExportOnly() attribute of the RooStats::HistFactory::Measurement object is now switched on by default, and the associated getter and setter functions are deprecated. They will be removed in ROOT 6.36. If you want to fit the model as well instead of just exporting it to a RooWorkspace, please do so with your own code as demonstrated in the hf001 tutorial.
Initial error values can be used for initializating the Hessian matrix to be used in Minuit2 minimization algorithms by setting the RooMinimizer::Config option setInitialCovariance to true. These values correspond to the diagonal entries of the initial covariance matrix.
RooFit::MultiProcess-enabled fitting developer/advanced documentation – available through GitHub – was updated. It now contains the most up to date usage instructions for optimizing load balancing (and hence run speed) using this backend.
Deprecations
The RooStats::MarkovChain::GetAsDataSet and RooStats::MarkovChain::GetAsDataHist functions are deprecated and will be removed in ROOT 6.36. The same functionality can be implemented by calling RooAbsData::reduce on the Markov Chain’s RooDataSet* (obtained using MarkovChain::GetAsConstDataSet) and then obtaining its binned clone(for RooDataHist).
The following methods related to the RooAbsArg interface are deprecated and will be removed in ROOT 6.36. They should be replaced with the suitable alternatives interfaces:
RooAbsArg::getDependents(): use getObservables()
RooAbsArg::dependentOverlaps(): use observableOverlaps()
RooAbsArg::checkDependents(): use checkObservables()
RooAbsArg::recursiveCheckDependents(): use recursiveCheckObservables()
TMVA SOFIE
The support for new ONNX operators has been included in the SOFIE ONNX parser and in RModel in order to generate inference code for new types of models. The full list of currently supported operators is available here
The list of operators added for this release is the following: - Constant and ConstantOfShape - If - Range - ReduceSum - Split - Tile - TopK
In addition support in RModel has been added to generate the code with dynamic input shape parameter, such as the batch size. These input shape parameters can be specified at run time when evaluating the model. Since not all ONNX operators in SOFIE support yet dynamic input parameters, it is possible to initialize a parsed dynamic model with fixed values. For this, a new member function, RModel::Initialize(const std::map<std::string,size_t> & inputParams, bool verbose = false) has been added. The RModel class has been extended to support sub-graph (needed for operator If), dynamic tensors and constant tensors (for example those defined by the operator Constant).
Graphics Backends
Web-based TWebCanvas
Support “haxis” draw option for histograms, allows superposition of several histograms drawn on the same pad with horizontal ty axis. Add tutorials\webcanv\haxis.cxx macro demonstrating new feature.
Support “frame” draw option for several primitives like TBox, TLine, TLatex. This enforce clipping of such objects by frame border. Provide demo in tutorials\webcanv\inframe.cxx macro
Provide batch mode for image production with headless browser. In such mode data for several canvases collected together (in batch) and then N images are produced with single invocation of the web browser (chrome or firefox). For instance after TWebCanvas::BatchImageMode(100) next 99 calls to TCanvas::SaveAs(filename) method will not lead to image files creation. But with following call all 100 images will be produced together. Alternatively one can use TCanvas::SaveAll() static method which allows to create images for several canvases at once.
Support multi-page PDF file creation with web-based canvas using svg2pdf.js library. Both with native and web-baed graphics one can do now:
In TGraphErrorsTGraphAsymmErrors and TGraphBentErrors, the error bars were drawn inside the marker when the marker was bigger than the error bars. This produced a weird plot. This is now fixed.
When error-bars exceeded the y range limits the end of error bars were nevertheless displayed was not correcton the x-bottom and top axis. So it looked like the total error bar while it was indeed not.
Choosing an appropriate color scheme is essential for making results easy to understand and interpret. Factors like colorblindness and converting colors to grayscale for publications can impact accessibility. Furthermore, results should be aesthetically pleasing. The following three color schemes, recommended by M. Petroff in arXiv:2107.02270v2 and available on GitHub under the MIT License, meet these criteria.
Implement properly the TScatter palette attributes as requested here.
Add TStyle::SetLegendFillStyle
3D Graphics Libraries
REve
Update RenderCore rendering engine to version 1.6 with improved implementation of Signed Distance Field (SDF) fonts.
Implement REveText element to draw text with SDF fonts in screen or world coordinates. See the new example in tutorials/eve7/texts.C
Add initial version of REve overlays: a 2D area in screen coordinates that can draw text and frames in relative proportions; support position and scale editing on the client side.
Draw axis labels with SDF fonts in the mixed space-screen coordinate system.
Introduce REveGeoTopNode: a wrapper over a TGeoNode, possibly displaced with a global transformation stored in REveElement. It holds a pointer to TGeoManager and controls for steering of TGeoPainter (fVisOption, fVisLevel and fMaxVisNodes).
Integrate JSRoot hierarchical node browser in REve as REveGeoTable element. The demonstration of this feature is included in example tutorial/eve7/eveGeoBrowser.C
Geometry Libraries
The geometry package is now optional and activated by default in the CMake configuration. To disable it, use the -Dgeom=OFF CMake option.
Web-based GUIs
Adjust rootssh script to be usable on MacOS. Fixing problem to start more than one web widget on remote node.
Fix rootbrowse script to be able properly use it with all kinds of web widgets. Provide --web=<type> argument as for regular root executable.
Update openui5 library to version 1.128.0. Requires use of modern web-browsers, skipping IE support.
Python Interface
Typesafe TTree::SetBranchAddress() for array inputs
If you call TTree::SetBranchAddress with NumPy array or array.array inputs, ROOT will now check if the array type matches with the column type. If it doesn’t, SetBranchAddress() will return a negative status code and print an error. Take for example this code snippet:
If the branch type is also double (like the type of the array indicated by "d"), the call to SetBranchAddress() would succeed with status code zero. If the type doesn’t match, you now get a clear error instead of garbage values.
The TPython::Eval() method is deprecated and scheduled for removal in ROOT 6.36. Its implementation was fragile, and the same functionality can be achieved with TPython::Exec(), using a C++ variable that is known to the ROOT interpreter for crossing over from Python to C++.