KaliVeda
Toolkit for HIC analysis
|
A global variable is an analysis tool for condensing the information in a multibody event into one or a few characteristic values. A simple example is the event multiplicity (the number of particles in each event), which can be used to characterize heavy-ion collision events in terms of violence or centrality. The global variable classes below can be used with any event described by a class derived from KVEvent, containing particles described by a class which inherits from KVNucleus.
There are several base classes used for implementing global variables:
Many specific implementations are provided - see the list here: Global Variables.
Each global variable class implements the calculation of a given observable for any set of nuclei; this is done independently of the selection of the nuclei in the set, or in what reference frame kinematics should be calculated for either selection purposes or for the calculation of the observable. The way the observable is calculated is defined by the implementation of the KVVarGlob::fill(const KVNucleus*) (for 1-body observables: see below) and KVVarGlob::Calculate() methods.
Global variables can be of different types:
Typical usage (pseudo-code):
Note that although the KVVarGlob::Fill() method is called for all particles, only those which satsify the conditions given to KVVarGlob::SetSelection() will be used to calculate the global variable.
Here is a more realistic example which you can follow by entering each line of code on the kaliveda command line. Consider an event containing different nuclei, which we can build up like so (see Nuclei and Events):
Now we'll characterise our event using two global variables: the largest atomic number \(Z\) of all nuclei in the event, and the total transverse energy of light charged particles (LCP: \(Z\leq 2\)):
At this stage we can print some informations on the configuration of each variable, for example:
Here we can see that KVEtransLCP works by summing the result of KVParticle::GetEtran() (non-relativistic transverse energy) for each particle in the event selected according to \(Z<3\), i.e. LCP. It is in fact a specialised version of KVEtrans (which calculates the total transverse energy of all particles, without selection), which itself is a specialised version of KVVGSum, a generic global variable for calculating multiplicities, summed or averaged quantities.
Now in order to fill our variables, we perform a loop over the nuclei in the event:
and after calculating the final values we find:
As we will see below, analyses involving several or many global variables are made much easier using a list of global variables, KVGVList.
The selection of particles which are taken into account is handled by the variable itself by calling method KVVarGlob::SetSelection(). This method takes as argument an object of class KVParticleCondition (typedef for KVTemplateParticleCondition<KVNucleus>):
This variable will now calculate the total charge \(Z_{tot}\) of all nuclei with polar angles \(60^o\leq\theta\leq90^o\).
To change the reference frame used by the variable to calculate kinematical properties of particles (including those used for particle selection), call method KVVarGlob::SetFrame() (see KVTemplateEvent::SetFrame() and KVParticle::GetFrame() for how to define and access different frames):
Assuming that a kinematical reference frame called CM
has been defined for the particles of the event when the global variable is filled, this variable will now calculate the total charge \(Z_{tot}\) of all nuclei with polar angles in the CM
frame \(60^o\leq\theta_{CM}\leq90^o\)
In order to give greater flexibility to global variable classes without the need to add member variables and the associated Get/Set methods, we provide methods to handle generic 'options' and 'parameters' for all variables.
An 'option' is a name-value pair, the value is a character string. Methods to use are:
A 'parameter' is a name-value pair, the value is a double-precision float value. Methods to use are:
A normalization factor can be applied to the value(s) calculated by any global variable, set with one of the following methods:
The value calculated for each event will be divided by the normalization factor.
Each global variable can be used to 'tag' the particles which are used for its calculation, i.e. those which satisfy the selection criteria set with KVVarGlob::SetSelection(). Each particle will be added to a group which can be subsequently used for iteration (see Nuclei and Events). By default, the group name will be the same as the global variable, but can be changed by giving an argument to the KVVarGlob::SetDefineGroup() method:
The KVGVList class handles lists of global variables. Schematic usage is as follows:
Particle selection criteria can be set for a list which will be applied to all variables in the list, using KVParticleCondition (KVTemplateParticleCondition<KVNucleus>):
Calculation of all global variables in the list in an event loop then proceeds schematically as follows:
1-body, 2-body and \(N\)-body variables are all calculated by KVGVList::CalculateGlobalVariables(). You should be aware that variables are calculated in the same order as they are added to the list with KVGVList::AddGV(). This is important to bear in mind as:
VAR2
which uses a kinematical frame defined by another global variable VAR1
in the list (see Definition of new kinematical frames) must be added to the list after VAR1
: the new kinematical frame defined by VAR1
will be applied to all particles of the event as soon as VAR1
has been calculated.One or more branches can be added to a TTree and filled with the values of all or some of the global variables in the list using method KVGVList::MakeBranches(TTree*). For each single-valued variable a branch with name
will be added. For multi-valued variables (those for which KVVarGlob::GetNumberOfValues() returns >1) we add
branches for each named value defined for the variable (see KVFlowTensor for an example of a multi-valued variable). The total number of branches added can be modified by KVVarGlob::SetMaxNumBranches(): calling this method with argument 0
will prevent any branch being added for the variable in question:
The event-by-event treatment including filling a TTree with the values of all global variables for each event then becomes particularly simple:
Conditions ('cuts') can be set on each variable which decide whether or not to retain an event for analysis. If any variable in the list fails the test, processing of the list is immediately abandoned.
Selection criteria are set using lambda expressions. In this example, the variable "mtot" must have a value of at least 4 for the event to be retained:
(the base class KVVarGlob pointer passed as argument to the lambda is the global variable itself, i.e. mtot
in the present example).
Any event selection criterion is tested as soon as each variable has been calculated. If the test fails, no further variables are calculated and the KVGVList goes into 'abort event' mode:
Variables in the list can be used to define new kinematical frames which can in turn be used by any variables which occur after them in the list. In order to do so, call method KVVarGlob::SetNewFrameDefinition() for the variable(s) in question with a lambda function having the following signature:
When called (e.g. by KVGVList::CalculateGlobalVariables()), the KVVarGlob pointer gives access to the global variable used to define the new frame.
As an example of use, imagine that KVZmax is used to find the heaviest (largest Z) fragment in the forward CM hemisphere, then the velocity of this fragment is used to define a "QP_FRAME" in order to calculate the KVFlowTensor in this frame:
Event classifier objects can be defined for any global variable in the list using method KVGVList::AddEventClassifier():
which returns a pointer to the event classifier object (KVEventClassifier), in order to set up either cuts or bins.
mtot_EC
is the default name for an event classification based on mtot
and will be used for the branch added to the user's analysis TTree by method KVGVList::MakeBranches().
If you want to implement a new global variable, there are two possibilities.
First, check that what you want to do is not possible with e.g. the KVVGSum class, or by changing the selection criteria and/or kinematical reference frame of an existing global variable: there is no need to write a new class if you want to calculate the total charge of fragments with \(5\leq Z\leq 15\) emitted in polar angle range \(10^o\leq\theta\leq 35^o\) in the centre-of-mass frame: just use a suitably modified KVZtot:
Note that in the second selection, no reference is made to the
"CM"
reference frame: the lambda function will receive a pointer to the kinematics of the nucleus in the"CM"
frame, as defined by the call to KVVarGlob::SetFrame().
If not, you can write your own global variable class. You need to decide first of all which base class to use (looking at the inheritance of existing global variables may help you make your choice). If your global variable will calculate the mean (and possibly also the variance) of some quantity, the base class to use is KVVarGlobMean. If your global variable will calculate a single value, use KVVarGlob1. If neither of the previous two cases apply, use the most general base class, KVVarGlob.
Next, decide if your global variable is of type 1-body (calculation based on properties of individual particles of the event, independently of the others), 2-body (calculation based on correlations between pairs of particles), or N-body (multibody correlations) (looking at existing classes may help to decide).
Then, use one of the following methods on the command line in order to generate skeleton '.h' and '.cpp' files for your class:
with 'type' equal to one of KVVarGlob::kOneBody, KVVarGlob::kTwoBody, KVVarGlob::kNBody.
When you have modified the skeleton according to your needs (see comments in generated code for help), you can test the compilation of your class in an interactive session:
You need to set up your environment correctly in order to tell ROOT where to find the sources for your global variables (this is essential for analysis tasks to run in batch mode), and in order to add your variables to the list available for KaliVeda analysis.
First modify (or create if it doesn't exist) your .rootrc
file, adding/modifying the following line:
You can use environment variables in this definition, as long as you enclose them in ‘’$()', e.g.
'/root'`. If you have several source directories, you can put them together:
After relaunching ROOT/KaliVeda, you will now be able to compile your class(es) even if you launch in a different directory.
Next, modify (or create if it doesn't exist) your .kvrootrc
file, adding for each of your global variables a line like this:
Then you can use your global variable in an analysis in exactly the same way as other variables:
You should try to avoid adding any new methods to your class (i.e. not defined by the interface of KVVarGlob). If you need additional parameters (named double
values) and/or options (named TString values) for your global variables, use the methods provided by KVVarGlob (see Options, parameters, reference frames, particle selection, etc.).
If there is no alternative but to add a new method, you can get away with it if you do: