Full information on CLHEP is available on the WEB:

   http://wwwinfo.cern.ch/asd/lhc++/clhep/index.html

Below is contents of the old README

-------------------------------------------------------------------------

Latest news
===========

*** May 15. 1997 by Nobu Katayama ***

CLHEP is now very close to Version 1.0 as defined at the May 96 workshop. 
We have new Random, Geometry (3D) and Units from Geant4 team. It now compiles
on HP, SGI, IBM(AIX), DEC(OSF1), SUN(Solaris) and PC(linux) with native and
GNU compilers. Tests run on all platforms, except that on DEC with cxx 5.3/4
the original testString gives a coredump. Randlux in testRandom gives
different results on different platform and testRandom goes into an infinite
loop on PC(linux). I am sure these Random problems will be fixed soon.
Another pending issue is Babar point/translateion/transformation need to be
merged into the new Geometry classes. I am sure we can put Babar's
functionalities into Evgueni's classes. The new Histogram classes will be
in sometime in June. That's it for now.

introduction
============

This directory contains a few utility classes which represents what I
would like to have in a future Class Library for High Energy Physics.
Most of them have been taken out of a draft version of the MC++ Event
Generator toolkit, hence they may contain some special features which
are not suitable for a general class library.

The classes are to be a starting point for discussions on what should
be in a High Energy Physics Class Library and what should not. And I am
looking forward to many good discussions on the net in the near future.

This distribution also contains two subdirectories containing code
which for the moment isn't quite "supported". You are nevertheless
strongly encouraged to look at this code and send your opinions to
hepnet.lang.c++ as it might become a permanent part of CLHEP in a near
future.

The vmp sub-directory has been taken out of the CLHEP distribution. It
is available from the "The HEP Experimental Code Catalog"
(http://afal01.cern.ch/C++/Catalog/Catalog.html) or with anonymous ftp
from ftp://cithe501.cithep.caltech.edu/pub/sushi/vmp-2.0.tar.Z or
ftp://freehep.scri.fsu.edu/freehep/C++/vmp/vmp-2.0.tar.Z.

The bfast subdirectory has also been taken out of the CLHEP
distribution. It is available from the "The HEP Experimental
Code Catalog" (http://afal01.cern.ch/C++/Catalog/Catalog.html).


Description
===========

The following classes are included in this distribution:

HepAList (AList.h) is a template-based list class developed from a
non-template list class written by Dag Bruck.

HepAListIterator (AIterator.h) is a template based list iterator
class for AList and was also developed from a non-template version
written by Dag Bruck.

Note that HepAList<T> is implemented as a array of pointers to T. Hence only
references and pointers to objects are stored - not the objects themselves.
It might be better to let HepAList<T> implement an array of class T, however
then you would loose the polymorfism when adding objects of a sub class of T.
I have found that I mostly want to keep the polymorfism of objects put in a
list, but I think this issue should be discussed carefully.

HepConstAList and HepConstAListIterator (ConstAList.h and ConstAIterrator.h)
are a variation  of the classes above for storing pointers to const objects.

HepString (Strings.h) is a simple character string class. Again a
slightly modified version of a class written by Dag Bruck.

According to Dag Bruck (member of the C++ standardization committee), the
future standard will include a character string class, so we should adopt
the specifications for that class as soon as they are available.

Hep3VectorF and Hep3VectorD (ThreeVector.h) are two three-
vector classes with float and double components respectively. I have
tried to design them so that the double and float versions can be
intermixed freely, just as the double and float built in types. 

HepRotation (Rotation.h Rotation.cc) is a 3 by 3 matrix class for
rotation of three-vectors. Simple rotations of three-vectors can
however be made without using this class to save time.

HepLorentzVectorF and HepLorentzVectorD (LorentzVector.h)
are two Lorentz vector classes with float and double components respectively
and are sub-classes of the Hep3VectorF and Hep3VectorD classes.

HepLorentzRotation (LorentzRotation.h) is a 4 by 4 matrix class for
Lorentz rotation of Lorentz vectors. It is a private sub-class of the
Rotation class for easy implementation of pure 3-d rotations but
preventing boosting of three-vectors with strange results.

When writing MC++ I realized the problem that some users wants double
precision Lorentz vectors to avoid problems with large boosts and
others need to have them in single precision to save space. Therefore
I have introduced a couple of typedefs which by default looks like this

typedef double Float;
typedef Hep3VectorD Hep3Vector;
typedef HepLorentzVectorD HepLorentzVector;

but with a #define in the CLHEP.h file they are changed to

typedef float Float;
typedef Hep3VectorD Hep3Vector;
typedef HepLorentzVectorD HepLorentzVector;

In this way it is easier to write code using the class library and
still allow the end user to decide whether he wants single or double
precision.

HepRandom (Random.h) is a random number generator class capable of
generating pseudo random numbers according to different distributions.
The actual algorithm use by HepRandom is up to the user to decide. Any
algorithm implemented in a sub class of the abstract HepRandomEngine
(RandomEngine.h) class can be assigned to a HepRandom object. By
default the algorithm described in F. James, Comp. Phys. Comm. 60
(1990) 329.  which is implemented in the HepJamesRandom
(JamesRandom.h) class.

HepCmdLine (CmdLine.h), HepCmdArg, HepCmdArgInt, HepCmdArgFloat
(CmdArg.h) etc. are used to handle command line arguments. HepCmdArg
and its subclasses are used to represent one command line argument,
either optional or positional. Optional arguments are those specified
just after the command with a '-'. Positional arguments occur after
all optional arguments. A set of HepCmdArg objects corresponding to
the allowed arguments to be given to a program is handled by an object
of the HepCmdLind class which parses the command line and assign
values to the HepCmdArg objects.

HepLockable (Lockable.h) is intended to be a (multiply inherited) base
class for objects which will be handled by a combinatoric engine. It
maintains an integer, which is used bit-by-bit for locks. When asked
to lock itself, HepLockable sets the appropriate bit and then asks all
its children to lock themselves with the same bit. When asked to
unlock, it does a similar process. A HepLockable is locked if any of
its bits are set, or if any of its children are locked.

HepLock (Lock.h) maintains a list of objects, and on demand, locks and
unlocks them. The locks are turned on/off immediately. When an object
is added, it is immediately locked if the lock is on. When an object
is removed, it is first unlocked (if needed). When the HepLock object
is deleted (or goes out of scope), its members are first unlocked (if
needed).

HepChooser (Chooser.h) is a combinatoric engine which uses locks (see
Lockable.h). A HepChooser can take between 1 and 6 lists of
objects. Then, the next() method or () operator will return the next
set of objects, or 0 if done. The set is returned as a pointer to a
HepAList.

HepCombiner (Combiner.h) is essentially the same as HepChooser, except
the results of next() or operator() is one object. The += operator are
used to combine a the objects returned from HepChooser into one. Also,
the child list of the combined object is built using the method
addChild().


HepMatrixD is an arbitrary matrix of doubles. HepVectorD is a column
vector. HepSymMatrixD is a symmetric matrix, and HepDiagMatrixD is a
diagonal matrix. There are also float variaties of these matrices;
replace the final 'D' with an 'F'. All the matrices are derived from
HepGenMatrixD, which provides a few virtual functions, particularly
those to determine the size of the matrix and those to access
individual elements. All the obvious operators between the different
matrices and with normal real numbers are implemented. Two element
access routines are provided: m(i,j) indexes from 1..N while m[i][j]
indexes from 0..(N-1). N.B. most of the methods (eg. sub()) start
indexing from 1. Many linear algebra algorithms are implemented,
included those using QR decomposition (methods/functions prefixed with
"qr_").

The classes HepTuple and HepHistogram are intended as virtual base
classes for any tuple or histogram class. The HepTupleManager class
can serve as base class for any collection of tuples and histogram,
for example, a set written to a file. The classes HBookXXX are
examples of real implementations of the tuple/histograms, using CERN's
HBOOK as the actual engine. Classes using hippoplotamus as a tuple
collector are available with that package.

Particle classes
================

I have included a suggestion for a "HepBaseParticle" class. It
basically only contains virtual functions to be redefined in derived
classes. The methods should in some way reflect the maximum amount of
information one would like to access from a particle. (You may want to
include more information or think some of it is unnecessary - in that
case, let us know!) If everyone derived their base particle class from
this it should be easy to link different toolkits and applications
together - either you use inheritance and work with the methods
declared in HepBaseParticle or, if you want functionality better
suited for your purposes, you make a copy of the particles -
preferably with a copy constructor

class MyBaseParticle: public HepBaseParticle {
public:
  MyBaseParticle(const HepBaseParticle & p);
/* ... */
};

Note that the HepBaseParticle class does not have any data members and
there is basically no overhead in deriving a 'special purpose'
particle class from it. Also if a derived class does not provide all
information defined by the virtual methods in HepBaseParticle, there
is no need to write 'dummy' methods for these as HepBaseParticle will
return sensible default values.

In the initial presentation of this HepBaseParticle suggestion in
hepnet.lang.c++, the class contained methods for accessing possible
measurement errors. After some discussion it became clear that the way
this was done wasn't very well thought through. It was suggested in
measurement errors should be implemented with covariance
matrices. Anyone willing to do this?

I have also included a class called "HepInterfaceParticle". It is
derived from HepBaseParticle and the only extension is that it
actually have data members corresponding to each member function. The
idea is that this class is to be used for communication between
different applications via the persistent streams. In this way eg. an
analysis program doesn't need to know about the actual classes used
when creating the particles but all information can still be
transmitted. 

Object Persistency
==================

HepPersistentBase (PersistentBase.h) is a abstract base class to be
used by any class hierarchy for achieving object persistent I/O. The
class has no data members, but declares a number of methods which has
to be implemented in the classes inheriting from it. Most of these
methods are very simple and can be declared and implemented using
simple macros.

HepPOStream and HepPIStream (POStream.h and POStream.h) are two
abstract base classes defining the procedure of writing and reading
objects persistently to and from streams. The two classes have three
classes each derived from them, implementing the actual output of data
to a stream in ASCII, binary and XDR format (POCharStream.h,
PICharStream.h, POBinStream.h, PIBinStream.h, POXdrStream.h,
PIXdrStream.h).

The main idea of the classes defining the object persistent I/O is to
be able to read and write complicated structures of pointers to
objects. Some of the features may seem kind of odd, and may be rather
special to what we need for MC++, and certainly the topic of object
persistency needs to be carefully discussed.

As an example of how to use the object persistent I/O, imagine we
have a program like MC++, with a "Factory" containing information
about particles and how they decay. A sample program may then look
like this:

int main() {

  MC_Factory theFactory;
  // create the factory

  HepPICharStream input("MC++SavedFactory");
  // open a persistent stream of ASCII characters reading from a file

  input >> theFactory;
  // read a factory previously saved to disc.

  MC_GenericParticle * p;
  // This is the base particle class in MC++ which inherits from
  // HepBaseParticle

  HepPOXdrStream output("|eventAnalysis");
  // open a persistent stream of XDR records which pipes things to a program
  // called eventAnalysis

  for ( int ieve = 0; ieve < 10000; ieve++ ) {
    p = theFactory.getParticle("e+e-collision");
    // get a collision particle from the factory

    p->decayAll();
    // perform the decay of the collision, ie. generate an event.

    HepInterfaceParticle * ip = new HepInterfaceParticle(*p);
    // Copy the event tree to objects of the HepInterfaceParticle class

    output << ip << flush;
    // write out the event

    delete p;
    delete ip;
    //delete all the particles in the event.
  }

}

The corresponding analysis program would look something like this

int main () {

  HepPIXdrStream input(cin);
  // create a persistent stream and associate it with the standard input.

  HepInterfaceParticle * ip;

  while (input >> ip) {
    // read an event

    MyAnalysisParticle * p = new MyAnalysisParticle(*ip);
    // Copy the event tree to objects of a class suitable for my analysis

    analyse(p);
    // analyse the event

    delete p;
    delete ip;
  }
}

The way it works is that the persistent output stream keeps a list of
all objects that has been written out. If it is told to write out a
pointer to an object, it first checks if this object has been written
out before, in which case only a number corresponding to this object
is written, if not, the object is written out and associated with a
number for further output of pointers to it. 

One problem arises when writing out a lot of events as in the example
above. It may very well happen that the 'p' points to the same space,
but the object stored there is completely different. Therefore the
output stream must be 'flushed' between each event, so that all
particles in the event is written out. However the particles contains
some pointers to objects within the Factory (to access information
from eg. the particle data table) and we don't want to write the whole
factory for every event. Therefore we 'save' the factory from being
flushed, using the save and noSave manipulators.

When reading the events in the analysis program everything works the
same.  When a pointer to an object is to be read, the input stream
checks if this object has been read before in which case it just reads
a number and returns a pointer to the corresponding object. If it
hasn't been read before an object of the corresponding class is
created and is told to read itself from the stream, and is appended to
a list of read objects and a pointer to it is returned to the caller.
The input stream of course knows itself when to 'flush' the read
objects and which of the objects should be saved from flushing. Note
btw. that flushing doesn't mean that the objects are deleted. The
deletion is instead up to the caller to perform.

Note that the analysis program does not have to have knowledge about
all the classes that are written to the stream from the generator
program. If the input stream is set 'tolerant' as in the example
above, it is possible to read objects of subclasses of HepParticle
that hasn't been linked to the program. Even if the sub classes
contains pointers to objects not present in the base class which is
linked, the pointer structure of the written objects are maintained in
a reasonable way.

To inform the input stream of which classes are available there is a
procedure to 'register' a persistent class with a class called
HepDescriptionList (DescriptionList.h) which keeps a static list of
objects of the HepPersistentClassDescription (ClassDescription.h)
class. This is done automatically with the macros defined in
PersistentBase.h by creating a static instance of the
HepDescriptionList class providing information to create a
HepPersistentClassDescription object. Note however that it is very
important that the static list of descriptions in the HepDescription
list is created _before_ any instances of the class. To ensure this a
file called HepPIOInit.o must be the first object file to be loaded in
a program using persistent I/O. This is guaranteed to work, at least
in a UNIX environment using gcc-2.4.5.

The HepPersistentClassDescription objects may also provide some
information on how to dynamically link object files containing classes
that are specified in a stream but wasn't linked to the program from
the beginning. I'm however not really sure on how to actually do this,
but I have provided some hooks through the HepGenericLoader
(GenericLoader.h) class for future implementations of this procedure.

The persistent streams can also handle multiple inheritance. However
if an class inherits virtually from another class more than once, the
corresponding base class object will be written out more than once.

Coding Rules
============

This version of CLHEP has been written to conform somewhat to the
rules and recommendations described in the paper "Programming in C++ -
Rules and Recommendations" written by Erik Nyquist and Mats Henricson
(obtainable from freehep in the file
freehep.scri.fsu.edu:hep-projects/CLHEP/c++.rules.ps). Not all of the
rules are followed however.

All global names are prefixed with "Hep" and all macros (except the
multiple includes preventive ones) are prefixed with "HEP_". If the
HEP_SHORT_NAMES macro is defined, a set of aliases for the global
names are defined in each header file (using typedef's and
define's. These aliases are usually just the full name without the
prefix "Hep". Note that the ANSI/ISO standard will include a namespace
operator which will make this procedure obsolete.

The classdoc program
====================

All the header files in this distribution are written to be easily
converted to a unix-style manual page by the classdoc program written
by Dag Bruck. I think that this program provides a very easy-to-use
class documentation - simply write the code and put in comments where
you usually would put them (there are of course also a few small
tricks you can use to get nicer output) and classdoc will do the
rest.

Installation
============

To test and install the library, run the script 'configure', this
script tries to guess e.g. what compilers you are using and then it
creates the make files. Note that you can by-pass the choices made by
the configure script by setting environment variables: set CXX to the
C++ compiler you want, 'FC' to the fortran compiler, 'INCLUDES' to the
directories you want to be searched for include files and 'LIBS' to
the libraries you want to link. Edit the top Makefile to make further
changes for your system.  Then do a 'make check' to compile the
library and to run a couple of test programs. If all the tests pass
you may install the library file and the header files by doing 'make
install'.  If you want to look at the classdoc program, do 'make
classdoc' and try it out by eg.  'classdoc AList.h'. If you want to
install classdoc, do 'make install_classdoc'.  You may also install
the classdoc-processed header files as man-pages by doing 'make
install_manpages'. 'make install_all' will do all the installation for
you in one go.

Note that if you run configure with the option
'--disable-persistent-streams' all usage of persistent streams is
disabled in CLHEP. The persistent streams rely heavily on templates
and some compilers therefore chokes on this code. If your compiler
fails to compile and test CLHEP you should re-run configure with this
option and try again.

The code should in principle run on any platform with gcc-2.6.1 or
later but has only been tested on the following platforms:

SparcStation (SunOS ans Solaris 2) with gcc-2.6.3 and libg++-2.6. No
problem.

Silicon Graphics iris4d with gcc-2.6.3 and libg++-2.6. No problem.

DEC alpha OSF/1 2.0 with the DEC C++ compiler. Some problems with the
system header files - see below.

Previous versions of the code has been compiled and may still work
on the following platforms:

HP 9000/730 with gcc-2.4.5 and libg++-2.4.

NeXTStation with gcc-2.3.1 and libg++-2.3.

IBM RS6000 with gcc-2.3.3 and libg++-2.3. Problems with the linker - see below

DECstation 3100 with the DEC C++ compiler. Problems with the system
header files - see below.

DECstation 3100 with gcc-2.5.8 and libg++-2.5.3. No problem.

Bug reports and discussions
===========================

If you have any comments, suggestions etc. please post a message to the
hepnet.lang.c++ news group.

Problems
========

* Older CFront based compilers cannot handle the persistent
streams. This means that some test programs will fail. In the coming
versions of CLHEP the persistent streams will be therefore optional.

* Older versions of libg++ (2.2 and older) doesn't seem to have the file
stdiostream.h included. To fix this, either get version 2.3 of libg++
or create a file called stdiostream.h with the following contents:

#ifndef STDIOSTREAM_H
#define STDIOSTREAM_H
#include <stdio.h>
#include <fstream.h>

class stdiobuf: public filebuf {
 public:
  inline stdiobuf(FILE * filedesc): filebuf(fileno(filedesc)) {}
};

#endif

This should work, at least for the persistent streams in CLHEP.

* The DEC C++ compiler has some problem finding the definition of some
overloaded operators. The CLHEP sources has been modified sligthly for
this reason.  It may look kind of ugly but it seems to work now.

* The Silicin Graphics compiler can't handle the templated overloading

template <class T>
HepPOStream & operator>> (HepPOStream &, T *& );

If anybody has an explanation to this I'm interested to hear it.

* On some machines, the "xdr.h" does not have function prototypes. If
so, you have to edit this file to compile CLHEP. (No don't edit the
system header - edit a copy of it and make sure this copy is included
instead of the original one). The easiest thing to do is to insert
ellipsis arguments in the definition of the functions called. The
definitions that has to be changed should look something like this:

extern void     xdrmem_create(...);
extern bool_t   xdr_float(...);
extern bool_t   xdr_double(...);
extern bool_t   xdr_char(...);
extern bool_t   xdr_u_char(...);
extern bool_t   xdr_string(...);
extern bool_t   xdr_int(...);
extern bool_t   xdr_u_int(...);
extern bool_t   xdr_long(...);
extern bool_t   xdr_u_long(...);
extern bool_t   xdr_short(...);
extern bool_t   xdr_u_short(...);
typedef bool_t (*xdrproc_t)(...);

and in the definition of 'struct XDR' the member x_setpostn should
look something like:

  bool_t  (*x_setpostn)(...);

* On IBM RS6000 running AIX 3.2 with gcc 2.3.3, there is a problem
with the linker. Even if you explicitly specify an object file on the
command line, ld may choose to ignore it if no unresolved references
is found in it. This causes problem for the persistent streams as they
rely on that classes can be linked even if they are not directly
referenced in the main program so that objects that are not known to
the main program can be read in from a stream. I don't know how to fix
this yet (any suggestions are welcome), meanwhile the test programs
may be run and executed if you compile them with -DHEP_STRANGE_LD.


References
==========

The HepLockable, HepLock, HepChooser, HepCombiner, HepCmdArg,
HepCmdArgInt, HepCmdArgFloat, HepCmdArgBoolean, HepCmdArgString,
HepCmdArgStringList and HepCmdLine classes was written by Paul
Rensing.

The methods for poissonian distributions of integers was written by
Irwin Sheer.

The classdoc program and the original list and string classes were
written by Dag Bruck, Department of Automatic Control, Lund Institute
of Technology, Box 118, S-221 00 Lund, Sweden. <dag@control.lth.se>

The rest of the code was mainly written by myself - Leif Lonnblad,
DESY (-T-), Notkestr 85, 2000 Hamburg 52, Germany. 
<lonnblad@ips102.desy.de> and Anders Nilsson, Dept. of
Theoretical Physics, Lund University, Solveg.  14a, S-223 62 Lund,
Sweden. <anders@thep.lu.se>

