ROOT Version 6.18 Release Notes

2019-09-11

Introduction

ROOT version 6.18/00 was released on June 25, 2019.

For more information, see http://root.cern

The following people have contributed to this new version:

Kim Albertsson, CERN/ATLAS,
Guilherme Amadio, CERN/SFT,
Bertrand Bellenot, CERN/SFT,
Iliana Betsou, CERN/SFT,
Jakob Blomer, CERN/SFT,
Brian Bockelman, Nebraska,
Rene Brun, CERN/SFT,
Philippe Canal, FNAL,
Javier Cervantes Villanueva, CERN/SFT,
Olivier Couet, CERN/SFT,
Alexandra Dobrescu, CERN/SFT,
Giulio Eulisse, CERN/ALICE,
Gerri Ganis, CERN/SFT,
Andrei Gheata, CERN/SFT,
Enrico Guiraud, CERN/SFT,
Stephan Hageboeck, CERN/SFT,
Jan Knedlik, GSI,
Sergey Linev, GSI,
Pere Mato, CERN/SFT,
Lorenzo Moneta, CERN/SFT,
Alja Mrak-Tadel, UCSD/CMS,
Axel Naumann, CERN/SFT,
Vincenzo Eduardo Padulano, Bicocca/SFT,
Danilo Piparo, CERN/SFT,
Fons Rademakers, CERN/SFT,
Henry Schreiner, Princeton,
Oksana Shadura, Nebraska,
Simon Spies, GSI,
Yuka Takahashi, Princeton and CERN/SFT,
Enric Tejedor Saavedra, CERN/SFT,
Matevz Tadel, UCSD/CMS,
Vassil Vassilev, Princeton/CMS,
Wouter Verkerke, NIKHEF/Atlas,
Zhe Zhang, Nebraska,
Stefan Wunsch, CERN/SFT

Deprecation and Removal

Deprecated packages

The Virtual Monte Carlo (VMC) interfaces have been deprecated for this release and will be removed in a future release. It is no longer built by default, but can still be enabled with the option -Dvmc=ON in the CMake configuration phase. A standalone version of VMC is being developed at https://github.com/vmc-project/vmc to replace the deprecated version in ROOT.

Removed packages

Support for the following optional components of ROOT has been removed:

In addition, the following deprecated parts of ROOT components have been removed:

Other changes

The deprecation of the GraphViz integration has been reverted since the code is still in use.

The ODBC interface, deprecated in ROOT 6.16, is no longer deprecated in ROOT 6.18. It is the main option to support databases on Windows, so the decision to deprecate it was reverted.

The xft option has been merged into x11 and is no longer used (its value is now ignored by ROOT).

Preprocessor deprecation macros

Deprecated Classes

class DoNotUseClass {
} R__SUGGEST_ALTERNATIVE("Use ... instead.");

It is activated by the preprocessor defines R__SUGGEST_NEW_INTERFACE. The former is useful when deprecation warnings should be activated/deactivated at global level, for example for an entire project. This could be done by defining R__SUGGEST_NEW_INTERFACE in the build system. If the warning needs to be confined within single translation units, irrespective of the definition of R__SUGGEST_NEW_INTERFACE, the R__ALWAYS_SUGGEST_ALTERNATIVE macro can be used:

#ifndef DONOTUSECLASS_H
#define DONOTUSECLASS_H

class DoNotUseClass {
} R__ALWAYS_SUGGEST_ALTERNATIVE("Use ... instead.");

#endif

Deprecated Functions

The same macro as for classes can be used for functions:

TIterator* createIterator() const
R__SUGGEST_ALTERNATIVE("begin(), end() and range-based for loops.") {
 return makeLegacyIterator();
}

I/O Libraries

THttpServer classes

The following methods were deprecated and removed:

The methods could be replaced by equivalent methods with other signature:

Core Libraries

Core Libraries

I/O Libraries

auto obj = directory->Get<MyClass>("some object");

TNetXNGFile

Added necessary changes to allow XRootD local redirection - Uses standard VectorReadLimits and does not query a XRootD data server (which is unknown in local redirection), when it is redirected to a local file - Adds a new constructor with a const char *lurl to TNetXNGFile and passes it to TFile, if set. This allows redirection to files that have a different name in the local file system and is important to allow derivation (for example to TAlien and TJAlienFile) while still keeping functionality via TArchiveFile when the file name in the local file system does not match *.zip

TBufferJSON

Add possibility to convert STL std::map, std::multimap, std::unordered_map, std::unordered_multimap classes into JSON object. This only possible when key typename is std::string (or compatible) and contains only valid JSON identifiers. By default these classes converted into JSON array of std::pair objects. To enable new feature, compact parameter should be 5:

std::map<std::string,int> obj;
obj["name1"] = 11;
obj["name1"] = 22;
auto json = TBufferJSON::ToJSON(&obj, 5);
// {"_typename": "map<string,int>", "name1": 11, "name2": 22}
auto dflt_json = TBufferJSON::ToJSON(&obj);
// [{"$pair" : "pair<string,int>", "first" : "name1", "second" : 11}, {"$pair" : "pair<string,int>", "first" : "name2", "second" : 22}]

Also one could put “JSON_object” string in class-member comments to enable this feature:

class Container {
   int field{5};
   std::unordered_map<std::string,double> data;  ///< JSON_object indicates conversion
};

Now one could disable storage of type information - _typename field. For that compact parameter has to include value 100. Be aware that such JSON representation may not be recognized by JSROOT. Maximal compression of JSON can be achieved now with compact parameter 128 = 100 + 20 + 5 + 3: 3 - remove all spaces and new lines 5 - convert map->object (when applicable) 20 - special compression of large arrays (auto-detected in JSROOT) 100 - suppressing _typename for all classes

TTree Libraries

RDataFrame

TLeafF16 and TLeafD32

Float16_t  floatVal;
Float16_t  floatArray[7];
Double32_t doubleVal;
Double32_t doubleArray[5];
TTree *tree = new TTree("tree", "An example tree using the new data types");
tree->Branch("floatVal",   &floatVal,    "floatVal/f");               // Float16_t value with default settings
tree->Branch("floatArray",  floatArray,  "floatArray[7]/f[0,100]");   // Float16_t array with range from 0 to 100
tree->Branch("doubleVal",  &doubleVal,   "doubleVal/d[0,1000,20]");   // Double32_t value with range from 0 to 1000 and 20 bits
tree->Branch("doubleArray", doubleArray, "doubleArray[5]/d[0,0,18]"); // Double32_t array without range and 18 bits

Bulk I/O

Histogram Libraries

TH1

TH2Poly

TF1

TKDE

Math Libraries

Clad

RooFit Libraries

RooJohnson PDF

The Johnson SU PDF has been added to RooFit. It comes with an analytical integral and a generator function, which make it superior (faster and more accurate) than implementing it manually with an interpreted/compiled formula.

HistFactory

hist2workspace performance optimisations. For a large, ATLAS-style Higgs–>bb workspace with > 100 systematic uncertainties and more than 10 channels, the run time decreases by a factor 11 to 12.

Faster, STL-like Collections in RooFit

RooFit’s collections RooArgSet and RooArgList have been made more STL-like. The underlying implementation used to be the RooLinkedList, but now both collections work with std::vector. The collections have an STL-like interface concerning iterators such that iterations over the two collections that looked like

TIterator* depIter = intDepList.createIterator() ;
RooAbsArg* arg;
while((arg=(RooAbsArg*)depIter->Next())) {
  ...
}
delete depIter;

now look like:

for (auto arg : intDepList) {
  ...
}

Depending on how many elements are iterated, RooFit will be between 10 and 20% faster if the new iterators are used. Heavily using old iterators might slow it down by 5 to 10%. Iterators in key classes have been updated, such that many workflows in RooFit are 10 - 20% faster.

Legacy iterators

The (three kinds) of legacy iterators in RooFit are still supported, such that old code will not break, but they are slower than begin(), end() and range-based for loops.

Important caveat: The old RooFit collections could be modified while iterating. The STL-like iterators do not support this (as for a e.g. std::vector)! Using the legacy iterators with the new collections (i.e. in existing code), mutating the collection is still possible in the following cases: - Inserting/deleting elements after the current iterator. - Changing an element at a position other than the current iterator - But not inserting/deleting before/at the current iterator position. With a debug build (with assertions), the legacy iterators will check that the collection is not mutated. In a release build, elements might be skipped or be iterated twice.

Moving away from the slower iterators

The legacy iterators have been flagged with a special deprecation macro that can be used help the user use the recommended ROOT interface. Defining one of the deprecation macros (either in a single translation unit or in the build system), and creating a legacy iterator will trigger a compiler warning such as:

<path>/RooChebychev.cxx:66:34: warning: 'createIterator' is deprecated: There is a superior alternative: begin(), end() and range-based for loops. [-Wdeprecated-declarations]
  TIterator* coefIter = coefList.createIterator() ;
                                 ^
1 warning generated.

TMVA

This release provides a consolidation and several fixes of the new machine learning tools provided in TMVA such as the Deep Learning module. The method TMVA::Types::kDL should be used now for building Deep Learning architecture in TMVA, while TMVA::Types::kDNN is now deprecated. TMVA::Types::kDL provides all the functionality of TMVA::Types::kDNN, i.e building fully connected dense layer, but in addition supports building convolutional and recurrent neural network architectures. These release contains improvements in the MethodDL such as: - fix droput support for dense layer - add protection to avoid returning NaN in the cross-entropy loss function

In addition we have :

PyMVA

2D Graphics Libraries

  auto h = new TH1F("h","h",5,0.5,5.5);
  h->SetBinContent(1,100000);
  h->SetBinContent(2,10000);
  h->SetBinContent(3,1000);
  h->SetBinContent(4,100);
  h->SetBinContent(5,10);
  h->SetMinimum(50.);
  h->SetMaximum(40000);
  h->Draw("L*");
  gPad->SetLogy();

3D Graphics Libraries

Database Libraries

The CMake module FindOracle.cmake was updated to support version 18.x of the Oracle client libraries.

JavaScript ROOT

New functionality from 5.7.0 release

New files location

JSROOT sources were moved from etc/http/ into js/ subfolder in ROOT sources tree. OpenUI5 files were moved to ui5/ subfolder. After ROOT compilation they can be found in $ROOTSYS/js/ and $ROOTSYS/ui5/ subfolders respectively.

Tutorials

Build, Configuration and Testing Infrastructure

CMake build system requirements and updates

The minimum required version of CMake has been updated to 3.9 or newer to be able to take advantage of new features such as native support for the CUDA language, among other things. Please refer to CMake’s release notes for further information.

The method to select the C++ standard has changed. Now the recommended way to select the C++ standard is via the option -DCMAKE_CXX_STANDARD=XX, which is the idiomatic way to do it in CMake. The old options still work, but have been deprecated and will be removed in a future release.

Build option descriptions have been updated to indicate which builtins require an active network connection during the build. You can inspect the list of options and their descriptions by running cmake -LH $PWD in the build directory.

The build system has been updated to remove most file globbing to improve the reliability of incremental builds when source files are added or removed.

A new check has been added to make ROOT fail during the configuration step if incompatible versions of the Python interpreter and its libraries are selected.

The all=ON option now tries to enable more options. Some options had their default value toggled to disabled, which affected all=ON. Now all options are listed explicitly so that they are enabled regardless of their default value.

Builtins

The following builtins had their versions updated for this release:

Header location and ROOT_GENERATE_DICTIONARY / ROOT_STANDARD_LIBRARY_PACKAGE

A change in the argument handling of ROOT_GENERATE_DICTIONARY and ROOT_STANDARD_LIBRARY_PACKAGE might need your attention: these macros now respect whether a header file was passed with its full relative path (the common case), or with a full path. The latter allows to find headers at runtime - at the cost of a loss of relocatability: you cannot move the library containing that dictionary to a different directory, because the header location is stored in the dictionary. This case is used by roottest but should likely not be used by anything but test suites.

Instead pass relative paths, together with a -I option to find the headers, plus setting ROOT_INCLUDE_PATH for finding the headers back at runtime. The ROOT stress suite is now updated to follow this behavior; see for instance the injection of $ROOTSYS/test in test/stressMathCore.cxx, allowing ROOT to find the header at runtime, whether interpreted (R__ADD_INCLUDE_PATH) or compiled (TROOT::AddExtraInterpreterArgs({"-I..."}) before interpreter construction).

If you called ROOT_GENERATE_DICTIONARY(Dict ${CMAKE_CURRENT_SOURCE_DIR}/subdir/Header1.h LINKDEF LinkDef.h) then update that call to ROOT_GENERATE_DICTIONARY(Dict Header1.h OPTIONS -I subdir LINKDEF LinkDef.h) if the header is usually included as #include "Header1.h", or to ROOT_GENERATE_DICTIONARY(Dict subdir/Header1.h LINKDEF LinkDef.h) if the header is usually included as #include "subdir/Header1.h". I.e. the general rule is: pass to ROOT_GENERATE_DICTIONARY (or ROOT_STANDARD_LIBRARY_PACKAGE) the spelling as #includeed.

As an important side-effect, ROOT_GENERATE_DICTIONARY and thus ROOT_STANDARD_LIBRARY_PACKAGE now require the header to be found at configuration time. We have seen too many cases where the header location was mis-stated, and as a consequence, CMake did not generate the proper dependencies. If the header should not be taken into account for dependencies and / or if the header will not be found (e.g. the standard library’s vector) please pass the header through the NODEPHEADERS option to ROOT_GENERATE_DICTIONARY or ROOT_STANDARD_LIBRARY_PACKAGE.

We believe that this simplification / regularization of behavior, and the additional checks are worth the possible changes on the user side.

PyROOT

If the fix or new feature is a pythonization related to a C++ class, the change is added to the respective section above.

Current PyROOT

Experimental PyROOT

@ROOT.DeclareCppCallable(["float"], "float")

def f(x):
   return 2.0 * x
ROOT.CppCallable.f(21.0)
# Returns 42.0

df = ROOT.ROOT.RDataFrame(4).Define("x", "CppCallable::f(rdfentry_)")

df.AsNumpy()
# Returns {'x': numpy.array([0., 2., 4., 6.], dtype=float32)}

Bugs and Issues fixed in this release

Release 6.18/02

Released on August 23, 2019

I/O Libraries

Bugs and Issues fixed in this release

Release 6.18/04

Released on September 11, 2019

Core Libraries

I/O Libraries

Binaries

Bugs and Issues fixed in this release

HEAD of the v6-18-00-patches branch

These changes will be part of a future 6.18/06.