ROOT Version 5.08/00 Release Notes


ROOT version 5.08/00 has been released December 15, 2005.

Binaries for all supported platforms are available at:

      http://root.cern.ch/root/Version508.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,
Jan Conrad,
Olivier Couet,
Christophe Delaere,
Denis Favre-Miville,
Valeri Fine,
Mark Fishler,
Markus Frank,
John Frankland,
Gerri Ganis,
Andrei Gheata,
Mihaela Gheata,
Masaharu Goto,
Andy Hanushevsky,
Christian Holm Christensen,
Anna Kreshuk,
Wim Lavrijsen,
Sergei Linev,
Jose Lo,
John Marraffino,
Pere Mato,
Richard Maunder,
Lorenzo Moneta,
Axel Naumann,
Paul Nilsson,
Eddy Offermann,
Valeriy Onuchin,
Andreas Peters,
Muriel Pivk,
Timur Pocheptsov,
Fons Rademakers,
Stefan Roiser,
Paul Russo,
Andras Zsenei


Base

License Change

With this release we've moved to the LGPL 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/...

New Class TPRegexp and PCRE Interface

The new TPRegexp class provides an interface to the PCRE (Perl Compatible Regular Expression) library. The TPRegexp class has also been interfaced with the TString class for easy string regexp operations.

A new tutorial regexp.C shows the power of this regexp class.

New TGFALFile and TGFALSystem Classes

A TGFALFile is like a normal TFile except that it reads and writes its data via the underlaying Grid access mechanism. TGFALFile file names are either a logical file name, a guid, an SURL or a TURL, like:
   gfal:/lfn/user/r/ram/galice.root
Grid storage interactions today require using several existing software components: The GFAL library hides these interactions and presents a Posix interface for the I/O operations. The currently supported protocols are: file for local access, dcap, gsidcap and kdcap (dCache access protocol) and rfio (CASTOR access protocol).

File naming convention: A file name can be a Logical File Name (LFN), a Grid Unique IDentifier (GUID), a file replica (SURL) or a Transport file name (TURL):

Note that for the TGFALFile plugin to work, all these pathnames should be prepended by gfal:.

The code is provided by the libGFAL plugin.

New MonaLisa Monitoring Pluging

New class TMonaLisa The new class TMonaLisa defines an interface to the MonaLisa Monitoring Services in ROOT. The TMonaLisa object is used to send monitoring information to a MonaLisa server using the MonaLisa ApMon package (libapmoncpp.so/UDP packets). The MonaLisa ApMon library for C++ can be downloaded at http://monalisa.cacr.caltech.edu/monalisa__Download__ApMon.html, with the current version being:

http://monalisa.cacr.caltech.edu/download/apmon/ApMon_cpp-2.0.6.tar.gz

The ROOT implementation is primary optimized for process/job monitoring, although all other generic MonaLisa ApMon functionality can be exploited through the ApMon class directly via gMonaLisa->GetApMon().

Improvements in the Build System on Windows

Several optimizations in the build system fix the problem where all plugins had to be relinked if either libCore or libCint was changed. Now this does not happen anymore, bringing the build efficiency to the level of the one on Unix/Linux.

Added Support for VC++2005

Made several modifications to support the new Microsoft VC++ 2005 compiler.

New TString Methods

New methods: These methods allow typical string based representations of floating point and integer numbers to be converted to floats and ints, like:
    "1 3030 440.0" or "123 456"

Miscellaneous

New option --config to root-config which returns the full string used to configure this specific version of ROOT.

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 TBits feature

We added support for the operators: |,&,^,<<.>>,|=,&=,^=,>>=,<<= and []  and for printing a TBits object via an ostream.

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.
Support for FreeBSD6 (autodetected by ./configure).

Thread Safety

Work has been done to make more classes thread safe, like when accessing global TROOT containers and classes like TDatime, TTimestamp, etc.

CINT


Developments in Trees

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%)! In addition we solved several issue involving complex class structures and collections (see cvs logs for details)

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 allowed 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.

We extended the support for pointers to varying length arrays of objects to include the cases:

  1. Foreign Objects: objects whose classes do not have a ClassDef macro, but do have dictionaries loaded (no default Streamer, but we do have TStreamerInfo).       
  2. Objects of classes with custom Streamer functions.
  3. Reading an object from a file when we do not have the dictionary loaded for the object's class, and then writing that object out to a file again (emulated objects).  This allows us to copy trees without have to have the class dictionaries loaded.
  4. Note that we still do not support the case of STL objects.

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.

TDirectory::Get and TDirectory::GetObject now rely on recursivity rather than changing the current directory to handle pathname.  This solves a problem appearing when the object looked-for has the same name as one.

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
We fixed a problem in arithmetic operation when signed char array (whichcan also be used as a string) is on the right hand.
We fixed a couple of issue regarding how saved TFormulas were restored by TFormula::Streame when they contain calls to external C++ function like TMath::Abs).

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 TFileSQL

Introduce a "transparent" access to SQL data base via standard TFile interface.

The main approach that each class (but not each object) has one or two tables with names like $(CLASSNAME)_ver$(VERSION) and $(CLASSNAME)_streamer_ver$(VERSION) For example: TAxis_ver8 or TList_streamer_ver5 Second kind of tables appears, when some of class members can not be converted to normalized form or when class has custom streamer. For instance, for TH1 class two tables are required: TH1_ver4 and TH1_streamer_ver4 Most of memebers are stored in TH1_ver4 table columnwise, and only memeber:

Double_t*  fBuffer;  //[fBufferSize]
can not be represented as column while size of array is not known apriory. Therefore, fBuffer will be written as list of values in TH1_streamer_ver4 table. All objects, stored in the DB, will be registered in table "ObjectsTable". In this there are following columns: Data in each "ObjectsTable" row uniqly identify, in which table and which column object is stored. In normal situation all class data should be sorted columnwise. Up to now following member are supported:
  1. Basic data types.
    Here is everything clear. Column SQL type will be as much as possible close to the original type of value.
  2. Fixed array of basic data types
    In this case n columns like fArr[0], fArr[1] and so on will be created. If there is multidimensional array, names will be fArr2[1][2][1] and so on
  3. Parent class.
    In this case version of parent class is stored and data of parent class will be stored with the same obj:id in corrspondent table. There is a special case, when parent store nothing (this is for instance TQObject). In that case just -1 is written to avoid any extra checks if table exist or not.
  4. Object as data member.
    In that case object is saved in normal way to data base and column will contain id of this object.
  5. Pointer on object.
    Same as before. In case if object was already stored, just its id will be placed in the column. For NULL pointer 0 is used.
  6. TString.
    Now column with limited width like VARCAHR(255) in MySQL is used. Later this will be improved to support maximum possible strings
  7. Anything else.
    Data will be converted to raw format and saved in _streamer_ table. Each row supplied with obj:id and row:id, where row:id indicates data, corresponding to this particular data member, and column will contain this raw:id
See the TSQLFile documentation for more details.
	 example of a session saving data to a SQL data base
	 =====================================================
	
	  const char* dbname = "mysql://host.domain:3306/dbname";
	  const char* username = "username";
	  const char* userpass = "userpass";
	
	  // Clean data base and create primary tables
	  TSQLFile* f = new TSQLFile(dbname, "recreate", username, userpass);
	  // Write with standard I/O functions
	  arr->Write("arr",TObject::kSingleKey);
	  h1->Write("histo");
	  // Close connection to DB
	  delete f;

	 example of a session read data from SQL data base
	 =====================================================
	
	  // Open database again in read-only mode
	  TSQLFile* f = new TSQLFile(dbname, "open", username, userpass);
	  // Show list of keys
	  f->ls();
	  // Read stored object, again standard ROOT I/O
	  TH1* h1 = (TH1*) f->Get("histo");
	  if (h1!=0) { h1->SetDirectory(0); h1->Draw(); }
	  TObject* obj = f->Get("arr");
	  if (obj!=0) obj->Print("*");
	  // close connection to DB
	  delete f;
	
Known problems and open questions.
  1. TTree is not supported by TSQLFile. There is independent development of TTreeSQL, which allows to store trees directly in SQL database
  2. TDirectory cannot work. Hopefully, will (changes in ROOT basic I/O is required)

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

Many new features have been introduced in the PROOF system. A new communication layer based on the top component of  XROOTD has been implemented. The new layer allows, in particular, to connect to the same PROOF sessions from different client terminals, to disconnect from a running session and to reconnect to a later time. The XROOTD server running XrdProofdProtocol, shortly XPD, acts as a coordinator or manager of PROOF sessions. To map on the client side the manager functionality brought by XPD, a new class has been introduced, TVirtualProofMgr. 

TVirtualProof has also been extended to accommodate the possibility of multiple sessions, to support asynchronous running mode and to handle the results of processed queries.

Finally a completely new GUI has been designed to handle all the new functionality in a more user-friendly way.

The libXrdProofd.so plugin

This library contains the code to run the protocol XrdProofdProtocol in a XROOTD application. A new application, xproofd, running by default the new protocol is available in $ROOTSYS/bin . To start the new daemon just make sure that $ROOTSYS and the execution and library paths are correctly set and execute

  ~> xproofd -p 1093

This will start a daemon with default settings, listening on port 1093 (for the time being the rootd default 1094 is hard-coded in XRD; it will be made configurable for future releases). The relevant directives applying to xrootd can be given via configuration file (the port can be specified there):

  ~> xproofd -c xpd.cf

See $ROOTSYS/etc/xpd.cf for an example activating authentication via the usual $HOME/.rootdpass file .
Examples of startup scripts can also be found in  $ROOTSYS/etc (see startXRD.sh, for a generic standalone script starting xrootd or xproofd in the background, and 'xproofd' for a init.d-like script).

TVirtualProofMgr: Proof Session manager

This class implements manager functionality for sessions. A manager instance is initialized using the static method TVirtualProofMgr::Create by passing the URL of the master, e.g.

root[0] TVirtualProofMgr *mgr = TVirtualProofMgr::Create("pcepsft43.cern.ch:5252")

There is one instance per unique master URL. The list of instantiated managers in available via gROOT->GetListOfProofs(). The list of sessions known the manager is available via  TVirtualProofMgr::QuerySessions():

root [1] TList *sessions = mgr->QuerySessions()
// # 1
// alias: pcepsft43.cern.ch, url: "proof://pcepsft43.cern.ch:5252/"
// tag: 0-pcepsft43-1134569200-31505
// status: idle, attached: NO (remote ID: 0)
(class TList*)0x93e5518

To be able to use the session one needs to attach to it with TVirtualProofMgr::AttachSession(Int_t locid):

root [2] TProof *p = mgr->AttachSession(1)
Starting master: opening connection ...
Starting master: OK
PROOF set to parallel mode (2 workers)
(class TVirtualProof*)0x91d59a0

Argument to AttachSession is the local ID of the session as shown by  QuerySessions. The attach operation is fast since there is no need to start any new process, but just to restore the connection.
A new session can be created using TVirtualProofMgr::CreateSession(const char *conf_file, ...):

root [3] TProof *p2 = mgr->CreateSession("proof.test.conf")
Starting master: opening connection ...
Starting master: OK
Opening connections to workers: OK (2 workers)
Setting up worker servers: OK (2 workers)
PROOF set to parallel mode (2 workers)
(class TVirtualProof*)0x9441070

the main argument being here the name of the configuration file to be used.
The additional functionality provided by the manager relates to disconnection; DetachSession(Int_t locid)  justs disconnect from the session, while ShutdownSession(Int_t locid) terminates the session. The same actions  are available from TProof using the new methods Detach() and Detach("S"), respectively; e.g., in the above example, p2->Detach("S") would terminate the second session.

The full manager functionality requires the new XProofd communication layer. The class works with reduced functionality also with the standard communication layer: CreateSession and AttachSession both create a new session (AttachSession using the default configuration file; and so are DetachSession and ShutdownSession, both terminating the session.

Sessions can still be started via TROOT::Proof(...): the relevant manager is started or attached to internally and the first active session is attached to; if none is available, a new one is created. TROOT::Proof returns now a pointer to the started session, to keep track of the sessions. For example, equivalent to the above is the following:

root[0] TProof *p = gROOT->Proof("pcepsft43.cern.ch:5252")


It is also possible to force the creation of a new session :

root[0] TProof *p2 = gROOT->Proof("pcepsft43.cern.ch:5252/?N")

The syntax is very convenient to exploit the disconnect/reconnect functionality when working with only one session.

The manager is able to detect automatically the kind of remote server (i.e. xprood of prood); this information is avaibale via TVirtualProofMgr::IsProofd().

Multi sessions

As mentioned above, the limit to only one PROOF session per ROOT client session has been removed. Sessions are started via the manager or TROOT::Proof(...) as shown above. The global gProof  refers now to the last open session or to the session selected via TProof::cd().
The list of active PROOF sessions per manager is available via TVirtualProofMgr::QuerySessions; the started managers via the global list gROOT->GetListOfProofs().

Each session has:



A Powerful New PROOF Session Management GUI

A new GUI which allows easy access to the many new PROOF features described above. The GUI is especially important now that we can have many active PROOF sessions each running mulitple queries. To start the new PROOF GUI do:
   gROOT->Proof()

 

Other improvements


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 in the new tutorial 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()

Capacity of shapes and weight of volumes

Analytical computation of shapes capacity implemented for most of the shapes:

   Double_t TGeoShape::Capacity() const;

The capacity cannot be computed for Boolean shapes in the general case, so the implementation for TGeoCompositeShape class is providing an estimate with 1% error (by sampling). Capacity is computed in [length3] where [length] is the used unit in defining the shape parameters.

The volume weight can be computed for a volume in a recursive way based on the shape capacity. This represents the sum of the weights of all daughter volumes plus the weigth of the unoccupied region of the volume itself.

   Double_t TGeoVolume::Weight(Double_t precision=0.01, Option_t *option="va");

In the method above, precision is meaningful only if the option does not contain "a" (analytical). In this case the weigth is estimated by sampling points in the volume bounding box. The letter "v" in option turns on verbosity.

Note: For weight computation, the length unit is assumed to be centimeter. Gases with density less than 0.01 are ignored.

Alignment of physical nodes

Physical nodes represent a unique object in the geometry, represented by a path like:

/TOP_1/A_1/B_5/C_3

Each element in this path represent a logical node identifier (volume positioned with respect to its mother volume frame) and provides a relative transformation matrix with respect to the frame defined by the upper level. The product of all transformations in the branch define the unique position of the object in the master frame. This transformation can be computed only after the geometry has been closed and represent the original (ideal) position of the object. The class TGeoPhysicalNode provides the tools to unalign the object C_3 with another relative matrix (w.r.t. volume B) after the geometry was closed.

   TGeoPhysicalNode::TGeoPhysicalNode(const char *path);

In order to unalign a physical node, one can either modify the existing matrix of C_3 by casting it to the proper type, or just provide a new matrix :

   TGeoTranslation *tr = (TGeoTranslation*)physNode->GetNode()->GetMatrix();
tr->SetTranslation(new_x, new_y, new_z);
physNode->Align(tr);

If a new matrix was provided, its ownership will pass to TGeoManager class. Note that one can also change the shape of the aligned node:

   void TGeoPhysicalNode::Align(TGeoMatrix *newmat=0, TGeoShape *newshape=0, Bool_t check=kFALSE);

The original global matrix of the physical node before mis-alignment caAn optional check can be performed to see if the align operation produces an illegal overlap.n be accessed at any time:

   TGeoHMatrix * TGeoPhysicalNode::GetOriginalMatrix() const

The manager class TGeoManager owns the list of all defined physical nodes:

   TObjArray *TGeoManager::GetListOfPhysicalNodes();

Notes:

An example of applying mis-alignment to an ideal geometry can be found at:

$ROOTSYS/tutorials/geodemo.C
http://root.cern.ch/root/html/examples/geodemo.C.html

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:

The usual way of generating dictionary information for and interacting with Reflex is as follows:

  1. 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.
  2. The so generated C++ files are compiled into a library
  3. Through a Builder API the dictionary library will be loaded into the Reflex system
  4. The Reflex user API provides the reflection information about the original C++ definitions.

The main user types of the Reflex API are:

Code changes since the import from the SEAL repository:

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.

Cintex and Reflex Integration

As a non-production, developer testing feature, rootcint can generate dictionaries which use the Reflex API. There are two options to generate such a dictionary: using cint's C++ parser, and using gccxml. The latter allows to validate and study the gccxml generated dictionaries.

None of them is meant to be a replacement for Cint's dictionaries yet; functionality is limited, even when using Cintex. You can generate reflex dictionaries for ROOT itself, loading the dictionaries into Cint using Cintex. You can not, however, generate non-cint dictionaries for any classes in Core, Hist, Graf, Graf3d, Gpad, Tree, and Matrix, due to dictionary initialization problems.

In a future release, Cint's dictionaries will be replaced by Reflex dictionaries. ROOT will support both generator options, rootcint and gccxml; there will be no need for Cintex, as Cint will use the Reflex API directly.

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 (in particular: STL), 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, range-checking of unsigned integer types, 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, all C++ typedefs now map onto the same python type, and typed null pointers (for use as value holders through pass-by-ref) can be created. A generic __setitem__ handler has been added that will allow assignment if a C++ class offers return by reference for operator[](int).

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. RINT, and the initial startup environment is more closely mimicking RINT. Tab-completion is added for file names in the local directory structure. Wrapper object prints show the C++ object address. Further workarounds for IPython are provided.

During startup, no GUI thread will be started in batch mode, and the creation of a TApplication object can be pre-empted. The shutdown sequence of the ROOT module has been made explicit, and, in interactive mode, C++ signals such as segmentation violations are turned (after a printing stack trace) into python exceptions. C++ globals now act just like python globals do.

Pythonization

TMinuit::SetFCN now accepts python functions, as do TF2/3 (modeled after the support for TF1). Use of TClonesArray is now safe. TTree, TBranch, and TFile member templates are available: the appropriate casting is done internally, based on the available run-time type information. TTree direct data access has been improved in speed and functionality. STL vector and string can be used with python-style iteration.





Linear Algebra package: IMPORTANT WARNINGS

The next version (in 2006) of the TMatrix and TVector classes will be using templates. As a result, the classes currently named TMatrixD, TMatrixF, TVectorD, TVectorF will become typedefs to TMatrix, TMatrix, TVector, TVector. The new package itself is totally back compatible. However you will not be able anymore to use forward declarations of the type
 class TMatrixD;
 class TVectorF;
 
These declarations will have to be replaced respectively by:
 #include "TMatrixDfwh.h"
 #include "TVectorFfwd.h"
 

We STRONGLY recommend to already use these includes with this release 5.08. The includes Txxxfwd.h are simple forward declarations. In the next release, these include will contain the correct declaration of TMatrixD, TVectorF using the corresponding typedefs.





TF1, TF2, TF3

Functions GetMinimumXY() and GetMinimumXYZ() were implemented in classes TF2 and TF3. These new functions allow to find the x and y (x, y and z) values, corresponding to the minimum of the function on its range. Method: first, a grid search is performed to find the initial estimate of the minimum location. Then, this initial estimate is used as the starting parameter of Minuit minimization.
Function TF1::GradientPar(), used by the TVirtualFitter::GetConfidenceIntervals() functions of the fitter classes, was added to TF1. It computes the gradient of the function wrt parameters at the selected point.
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.

Minimization and fitting

TVirtualFitter

A new function GetConfidenceIntervals() was added to the TVirtualFitter, TFitter and TLinearFitter classes. It computes confidence intervals on the fitted function. Two interfaces are provided, one to simply compute the intervals at the selected points, the other to facilitate drawing of computed intervals along with the fitted function and histogram/graph.

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

  • when using TLinearFitter directly, call EvalRobust() function instead of Eval() after adding the points and setting the fitting function.
  • when using TH1::Fit, TGraph::Fit... functions, call it with option "rob", or, if the fraction of good points in data is known, with this fraction. For example
    myGraph->Fit("pol3", "rob=0.75");
    
Note, that standard errors on parameters are not computed!

 

TMath

New function Quantiles(), that computes sample quantiles. All 9 commonly used definitions of sample quantiles are provided, with default being the same as in the R-package.

New 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. The tutorial mathcoreSpecFunc.C shhows example how to use these functions in comparison with those provided by ROOT::TMath.

  • Probability Distribution Functions (PDF): distribution functions of binomial, breit-wigner, cauchy, chi-squared, exponential, fdistribution, gamma, lognormal, normal and poisson, t-distribution. Examples are provided in the tutorial mathcoreStatFunc.C.

  • 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, cauchy, normal, exponential and lognormal. More functions are present in the MathMore package.

  • GenVector: package for 3D and 4D Vectors. This package provides C++ classes to describe the geometric 3D vectors, the 4D physics Lorentz vectors and their transformations, like rotations in 3D and 4D (boost + 3D rotation). The functionality of this package is similar to the one provided by the CLHEP Vector and Geometry libraries and the ROOT Physics classes. The main characteristics of this package compared to the classes present in CLHEP and in ROOT libPhysics are:
    • possibility to have vectors based on various coordinate systems in 3 and 4 dimensions:
      • Cartesian3D, Polar3D and Cylindrical3D and CylindricalEta3D;
      • PxPyPzE4D, PxPyPxM4D, PtEtaPhiE4D and PtEtaPhiM4D;
    • distinction between points (PositionVector3D class) and vectors (DisplacementVector3D class);
    • possibility to have vector classes based on arbitrary scalar type (they are templated on the scalar value type);
    • optimized performances using inline functions and avoiding to use virtual functions ;
    • an easy connection to the to the CLHEP vector and geometry classes and to the linear algebra vector and matrix classes, in particular to the TMatrix and SMatrix classes. For example, via the templated functions Mult in the VectorUtil namespace, we can multiply all 3D Vectors, Points and LorentzVectors with any linear algebra matrix implementing the operator(i,j).

    Transformations of the 3D and 4D Vector classes are possible by using the following classes:

    • various type of 3D rotation classes to describe the various types of rotations, such as Rotation3D for rotations based on 3x3 matrices, EulerAngles, AxisAngle, Quaternion and the axial rotations (RotationX, Y and Z);
    • 4D LorentzRotation class represented by a 4x4 matrix and a Boost class to represent a pure Lorentz boost along an arbitrary direction and BoostX, Y and Z for boosts along the axes;
    • a class Transform3D to describe the combination of 3D rotation and translations. The transformations can be applied to both DisplacementVector3D and PositionVector3D but with different results. The DisplacementVector3D only rotates, while the PositionVector3D translates and rotates. Transformations can be applied also to the Plane3D class which represents a 2 dimensional surface spanned by two linearly independent vectors.

See here for more information on the GenVector package and for the API documentation. The test program stressVector.cxx in the ROOT test directory show the capabilities of the GenVector classes comparing the performances with the ROOT Physics classes. The new tutorial mathcoreVectorIO.C show how to write and read in a Tree the new mathcore LorentzVector classes and the tutorial mathcoreVectorCollection.C how to store a collection of LorentzVector's in a std::vector container and to archive them in ROOT Treee. The tutorial mathcoreGenVector.C test the package and provide as well examples on how to use the GenVector classes.

MathCore can be built as an independent package from a tar file or directly from CVS. The library built in ROOT contains in addition the CINT dictionary for all mathcore classes and a big fraction of all the templated functions.
All the classes and functions of MathCore are in the namespace ROOT::Math and the header files are installed under $ROOTSYS/include/Math.
More detailed description of the current released MathCore, including the reference documentation and the link to download, can be found at this location.

 

New 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
      • Secant
      • Newton
      • Steffenson

  • 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 functionality. 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 there might be a slight evolution in the user interface in the initial stage if strong user needs arise to do so.

New Package SMatrix

Add new package for linear algebra matrices and vectors, optimized for small dimension sizes. The matrix and vector classes are templated on the scalar type and on the matrix and vector dimensions. Therefore, they can be used ONLY when the dimensions are known at compile time. The package uses expression templates to achieve an high level optimization by minimizing the creation of temporary objects when performing matrix operations. The package has been developed initially by T. Glebe as part of the HeraB analysis software (see here) and a subset of the original package has been now ported to ROOT and adapted to meet the ROOT coding conventions and to satisfy the requirements of the LHC experiments. In particular the following modifications or improvements have been applied:

  • optimized Cramer inversion for matrices up to size 6x6
  • methods to invert a matrix and to calculate the determinant which are const (i.e they do not change the original content of the matrix)
  • possibility to return, as a copy, a sub vector or a sub matrix
  • support for STL like iterators

The test program in smatrix/test directory, testOperation.cxx and testKalman.cxx show how the SMatrix and SVector classes can be used and measure the CPU performances in matrix and vector operations comparing with the TMatrixD and TVectorD classes from the ROOT Matrix library.

More information on the new SMatrix package can be found at this location.

 

New Package Minuit2


This package contains the new object oriented re-implementation of MINUIT in C++, developed by M. Winkler and F. James in the context of the SEAL project. These new version contains basically all the functionality present in the old Fortran and TMinuit version. Furthermore, it provides the FUMILI algorithm, for least square and log likelihood minimizations. More information on the new C++ can be found on the MINUIT Web Site.

Minuit2 contains the C++ MINUIT package imported in ROOT from the SEAL project. The API has been changed to follow the ROOT coding convention (function names starting with capital letters) and the classes have been moved inside the namespace ROOT::Minuit2. In addition, the ROOT distribution contains classes needed to integrate Minuit2 in the ROOT framework. Two implementation of the TVirtualFitter interface exist: TFitterMinuit and TFitterFumili, which define two different fitter plug-in's: Minuit2 and Fumili2. Some helper classes are present for implementing the objective function interface (FCNBase) required by MINUIT minimization.

Minuit2 can be used through the TVirtualFitter interface or directly using the C++ interface of the ROOT::Minuit2 classes.
For example for fitting an histogram via the TVirtualFitter, one needs to select first the Minuit2 fitter plugin by:

TVirtualFitter::SetDefaultFitter("Minuit2");  // or Fumili2 for the FUMILI algorithm
h1->Fit()
 
or for minimization problem, passing the FCN function to minimize, one can do:
TVirtualFitter::SetDefaultFitter(fitter);
TVirtualFitter * minuit2 = TVirtualFitter::Fitter(0,2);
 

and then set the parameters, the FCN and minimize using the TVirtualFitter methods: SetParameter, SetFCN and ExecuteCommand like in the old minuit example tutorial. Examples on how to use the Minuit2 and Fumili2 plug-in's are provided in the tutorials minuit2FitBench.C, minuit2FitBench2D.C and minuit2GausFit.C .

Examples on how to use directly Minuit2, without the ROOT interface are provided in the tests present in the directories minuit2/tests/MnSim and minuit2/test/MnTutorial. More information on the C++ interface can be also found on the new MINUIT user guide or looking at the reference documentation.

Minuit2, without the ROOT TVirtualFitter interface classes, can be built and used as an independent package. See the file minuit2/build/INSTALL.

 

 

New class TSPlot

A common method used in High Energy Physics to perform measurements is the maximum Likelihood method, exploiting discriminating variables to disentangle signal from background. The crucial point for such an analysis to be reliable is to use an exhaustive list of sources of events combined with an accurate description of all the Probability Density Functions (PDF).

To assess the validity of the fit, a convincing quality check is to explore further the data sample by examining the distributions of control variables. A control variable can be obtained for instance by removing one of the discriminating variables before performing again the maximum Likelihood fit: this removed variable is a control variable. The expected distribution of this control variable, for signal, is to be compared to the one extracted, for signal, from the data sample. In order to be able to do so, one must be able to unfold from the distribution of the whole data sample.

The TSPlot method allows to reconstruct the distributions for the control variable, independently for each of the various sources of events, without making use of any a priori knowledge on this variable. The aim is thus to use the knowledge available for the discriminating variables to infer the behavior of the individual sources of events with respect to the control variable.

TSPlot is optimal if the control variable is uncorrelated with the discriminating variables.

A detail description of the formalism itself, called sPlot is given in M. Pivk and F.R. Le Diberder, Nucl.Inst.Meth.A(in press), physics/0402083

More information about the method and some examples of usage can be found in the TSPlot class description and tutorials.

 

New class TGraphQQ

This new class allows to draw quantile-quantile plots.
Quantile-quantile plots are used to determine if 2 datasets come from the same distribution, or if 1 dataset comes from specified theoretical distribution, such as normal.
The advantage of qq-plot is that it not only shows that the underlying distributions are different, but, unlike the analytical methods, it also gives information on the nature of this difference: heavier tails, different location/scale, different shape, etc. More information and some examples can be found in the class description

GUI

New features in TRootBrowser

  • browsing files in the different image formats:
    xpm, gif, jpeg, png, tiff, tga, ppm, pnm, bmp, xbm, xcf, cur, ico.
  • browsing PS, EPS, PDF files (gs, aka GhostScript program must be installed).
  • dynamic generation of icons. If some macro after execution creates a new canvas a small image with canvas content becomes a new icon for this macro.

     

  • If file is a text file its content will be displayed in the right pane of the browser. If it's a C++ macro after execution it can be editted in the browser and re-executed.
  • new toolbar buttons added which allow:
    • forward, backward "history navigation"
    • refresh browser content
    • invoke "find dialog"
    • execute editted macro
    • interrupt editted macro execution
    • save editted macro

     

     


  • 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.

    Added a new member / option in TGListTree allowing to disable item opening on doubleclick.

     

  • 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 menus behavior. Users are allowed to change the title of the context menu by:
            TObject* anyObj;
            anyObj->IsA()->SetContextMenuTitle("myTitle");
       
  • Added two new methods to the TGView class that help to show the top or the bottom of the text viewer page.

  • TGListView - support listbox entries with icons in addition to the text.

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.

Object Editors Improvements

  • Marker Editor - the marker pop up window shows 18 predefined marker types for user choice; 3 of them (type 1, 6, 7) have fixed size. The marker size combo box is replaced by a number entry for faster size setting.
  • Histogram Editors - improved performance of both TH1/2Editor . The interface of TH1Editor works for histograms drawn with option 'same';

Qt Interface

  • Implement TVirtualX::ListFonts method to provide TGFontDialog widget
  • New static method TQtWidget::InitRint to instantiate ROOT within Qt-based applications
  • Some extra features for rootlibs.pri and rootcintrules.pri to facilitate the Qt build on Mac (native GUI) platform
  • Improved behavior of many widgets: tool tips, combo and list boxes, menus, text and number entries, file dialogs.
  • Porting the mouse wheel as an input device.
  • Two new "Qt project files" added to build Qt-layer alone with Qt "qmake" utility.
                 $ROOTSYS/qtroot/qtroot.pro
                 $ROOTSYS/qt/qt.pro
          

OpenGL developments:

Features and Interaction

  • New code to draw shapes outline style - enable with 't' key. This provide s a 'line-drawing' style, with filled polygons outlined in black - rendering take approx twice as long. Draw styles now:
  • Interactive clipping
    • Enable under Scene/Clipping in the side GUI panel
    • Two types - plane and box
    • Adjust via direct entry in properties of GUI boxes, or interactively. Check 'Show/Edit' checkbox - clip object is shown in light brown in viewer. Current manipulator is attached to it allowing in place editing (see below for use)
  • Manipulators - widget attached to selected object (limited to clip object s only at present). Allows manipulation along/around local axis (red/X, green/Y, blue/Z). In some cases a manipulation is not permitted (e.g clip plane cannot be scaled) in which case manipu lator component is greyed and inactive. Three types:
    • Translation - Translation along local axis (v key)
    • Scaling - Scale along local axis (x key)

    • Rotatation - Rotate local axis (c key)
  • 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
  • New options for axes (draw at scene edge or through origin) and simple reference position marker - moved to 'Guide' tab under 'Scene' is GUI.
  • 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.
  • Improvement to perspective cameras - level floor formed from 2 of the 3 world axes - avoids tipping of horizon. Added missing two combinations under renamed 'Camera' menu:
    • Perspective (Floor XOZ) - default.
    • Perspective (Floor YOZ)
    • Perspective (Floor XOY)
  • Two interaction modes for rotation manipulator
    • Normal - when ring is at reasonable angle - follow ellipse round as previously (with line to dragged point on ring)
    • Shallow - when ring plane is at shaloow angle to eye (very tight ellipse) - use pixel delta (drag) on viewport along ring plane (with movement arrows)
  • Improvements to orthographic cameras - Larger range/sensitivities, better auto-framing, lighting.

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 + center sphere (Green)
    • Origin (0,0,0) as white sphere
    • Camera interest frustum basis (Red)
    • Camera interest frustum basis as box (Orange)
    • Current interest box (Blue)
    • Previous interest box (Grey)
    • Active light positions (yellow spheres)
  • 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.
  • Legos and Surfaces can be displayed with GL directly in a TPad. Almost all the standard option are available (SURF, SURF1, LEGO, LEGO1 etc .. )
  • File output can be done in gif, jpeg, pgn etc .. formats.
  • 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.
    • It is not yet possible to do the output in a PostScript file.

 

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:

  1. Create / obtain viewer handle
  2. Begin scene on viewer
  3. Fill mandatory parts of TBuffer3D describing object
  4. Add to viewer
  5. Fill optional parts of TBuffer3D if requested by viewer, and add again
    ... repeat 3/4/5 as required
  6. 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

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.
  • New method SetHatchesLineWidth to set the hatches line width for hatch styles > 3100

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.

TPad

New method BuildLegend to automatically add a TLegend in a Pad.

TGraph2D

  • New option "Line" to paint TGraph2D. TGraph2D are connected with with a 3D polyline.
  • 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.
  • New function void SetImage(ASImage * aimag)

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.
  • The marker size is now the same as the one on screen.
  • 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()

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:
  1. distorted arrows' heads
  2. 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.
  • Some modifications for the CUPS printing system.
  • Remove the %%BeginSetup/%%EndSetup section as it was empty since the last CUPS modification. With that empty section tools like "psresize" didn't work anymore on PS files generated by ROOT.

SVG

  • In SVG text strings:
                                                                                    
              < is now changed to &lt;
              >        "          &gt;
              &        "          &amp;
    
    < > and & are SVG's control characters and cannot be written directly.
  • Tags and text always start in column 1

Bitmap output

Bitmap files like gif, jpg, png etc ... are now created without highlight color around the current TPad.

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.

Axis drawing

  • 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.
  • Label size was wrong when the text precision was equal to 3.
  • In case of log scale on a vertical axis, the x-position of the extra labels (when SetMoreLogLabels is true) was not computed the same way as the x-position of the decades labels. Therefore they where not aligned.

TGraphErrors

  • The fill style for boxes (option 3) was ignored.
  • 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");
    }
    

TGraph

  • A better version of the TGraph constructor creating a TGraph from an input ascii file.
  • The following example produced a wrong output:
                                                                                    
    {
       hpx1 = new TH1F("hpx1","hpx1",100,-4,4);
       hpx2 = new TH1F("hpx2","hpx2",100,-4,4);
       Float_t px, py;
       for (Int_t i = 0; i < 25000; i++) {
          gRandom->Rannor(px,py);
          hpx1->Fill(px);
          hpx2->Fill(px);
          hpx2->Fill(py);
       }
       hpx1->SetFillColor(2);
       hpx1->SetFillStyle(3004);
       hpx1->Draw("LF2");
       hpx2->SetFillColor(1);
       hpx2->SetFillStyle(3005);
       hpx2->Draw("LF2 same");
    }
    
    The black histogram was not completly hatched.

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.
  • The angular variables in POL, SPH, CYL and PSR representations are now mapped correctly.
  • Protect THistPainter::PaintBoxes against a division by 0 in case of code like
       hh = new TH2F("hh","hh",100,0,1,100,0,1);
       hh->Fill(200,200); // out of range value, so that
       GetSumOfWeights()==0
       hh->Draw("box");
    
  • PaintErrors: In case of log scale on a Y axis with a positive maximum value and a minimum value less or equal to 0, a new minimum is computed as a percentage of the maximum. This rule is fine but may brings back visible some bins which are out of range in linear mode. A new test has been added to prevent that. This problem is visible since revision 1.197. Previously the test modified in that revision was able to filter such wrong cases.
  • In case of 1D histograms plotted as a LEGO or a SURFACE, one had to change the option LogZ to set the logarithmic scale on the Y axis. Setting the option LogY produced an error. This is now fixed.

New tutorials

  • double32.C
  • loopdir.C
  • treefriend.C
  • fitLinearRobust.C
  • importCode.C
  • readCode.C
  • RoofitDemo.C
  • assembly.C
  • mathcoreVectorIO.C
  • mathcoreVectorCollection.C
  • mathcoreStatFunc.C
  • mathcoreSpecFunc.C
  • mathcoreGenVector.C
  • mathcoreCDF.C
  • minuit2FitBench.C
  • minuit2FitBench2D.C
  • minuit2GausFit.C
  • glsurfaces.C
  • psview.C
  • copyFiles.C
  • ConfidenceIntervals.C
  • sqlcanvas.C
  • sqltables.C
  • thumbnail.C
  • glViewerExercise.C
  • TestSPlot.C
  • regexp.C


ROOT page - Class index - Top of the page