# Difference: LoKiLUG (6 vs. 7)

#### Revision 72007-07-28 - VanyaBelyaev

Line: 1 to 1

 META TOPICPARENT name="LoKi"

# LoKi User Guide

Line: 76 to 78
actual physics content by technical C++ semantic. The idea of user-friendly components for physics analysis were essentially induced by the spirit of following packages:
Changed:
<
<
• KAL language (Kinematical Analysis Language) by genius Hartwig Albrecht. KAL is an interpreter language written on FORTRAN (It is cool, isn't it?). The user
>
>
• KAL language (Kinematical Analysis Language) by genius Hartwig Albrecht. KAL is an interpreter language written on FORTRAN (It is cool, isn't it?). The user
writes script-like ASCII file, which is interpreted
Changed:
<
<
and executed by standard KAL executable. The package
>
>
and executed by standard KAL executable. The package
was very successfully used for physics analysis by ARGUS collaboration.
Changed:
<
<
• Pattern and GCombiner packages by Thorsten Glebe.
>
>
• Pattern and GCombiner packages by Thorsten Glebe.
These nice, powerful and friendly C++ components are used now for the physics analysis by HERA-B collaboration
Changed:
<
<
>
>
• Some obsolete CLHEP classes, like HepChooser and HepCombiner

• Loki library by Andrei Alexandrescu. The library from one side is a state-of-art for so called generic meta-programming and compile time programming, and simultaneously from another side it is the excellent cook-book, which contains very interesting, non-trivial and non-obvious recipes for efficient solving of major common tasks and problems.
Changed:
<
<
The attractiveness of specialised, physics-oriented code
>
>
The attractiveness of specialized, physics-oriented code
for physics analysis could be demonstrated e.g. with "typical"
Changed:
<
<
code fragment in KAL:
>
>
code fragment in KAL:
%SYNTAX{ syntax="fortran" numbered="1000" numstep="10"}%
>
>
HYPOTH E+ MU+ PI+ 5 K+ PROTON

IDENT PI+ PI+

Line: 119 to 122
ENDSEL

GO 1000000

>
>
%ENDSYNTAX%
Changed:
<
<
This KAL pseudo-code gives
>
>
This KAL pseudo-code gives
an example of self-explanatory code. The physical content of selection of ,
Line: 134 to 138
One could argue that it is not possible to get the similar transparency of the physical content of code with native C++. The best answer to this argument could be just an example
Changed:
<
<
from T. Glebe's Pattern of
>
>
from T. Glebe's Pattern of
reconstruction: %SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
>
>
TrackPattern piMinus = pi_minus.with ( pt > 0.1 & p > 1 ) ;
>
>
TrackPattern piPlus = pi_plus.with ( pt > 0.1 & p > 1 ) ;
>
>
TwoProngDecay kShort = K0S.decaysTo ( PiPlus & PiMinus ) ;
>
>
kShort.with ( vz > 0 ) ;
>
>
kShort.with ( pt > 0.1 ) ;
>
>
%ENDSYNTAX%
Line: 146 to 156

This code fragment is not so transparent as specialized

Changed:
<
<
KAL pseudo-code but it is easy-to-read,
>
>
KAL pseudo-code but it is easy-to-read,
the physical content is clear, and it is just a native C++! I personally tend to consider the above code as an experimental prove of possibility to develop easy-to-use
Line: 171 to 185
The physical content of these lines is quite transparent. Again I suppose that it is not obscured with C++ semantics.
Changed:
<
<
From these LoKi lines it is obvious that an essential emulation of KAL semantics is performed. Indeed I think that KAL was just state-of-art for physics pseudo-code and is practically impossible to make something better. But of course it is
>
>
From these LoKi lines it is obvious that an essential emulation of KAL semantics is performed. Indeed I think that KAL was just state-of-art for physics pseudo-code and is practically impossible to make something better. But of course it is
the aspect where I am highly biased.

LoKi follows general Gaudi architecture and indeed it is just a thin layer atop of tools, classes, methods and utilities from

Changed:
<
<
developed withing DaVinci project.
>
>
developed within DaVinci project.

Changed:
<
<
Since LoKi is just a thin layer, all DaVinci tools are available in LoKi and could be directly invoked and manipulated.
>
>
Since LoKi is just a thin layer, all DaVinci toolsare available in LoKi and could be directly invoked and manipulated.
However there is no need in it, since LoKi provides the physicist with significantly simpler, better and more friendly interface.
>
>

### Acknowledgments

As a last line of this chapter I'd like to thank Galina Pakhlova, Andrey Tsaregorodtsev and Sergey Barsuk
Changed:
<
<
for fruitfull discussions and active help in overall desing of LoKi. It is a pleasure to thank Andrey Golutvin as the first active user of LoKi
>
>
for fruitfull discussions and active help in overall desing of LoKi. It is a pleasure to thank Andrey Golutvin as the first active user of LoKi
for constructive feedback. Many people have contributed in a very constructive way into available LoKi functionality and development directions. Within them I would like to thank Victor Coco,
Line: 205 to 222
Gerhard Raven, Thomas Ruf, Hugo Ruiz Perez,
Changed:
<
<
Jeroen van Tilburg and
>
>
Jeroen van Tilburg, and
Benoit Viaud.
Changed:
<
<
It is the real pleasure to thank the leaders of ITEP/Moscow, CERN-LBD, LAPP/Annecy and Syracuse University teams for the kind support.
>
>
It is the real pleasure to thank the leaders of ITEP/Moscow (Andrey Golutvin), CERN-LBD (Hans-Jurgen Hilke and Hans Dijkstra), LAPP/Annecy (Marie-Noelle Minard and Boleslav Pietrzyk) and Syracuse University (Sheldon Stone and Tomasz Skwarnicki) teams for the kind support.

### Who is LoKi?

• Loki is a god of wit and mischief in Norse mythology
Line: 244 to 267

LoKi allows to select/filter a subset of reconstructed

Changed:
<
<
particles (of C++ type LHCb::Particle) which fulfills
>
>
particles (of C++ type LHCb::Particle) which fulfills
the chosen criteria, based on their kinematic, identification and topological properties and to refer later to this selected subset with the defined tag: %SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
Line: 257 to 283
These particles are copied into internal local LoKi storage and could be accessed later using the symbolic name "AllKaons".
Changed:
<
<
In this example ID and PT are predefined
>
>
In this example ID and PT are predefined
LoKi variables or functions (indeed they are function objects, or functors in C++ terminology) which allow to extract the identifier and the transverse momentum for
Line: 270 to 296
LoKi defines many frequently used variables and set of the regular mathematical operation on them '+', '-', '*', '/' and all elementary functions, like
Changed:
<
<
sin, cos, log, atan, atan2, pow etc,
>
>
sin, cos, log, atan, atan2, pow etc,
which could be used for construction of variables of
Changed:
<
<
the arbitrary complexity. Cuts and variables are discussed in
>
>
the arbitrary complexity. Cuts and variables are discussed in
detail in subsequent chapters

Indeed the function select has a return value of type Range,

Line: 340 to 377
In a similar way one can select Monte Carlo particles (of C++ type LHCb::MCParticle), which satisfy the certain criteria:
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
MCRange kaons = mcselect ( "AllMCKaons" , abs( MCID ) == 321 && MCPT > 100 * MeV ) ;
Line: 354 to 392
/* do something with this raw C++ pointer */ }
Changed:
<
<
>
>
%ENDSYNTAX%
The differences with respect the previous case are
• one needs to use the function mcselect instead of select
Line: 368 to 406
Similar to the selection of reconstructed particles and the selection of Monte Carlo particles one can perform the selection of Generator particles (of C++ type HepMC::GenParticle):
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
GRange kaons = gselect ( "AllGenKaons" , abs( GID ) == 321 && GPT > 100 * MeV ) ;
Line: 382 to 420
/* do something with this raw C++ pointer */ }
Changed:
<
<
>
>
%ENDSYNTAX%
One sees that the C++ code essentially the same with the minor difference:
• one needs to use the function gselect instead of select and mcselect
• the return value of this function has C++ type GRange and behaves like the container of const HepMC::GenParticle*
Line: 394 to 433

### Selection of Vertices

The similar approach is used for selection/filtering of vertices (of C++ type LHCb::VertexBase):

Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
VRange vs = vselect( "GoodPVs" , PRIMARY && 5 < VTRACKS && VCHI2 / VDOF < 10 );

Changed:
<
<
>
>
%ENDSYNTAX%
Here from all vertices loaded by DaVinci one selects only the vertices tagged as "Primary Vertex" (PRIMARY) and constructed from more that 5 tracks (5<VTRACKS)
Line: 430 to 470
LHCb::RecVertex::ConstVector, LHCb::RecVertex::Container and from arbitary sequence of objects, convertible to const LHCb::VertexBase*:
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
VRange vertices_1 = ... ; VRange vs1 =
Line: 453 to 493
vertices_3.end () , // end of input sequence PRIMARY && 5 < VTRACKS ); // cut

Changed:
<
<
>
>
%ENDSYNTAX%
In summary, for selection of vertices:
• one needs to use the function vselect
Line: 486 to 521
container of objects the object which maximizes or minimizes some function. The selection of the primary vertex with the maximal multiplicity could be considered as typical example:
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
// get all primary vertices VRange vrtxs = vselect( "GoodPVs" , PRIMARY ) ;

const LHCb::VertexBase* vertex = select_max( vrtxs , VTRACKS ) ;

Changed:
<
<
>
>
%ENDSYNTAX%
Here from the preselected sample of primary vertices vrtxs one selects only one vertex which maximizes Vertex function VTRACKS with value equal to the number of tracks participating in this primary vertex.
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
// get all primary vertices: VRange vrtxs = vselect( "GoodPVs" , PRIMARY );
Line: 510 to 545
// find the primatry vertex with minimal B-impact parameter const LHCb::VertexBase* vertex = select_min( vrtxs , VIP( B , geo() ) ) ;

Changed:
<
<
>
>
%ENDSYNTAX%
Here from the preselected sample of primary vertices vrtxs one selects the only vertex which minimize function VIP, with value equal to the impact parameter of
Line: 518 to 553

The templated methods select_max and select_min are type-blind and they could be applied e.g. to the containers of particles:

Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
Range kaons = select( .... );

const LHCb::Particle* kaon = select_min( kaons , abs( PY ) + sin( PX ) ) ;

Changed:
<
<
>
>
%ENDSYNTAX%
Here from the container of preselected kaons the particle, which gives the minimal value of funny combination
Changed:
<
<
$\left|{\mathrm{p_y}}\right|+ \sin {\mathrm{p_x}}$ is selected.
>
>
is selected.
The methods select_min_ and =select_max also allow the conditional selection of minimal/maximal candidate:
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
MCRange kaons = mcselect( "kplus" , MCID == "K+" ) ;
Line: 547 to 582
/* do something with this raw C++ pointer */ }
>
>
%ENDSYNTAX%

Deleted:
<
<
Here the maximum is searched only within the particles whcih satisfy the cut (0<MCPZ) - the z-component of particle momenta must be positive..
Line: 557 to 592
All selection functions, described above returns the light pseudocontainer of selected objects. Alternatively the selection result could be accessed using the unique tag (used as the first
Changed:
<
<
string argument of the functions *select) and the function *selected:
>
>
string argument of the functions select) and the function selected: %SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
// get all previously selected particles, tagged as "MyGoodKaons": Range goodK = selected ( "MyGoodKaons" ) ;
Line: 569 to 604
// get all previosly selected Generator particles, tagged as "My good b-quarks": GRange bquarks = mcselected ("My good b-quarks") ;

Changed:
<
<
>
>
%ENDSYNTAX%

Line: 585 to 618
Above it has been already shown how to perform simple looping over the selected range of particles:
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
Range kaons = select( "AllKaons" , abs( ID ) == 321 && PT > 100 * MeV );
Line: 595 to 628
/* do something with this raw C++ pointer */ }
Changed:
<
<
>
>
%ENDSYNTAX%
Equivalently one can use methods Range::operator(), Range::operator[] or Range::at():
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
Range kaons = select ( "AllKaons" , abs( ID ) == 321 && PT > 100 * MeV );
Line: 609 to 642
const LHCb::Particle* k3 = kaons .at ( index ) ; // use Range::at }

Changed:
<
<
>
>
%ENDSYNTAX%
The result of operators are not defined for invalid index, and Range::at method throws an exception for invalid index.

In principle one could combine these one-particle loops to get the

Line: 622 to 656
using the special object Loop. All native C++ semantics for looping is supported by this object, e.g. for native C++ for -loop:
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
// loop over all "kaon- kaon+ "combinations for ( Loop phi = loop ( "kaon- kaon+" ) ; phi ; ++phi )
Line: 630 to 664
/* do something with the combination */ }

Changed:
<
<
>
>
%ENDSYNTAX%
The while -form of the native C++ loop is also supported:
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
Loop phi = loop( "kaon- kaon+" ) ; while ( phi )
Line: 642 to 677
++phi ; // go to the next valid combination }

Changed:
<
<
>
>
%ENDSYNTAX%
The parameter of loop function is the selection formula
Line: 654 to 689
within the loop over multiparticle combinations, e.g. for the following loop the given pair of two photons will appear only once:
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
Loop pi0 = loop( "gamma gamma" ) ; while ( pi0 )
Line: 664 to 699
++pi0 ; // go to the next valid combination }

Changed:
<
<
>
>
%ENDSYNTAX%
Internally LoKi eliminates such double counting through the discrimination of non-ordered combinations of the particles of the same type.
Line: 677 to 712

For access to the daughter particles (the selection components) one could use following constructions:

Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
for ( Loop D0 = loop( "K- pi+ pi+ pi-" ) ; D0 ; ++D0 ) {
Line: 687 to 722
const LHCb::Particle* pim = D0(4) ; // the fourth daughter particle }

Changed:
<
<
>
>
%ENDSYNTAX%
Please pay attention that the indices for daughter particles starts from 1, because this is more consistent with actual notions "the first daughter particle", "the second daughter particle", etc. The index 0 is reserved for the whole combination. Alternatively one could use other functions with a bit more verbose semantics:
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
for( Loop D0 = loop( "K- pi+ pi+ pi-" ) ; D0 ; ++D0 ) {
Line: 704 to 739
const LHCb::Particle* pim = D0->particle(4) ; // the fourth daughter }

Changed:
<
<
>
>
%ENDSYNTAX%
Since the results of all these operations are raw C++ pointers to LHCb::Particle= objects, one could effectively reuse the functions & cuts for extraction the useful information:
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
for ( Loop D0 = loop( "K- pi+ pi+ pi-" ) ; D0 ; ++D0 ) {
Line: 717 to 752
const double PTpm = PT( D0(4) ) ; // Momentum of "pi-" }

Changed:
<
<
>
>
%ENDSYNTAX%
Plenty of methods exist for evaluation of different kinematic quantities of different combinations of daughter particles:
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
for ( Loop D0 = loop( "K- pi+ pi+ pi-" ) ; D0 ; ++D0 ) {
Line: 735 to 770
doule m13 = D0->m(1,3) ; // mass of 1st and 3rd particles }

Changed:
<
<
>
>
%ENDSYNTAX%
Alternatively to the convenient short-cut methods Loop::p, Loop::m one could use the equivalent methods Loop::momentum and Loop::mass respectively.
Line: 747 to 783
to be supplied with the type of the particle. The information on the particle type can be introduced into the loop in the following different ways:
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
// particle name for ( Loop D0 = loop( "K- pi+ pi+ pi-", "D0" ) ; D0 ; ++D0 ) { ... }
Line: 771 to 809
// perform a loop: for ( ; D0 ; ++D0 ) { ... }

Changed:
<
<
>
>
%ENDSYNTAX%
For properly instrumented looping construction one has an access to the information about the effective mother particle of the combination:
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
for ( Loop D0 = loop ( "K- pi+ pi+ pi-", "D0" ) ; D0 ; ++D0 ) {
Line: 787 to 825
const LHCb::Vertex* v_2 = D0->vertex() ; }

Changed:
<
<
>
>
%ENDSYNTAX%
The example above shows several alternative ways for accessing information on "the effective particle" and
Line: 797 to 835
to the types const LHCb::Particle* and const LHCb::Vertex* allows to apply all machinery of Particle and Vertex functions and cuts to the looping construction:
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
for ( Loop D0 = loop( "K- pi+ pi+ pi-", "D0" ) ; D0 ; ++D0 ) { double mass = M( D0 ) / GeV ; // mass in GeV
Line: 805 to 843
double pt = PT ( D0 ) ; // transverse momentum }
Changed:
<
<
>
>
%ENDSYNTAX%

### Saving of the interesting combinations

Changed:
<
<
Every interesting combination of particles could be saved for future reuse in LoKi and/or DaVinci:
>
>
Every interesting combination of particles could be saved for future reuse in LoKi and/or DaVinci: %SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
for ( Loop phi = loop( "kaon- kaon+" , "phi(1020)" ) ; phi ; ++phi ) { if( M( phi ) < 1.050 * Gev ) { phi->save( "phi" ) ; } }

Changed:
<
<
>
>
%ENDSYNTAX%
When particle is saved in internal LoKi storage, it is simultaneously saved into DaVinci's Desktop Tool.
Line: 848 to 885
The helper utility MCMatch could be used to check if given reconstructed particle has the match with given Monte Carlo particle:
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
MCMatch mcmatch = mcTruth ("My MC-truth matcher") ;
Line: 856 to 893
for ( Loop D0 = loop( "K- pi+", "D0" ) ; D0 ; ++D0 ) {
>
>
if ( mcmatch( D0 , MCD0 ) ) { plot ( M(D0) / GeV , "Mass of true D0 1 " , 1.5 , 2.0 ) ;}
>
>
// the same as previous if ( mcmatch->match( D0 , MCD0 ) ) { plot ( M(D0) / GeV, "Mass of true D0 2 " , 1.5 , 2.0 ) ;}
>
>
}
Changed:
<
<
>
>
%ENDSYNTAX%
The actual Monte Carlo matching procedure is described in detail here.

MCMatch object could be used for repetitive matching with sequences of arbitrary type of Monte Carlo and reconstructed particles:

Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
// some 'sequence' or 'range' type typedef std::vector MCSEQ ;
Line: 900 to 941
mcps.begin () , // begin of MC sequence mcps.end () ) ; // end of MC sequence

Changed:
<
<
>
>
%ENDSYNTAX%

The methods described above are template, and therefore they could be

Line: 910 to 951
Of course in the spirit of LoKi is to provide the same functionality in a more useful and elegant way as ordinary predicate or cut:
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
const LHCb::MCParticle* MCD0 = ... ;

Line: 919 to 960
for ( Loop D0 = loop( "K- pi+", "D0" ) ; D0 ; ++D0 ) {
>
>
// use it! if ( mc( D0 ) ) { plot ( M(D0) / GeV , "mass of true D0" , M(D0)/GeV, 1.5 , 2.0 ) ;}
>
>
}
Changed:
<
<
>
>
%ENDSYNTAX%
The latter way is especially convenient for analysis.
Changed:
<
<

>
>

# LoKi Reference Manual

See here

Copyright &© 2008-2019 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback