ROOT Version 5.04/00 Release Notes
A new development version ROOT 5.04/00 has been released September 20, 2005.
Binaries for all supported platforms are available at:
http://root.cern.ch/root/Version504.html
Versions for AFS have also been updated. See the list of supported platforms:
http://root.cern.ch/root/AFS.html
For more information, see:
http://root.cern.ch
The following people have contributed to this new version:
Ilka Antcheva,
Maarten Ballintijn,
Bertrand Bellenot,
Zev Benjamin,
Marek Biskup,
Walter Brown,
Rene Brun,
Philippe Canal,
Olivier Couet,
Denis Favre-Laville,
Valeri Fine,
Mark Fishler,
Markus Frank,
Gerri Ganis,
Andrei Gheata,
Mihaela Gheata,
Masaharu Goto,
Christian Holm Christensen,
Anna Kreshuk,
Wim Lavrijsen,
Sergei Linev,
Jose Lo,
Richard Maunder,
Lorenzo Moneta,
Axel Naumann,
Eddy Offermann,
Valeriy Onuchin,
Andreas Peters,
Timur Pocheptsov,
Fons Rademakers,
Stefan Roiser,
Andras Zsenei
Base
License Change
With this release we've moved to the LPGL license. The LGPL is very liberal
Open Source license with should not impede much our many long time commercial
users, while at the same time put ROOT solidly in the Open Source domain.
New Class TMacro
This class allow for storing a C++ macro in a ROOT file.
In addition to being stored in a ROOT file a TMacro can be executed,
edited, etc.
A macro can be built line by line by calling the AddLine() function,
or it can be created directly from a file via a special constructor.
A macro can be executed via the Exec() function. Arguments can be
specified when calling Exec().
A macro can be drawn in a pad. When the pad is updated, the macro is
automatically executed.
The code in the macro can be saved via the SaveSource() function.
If the macro is in the list of primitives of a pad/canvas, the macro
will be saved in the script generated by TCanvas::SaveSource().
A macro can be written to a ROOT file via TObject::Write().
Examples:
TMacro m("Peaks.C"); //macro m with name "Peaks" is created
//from file Peaks.C
m.Exec(); //macro executed with default arguments
m.Exec("4"); //macro executed with argument
m.SaveSource("newPeaks.C");
TFile f("mymacros.root","recreate");
m.Write(); //macro saved to file with name "Peaks"
Multi-level TAB Completion
Support for multi-level TAB completion in the ROOT shell, like:
obj->GetVariable1ptr()->GetVar2Ptr()->[tab]
Previously only the first level after obj-> could be expanded.
New Class TFileMerger
This new class allows for easy copying of two or more files using the
many TFile plugins (i.e. it can copy from Castor to dCache, or from
xrootd to Chirp, etc.). Its file merge functionality is taken from hadd.
To use it do, e.g.:
TFileMerger m
m->Cp("srcUrl", "destUrl")
or
m->AddFile("url1")
m->AddFile("url2")
m->Merge()
The AddFile() and Merge() use the Cp() to copy the file locally before
making the merge, and if the output file is remote the merged file
will be copied back to the remote destination.
New TFile Feature
Support for opening files in raw mode when the file url contains the
option string "filetype=raw", like "anyfile.tgz?filetype=raw".
This allows TFile and its many remote access plugins to be used to open
and read any file. This is used by the TFileMerger::Cp() method to copy
any file from and to Grid storage elements (e.g. from Castor to dCache,
from xrootd to a local file, and all possible permutations).
New TUrl Feature
Added support for file namespaces, like: /alien/user/rdm/bla.root, which
will be split in protocol=alien, file=/user/rdm/bla.root. Special
namespaces like /alien/ are added via [system].rootrc. This also allows us to
directly support filenames like /castor/cern.ch/... instead of
castor:/castor/cern.ch/...
XML DOM Parser
The DOM (Document Object Model) is a
platform and language-neutral interface that will allow programs and
scripts to dynamically access and update the content, structure and
style of documents. The DOM parser, as the previously introduced SAX
parser, are internally using libxml2.
The DOM parser comes with two new tutorials: DOMParsePerson.C
and DOMRecursive.C.
Castor 2 Support in TCastorFile
Castor v2 is now supported by the TCastorFile class. Both
protocols, Castor v1 and v2 ar supported. The plugin needs to be
linked with the new castor-2.0.0 library.
New Ports
Finalized the port to MacOS X Tiger (10.4).
On Tiger the default Fortran compiler is gfortran. Usage of the optional
g95 is possible by setting g95 in ROOTBUILD, e.g.:
export ROOTBUILD="debug g95"
New port to AIX5 with gcc and at the same time improved the port to xlC.
Thread Safety
Work has been done to make more classes thread safe, like when accessing
global TROOT containers and classes like TDatime, TTimestamp, etc.
Developments in Trees
Misc.
We improved the performance of TBranchElement::SetAddress by increasing the
caching of TClass pointers and offsets. Also leverage the use of TClassRef
to reduce the number of calls to gROOT->GetClass. Optimize a couple of
additional functions. The improvement is dramatic for the 2nd call to
SetAddress on the same branch object (90%)!
We fixed a problem in the writing of fBits when it was writing in its own
branch and the object were referenced. We improved on the support of nested
TTree Friend (use multiple locks instead of only one). We enabled the
browsing/Drawing of emulated std::map
Meta
Significantly improved the IsA lookup for foreign classes
(i.e the lookup by typeid). It is inspired from the implementation
used by POOL/Reflex. It uses a new abstract interface TVirtualIsAProxy.
We Improved performance of TClassRef.
Nested namespace are now alloed in a rootmap file.
Input/Output
We introduced a new feature allowing the customization of
the constructor used by the I/O.
The constructor actually called by the ROOT I/O can be customized by
using the rootcint pragma:
#pragma link C++ ioctortype UserClass;
For example, with this pragma and a class named MyClass,
this method will called the first of the following 3
constructors which exists and is public:
MyClass(UserClass*);
MyClass(TRootIOCtor*);
MyClass(); // Or a constructor with all its arguments defaulted.
When more than one pragma ioctortype is used, the first seen as priority
For example with:
#pragma link C++ ioctortype UserClass1;
#pragma link C++ ioctortype UserClass2;
We look for the first existing public constructor in the following order:
MyClass(UserClass1*);
MyClass(UserClass2*);
MyClass(TRootIoCtor*);
MyClass(); // Or a constructor with all its arguments defaulted.
New utility classs TDirectory::TContext to keep track and
restore the current directory. With this construct C++
exceptions will be guaranteed to properly restore the
current directory pointer.
We added a new member function, TDirectory::GetDirectory, which factors out
the code of TDirectory::cd and its static counterpart TDirectory::Cd.
TDirectory::GetDirectory can be used to quietly find out if a directory
exist:
TDirectory *mydir = myfile->GetDirectory(somepath);
if (mydir==0) mydir->mkdir(somepath);
myfile->cd(somepath);
We improved performance of reading of legacy ROOT 3 files.
Improved streaming speed for std::string.
Improve performance of STL container streaming.
TFormula
New implementation of the executor part of TFormula which minimizes
the size of the existing switch statement by combining some operation
and/or replacing some operations by a single indirect function call.
This result in a significant speed-up of the execution.
The change is fully backward compatible since the new optimized
operation are stored in an additional set of transient data members.
(fExprOptimized and fOperOptimized).
Function with default paramater can not yet be properly handled
via the faster function primitive mechanism.
We extended the syntax to allow to calls function whose names start
(but are different from) gaus, landau, rndm or expo.
Insured that the paramaters of the Formula are properly restored
by TFormula::Streamer even if the formula contains calls to
external C++ function (like TMath::Abs).
Added support for the creation of TF1, TF2 and TF3 object from function with
the signature
double (*)(const double*,const double*);
from compiled code. So far only double (*)(double*,double*)
was supported
TTreeFormula
Add a new member function TTreeFormula::ResetLoading. This can
be used instead of calling TTreeFormula::EvalInstance(0) to insure
the proper loading of the branches. In particular this solves issues
when the formula is invalid (invalid indices for example) for the first
instance.
New class TTreeSQL
We introduced the first version of TTreeSQL facility. This
new facility allows the storing and restoring of TTree to and from
an SQL database:
TSQLServer *dbserver =
TSQLServer::Connect("mysql://localhost:3306/rootDev","rootdevel",
"r00tg6ys");
dbserver->Query("drop table ntuple;");
ntuple = new TTreeSQL(dbserver, "rootDev", "ntuple");
If the database contain a table named ntuple, this will connect to it and
let
you use any of TTree functionality on (Scan, Draw, etc.)
If the database does not contain a table named ntuple, it will created once
you called the first Fill on the TTree. This version supports the leaflist
type of branches.
Proof
Support added for several new features.
Multi sessions
The limit to only one PROOF session per ROOT client session
has been removed. Sessions are still started via TROOT::Proof(…),
but a pointer to the started session is now returned, e.g.
root[0] TProof *p1 = gROOT->Proof(“lxa0123.cern.ch”)
root[1] TProof *p2 = gROOT->Proof(“lxb1234.cern.ch”,”proof.std.conf”)
The global gProof refers now to the last open
session or to the session selected via TProof::cd().
The list of active PROOF sessions is available via gROOT->GetListOfProofs().
Each session has:
- a GUI
progress dialog, which is started when the first processing action is
started;
- a
list of results (TQueryResult objects, see below) which can
accessed via TProof::GetQueryResults();
- a unique identifier or session tag, a string generated by the master and which can be
accessed via TProof::GetSessionTag(); the session tag
contains the master host name, the time at which the PROOF session has
started and the process ID of the top master server.
Asynchronous running
mode
This feature makes possible to process selectors queries
asynchronously, i.e. without blocking the client ROOT session. Process requests
are sent to the PROOF top master and added to the internal queue. Queued
requests are processed sequentially. At the end of processing a copy of the
results is sent back to the client who can proceed to finalize the query using TProof::Finalize(),
which internally calls TSelector::Terminate(). Asynchronous running
mode is activate by passing “ASYN” as option to TProof::Process(), e.g.
gProof->Process(mydataset, “MySelec.C”,
“ASYN”).
By default processing is synchronous (blocking): the default
mode can be modified with TProof::SetQueryMode(mode),
e.g.
gProof->SetQueryMode(TProof::kAsync).
The status of the submitted queries can be displayed at any
moment with TProof::ShowQueries().
To avoid screwing up the ROOT prompt, any printout occurring
during asynchronous processing is redirected to a log file which can be browsed
either at the ROOT prompt using TProof::ShowLog()or by
clicking on the appropriate button on the GUI.
TQueryResult:
a container for query information
This new class has been introduced to organize in one entity
all the information available about a query.
It contains:
- query
status, start and end processing time, selector files, input data, environment,
log file and outputs;
- a unique reference is assigned to the
query composed of the PROOF session tag and a unique sequential number.
An instance of this class is created by the top master upon
receipt of query processing request. The instance is updated each time an
action is performed on the query. At the master of processing the master sends
back a copy of the instance to the client who stores it in a list owned by the
PROOF session. The master also saves a copy of the instance into the sandbox,
in such a way that it may be re-accessed later on in case of need.
TProof::ShowQueries(Option_t *opt)
This method allows to display information about all queries
known by the master, included those processed by other sessions and still
having an entry in the remote sandbox. By default, ShowQueries() shows
information only for the queries processed by the current session.
Available options are:
‘A’: show
information about all the queries known by the master; this triggers a scan of
the sandbox.
‘L’: show information about the queries already retrieved
‘F’: show all details available about the query; by default only a
line with the head information is shown.
Options are case insensitive. If ‘L’ is
specified ‘A’ is ignored.
The policy for keeping query results depends on the type of
query as follows:
- Selector queries: all are kept on the
master and the client, unless cancelled or aborted; quota limits are
foreseen but not yet implemented.
- Draw queries: none is kept on the
master, the last one is kept on the client; the maximum number queries to
be kept on the client can be changed using TProof::SetMaxDrawQueries(Int_t newmax).
Finalize, Retrieve,
Archive and Remove functionality
A set of new methods have been added to the TVirtualProof interface to administrate the
available queries.
All these methods have as main argument either the unique
query reference or the sequential number reported by TProof::ShowQueries
·
Finalize(Int_t query, Bool_t force) / Finalize(const char *queryref,
Bool_t force)
With no arguments it finalizes the last query processed. Finalize can be run
only once on the query instance received from the top master, because TSelector::Terminate() modifies
the initial output list. The boolean
force can be used to force a new retrieval of the instance.
·
Retrieve(Int_t query, const char
*file) / Retrieve(const char *queryref, const char
*file).
Retrieve a query from the master and store it in memory. If a valid path is
defined (i.e valid for TFile::Open()), the TQueryResult
instance is also streamed to a file defined by file.
·
Archive(Int_t query, const char
*path) / Archive(const char *queryref, const char
*path)
Archives at master the referenced query. The path has the format
requested by TFile::Open.
A default path can specified using “Default” as reference, e.g.
gProof->Archive(“Default”,”root://datasrv01.some.wh:6756//data001”).
If specified the default path is used to build a unique file name of the form
<default_path>/session-<session_tag>-<query_numer>.root
e.g. ”root://datasrv01.some.wh:6756//data001/session-0-pcepsft43-1127127540-25793-2.root”.
·
Remove(Int_t query, Bool_t all) / Remove(const char *queryref,
Bool_t all)
Removes the query on the master and, optionally, also locally.
An additional method
CleanupSession(const
char *sessiontag) is provided to remove all queries of session identified by sessiontag. If
the session sesssiontag
is still alive the request is ignored.
Other improvements
- GUI progress dialog. The progress
dialog is now started whenever a processing is started, i.e. also for Draw
actions. There is now one dialog box per session (and not per query).
Information about the query processing performance is kept in TQueryResult and can be displayed using
option “F” to TProof::ShowQueries(). The dialog box now also gives the
possibility to display the log messages per query or the whole set. A coherency problem for enabling/disabling
of Stop/Cancel buttons has been
fixed.
- TProof::UploadPackage. Package
uploading to master or to slaves is now done via the already open
connection, i.e. there is no need to start a rootd on each node of the cluster
to receive the packages.
· Progressive packetizer (TPacketizerProgressive). This class implements a new packetizer, a generator of packets to be processed on PROOF slave servers. A packet is an event range (begin entry and number of entries) or object range (first object and number of objects) in a TTree (entries) or a directory (objects) in a file. Packets are generated taking into account the performance of the remote machine, the time it took to process a previous packet on the remote machine, the locality of the database files, etc. This packetizer does not pre-open the files to calculate the total number of events, it just walks sequentially through the list of files.
- Optimization of sequential slave
startup. The two main steps of slave startup have been
de-synchronized allowing to introduce some sort of parallelism without the
use of threads. This allows to significantly improve
the startup time for clusters of relatively slow machines.
- Sequential
running mode ( TProof::SetParallel(0) ). Progress bar has
been activated.
- Support for Friend Trees. Friends can be added to a TDSet using
TDSet::AddFriend(). Also TChain::MakeTDSet() creates a TDSet from a
TChain and adds all chain's friends to it.
- Support for Indexes. Indexes can be used with PROOF to connect events
from different trees. There are two ways of using them. The first one
is if the friend has the same number of files. In this case the files
will be matched in the same way as without indexes (i.a. first file
from the main chain with the first file of the friend chain, second
file with the second, etc.) but events inside files are matched
according to values of the index. The second case is if there is only
one file in the friend chain.
Geometry package enhancements
Assemblies of volumes
New classes created to describe volume assemblies:
TGeoVolumeAssembly : public TGeoVolume
TGeoShapeAssembly : public TGeoBBox
An assembly represents a union of more than 2 volumes positioned with respect to
the local assembly reference frame. Assemblies behave like normal volumes, but
their shape is defined as the union of the shapes of the volumes positioned
inside. This shape is represented by the class TGeoShapeAssembly, which is
automatically created and updated whenever a new node is added to the assembly
content. This makes the assembly a self-contained volume in the sense that any
point inside it is automatically inside one of the components. For this reason
an assembly volume does not need a medium/material nor a shape to be defined.
Creating an assembly can be done in a very similar way as creating a volume:
TGeoVolumeAssembly *assembly = new TGeoVolumeAssembly("STRUCT"); // assembly volume
assembly->AddNode(pVol1, id1, pMatrix1); // components of the assembly
assembly->AddNode(pVol2, id2, pMatrix2);
...
The components have to obey the same rule of thumb as any positioned volume:
they should not overlap each other. On the other hand they formally cannot
extrude the assembly container since the later is defined by them.
Assemblies can be positioned as nodes in any other volume and support nesting
and replication. A detailed example of their usage can be found at:
$ROOTSYS/tutorials/assembly.C
There are several advantages in using assemblies instead of normal volumes
whenever the definition of a replicated complex structure is needed. In such
cases generally it is difficult to define a container that perfectly fits to the
structure, therefore one usualy defines a larger one with a simple shape. The
problem may appear when positioning this container because it may overlap with
other volumes (not allowed). To avoid this, people split the structure in many
components and place them individually without defining a container, resulting
in flat structures which are hard to optimize at certain geometry levels. All
these can be avoided by using assemblies. The automatically-generated
TGeoShapeAssembly uses the same optimization mechanisms for navigation as
volumes.
Assemblies can be browsed as nodes in the geometry tree and generate an
additional geometry level, but they are invisible during navigation. Any
navigation query performed in a geometry having assemblies will end-up in
non-assembly leafs. Tests demonstated that grouping the existing nodes of a
volume with many components via assemblies improve navigation performance.
Therefore there is no penalty in performance observed due to usage of
assemblies.
Additions related to navigation
New combined querry: TGeoNode* TGeoManager::FindNextBoundaryAndStep(Double_t
propStep=TGeoShape::Big(), Bool_t compSafe=kFALSE)
The method was optimized to performs several navigation tasks in one go. Prior
to its usage one have to initialize the current global point/direction and to
locate the state:
TGeoManager::InitTrack(Double_t *point, Double_t *dir); // or a combination
// performing FindNode() task
After the initialization is completed, one can use the new method to propagate
the current track to the next boundary. The input propStep is the maximum step
allowed by the user for locating next boundary. If the boundary is found further
away, the current point is propagated with propStep and the current node is
returnes as final location. In case the user requires also computation of the
safe distance, it has to provide compSafe = true.
If a boundary is found closer than the proposed step, the modeller will
propagate the current state with the found distance and the state (TGeoNode)
after crossing the boundary is returned. The propagation distance to the
boundary can be retreived via:
Double_t TGeoManager::GetStep()
To test if the boundary crossing really occured, one can use:
Bool_t TGeoManager::IsOnBoundary()
If this is the case, the normal vector to the crossed surface can be computed
via the "fast" approach:
Double_t *TGeoManager::FindNormalFast()
One can use the new query method to propagate a ray from boundary to boundary
until getting outside of the geometry. If this is the case, the computation of
the safe distance make sense only for the first query (for subsequent ones it
will be 0). To retreive the safe distance one should call:
Double_t TGeoManager::GetSafeDistance()
Miscellaneous
Several improvements or fixes related to: navigation consistency near
boundaries, graphics (mesh poligonal representation), matrix package, caching.
Major developments related to OGL 3D viewer.
Reflex
Reflex is a new package in the ROOT environment since the 5.x release series.
It provides reflection capabilities for C++. Reflection being the ability to
introspect and interact with C++ "constructs" (e.g. types, scopes,
members, etc.) at runtime in a generic way. With the use of dictionary libraries,
which contain the meta information about C++ definitions, Reflex allows generic
interaction withoug prior knowlegdge about original definitions.
For the time being Reflex is an optional package in ROOT. If the build of
the Reflex library is wanted it has to be triggered with "--enable-reflex" at
the configuration step of the ROOT build procedure. In a mini-workshop in May
2005 at CERN it was decided that Reflex will closely cooperate with CINT. Below
you may find a brief overview of the features, way of interaction and main
user types of the package. For any more details on the functionality of the
package, the current status and future developments concerning this cooperation
with CINT please check out the ROOT
workshop presentation about Reflex.
The main features of Reflex are:
- close to ISO/IEC standard for C++
- light and standalone system without external
dependencies
- automatic and non-intrusive generation of reflection information
- dictionaries
can be produced for every gcc compatible source code
- written for multi platform/compiler
- optimized on (dictionary) library size
and memory consumption
The usual way of generating dictionary information for and interacting with
Reflex is as follows:
- The C++ files containing the definition of the types the dictionary information
is wanted for are parsed and dictionary source code (in C++) is produced.
There are two ways how this source code can be generated.
- CINT can parse the C++ definitions and a front-end (similar
to rootcint/makecint) will generate C++ dictionary source code
- an extension of the gcc compiler called gccxml parses
the definition files and generates XML output. This XML information is
further processed by a Python script which generates C++ dictionary source
code from it (not committed to the Root cvs repository yet)
- The so generated C++ files are compiled into a library
- Through a Builder API the dictionary library will be loaded
into the Reflex system
- The Reflex user API provides the reflection information about the original
C++ definitions.
The main user types of the Reflex API are:
- Type is an abstraction of a C++ type. Types are pointers, pointers
to member, typedefs, arrays, functions, fundamentals, unions, enums and classes.
- Scope is an abstraction of a C++ scope which are classes, namespaces,
enums and unions.
- Member is the abstraction of either a data- or a function member.
- Object is the abstraction of a C++ object. An object is of
a given type and allocates an amount of memory.
- PropertyLists can be attached to Types,
Scopes and Members and are containers of key value pairs. The
key being a string and the value an object of arbitrary type.
- Base is the abstraction of a C++ base class. It contains information
such as the type of inheritance and the base class offset.
- TypeTemplate the abstraction of a templated type.
- MemberTemplate the abstraction of a templated member.
Cintex
Cintex is a new package in the ROOT environment since the 5.x release series.
It provides a (uni-directonal) gateway from Reflex dictionary information to
CINT dictionary information.
This gateway allows CINT users to interact seemlessly with Reflex dictionary
information. As Reflex dictionary information is very small both in library
size and memory allocation the additional overhead using this gateway is also
small.
Enabling the Cintex gateway is done through the static function "Cintex::Enable()".
Once this function has been called all Reflex dictionaries currently in memory
or dictionaries loaded in the future will be propagated to CINT's internal
memory structures.
For the time being Cintex is an optional package in ROOT. If the build of
the Cintex library is wanted it has to be triggered with "--enable-cintex"
at the configuration step of the ROOT build procedure. Cintex is an internal
package to the ROOT framework and should not be visible for the "general" ROOT
user.
PyROOT
There are several improvements to the pythonization of ROOT classes, the
interaction with the interpreter environment, and the treatment of (low-level)
C++ features.
Python/C++ language features
Support is added for inner classes, templated classes, pre-processor macro's
of builtin types, ptr-to-ptr and ref-ptr argument types, object return-by-value,
object argument-by-value, double/long argument-by-ref, array assignment, and the
supported array/buffer types have been completed for all C++ builtins.
The memory policy has been extended to use either heuristics (default) or to be
strict, the ownership of individual objects can be set by hand, addresses of
objects can be taken, and all C++ typedefs now map onto the same python type.
There is a dedicated NULL object that should be used explicitly to pass a null
pointer, and typed null pointers (for use as value holders) can be created.
Interpreter environment
The python help() system is now supported: it will e.g. show the C++ signatures
of functions. CINT errors/warnings are treated as python exceptions/warnings
and error reporting has been improved, e.g. overloaded functions that fail show
a message for each individual overload.
The .L CINT command is supported, objects from TFile's can now be used directly,
cf. CINT, and the initial startup environment is more closely mimicking RINT.
Tab-completion is added for file names in the local directory structure.
Further workarounds for IPython are provided.
Pythonization
TMinuit::SetFCN accepts python functions, as do TF2/3 (modeled after the support
for TF1). TTree and TFile member templates are available: the appropriate
casting is done internally, based on the available run-time type information.
STL vector and string can be used with python-style iteration.
Fitting
Robust fitting - Least Trimmed Squares regression (LTS)
A new method for robust fitting was added to the TLinearFitter class, to
be used for fitting linear functions in presense of outliers in the data.
Even a single gross outlier can greatly influence the results of least-
squares fitting procedure, and in this case use of robust(resistant)
methods is recommended.
The method implemented here is based on the article and algorithm:
Computing LTS Regression for Large Data Sets by P.J.Rousseeuw and
Katrien Van Driessen.
The idea of the method is to find the fitting coefficients for a subset
of h observations (out of n) with the smallest sum of squared residuals.
The size of the subset h should lie between (npoints + nparameters +1)/2
and n, and represents the minimal number of good points in the dataset.
The default value is set to (npoints + nparameters +1)/2, but if you are
sure that the data contains less outliers it's better to change h
according to your data.
To perform a robust fit one can
Note, that standard errors on parameters are not computed!
TF1
Improvement of min/max finding routines. Now first a grid search is
performed to bracket the extremum and then Brent's method is used for
minimization. Brent's method is a combination of golden section search
and parabolic interpolation.
MathCore Package
This is a new package introduced in ROOT version 5. It provides a collection of functions and C++ classes for HEP numerical computing. This library provides the basic and most used mathematical functionality, while MathMore provides more advanced functionality. MathCore contains up to now:
- Special Functions: Gamma, Beta and Error Function. The naming of the functions is the one proposed to the new version of the C++ standard library
- Probability Distribution
Functions (PDF): distribution functions
of binomial, breit-wigner, chi-squared, exponential, fdistribution, gamma, lognormal, normal and poisson, t-distribution. One example is the normal_pdf.
- Cumulative Distribution Functions (CDF): lower and upper tail integrals of the probability distribution function. The lower tail are the quantile (for example normal_quant) , while the upper tail are the probabilities (normal_prob). The functions present in mathcore are: breit-wigner, normal, exponential and lognormal. More functions are present in MathMore.
- GenVector: package for 3D and 4D Vectors. This package provides C++ classes to describe the geometic 3D vectors, the 4D physics Lorentz vectors and their transformations, like rotations in 3D and 4D (boost + 3D rotation). See here for more information on the GenVector package and ofr the API documentation. The main characteristics of this package compared to the current classe in the Physics package are:
- possibility to have Vector based on various coordinate systems
such as Cartesian, Polar and Cylindrical
- distinction between position vectors (Points) and displacement vectors
- possibility to have Vector classes based on arbitrary scalar type (they
are templated on the scalar value type)
- An easy connection to Linear Algebra Vector and Matrices classes and to similar package currently existing, like CLHEP, is also provided
More detailed description of the current released software can be found at this location.
MathMore Package
It is a new package introduced in the present version of ROOT. It
incorporates mathematical functionality which might be needed for an
advanced user (as opposed to MathCore which addresses the primary needs
of users). The need of separating the mathematical functionality is
twofold. In order to keep the size of the core of ROOT reasonable only
the most used mathematical functionality should be included in it.
Secondly, there are licensing issues concerning some of the more
advanced functionality which uses GSL. One of the design goals is to
hide the implementation, i.e. presently for most of the mathematical
functionality GSL is used underneath. However, it would be very easy to
shift to another package, like CEPHES, or any other package appearing
in the future, it would be completely transparent to the user and
straightforward for the developer. As of now, MathMore is composed of
the following major parts:
- Special Functions: bessel
functions with fractional order, elliptic integrals, Laguerre and
Legendre polynomials, hypergeometric functions.
- Cumulative Distribution
Functions and their inverses: cumulative distribution functions
of chi-squared, gamma, f and t-distributions and their inverses. There
are also the inverses of the CDFs of the Breit-Wigner, exponential,
Gaussian, lognormal and uniform distributions.
- Function Infrastructure:
definition of function classes that the user can inherit from combined
with some implementations (for example ParamFunction for parametric
functions). Also provides wrappers to encapsulate global C functions
and use them in the mathematical operations.
- Derivation: classes for
computing numerical derivatives of a function.
- Integration: classes for
performing numerical integration of a function in one dimension.
Various types of adaptive and non-adaptive integration are supported.
These include integration over infinite and semi-infinite ranges and
singular integrals.
- Interpolation: classes
for performing function interpolation of points using linear,
polynomial, Akima and Akima periodic algorithms.
- Root Finding: classes
which find the root of one dimensional functions. The possible types of
root-finding algorithms are:
- Root Bracketing Algorithms which they do not require function
derivatives
- Bisection
- False position
- Brent-Dekker
- Root Finding Algorithms using Derivatives
- Chebyshev Polynomials:
Class describing a Chebyshev series which can be used to approximate a
function
in a defined range.
Obviously, as user needs might evolve, we intend to add new
functionalities. More detailed description can be found at the MathMore reference documentation.
Disclaimer: as it is a new
package, some user needs might have been ignored. As we will
continually try to improve ROOT ther might be a slight evolution in the
user interface in the initial stage if strong user needs arise to do so.
GUI
- Implemented a new check box feature to TGListTree widget. This option
allows checkboxes on the tree nodes to turn on/off pieces of the tree
hierarchy. Used in the ROOT browser to toggle visibility of geometries.
The different checkbox states are as follows:
- Checked: the list tree item and all its children are checked;
- Unchecked: the list tree item and all its children are unchecked;
- Checked and greyed: the list tree item is checked, but at least one
of its children is not;
- Unchecked and greyed: the list tree item is unchecked, but at least
one of its children is checked
This new feature can be used as shown below:
TGListTree *fLt;
fLt = new TGListTree(fTreeView, kHorizontalFrame, fgWhitePixel);
...
// Add an item with a checkbox to the list tree.
TGListTreeItem *item = fLt->AddItem(0, name, obj, 0, 0, kTRUE);
// Check or uncheck this item setting the second parameter to kTRUE or kFALSE.
fLt->CheckItem(item, (Bool_t)check);
Usage of this feature with the TBrowser:
void AnyClass::Browse(TBrowser b) {
// Add the class 'AnyClass' to the browser.
b->Add(this);
// Add a checkbox to the list tree item. The parameter 'ischecked' is Bool_t variable.
b->AddCheckBox(this, ischecked);
// Connect the Checked() signal to a slot method of AnyClass.
Connect("TRootBrowser", "Checked(TObject*,Bool_t)", "AnyClass", this, "SetChecked(TObject*,Bool_t)");
}
The new methods added to TGListTree class are:
- CheckItem(TGListTreeItem *item, Bool_t check = kTRUE);
- SetCheckBox(TGListTreeItem *item, Bool_t on = kTRUE);
- ToggleItem(TGListTreeItem *item);
- Checked(TObject *obj, Bool_t check); //*SIGNAL*
- and the checkbox option in: AddItem(..., Bool_t checkbox);
In addition, the new icons for list tree item check boxes were created in
relation to the existing TGeo shapes. Added mime types linking new icons
to the object types.
- TCanvas objects (for example stored in a ROOT file) can be embedded
dynamically into a TRootEmbeddedCanvas following way:
TCanvas* oldCanvas = fEmbeddedCanvas->GetCanvas();
if (oldCanvas) {
delete oldCanvas;
}
// Get a canvas from the file.
fCurrentCanvas = (TCanvas *)file->Get(CanvasName);
if (fCurrentCanvas == 0)
return;
fEmbeddedCanvas->AdoptCanvas(fCurrentCanvas);
fCurrentCanvas->Draw();
fCurrentCanvas->Modified();
fCurrentCanvas->Update();
- Improvements in the popup menus and cascaded manues behavior.
- Added two new methods to the TGView class that help to show the top or
the bottom of the text viewer page.
Style Manager
- This new Graphical User Interface is created to manage the styles in
a ROOT session. It allows users to edit styles, to import, export them
using macros, to apply a currently selected style on the selected object
or on all canvases, to change the gStyle.
The Style Manager interface is composed of two parts:
- the top level interface that manages a list of styles;
- the style editor, which deals with the current style settings.
- The top level interface contains:
- The combo box 'Available Styles'
that shows the list of all available styles in the current ROOT session.
The field on the right shows the setting of the gStyle. You can set the
global variable gStyle to the selected style by clicking on the button
in the middle.
- The group frame 'Apply on' displays information for the currently
selected canvas and object in the ROOT session. This selection might
be changed by clicking on another object with the middle mouse button
You have a choice to apply a style on the selected object or
on all available canvases.
WARNING: You cannot undo the changes after applying the style! If
you are not sure of that action, it may be better to see a preview
of what you are going to apply.
If the check button 'Preview' is selected, a preview of the selected
canvas according to the selected style will be shown. The selection
of the next check button 'Run Time Preview' will apply updates of
the preview any time a value of the selected style is changed. For
drawings that take a time it is better to disable this option.
- Create a new style:
A new style can be created via the Style menu/New... or the toolbar.
A clone of the selected style will be used as a base of the new
style. All its values can be modified via the style editor later.
The dialog that appears will ask for the name and description of the
new style.
- Import a style (from a macro):
A style macro can be imported at any time. The new imported style in
the ROOT session will become the selected one.
- Import a style (from a canvas):
You can do that selecting the Style menu/Import from.../Canvas or
the corresponding Tool bar button. A new style will be created in the
ROOT session and will become the selected one. This style is a clone
of the gStyle with modified values as they are set in the currently
selected canvas. You can import a style from any canvas and apply it
later on some objects.
- Export a style (in a C++ macro file):
To store a style longer than for the current ROOT session you can
save it in a C++ macro file. This can be done via the menu or the
tool bar button. There is a naming convention for the style macros:
the name must be 'Style_*.C', where * can be replaced by anything
you want.
- Delete a style:
The selected style can be deleted from the list when you use the
Style menu/Delete or the corresponding tool bar button. The selected
style is removed from the list of all available styles for the
current ROOT session. WARRNING: it will be lost if you didn't saved
it in a C++ macro file before its deletion. Also, you cannot delete
the selected style if it is set to gStyle. A message 'Can not delete
gStyle' will be displayed on the CINT prompt.
- The style editor interface:
- Open / close the style editor:
The button 'Edit >>' opens the style editor and its label changes to
'Close <<'. For all details of what can be changed and how please see
the provided Help.
- Reset a style (to a previously saved state):
When the editor is opened, the 'Reset' button allows you to reset
the values of the selected style for editing. Doing that you cancel
all changes made since the last time you saved that style in a macro.
If the selected style is one of the five ROOT styles (Plain, Bold,
Video, Pub or Default), it will be recreated.
- Update the preview:
The button 'Update Preview' is available when a preview is shown and
the run time option is not selected. This button allows you to
refresh the preview any time you want to see how the style you edit
looks like.
- Help button:
Provides a help of the currently selected tab.
OpenGL developments: Features and Interaction
- New code to draw shapes outline style - enable with 't' key. This provides
a 'line-drawing' style, with filled polygons outlined in black - rendering
take approx twice as long.
- Extended camera interactions
- Rotate (Orbit) : LMB + Drag
- Truck (Pan) : MMB + Drag, or arrow keys.
- Dolly (interactive move in/out) : RMB + Drag
- Zoom (field of view) : Mouse Wheel, or 'j' / 'k' keys.
- Modifiers applied
to above adjust sensitivity
- Shift: x 10
- Ctrl: x 0.1
- Shift+Ctrl: x 0.01
- Double click any button to reset the camera.
- Moved selected object
interaction to:
- Select : Shift + LMB
- Move Selected Object : MMB + Shift
- Context Menu Selected Object: RMB + Shift
- Transparent objects:
- Picking - now pick closest opaque objects first, and if none closest
transparent one.
- Ensure transparent selected object is only drawn once.
- Allocate pro-rata time for transparent drawing - previous assumption
that number transparent << number opaque was invalid in some
cases.
Performance / Quality
Major internal re-structuring of GL viewer to support:
- Repeated addition of duplicate placed shapes - added new
classes TGLLogicalShape (a unique local frame 'shape') and TGLPhysicalShape
(a placement of TGLLogicalShape), held in stl::maps in new TGLScene. Previous
shape hierarchy TGLScene object moved to local reference frame, and derives
from TGLLogicalShape. TGLPhysical shape holds translation matrix,
and color/transparency attributes, loads these before asking the referenced
TGLLogicalShape to draw.
- Dynamic scene builds: Only accept objects of interest into viewer - fall
within expanded camera limits, and above certain size c.f. whole scene. Viewer
can prompt external client (pad) to republish objects to it, when camera
limits have changed significantly. Logical shapes always retained, physicals
ones destroyed and cretaed as camera moves through scene. Enables viewer
to connect to very large geometries without being overloaded, pulling
required
parts
on
demand.
Extended
TGLCamera class with OfInterest() + other internals to test.
- Level of detail (LOD) scheme: Calculate a hint for quality of tessellation
(by projecting shape bounding box onto screen). Shape's Draw() passed this,
based on projected screen size - enable sensible tessellation (TGLSphere
only using at present).
- Common display list cache: TGLLogicalShape and TGLPhysicalShape derive
from common TGLDrawable, and can enable capture to common TGLDisplayListCache,
including LOD hints (caches each Draw of certain quality). TGLDrawable can
disable caching of general or LOD basis. (TGLSphere only using at present).
- Multi-pass rendering:
- Interactive (speed). Reduce all shapes LOD hint (tessellation cost),
draw sorted from large -> small objects, terminate after 150msec,
discard very low (small) LODs.
- Final(quality) - full LOD quality, unlimited time, no dropping.
Misc Internals
- TGLPerspectiveCamera/TGLOrthoCamera: Improve near/far clip plane calculations
- set using current projected scene limits. Reduces depth buffer precision
problems - seen particularly on MESA software GL.
- Added new TGLBoundingBox, supports both axis aligned and orientated BB,
with various overlap/projection testing in conjunction with TGL Camera classes.
- Tuning based on VTune examination
- Cache axes in TGLBoundingBox, reduce creation/destruction of excessive
temp objects.
- Add a cheap sphere/sphere test first in TGLBoundingBox::Overlap
- Only do scene rebuilds after a final quality draw has completed.
Added several debugging aids:
- Viewer debug mode - enable with 'd' key. Viewer stops automatic scene rebuilds
- these can be force explicitly using space key. Also draws out:
- Scene bounding box (Green)
- Camera interest frustum basis (Red)
- Camera interest frustum basis as box (Orange)
- Current interest box (Blue)
- Previous interest box (Grey)
- Tracing of viewer scene contents, draw loads, timing etc - variable level
of detail from gDebug=3 to gDebug=6
GL-in-TPad
- Reorganize internals of GL viewer to allow it to be embedded
directly into TP ad object.
- Removed all GUI components from core TGLViewer,
created new TGLSAViewer (SA = Standalone), derives from TGLViewer and
contains the TGLSAFrame GUI.
- Created new TGLManager (replacement for TGLKernel/TVirtualGL)
a base abstract class, responsible for window creation, gl-context/glpixmap
and context creation, manipulation with
gl-context
and gl-pixmap.
TGWin32GLManager - concrete implementation for Win32
TGX11GLManager - concrete implementation for X11.
- GL-in-TPad enabled with: gStyle->SetCanvasPreferGL(kTRUE) to
turn on GL
support.
- Development still in progress - notable limitations:
- Can be used with g3d
and geom now (not with hists, polylines or polymarkers, composite shapes
do not work).
- In case of complex geometry the selection is very slow now.
3D Viewer Infrastructure Overview
The 3D Viewer infrastructure has had a re-design to better support more advanced
viewers. It consists of:
- TVirtualViewer3D interface: An abstract handle to the viewer, allowing
client to test preferences, add objects, control the viewer via scripting
(to be added) etc.
- TBuffer3D class hierarchy: Used to describe 3D objects
("shapes")
- filled /added by negotiation with viewer via TVirtualViewer3D.
Together these allow clients to publish objects to any one of the 3D viewers
(currently OpenGL/x3d,TPad), free of viewer specific drawing code. They allow
our simple x3d viewer, and considerably more sophisticated OpenGL one to both
work with both geometry libraries (g3d and geom) efficiently.
Publishing to a viewer consists of the following steps:
- Create / obtain viewer handle
- Begin scene on viewer
- Fill mandatory parts of TBuffer3D describing object
- Add to viewer
- Fill optional parts of TBuffer3D if requested by viewer, and add again
... repeat 3/4/5
as required
- End scene on viewer
Creating / Obtaining Viewer
Create/obtain the viewer handle via local/global pad - the viewer is always
bound to a TPad object at present [This may be removed as a restriction in
the future] . You should perform the publishing to the viewer described below
in the Paint() method of the object you attach to the pad (via Draw())
TVirtualViewer3D * v = gPad->GetViewer3D("xxxx");
" xxxx" is viewer type: OpenGL "ogl", X3D "x3d" or
Pad "pad" (default). The viewer is created via the plugin manager,
attached to pad, and the interface returned.
Begin / End Scene
Objects must be added to viewer between BeginScene/EndScene calls e.g.
v->BeginScene();
.....
v->AddObject(....);
v->AddObject(....);
.....
v->EndScene();
The BeginScene call will cause the viewer to suspend redraws etc, and after
the EndScene the viewer will reset the camera to frame the new scene and redraw.
[x3d viewer does not support changing of scenes - objects added after the
first Open/CloseScene pair will be ignored.]
Filling TBuffer3D and Adding to Viewer
The viewers behind the TVirtualViewer3D interface differ greatly in their
capabilities e.g.
- Some know how to draw certain shapes natively (e.g. spheres/tubes in
OpenGL) - others always require a raw tessellation description of points/lines/segments.
- Some
need the 3D object positions in the global frame, others can cope with
local frames + a translation matrix - which can give considerable performance
benefits.
To cope with these situations the object buffer is filled out in negotiation
with the viewer. TBuffer3D classes are conceptually divided into enumerated
sections Core, BoundingBox, Raw etc (see TBuffer3D.h for more details).

The SectionsValid() / SetSectionsValid / ClearSectionsValid() methods of TBuffer3D
are used to test/set/clear these section valid flags.
The sections found in TBuffer3D (Core/BoundingBox/Raw Sizes/Raw)
are sufficient to describe any tessellated shape in a generic fashion. An additional ShapeSpecific section
in derived shape specific classes allows a more abstract shape description
("a sphere of inner radius x, outer radius y"). This enables a viewer
which knows how to draw (tessellate) the shape itself to do so, which can bring
considerable performance and quality benefits, while providing a generic fallback
suitable for all viewers.
The rules for client negotiation with the viewer are:
- If suitable specialized TBuffer3D class exists, use it, otherwise use
TBuffer3D.
- Complete the mandatory Core section.
- Complete the ShapeSpecific section
if applicable.
- Complete the BoundingBox if you can.
- Pass this buffer to the viewer using
one of the AddObject() methods - see below.
If the viewer requires more sections to be completed (Raw/RawSizes) AddObject()
will return flags indicating which ones, otherwise it returns kNone. You must
fill the buffer and mark these sections valid, and pass the buffer again. A
typical code snippet would be:
TBuffer3DSphere sphereBuffer;
// Fill out kCore...
// Fill out kBoundingBox...
// Fill out kShapeSpecific for TBuffer3DSphere
// Try first add to viewer
Int_t reqSections = viewer->AddObject(buffer);
if (reqSections != TBuffer3D::kNone) {
if (reqSections & TBuffer3D::kRawSizes) {
// Fill out kRawSizes...
}
if (reqSections & TBuffer3D::kRaw) {
// Fill out kRaw...
}
// Add second time to viewer - ignore return cannot do more
viewer->AddObject(buffer);
}
}
ShapeSpecific: If the viewer can directly display the buffer without
filling of the kRaw/kRawSizes section it will not need to request client side
tessellation.
Currently we provide the following various shape specific classes, which the
OpenGL viewer can take advantage of (see TBuffer3D.h and TBuffer3DTypes.h)
- TBuffer3DSphere - solid, hollow and cut spheres*
- TBuffer3DTubeSeg - angle tube segment
- TBuffer3DCutTube - angle tube segment with plane cut ends.
*OpenGL only supports solid spheres at present - cut/hollow ones will be
requested tessellated.
Anyone is free to add new TBuffer3D classes, but it should be clear that the
viewers require updating to be able to take advantage of them. The number of
native shapes in OpenGL will be expanded over time.
BoundingBox: You are not obliged to complete this, as any viewer
requiring one internally (OpenGL) will build one for you if you do not provide.
However
to do this the viewer will force you to provide the raw tessellation, and the
resulting box will be axis aligned with the overall scene, which is non-ideal
for rotated shapes.
As we need to support orientated (rotated) bounding boxes, TBuffer3D requires
the 6 vertices of the box. We also provide a convenience function, SetAABoundingBox(),
for simpler case of setting an axis aligned bounding box.
Master/Local Reference Frames
The Core section of TBuffer3D contains two members relating to reference
frames:
fLocalFrame & fLocalMaster. fLocalFrame indicates
if any positions in the buffer (bounding box and tessellation vertexes) are
in local or master (world
frame). fLocalMaster is a standard 4x4 translation matrix (OpenGL
colum major ordering) for placing the object into the 3D master frame.
If fLocalFrame is kFALSE, fLocalMaster should contain an
identity matrix. This is set by default, and can be reset using SetLocalMasterIdentity() function.
Logical & Physical Objects
There are two cases of object addition:
- Add this object as a single independent entity in the world reference
frame.
- Add
a physical placement (copy) of this logical object (described in local
reference frame).
The second case is very typical in geometry packages, GEANT4, where we have
very large number repeated placements of relatively few logical (unique) shapes.
Some viewers (OpenGL only at present) are able to take advantage of this by
identifying unique logical shapes from the fID logical ID member of
TBuffer3D. If repeated addition of the same fID is found, the shape
is cached already - and the costly tessellation does not need to be sent again.
The viewer can
also perform internal GL specific caching with considerable performance gains
in these cases.
For this to work correctly the logical object in must be described in TBuffer3D
in the local reference frame, complete with the local/master translation. The
viewer indicates this through the interface method
PreferLocalFrame()
If this returns kTRUE you can make repeated calls to AddObject(), with TBuffer3D
containing the same fID, and different fLocalMaster placements.
For viewers supporting logical/physical objects, the TBuffer3D content refers
to the properties of logical object, with the fLocalMaster transform and the
fColor and fTransparency attributes, which can be varied for each physical
object.
As a minimum requirement all clients must be capable of filling the raw tessellation
of the object buffer, in the master reference frame. Conversely viewers must
always be capable of displaying the object described by this buffer.
Scene Rebuilds
It should be understood that AddObject is not an explicit command to the viewer
- it may for various reasons decide to ignore it:
- It already has the object internally cached .
- The object falls outside
some 'interest' limits of the viewer camera.
- The object is too small to
be worth drawing.
In all these cases AddObject() returns kNone, as it does for successful addition,
simply indicating it does not require you to provide further information about
this object. You should
not try to make any assumptions about what the viewer did with it.
This enables the viewer to be connected to a client which sends potentially
millions of objects, and only accept those that are of interest at a certain
time, caching the relatively small number of CPU/memory costly logical shapes,
and retaining/discarding the physical placements as required. The viewer may
decide to force the client to rebuild (republish) the scene (via
a TPad
repaint
at
present),
and
thus
collect
these
objects if
the
internal viewer state changes. It does this presently by forcing a repaint
on the attached TPad object - hence the reason for putting all publishing to
the viewer in the attached pad objects Paint() method. We will likely remove
this requirement in the future, indicating the rebuild request via a normal
ROOT signal, which the client can detect.
Physical IDs
TVirtualViewer3D provides for two methods of object addition:virtual Int_t AddObject(const
TBuffer3D & buffer, Bool_t * addChildren = 0)
virtual Int_t AddObject(UInt_t physicalID, const TBuffer3D & buffer, Bool_t * addChildren = 0)
If you use the first (simple) case a viewer using logical/physical pairs
will generate IDs for each physical object internally. In the second you
can specify
a unique identifier from the client, which allows the viewer to be more
efficient. It can now cache both logical and physical objects, and only discard
physical
objects no longer of interest as part of scene rebuilds.
Child Objects
In many geometries there is a rigid containment hierarchy, and so if the viewer
is not interested in a certain object due to limits/size then it will also
not be interest in any of the contained branch of descendents. Both AddObject()
methods have an addChildren parameter. The viewer will complete this (if passed)
indicating if children (contained within the one just sent) are worth adding.
Recyling TBuffer3D
Once add AddObject() has been called, the contents are copied to the viewer
internally. You are free to destroy this object, or recycle it for the next
object if suitable.
New printing facilities in batch via TASImage
TASImage is an
interface to image processing library using libAfterImage.
It allows reading and writing of images in different
formats, several image manipulations (scaling, tiling, merging,
etc.) and displaying in pads.
The size of the image on the screen does not depend on the original
size of the image but on the size of the pad. Therefore it is very
easy to resize the image on the screen by resizing the pad.
Besides reading an image from a file an image can be defined by a
two dimensional array of values. A palette defines the color of
each value.
The image can be zoomed by defining a rectangle with the mouse.
The color palette can be modified with a GUI, just select
StartPaletteEditor() from the context menu.
The new class TImageDump using TASImage and derived from TVirtualPS
allows to save canvas in GIF, JPEG etc, image formats in batch mode.
Before this clas was intriduced it was not possible to generate bitmap files
(in particular GIFfiles) in batch, such files were generated from a TCanvas.
Now the method TPad::Print or TPad::SavesAs can be used
in macro running in batch (root -b) to generated bitmap files
(gif, jpeg, png, xpm, tiff). Example:
$ root -b
root [0] .x hsimple.C
root [1] c1->Print("c1.gif");
The full description of TPad::Print options is now:
TPad::Print(const char *filename, Option_t *option)
filename extension (or option) can be:
"ps" - Postscript file is produced (see special cases below)
"eps" - an Encapsulated Postscript file is produced
"pdf" - a PDF file is produced
"svg" - a SVG file is produced
"gif" - a GIF file is produced
"xpm" - a XPM file is produced
"png" - a PNG file is produced
"jpg" - a JPEG file is produced
"tiff" - a TIFF file is produced
"cxx" - a C++ macro file is produced
"xml" - a XML file
"root" - a ROOT binary file
Some extras options:
"Portrait" - Postscript file is produced (Portrait)
"Landscape" - Postscript file is produced (Landscape)
"Preview" - an Encapsulated Postscript file with preview is produced.
All these option (except "Preview") are availabe from the File menu in TCanvas.
TImageDump
TImageDump save canvas as an image (GIF, JPEG, PNG, XPM, TIFF etc.)
It can be used in any mode (batch, interactive) as follows:
TCanvas *c1;
TImageDump *imgdump = new TImageDump("test.png");
c1->Paint();
imgdump->Close();
Other new features in the graphics area
TGraph2D
New option "Line" to paint TGraph2D. TGraph2D are connected with
with a 3D polyline.
TStyle
- New data member and corresponding Getter/Setter
Width_t fLegendBorderSize; //TLegend box border size
Width_t GetLegendBorderSize() const {return fLegendBorderSize;}
void SetLegendBorderSize(Width_t size=4)
The "Plain" style initializes the legend border size to 1.
All other styles to 4.
In TLegend constructor, the legend border size is set by default to
the current value in gStyle.
- The line styles defined via TStyle::SetLineStyleString() are now
available for all graphical interfaces: SVG, PostScript, PDF, X11, and
Win32GDK. Previously they were visible only in PostScript files. They
are still missing for Qt driver.
- Line styles 5 to 10 are predefined.
- TGedAttLineEditor shows the new line styles.
TPaveStats
Skewness and kurtosis can now be displayed in TPaveStats (1D and 2D
histos).
Skewness and kurtosis are available in the TPaveStats editor
Errors can be displayed for 2D histograms statistics.
- New method SetHatchesLineWidth to set the hatches line width for
hatch styles > 3100
TPad
New method BuildLegend to automatically add a TLegend in a Pad.
TGraph2D
New method SetHistogram. It allows to define the histogram to be
filled. This is useful to set the range of the X and Y axis.
Example:
void graph2dhist()
{
TCanvas *c = new TCanvas("c","Graph2D example",0,0,700,600);
Double_t x, y, z, P = 6.;
Int_t np = 300; // generate this many nodes
TGraph2D *dt = new TGraph2D();
TH2D* h2 = new TH2D("h2","h2",40,-6,6,40,-10,10);
dt->SetHistogram(h2);
TRandom *r = new TRandom();
for (Int_t N=0; N<np; N++) {
x = 2*P*(r->Rndm(N))-P;
y = 2*P*(r->Rndm(N))-P;
z = (sin(x)/x)*(sin(y)/y)+0.2;
dt->SetPoint(N,x,y,z);
}
gStyle->SetPalette(1);
dt->Draw("TRI1 p0");
}
TASImage
- New method GetImageBuffer is introduced. It returns in-memory buffer
compressed according to the image type.
Buffer must be deallocated after usage.
This method can be used for sending images over the network.
- New method SetImageBuffer introduced. It creates image from compressed
buffer. Supported formats:
PNG - by default
XPM - two options exist:
1. xpm as a single string (raw buffer). Such a string
is returned by GetImageBuffer method.
For example:
char *buf;
int sz;
im1->GetImageBuffer(&buf, &int, TImage::kXpm); /*raw buffer*/
TImage *im2 = TImage::Create();
im2->SetImageBuffer(&buf, TImage::kXpm);
2. xpm as an array of strigs (preparsed)
For example:
char *xpm[] = {
"64 28 58 1",
" c #0A030C",
". c #1C171B"
...
TImage *im = TImage::Create();
im->SetImageBuffer(xpm, TImage::kXpm);
- Custom Streamer was implemented. That allows to save images in ROOT files.
Image's thumbnail is also saved into a file.
- galaxy_image.C tutorial is modified according to new saving schema.
- New demo file gallery.root added to tutorials. It contains thumbnailed
and browsable pictures produced by some ROOT tutorials.
- Fix bug im TASImage::DrawRectangle methods. Thanks to Thomas Bretz
for reporting it.
- TKey class.
Possibility to save thumbnail/icon as XPM string along with object added.
Currently such mechanism is used for saving thumbnailed images.
- TGPicture. Platform-dependent code was removed. Now TGPictures
are created by TImage objects.
- TRootBrowser classes. Possibility to show objects with dynamically created
icons added.
PostScript / PDF
- Structuting directive %%Orientation added in PS files.
This allows the PostScript viewers
(like gv) to display automatically the PS files with the correct
orientation.
- Optimize size of markers in case of very small pads
- Patterns number 1 to 25 are now available in PDF
- PostScript and PDF files can now use the CMYK color model. A new TStyle method
(SetColorModelPS) allows to choose the color model (RGB or CMYK).
TStyle::SetColorModelPS(Int_t c)
Defines the color model use by TPostScript and TPDF (RGB or CMYK).
CMY and CMYK models are subtractive color models unlike RGB which is an
additive. They are mainly used for printing purposes. CMY means Cyan Magenta
Yellow to convert RGB to CMY it is enough to do: C=1-R, M=1-G and Y=1-B.
CMYK has one more component K (black). The conversion from RGB to CMYK is:
Double_t Black = TMath::Min(TMath::Min(1-Red,1-Green),1-Blue);
Double_t Cyan = (1-Red-Black)/(1-Black);
Double_t Magenta = (1-Green-Black)/(1-Black);
Double_t Yellow = (1-Blue-Black)/(1-Black);
CMYK add the black component which allows to have a better quality for black
printing. PostScript and PDF support the CMYK model.
c = 0 means TPostScript and TPDF will use RGB color model (default)
c = 1 means TPostScript and TPDF will use CMYK color model
TArrow
It is now possible to draw "begin" and "end" bars on arrows.
TArrow, TCurlyArc,TCurlyLine
Implement default attributes values and the corresponding getters
and setters
TArrow
static Float_t fgDefaultAngle; //default Arrow opening angle (degrees)
static Float_t fgDefaultArrowSize; //default Arrow Size
static TString fgDefaultOption; //default Arrow shapes
TCurlyArc
static Double_t fgDefaultWaveLength; //default wavelength
static Double_t fgDefaultAmplitude; //default amplitude
static Bool_t fgDefaultIsCurly; //default curly type
TCurlyLine
static Double_t fgDefaultWaveLength; //default wavelength
static Double_t fgDefaultAmplitude; //default amplitude
static Bool_t fgDefaultIsCurly; //default curly type
These default value are used at creation time for these primitives.
Bug fixes ad Improvments in Graphics area
TMultiGraph
Add a new function
Option_t *TMultiGraph::GetGraphDrawOption(const TGraph *gr) const
Which returns the draw option for the TGraph gr in this TMultiGraph.
The return option is the one specified when calling TMultiGraph::Add(gr,option).
TStyle
In SetPalette: The DeepSea palette is defined only if needed. Without
this protection the following macro went slower and slower.
{
for (int i=0; i<10; i++) {
TStopwatch clock;
clock.Start();
gStyle->SetPalette(51, NULL);
clock.Print();
}
}
TCreatePrimitives
Some log scales support was missing
TGraphDelaunay (TGraph2D drawing)
Postpone the creation of the triangles data structure and the hull
finding. They are now done only when really needed. This increases the
performances in cases where triangles and hull are not useful, for
instance when a TGraph2D is drawn with option "P" only.
TH1
TH1::TH1() now uses UseCurrentStyle() to initialize the default
histogram "style parameters". In particular it initializes properly the
Histogram Fill Color to 0 which prevent the following three lines to
generate a "X11 Fatal Error".
TH1D h
h.SetBins(5000000,0,1)
h.Draw()
TGraph
A better version of the TGraph constructor creating a TGraph from an input ascii file.
TArrow
Complete rewrite of TArrow::PaintArrow. The previous version used the
pixel coordinates. This method generated many rounding errors. The
visible effects on arrows were:
- distorted arrows' heads
- misplaced arrow compared to a Tline at the same coordinates.
The new TArrow::PaintArrow version fixes these two problems. Instead of
using pixel coordinates it uses "true NDC" coordinates. The "ROOT NDC
coordinates" are not appropriate in this case because X an Y axis are not normalized
the same way, therefore angles are not kept during a rotation.
THStack
- The maximum number of histograms in a THStack plotted as lego plot was
18. Now there is no limit anymore.
- THStack colors are now stored in a dynamic arrays. Previously they were
stored in a fixed length arrays of 10 entries.
2D polygons clipping
Clip polygons using the Sutherland-Hodgman algorithm. The previous
algorithm used (Cohen-Sutherland) is a line clipping algorithm which
produces wrong results on polygons. This new algorithm is implemented in
the function TPad::ClipPolygon used in the PaintFillArea method in its
Double_t version ONLY. The Float_t version of PaintFillArea prints a
warning.
Sutherland and Hodgman's polygon-clipping algorithm uses a divide-and-conquer
strategy: It solves a series of simple and identical problems that, when
combined, solve the overall problem. The simple problem is to clip a polygon
against a single infinite clip edge. Four clip edges, each defining one boundary
of the clip rectangle, successively clip a polygon against a clip rectangle.
Steps of Sutherland-Hodgman's polygon-clipping algorithm:
- Polygons can be clipped against each edge of the window one at a time.
Windows/edge intersections, if any, are easy to find since the X or Y coordinates
are already known.
- Vertices which are kept after clipping against one window edge are saved for
clipping against the remaining edges.
- Note that the number of vertices usually changes and will often increases.
The clip boundary determines a visible and invisible region. The edges from
vertex i to vertex i+1 can be one of four types:
- Case 1 : Wholly inside visible region - save endpoint
- Case 2 : Exit visible region - save the intersection
- Case 3 : Wholly outside visible region - save nothing
- Case 4 : Enter visible region - save intersection and endpoint
PostScript
Protection added to TVirtualPS::PrinStr and TVirtualPS::PrintFast
to take into account the terminating null character.
THistPainter::PaintErrors
The polygon drawn in case of option E3 (and E4) was
wrongly clipped when a Y value was greater than the Y axis maximum.
TCanvas
The TCanvas size in interactive mode and batch mode were different (4
pixels horizontally and 28 vertically). Most of the time this was not a
real problem. But in some cases the same macro produced a different
result executed interactively or in batch. For instance the following
macro executed in batch did not show the histogram title in the
PostScript output. This patch make sure that batch interactive canvas
sizes are the same.
{
TCanvas *c2 = new TCanvas("c2","",0,0,600,900);
c2->Divide(3,3);
TH1F *h = new TH1F("h","This is a really long title for test purposes only
hopefully long enough hehehe",100,0,100);
c2->cd(1);
h->Draw();
c2->Print("test.ps");
}
TLegend
In case the user doesn't supply a label for the legend entry (or NULL pointer)
the label for the entry is set to the title of the TObject referenced in the
first argument.
TTF
Font wingding.ttf (number 14) was not working. Nothing was displayed.
TGraphErrors
The fill style for boxes (option 3) was ignored.
TGaxis
Always paint the axis title before painting the tick marks.
This fixes a problem when setting the number of divisions to 0.
In this case the axis title was not drawn.
TGraphErrors
If a point is outside the pad limits it is set
to the limit it exceed. Previously it was not initialized. This produced
random drawing with the following macro:
{
const int n=200;
double x[n],y[n],e[n];
TCanvas *c1 = new TCanvas("c1", "Test",800,600);
for (int i=0;i<n;i++) {
x[i]=i;
y[i]=sqrt(i);
e[i]=y[i]/(i+1);
}
TH1D *Fond = new TH1D("Fond","",2,0,n);
Fond->SetMinimum(0);
Fond->SetMaximum(10);
Fond->Draw();
TGraphErrors *gr = new TGraphErrors(n,x,y,0,e);
gr->SetFillColor(17);
gr->Draw(" E3");
}
GL/gl2ps
- New version of gl2ps
- New options to improve outline drawing in GL/PS files.
THistPainter
Problems in CONT4 contour option fixed:
- Tick marks were on the wrong axis' side.
- It was not possible to draw axis's grid.
- SetTickx() and SetTicky() had no effect.
The axis for CONT4 are now drawn with THistPainter::PaintAxis(), not
anymore using TPainter3dAlgorithms.
Qt interface
New tutorials
- double32.C
- loopdir.C
- treefriend.C
- fitLinearRobust.C
- RoofitDemo.C
- assembly.C
- mathcoreVectorIO.C
- mathcoreVectorCollection.C
- mathcoreStatFunc.C
- mathcoreSpecFunc.C
- mathcoreTreeLV.C
- mathcoreLV.C
- mathcoreGenVector.C
- mathcoreCDF.C
- mathcoreTreeLV.C
ROOT page - Class index - Top of the page