There is a Makefile in every subdirectory with source code. Simply saying
"make" in every subdirectory will compile and link code into shared libraries
and into programs if any.
User file must be added to Makefile and "make depend" command must
be given for make utility to correctly adjust all dependencies.
There is also Makefile in SasyHomeDir which simply goes around all
subdirectories and calls makefiles in them.
First library to compile must be "kernel" library libTot.so. Source
code for it is in ./src . All other libraries depend on it. Other
libraries may be compiled in any order ( at the moment they do not depend
on each other and I want to keep them this way by separating mutually dependent
makers into separate libraries. Executable programs of course must be compiled
and linked last because they depend on all shared libraries.
Also, you may turn off all statements "assert" in your program
if you use option "-DNDEBUG".
So, fastest program will be if you use "-O3 -DNDEBUG".
How to debug
First of all you need to change flags to compiler, in bash:
export SasyMakeOption='-D_DEBUG_KA_ -g'
first flag tells program to execute code sandwiched between
#ifdef _DEBUG_KA_ and #endif. Second flag tells compiler
to make debug version of executable. Standard debuggers then can be used
to do debugging.
Later when you want to look only at events which satisfied the maker above you have to say after declaration of LegsRun object:
theRun->SetEventList("MUMU");
this will make sure that looping will be done only on events from the
list.
Again, you have to remember that these kind of preliminary cuts apply
to ALL makers, ALWAYS untill you specifically turn them off.
Forst you need to create your working place:
You can create new makers most easily by editing a copy of
existing makers which do almost what you want to do.
If you want to integrate your classes into the SasySoft system,
you have to add the following line to your class header files (as part
of
the public part of the class definition):
ClassDef(ClassName,ClassVersionID) //The class title
See for example LegsMakerSample.h. The ClassVersionID is used by the ROOT I/O system. It is written on the output stream and during reading you can check this version ID and take appropriate action depending on the value of the ID ( not really used by me at all 05/23/00). Every time you change the layout of a class you should increase its ClassVersionID by one. The ClassVersionID should be greater or equal to 1. Set ClassVersionID=0 in case you don't need object IO support. Generally for makers it is needed to be able to have histos automatically written into output root file.
NOTE: the ClassDef macro must be the last item before the closing '};'
in a class definition. It contains its own private and public tags
so it can be added to either a private or public part of a
class definition.
Similarly, in your implementation file you must add the statement:
ClassImp(ClassName)
See for example LegsMakeSample.cxx. Note that you MUST provide a default constructor for your classes, i.e. a constructor with zero parameters or with one or more parameters all with default values in case you want to use object I/O. If not you will get a compile time error.
The ClassDef and ClassImp macros are defined in the file Rtypes.h. This file is referenced by all ROOT include files, so you will automatically get them if you use a ROOT include file.
The ClassDef and ClassImp macros are necessary to link your classes
to the dictionary generated by CINT to get access to the RTTI and object
I/O features of ROOT. The RTTI system allows
you to, a.o. find out to which class an object belongs, its baseclasses,
its datamembers and methods, the method signatures, etc. This information
is used to make advanced object browsers and
by the automatic documentation generation system. The object I/O system
allows you to store and retrieve objects (and arbitrarily complex object
structures) from a ROOT database.
If you are only interested in interactive access to your classes via
the command line or macro processor you do not need to use the ClassDef
and ClassImp macros.
So much for ROOT requirements. Now SasySoft requirements:
Unique feature of SasySoft is that it's makers have to be children-classes of one class "LegsMaker".
Here is simplified header for the class:
class LegsMaker: public TDirectory
{
public:
LegsMaker(){;}
LegsMaker(const Text_t *name,const Text_t *title, LegsRun* theRun
= NULL,const int add = 1);
virtual ~LegsMaker(){;}
virtual void Init(); //! initializes all histograms and other
member variables.
virtual Bool_t Make(); //! called by LegsRun every event when
LegsRun::Loop() is called.
virtual void RunEnd(); //! called at the end of run
Bool_t fDo;//!
protected:
LegsRun* it; //!
ClassDef(LegsMaker,3) // Base class for all makers
};
As you can see it has two constructors, one allowing passing of parameters
such as name and title. The other "default" constructor is present to make
ROOT happy.
Virtual destructor is also something ROOT and C++ decided they need
to have.
Then three "useful" functions follow. Comments say it all.
The fDo data member is there to make possible for SasySoft to turn on
and off a maker when interactively looking at events with 3D display. If
fDo is true, then the maker will be used.
Of course in a batch fDo should be always true. User should not
mess with this flag. If you don't want maker to be processed in batch -
don't declare it. In future if I do not forget I will protect similar variables
so that user can't mess it up.
Well, pointer to the run which is being processed is stored in "it".
Last line has been described above in ROOT's requirements.
Here is a sample maker:
class LegsMakerSample: public LegsMaker
{
public:
// data members :
TH1F* fHistPol;
// standard functions MUST exist in order to link to LegsRun.
LegsMakerSample(int add = 1);
virtual ~LegsMakerSample(){;}
void Init(); // books all histograms and other member variables.
Bool_t Make(); // called by LegsRun every event when LegsRun::Loop()
is called.
// this is the main function from which other functions can
be called.
void RunEnd(); // executed at end of run, called by LegsRun::RunEnd()
// here one may do whatever he wants.
// user functions may be HERE
// but better style is to put them into private section
protected:
// user code HERE
private:
// user code HERE
ClassDef(LegsMakerSample,2) // Sample user maker
};
Of course this sample source is not as uptodate as the source files
themselves are - if in doubt, look at the files in "reference guide".
OK, I hope I gave an idea of what the makers are.
See "CINT as Dictionary Generator" for a detailed description on how
to generate a dictionary.
There is a script called dist.sh in directory $SasyHomeDir/scripts.
Running this script should clean all source directories of object files,
libraries, core files, and twobody kinematics lookup tables and then tar
needed files into one archive named SasySoft_vXXX.tar.gz. This file
is all that is needed to setup the system on another machine.
Caution: script dist.sh relies on naming convention that all maker
directories are in $SasyHomeDir and have prefix "maker". So if you create
new directory of your own makers and put it into subdirectory of $SasyHomeDir
named maker* then it will be automatically added to distribution.
Suggested reasonably simple naming scheme for distribution files:
SasySoft_vXXX_YourInitialsHere.tar.gz
this would tell that "kernel" part of the program ( the one that resides in src directory) is version number XXX and makers (in maker* directory) are modified by you. It is very bad idea to change makers that reside in other peoples directories. It is much better to copy what you need into your new directory and keep all changes to that directory. This way it is very easy to work with code and track changes and errors.
Changing kernel part od SasySoft by many people independently seems to be trouble - nobody will find any tracks of anything and the whole idea of having standard analysis interface will be only dream and the program slowly will diintegrate into little pieces of what diferent people managed to accomplish but the pieces will not add up together...
I guess frequent workshop meetings and one standard well documented
version of SasySoft kernel for all is needed desperately just as one ROOT
version and one version of NQ are needed.
One can have several versions of SasySoft installed simultenuosly and switch between them by changing environment variable SasyHomeDir.
should work now.
It will use same directories for data and output results, but different
calibration parameters.
STL does not live in peace with ROOT on many occasions. This time
compromise is possible.
Look at LegsPart constructor that takes vector as parameter. If I simply
put declaration of clump below declaration of the constructor it stops
working !
So, in order to pass some vector around as parameter you need to declare
one in header file first.