CLHEP and ROOT - Request for Comments

From: Rutger van der Eijk (r36@nikhef.nl)
Date: Thu Jun 03 1999 - 13:01:08 MEST


Hi Peter and others,

Sorry to react (so) late to your request for comments. In my opinion you
hit an issue which is important in general. So I would like to still
comment on it.

You wonder what is the required 'purpose' of the "rootification" of CLHEP.
>From a user point of view it is for me: I would like to be able to use the
(some) CLHEP classes within ROOT. As already quite some code is written
using CLHEP I don't want to have to change/break this code (to much) to be
able to use it together with ROOT. 

ROOT provides an excellent framework for all forms of data handling
(acquisition, reconstruction, analysis, ...) especially related to HEP. By
now it is surely (probably?) the most widely used C++ framework used in
HEP. I think a framework should provide the means to incorporate other
packages (or maybe even frameworks). From a user point of view I (might)
want to be able to use as well ROOT as CLHEP. A user doesn't want to deal
with the 'technical' issues infolved and therefore the framework should
solve this problem. (Ofcourse we can't ask a framework to be able to deal
with every imaginable package.)

>From this point of view your first 'option' (reusing the 'brain's
of CLHEP) doesn't give me the wanted functionality. ROOT already provides
lineair algebra functionality with the  'Linear Algebra, Matrix and Vector
Classes'. If in CLHEP we find some ideas/algorithms that ROOT can use they
can always be incorporated. However I would like to be able to really use
the CLHEP classes.

Your second 'option' implies changes to the CLHEP classes. This is an
solution that could do the job but I don't like it because of the reasons
you already mentioned. As I user I don't want to bother about changing
types/class names and member functions in my excisting code. typedefs
could be a (partial) solution for this but it seems a bit strange.
Therefore I only see the 'minimal changes' idea as a possible/serious 
solution. This option still implies however changing CLHEP which gives
the maintenance problem you mentioned (this could ofcourse be automated),
I therefore don't consider it 'optimal'.

I think your 3th proposal or something similair is a better solution.
As you correctly mention, one (!) of the main objectives of 'object
orientation' is to reuse and extend existing code. Therefore I think a
framework should provide means to incorporate other packages/frameworks.
Copying them (first option) is not a good idea. A framework (ROOT) can't
(man power) and shouldn't do everything. If we find components from
outside which are usefull (CLHEP) we want to reuse them without changing
them (CLHEP community is and stays responsable for CLHEP aspects). The
framework wants/requires the addition of extra features (ROOT IO) it needs
to add them in such a way that the original code doesn't break.

How can this be achievd within ROOT ?
- Writing a wrapper is probably a solution that will work from the ROOT
point of view. However I think this still involves changing code which is
already written in terms of CLHEP classes. In order for wrappers to work
the CLHEP classes have to use interfaces. And the user should
(excisting code) program in terms of these interfaces. As this is not the
case a wrapper gives problems.
- Another solution within the ROOT framework might be to handle the CLHEP
classes in a similair way as 'fundamental' types. TBuffer has special
members to stream int/float etc... Similair lines could be added to stream
CLHEP objects. These streamers could be implemented using CLHEP getters
and setters. Maybe they don't have to be added to TBuffer. E.g. for me the
following seems to work:

TBuffer& operator>>(TBuffer& R__b, Hep3Vector& vec3)
{
  // Stream into an object of class Hep3Vector ('vec3') from TBuffer
'R__b'.

  HepDouble tNum;
  R__b >> tNum;
  vec3.setX(tNum);
  R__b >> tNum;
  vec3.setY(tNum);
  R__b >> tNum;
  vec3.setZ(tNum);

  return R__b;
}


TBuffer& operator<<(TBuffer& R__b, const Hep3Vector& vec3)
{
  // Stream an object of class Hep3Vector ('vec3') into TBuffer 'R__b'.

  R__b << vec3.x();
  R__b << vec3.y();
  R__b << vec3.z();

  return R__b;
}


As I don't oversee all the ROOT details I'm not 100% sure if this
works. If it does it however it ensures:
- not changing CLHEP with the advantages:
  - responabilty (+credits) by CLHEP
  - maintaines easy
  => if some additions to CLHEP we don't have to copy all the code
  (only modify streamers if necessary)
- get the ROOT-IO functionality.


To be short: I agree with Peter. 

cheers,

Rutger van der Eijk


On 20 May 1999 Peter Malzacher wrote:

> Hi,
>
> as one of my homeworks problem after the ROOT workshop at Fermilab
> I "rootified" the Vector package of CLHEP. But I have doubts
> whether it is useful to release them to public use.
>  
> At the workshop it was agreed to "rootify" CLHEP. But it was
> not too clear what the main purpose of these "rootification"
> should be:
>   - Is it to incorporate functionality in ROOT which is not yet there?
>   - Or to use the codes written with CLHEP classes in ROOT without 
>   changes?
>   - Or is it to use ROOT I/O for CLHEP objects?
>  
> What is the main objective: Ease of use for ROOT users or for
> CLHEP users?
> 
> To use CLHEP functionality in ROOT one has at least the following
> options:
> 
> 1. Include some of the functionality of CLHEP in ROOT, i.e. take 
>    ideas, algorithms etc from CLHEP to enhance ROOT.
>    
> 2. Rootify CLHEP or parts of CLHEP
>      Minimal changes:
>      - generate LinkDef.h (to use CLHEP as is)
>      - insert ClassDef/ClassImp and inherit from TObject or TNamed
>        (to use ROOT I/O)
>      Medium changes:
>      - change types eg: HEPDouble -> Double_t ...
>      - change class names eg: HepLorentzVector -> TLorentzVector
>      - change math functions eg min/max/sqrt .. to TMath::Min/Max/Sqrt
>        (to get rid of CLHEPs TemplateFunctions.h)
>      Maximal changes:
>      - move to ROOT naming conventions 
>        eg for member functions:  setX() -> SetX(), x() -> GetX(), ...
>      - Change the comments to the ROOT documentation standards
>        eg move or copy the member function description from the 
>        header file to the source file. 
> 
> 3. Wrapper / Adapter / Mixing classes in ROOT which delegates the
>    work to CLHEP
> 
> For option 1 it is important to know which packages are needed in ROOT,
> which functionality is missing. Which of the packages:
> Combination, Geometry, Matrix, Random, Units and Vector
> (see the CLHEP homepage: http://wwwinfo.cern.ch/asd/lhc++/clhep/ )
> are needed in ROOT. It would be a one-time
> effort. I think it would be difficult to reimport changes
> of the CLHEP after that first step.
> 
> With options 2 and 3 one has to decide whether it is useful to include 
> the full (fat!) interface of CLHEP or whether it should be minimized:
> e.g. the new HEPLorentzVector class has three different access methods
> to its components Fortran-like v(0) C-like v[0] and v.x() (there are a 
> lot of similar examples in the random classes).
> 
> Option 3 seems to me the promissing way. 
>   - There could be a version problem but if it is possible to include
>     in CLHEP a version number which could  be inquired at runtime it 
>     could be implemented in a save way. 
>   - It would be an example of one of the main objectives of object 
>     orientation: using and extending existing programs without 
>     modifiying them. 
>   - The responsibilities and the credits of the ROOT and the CLHEP team
>     would be clearly exposed.
>   - It would be clear to users where to look for the documentation.
>   - The most important point: the maintance of such a scheme could 
>     easily be semi-automated.  
> 
> The ROOT team has agreed to incorporate a "rootified" version of
> the Vector package into ROOT. However I am not convinced that a
> simple "rootification" is justified. I see the following two
> problems:  
> 1. A set of classes along the lines of option 2 with medium changes 
>    is ready. It would be easy to move it to the full ROOT naming 
>    scheme, but than it would be more difficult to use existing code 
>    (if one changes only types - a set of typedefs is all needed, 
>    but if one changes memberfunction names ...). 
> 2. Is it useful to put the full (for historical reasons) fat 
>    interface into ROOT. A leaner version would be much better for
>    the normal ROOT user. 
> 
> In short: my feeling is that the current version is halfway between
> option 1 and 3 and therefore not too usefull for an experienced CLHEP
> user (he has to change his code), but to difficult to overloaded
> for somebody who will just use a LorentzVector class in ROOT.



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:34 MET