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