Re: CLHEP and root united

From: Rene Brun (Rene.Brun@cern.ch)
Date: Mon Jul 06 1998 - 11:28:06 MEST


Hi Stefan,
This is a very impressive work. Congratulations!!

One of the classical problems with existing class libraries
is that objects cannot be made persistent. I understand from your
message that you have an interface for the CLHEP containers.
With your changes, can you embed an Hep3Vector into a class
and write an object of this class?

I would like to hear opinions on the strategy to adapt.
It would probably be interesting to distribute the modified CLHEP
together with the Root binaries (at least in a medium or long term).

Meanwhile, I assume that you will provide a Web page documenting
your changes and some examples of use.

Rene Brun


stefan kluth wrote:
> 
> Dear Rooters!
> 
> I have managed to compile and link the more useful parts of CLHEP into
> a shared library, which can be loaded into root. It contains the following
> pieces:
> Hep3Vector, HepRotation HepTranslation HepTransformation, HepPoint
> HepLorentzVector, HepLorentzRotation
> HepGenMatrix HepMatrix HepSymMatrix HepDiagMatrix HepVector
> HepAList<T>, HepConstAList<T>, HepAListR<T>
> HepAIterator<T>, ConstAIterator<T>
> 
> The 3 and Lorentzvectors together with the transformation classes provide
> a quite complete command set for many calculation typical in HEP.
> 
> The HepMatrix and Co. classes contain a convenient set of linear algebra
> functions including inversion, diagonalisation and solving of sets of
> linear equations. Compared to the root-matrix classes one wins on ease of
> use (IMHO) and the lack of efficiency doesn't really matter for small to
> medium scale computations performed on the command line or in a macro.
> For large computations in batch jobs one might suffer from a performance
> penalty.
> 
> The CLHEP template based lists and corresponding iterators can be used
> only with instantiated templates in a separate precompiled shared library.
> The template class HepAListR<T> is ready for root-IO, such that one can
> write lists of any root-streamable objects to root files.
> 
> The CLHEP package can be found in by anonymous ftp to persil.lbl.gov in
> pub/CLHEP-root. You find there also an example application of using the
> HepAListR<T> template container to contruct a ntuple-like tree in the
> archive streamCLHEP.tar.gz.
> 
> Please let me know of any comments, questions or additions you might have.
> 
> cheers, Stefan
> 
> PS: Below I append my root-template-howto:
> 
> It is possible to fully link precompiled instantiated template classes
> into root by following this recipie:
> 
> 1) Insert the macros ClassDefT and ClassImpT in place of the normal
>    root macros ClassDef and ClassImp in your template class code.
> 
> Here is the ClassDefT and ClassImpT macro defintion I use:
> 
> #define ClassDefT(name,id) \
> private: \
>   static TClass *fgIsA; \
> public: \
>   static const char *DeclFileName() { return __FILE__; } \
>   static int DeclFileLine() { return __LINE__; } \
>   static const char *ImplFileName(); \
>   static int ImplFileLine(); \
>   static Version_t Class_Version() { return id; } \
>   static TClass *Class(); \
>   static const char* SetClassName(); \
>   static void Dictionary(); \
>   virtual TClass *IsA() const { return name::Class(); } \
>   virtual void ShowMembers(TMemberInspector &insp, char *parent); \
>   virtual void Streamer(TBuffer &b); \
>   friend TBuffer &operator>> (TBuffer &buf, name *&obj);
> 
> #define _ClassImpT_(name,Tmpl) \
>    template <class Tmpl> TClass* name<Tmpl>::Class() \
>           { if (!fgIsA) name<Tmpl>::Dictionary(); return fgIsA; } \
>    template <class Tmpl> const char* name<Tmpl>::ImplFileName() \
>      { return __FILE__; } \
>    template <class Tmpl> int name<Tmpl>::ImplFileLine() { return __LINE__; } \
>    template <class Tmpl> TClass* name<Tmpl>::fgIsA = 0;
> // Don't know how to deal with this yet
> //   _ClassInit_(name)
> #define ClassImpT(name,Tmpl) \
>    template <class Tmpl> void name<Tmpl>::Dictionary() { \
>       TClass *c = CreateClass(SetClassName(), Class_Version(), \
>                               DeclFileName(), ImplFileName(), \
>                               DeclFileLine(), ImplFileLine()); \
>       fgIsA = c; \
>    } \
>    _ClassImpT_(name,Tmpl)
> #endif
> 
> These could in principle be part of Rtypes.h. For the moment you will
> have to put these in a private additional header file. The main difference
> is the additional member function SetClassName() and the insertion of
> "template <class Tmpl>" in front of member functions which depend on
> the template parameter.
> 
> I could not work out how to extend the statements in the macro
> _ClassInit_(name), so I just don't use it. Empirically, it doesn't
> seem to do any harm.
> 
> 2) Produce some "application code", which instantiates the templates
> you want to use in root. For example, a piece of code containing the
> line
> 
>   HepAListR<HepLorentzVector> vl;
> 
> will result in the instantiation of HepAListR<HepLorentzVector>. A simple
> but complete example is provided in the package streamCLHEP.tar.gz
> 
> 3) Proceed as usual, i.e. create a linkdef.h file with a line for every
> template instantiation you need, e.g.
> 
> #pragma link C++ class HepAListR<HepLorentzVector>-;
> 
> The "-" is there, because the streamable HepAListR<T> has a custom
> Streamer method. Now run rootcint in the usual way. This will produce
> the defintions for some of the functions declared above in the macros
> separately for every template instantiation.
> 
> The definition for SetClassName() is produced by a special program which
> is run directly after the rootcint step. It produces e.g.
> 
> // Set the class name for HepAList<HepLorentzVector>:
> const char* HepAListR<HepLorentzVector>::SetClassName() {
>   return "HepAListR<HepLorentzVector>";
> }
> 
> This step could be done by rootcint itself, of course. An example of the
> program can be found in the CLHEP-root package CLHEP.tar.gz as clhepcint.cc.
> 
> 4) Compile and link your "application code" together with the output
> from running rootcint and clhepcint into a shared lib in the usual way.
> 
> 5) Start root and load the shared lib. Now you can use your instantiated
> template as a type and for example do:
> root [1] HepAListR<HepLorentzVector> vlist;
> root [2] HepLorentzVector l1=(1,2,3,4);
> root [3] HepLorentzVector l2=(5,6,7,8);
> root [4] vlist.append( l1 );
> root [4] vlist.append( l2 );
> 
> ---Stefan Kluth---------------Lynen Fellow----------------|\--|\-------
> -  LBNL, MS 50A 2160       -  phone:  +1 510 495 2376  -  |/  |/      -
> -  1 Cyclotron Rd.         -  fax:    +1 510 495 2957  -  |\/\|\/\|'  -
> ---Berkeley, CA94720, USA-----e-mail: SKluth@lbl.gov------|/\/|/\/|----



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