Difference: LoKiLUG (1 vs. 9)

Revision 92008-05-17 - VanyaBelyaev

Line: 1 to 1
 
META TOPICPARENT name="LoKi"

LoKi User Guide

Line: 964 to 964
  {

// use it!

Changed:
<
<
if ( mc( D0 ) ) { plot ( M ( D0 ) / GeV , "mass of true D0" , M(D0)/GeV, 1.5 , 2.0 ) ; }
>
>
if ( mc( D0 ) ) { plot ( "mass of true D0" , M ( D0 ) / GeV , 1.5 , 2.0 ) ; }
  }
Line: 977 to 975
  See here

Added:
>
>

Commonly used LoKi::Hybrid::Filters

 
Added:
>
>
The list of commonly used LoKi::Hybrid::Filters could be inspected here.
 

Added:
>
>

 -- Vanya Belyaev - 12 Jul 2007 \ No newline at end of file
Added:
>
>

-- Vanya BELYAEV - 17 May 2008

Revision 82007-07-29 - VanyaBelyaev

Line: 1 to 1
 
META TOPICPARENT name="LoKi"

LoKi User Guide

Line: 894 to 894
 for ( Loop D0 = loop( "K- pi+", "D0" ) ; D0 ; ++D0 ) {
Changed:
<
<
if ( mcmatch ( D0 , MCD0 ) ) { plot ( M(D0) / GeV , "Mass of true D0 1 " , 1.5 , 2.0 ) ;}
>
>
if ( mcmatch ( D0 , MCD0 ) ) { plot ( M(D0) / GeV , "Mass of true D0 1 " , 1.5 , 2.0 ) ;}
  // the same as previous
Changed:
<
<
if ( mcmatch -> match ( D0 , MCD0 ) ) { plot ( M(D0) / GeV, "Mass of true D0 2 " , 1.5 , 2.0 ) ; }
>
>
if ( mcmatch -> match ( D0 , MCD0 ) ) { plot ( M(D0) / GeV, "Mass of true D0 2 " , 1.5 , 2.0 ) ; }
  }
Line: 962 to 964
  {

// use it!

Changed:
<
<
if ( mc( D0 ) ) { plot ( M ( D0 ) / GeV , "mass of true D0" , M(D0)/GeV, 1.5 , 2.0 ) ; }
>
>
if ( mc( D0 ) ) { plot ( M ( D0 ) / GeV , "mass of true D0" , M(D0)/GeV, 1.5 , 2.0 ) ; }
  }

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:
<
<
>
>
  These nice, powerful and friendly C++ components are used now for the physics analysis by HERA-B collaboration
Changed:
<
<
>
>
 
  • 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"}%
Added:
>
>
  HYPOTH E+ MU+ PI+ 5 K+ PROTON

IDENT PI+ PI+

Line: 119 to 122
  ENDSEL

GO 1000000

Added:
>
>
 %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"}%
Added:
>
>
 TrackPattern piMinus = pi_minus.with ( pt > 0.1 & p > 1 ) ;
Added:
>
>
 TrackPattern piPlus = pi_plus.with ( pt > 0.1 & p > 1 ) ;
Added:
>
>
 TwoProngDecay kShort = K0S.decaysTo ( PiPlus & PiMinus ) ;
Added:
>
>
 kShort.with ( vz > 0 ) ;
Added:
>
>
 kShort.with ( pt > 0.1 ) ;
Added:
>
>
 %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.
Added:
>
>

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 */ }
Added:
>
>
%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
 

Access to the daughter particles

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 ) {
Added:
>
>
  if ( mcmatch( D0 , MCD0 ) ) { plot ( M(D0) / GeV , "Mass of true D0 1 " , 1.5 , 2.0 ) ;}
Added:
>
>
  // the same as previous if ( mcmatch->match( D0 , MCD0 ) ) { plot ( M(D0) / GeV, "Mass of true D0 2 " , 1.5 , 2.0 ) ;}
Added:
>
>
  }
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 ) {
Added:
>
>
  // use it! if ( mc( D0 ) ) { plot ( M(D0) / GeV , "mass of true D0" , M(D0)/GeV, 1.5 , 2.0 ) ;}
Added:
>
>
  }
Changed:
<
<
>
>
%ENDSYNTAX%
 The latter way is especially convenient for analysis.
Changed:
<
<

LoKi Reference Manual

>
>

LoKi Reference Manual

  See here

Revision 62007-07-16 - VanyaBelyaev

Line: 1 to 1
 
META TOPICPARENT name="LoKi"
Changed:
<
<

LoKi User Guide & Reference Manual

>
>

LoKi User Guide

 
Added:
>
>
For completeness see also LoKi Reference Manual
 
Added:
>
>
 


Line: 21 to 23
 
Changed:
<
<

LoKi User Guide

>
>

LoKi User Guide

 
Changed:
<
<

Introduction

>
>

Introduction

  All off-line OO software for simulation,
Line: 52 to 54
 Often a simple operation corresponding to one "physics" statement results in an enormous code with complicated and probably non-obvious content:
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
  ParticleVector::const_iterator im; for ( im = vDsK.begin(); im = vDsK.end(); im++ ) { if((*im)->particleID().pid() == m_DsPlusID||
Line: 64 to 66
  return StatusCode::FAILURE; } }
Changed:
<
<
>
>
%ENDSYNTAX%
 The usage of comments becomes mandatory for understanding makes the code even longer and again results in additional complexity.
Line: 97 to 98
 The attractiveness of specialised, physics-oriented code for physics analysis could be demonstrated e.g. with "typical" code fragment in KAL:
Changed:
<
<
>
>
%SYNTAX{ syntax="fortran" numbered="1000" numstep="10"}%
  HYPOTH E+ MU+ PI+ 5 K+ PROTON

IDENT PI+ PI+

Changed:
<
<
IDENT K+ K+
>
>
IDENT K+ K
  IDENT PROTON PROTON IDENT E+ E+ IDENT MU+ MU+
Line: 117 to 119
  ENDSEL

GO 1000000

Changed:
<
<
>
>
%ENDSYNTAX%
  This KAL pseudo-code gives an example of self-explanatory code. The physical content of selection of
Changed:
<
<
${\mathrm{D}}^{*+}\rightarrow {\mathrm{D}}^0 \pi^+$, followed by ${\mathrm{D}}^0\rightarrow {\mathrm{K}}^-\pi^0$ decay is clear and unambigously visible between lines. Indeed no comments
>
>
, followed by decay is clear and unambigously visible between these lines. Indeed no comments
 are needed for understanding the analysis within 2 minutes.
Line: 133 to 135
 similar transparency of the physical content of code with native C++. The best answer to this argument could be just an example from T. Glebe's Pattern of
Changed:
<
<
${\mathrm{K}}^0_{\mathrm{S}}\rightarrow \pi^+\pi^-$ reconstruction:
>
>
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 ) ;
Changed:
<
<
>
>
%ENDSYNTAX%
 

This code fragment is not so transparent as specialized

Line: 154 to 155
  Here it is a good moment to jump to the end of the whole story and present some LoKi fragment for illustration:
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
  select ( "Pi+" , ID =="pi+" && P > 5 * GeV ) ; select ( "K-" , ID =="K-" && P > 5 * GeV ) ;
Added:
>
>
  for ( Loop D0 = loop("K- pi+","D0") ; D0 ; ++D0 ) { if ( P( D0 ) > 10 * GeV ){ D0->save("D0"); }
Line: 163 to 165
  } for ( Loop Dstar = loop( "D0 Pi+" , "D*+" ) ; Dstar ; ++Dstar ) {
Changed:
<
<
plot ( M( Dstar ) / GeV , " Mass of D0 pi+ " , 2.0 , 2.1 , 100 );
>
>
plot ( M ( Dstar ) / GeV , " Mass of D0 pi+ " , 2.0 , 2.1 ) ;
  }
Changed:
<
<
>
>
%ENDSYNTAX%
  The physical content of these lines is quite transparent. Again I suppose that it is not obscured with C++ semantics.
Line: 209 to 210
 It is the real pleasure to thank the leaders of ITEP/Moscow, CERN-LBD, LAPP/Annecy and Syracuse University teams for the kind support.
Changed:
<
<

Who is LoKi?

>
>

Who is LoKi?

 
  • Loki is a god of wit and mischief in Norse mythology
  • LoKi could be interpreted as Loops&Kinematics
Changed:
<
<

LoKi ingredients

>
>

LoKi ingredients

  Typical analysis algorithm consists of quite complex combination of the following elementary actions:
Line: 236 to 237
  LoKi has been designed to attack all these five major actions.
Changed:
<
<

Selection

>
>

Selection

 
Changed:
<
<

Selection of Particles

>
>

Selection of Particles

 

LoKi allows to select/filter a subset of reconstructed 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:

Changed:
<
<
    
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
  select( "AllKaons" , abs( ID ) == 321 && PT > 100 * MeV ) ;
Changed:
<
<
>
>
%ENDSYNTAX%
 Here from all particles, loaded by DaVinci, the subset of particles identified as charged kaons (abs(ID)==321) with transverse momentum greater
Line: 283 to 282
 sub-selections. The following example illustrates the idea: the selected sample of kaons is subdivided into samples of positive and negative kaons:
Changed:
<
<
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
  Range kaons = select( "AllKaons" , abs( ID ) == 321 && PT > 100 * MeV ); select( "kaon+" , kaons , Q > 0.5 ) ; select( "kaon-" , kaons , Q < -0.5 ) ;
Changed:
<
<
>
>
%ENDSYNTAX%
 Here all positive kaons (Q>0.5) are selected into the subset named "kaon+" and all negative kaons (Q<-0.5) go to the subset named "kaon-". These subsets again could be subject to further selection/filtering
Line: 300 to 297
 LHCb::Particle::Vector, LHCb::Particle::ConstVector and LHCb::Particle::Container (also known as LHCb::Particles).
Changed:
<
<
    
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
  const LHCb::Particle::ConstVector& particles = ... ; Range kaons_1 = select( "Kaons_1" , particles , abs( ID ) == 321 ) ;

const LHCb::Particle::Container* event = get<LHCb::Particle::Container>( "..." ) ; Range kaons_2 = select( "Kaons_2" , event , 321 == abs( ID ) ) ;

Changed:
<
<
>
>
%ENDSYNTAX%
  Also any arbitrary sequnce of objects, implicitely convertible to the C++ type const LHCb::Particle* can be used as input for selection of particles:
Changed:
<
<
    
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
  /// SEQUENCE is an arbitrary sequence of objects,
Changed:
<
<
/// implicitely convertible to /// type Particle*. e.q. std::vector<Particle*>, /// ParticleVector, Particles, std::set<Particle*> etc.
>
>
/// implicitely convertible to type const LHCb::Particle* /// e.q. std::vector<LHCb::Particle*>, /// LHCb::Particle::ConstVector, LHCb::Particles, std::set<LHCb::Particle*> etc.
  SEQUENCE particles = ... ;
Changed:
<
<
Range kaons = select( "AllKaons" , // 'tag'
>
>
Range kaons = select ( "AllKaons" , // 'tag'
  particles.begin () , // begin of sequence particles.end () , // end of sequence abs( ID ) == 321 ) ; // cut
Changed:
<
<
>
>
%ENDSYNTAX%
  The output of selection (object of type Range) could be directly inspected through the explicit loop over the content of the selected container:
Changed:
<
<
 
    
>
>
%SYNTAX{ syntax="cpp" numbered="1000" numstep="10"}%
  Range kaons = select( "AllKaons" , abs( ID ) == 321 && PT > 100 * MeV ) ;

// regular C++ loop:

Line: 341 to 333
  const LHCb::Particle* k = *kaon ; /* do something with this raw C++ pointer */ }
Changed:
<
<
>
>
%ENDSYNTAX%
 
Changed:
<
<

Selection of Monte Carlo Particles

>
>

Selection of Monte Carlo Particles

  In a similar way one can select Monte Carlo particles (of C++ type LHCb::MCParticle), which satisfy the certain criteria:
Line: 372 to 363
 

Changed:
<
<

Selection of Generator Particles

>
>

Selection of Generator Particles

  Similar to the selection of reconstructed particles and the selection of Monte Carlo particles one can perform the selection of
Line: 400 to 391
 

Changed:
<
<

Selection of Vertices

>
>

Selection of Vertices

  The similar approach is used for selection/filtering of vertices (of C++ type LHCb::VertexBase):
Line: 475 to 466
 
Changed:
<
<

Selection of Monte Carlo Vertices and Generator Vertices

>
>

Selection of Monte Carlo Vertices and Generator Vertices

  The selection of Monte Carlo Vertices and Generator Vertices is performed similar to the the selection of reconstructed Vertices with following difference:
Line: 489 to 480
 

Changed:
<
<

Selection of minimal/maximal candidate

>
>

Selection of minimal/maximal candidate

  It is not unusual to select from some sequence or container of objects the object which maximizes or minimizes
Line: 562 to 553
 

Changed:
<
<

Access to the selected objects

>
>

Access to the selected objects

  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
Line: 584 to 575
 

Changed:
<
<

Loops

>
>

Loops

 
Changed:
<
<

Looping over the reconstructed particles

>
>

Looping over the reconstructed particles

 
Changed:
<
<
Simple one-particle loops
>
>

Simple one-particle loops

  Above it has been already shown how to perform simple looping over the selected range of particles:
Line: 625 to 616
 effective loops over multi-particle combinations. But this gives no essential gain.

Changed:
<
<
Loops over the multi-particle combinations
>
>

Loops over the multi-particle combinations

  Looping over multi-particle combinations is performed using the special object Loop.
Line: 679 to 670
 combinations of the particles of the same type.
Changed:
<
<

Access to the information inside the multi-particle loops

>
>

Access to the information inside the multi-particle loops

  Inside the loop there are several ways to access the information about the properties of the combination.
Changed:
<
<
Access to the daughter particles
>
>

Access to the daughter particles

  For access to the daughter particles (the selection components) one could use following constructions:
Line: 749 to 740
 Loop::m one could use the equivalent methods Loop::momentum and Loop::mass respectively.

Changed:
<
<
Access to the mother particle and its properties
>
>

Access to the mother particle and its properties

  Access to information on the effective mother particle of the combination requires the call of loop method
Line: 840 to 831
 containers/selections.

Changed:
<
<

Patterns

>
>

Patterns

 
Changed:
<
<

Usage of kinematic constraints in LoKi

>
>

Usage of kinematic constraints in LoKi

 

Changed:
<
<

Access to Monte Carlo truth information

>
>

Access to Monte Carlo truth information

 
Changed:
<
<

Monte Carlo truth matching

>
>

Monte Carlo truth matching

  LoKi offers fast, easy, flexible and configurable access to Monte Carlo truth information.
Line: 936 to 927
 The latter way is especially convenient for analysis.
Deleted:
<
<

 

LoKi Reference Manual

Changed:
<
<

LoKi's Particle Functions

ALL
The trivial "select-all" predicate of C++ type LoKi::BooleanConstant(true), which always returns true
ABSID
The simple function (of type LoKi::Particles::AbsIdentifier()), which returns the absolute value of PDG-identifier of the particle:
   const LHCb::Particle* p = ... ;
   const double absid = ABSID( p ) ;
For the invalid argument LoKi::Constanst::InvalidID is returned.The special comparison operators against std::string and LHb::ParticleID objects are defined:
   Range kaons = select ( "kaons" , "K+" == ABSID ) ;
   Range muons = select ( "muons" , LHCb::ParticleID( 13 ) == ABSID ) ;
See also ID
EQUALTO
Simple predicate ( of C++ type LoKi::EqualToValue) which checks if the value of the certain function equal to some predefined value:
   Range k1 = select ( "positive" , EQUALTO( Q , +1.0 ) ) ;
   Range k2 = select ( "positive" , Q == +1 ) ; ///< the same
HASKEY
Predicate which returns true if the argument has the assigned key, see also KEY
KEY
Function, which returns the value of the assigned key. For invalid arguments, of if no key is assigned LoKi::Constants::InvalidKey is returned, see also HASKEY
ID
The simple function (of type LoKi::Particles::Identifier()), which returns the value of PDG-identifier of the particle:
   const LHCb::Particle* p = ... ;
   const double id = ID( p ) ;
For the invalid argument LoKi::Constanst::InvalidID is returned.The special comparison operators against std::string and LHb::ParticleID objects are defined:
   Range kaons = select ( "kaons" , "K+" == ID ) ;
   Range muons = select ( "muons" , LHCb::ParticleID( 13 ) == ID ) ;
See also ABSID
NONE
The trivial "select-none" predicate of C++ type LoKi::BooleanConstant(false), which always returns false
ONE
The trivial function of C++ type LoKi::Constant(1), which always returns 1
PALL
alias for ALL, see here
PFALSE
alias for NONE, see here
PNONE
alias for NONE, see here
PONE
alias for ONE, see here
PSWITCH
alias for SWITCH, see here
PTRUE
alias for ALL, see here
PZERO
alias for ZERO, see here
SWITCH
The function (C++ type LoKi::Switch), which acts according the rule: result = condition ? function1 : function2:
   Fun signedPT = SWITCH( 0 < Q , PT , -1*PT ) ; 
VALID
The trivial function of C++ type LoKi::Valid(), which check the validity of the argument:
   const std::vector<const LHCb::Particle*>& p = ... ;
   // check for invalid pointers:
   if ( std::find_if ( p.begin() , p.end() , !VALID ) != p.end() ) { ... there are null pointers ... }  
ZERO
The trivial function of C++ type LoKi::Constant(0), which always returns 0
>
>
See here
 

Revision 52007-07-15 - VanyaBelyaev

Line: 1 to 1
 
META TOPICPARENT name="LoKi"

LoKi User Guide & Reference Manual

Line: 945 to 945
 
Added:
>
>

LoKi's Particle Functions

ALL
The trivial "select-all" predicate of C++ type LoKi::BooleanConstant(true), which always returns true
ABSID
The simple function (of type LoKi::Particles::AbsIdentifier()), which returns the absolute value of PDG-identifier of the particle:
   const LHCb::Particle* p = ... ;
   const double absid = ABSID( p ) ;
For the invalid argument LoKi::Constanst::InvalidID is returned.The special comparison operators against std::string and LHb::ParticleID objects are defined:
   Range kaons = select ( "kaons" , "K+" == ABSID ) ;
   Range muons = select ( "muons" , LHCb::ParticleID( 13 ) == ABSID ) ;
See also ID
EQUALTO
Simple predicate ( of C++ type LoKi::EqualToValue) which checks if the value of the certain function equal to some predefined value:
   Range k1 = select ( "positive" , EQUALTO( Q , +1.0 ) ) ;
   Range k2 = select ( "positive" , Q == +1 ) ; ///< the same
HASKEY
Predicate which returns true if the argument has the assigned key, see also KEY
KEY
Function, which returns the value of the assigned key. For invalid arguments, of if no key is assigned LoKi::Constants::InvalidKey is returned, see also HASKEY
ID
The simple function (of type LoKi::Particles::Identifier()), which returns the value of PDG-identifier of the particle:
   const LHCb::Particle* p = ... ;
   const double id = ID( p ) ;
For the invalid argument LoKi::Constanst::InvalidID is returned.The special comparison operators against std::string and LHb::ParticleID objects are defined:
   Range kaons = select ( "kaons" , "K+" == ID ) ;
   Range muons = select ( "muons" , LHCb::ParticleID( 13 ) == ID ) ;
See also ABSID
NONE
The trivial "select-none" predicate of C++ type LoKi::BooleanConstant(false), which always returns false
ONE
The trivial function of C++ type LoKi::Constant(1), which always returns 1
PALL
alias for ALL, see here
PFALSE
alias for NONE, see here
PNONE
alias for NONE, see here
PONE
alias for ONE, see here
PSWITCH
alias for SWITCH, see here
PTRUE
alias for ALL, see here
PZERO
alias for ZERO, see here
SWITCH
The function (C++ type LoKi::Switch), which acts according the rule: result = condition ? function1 : function2:
   Fun signedPT = SWITCH( 0 < Q , PT , -1*PT ) ; 
VALID
The trivial function of C++ type LoKi::Valid(), which check the validity of the argument:
   const std::vector<const LHCb::Particle*>& p = ... ;
   // check for invalid pointers:
   if ( std::find_if ( p.begin() , p.end() , !VALID ) != p.end() ) { ... there are null pointers ... }  
ZERO
The trivial function of C++ type LoKi::Constant(0), which always returns 0

 
Deleted:
<
<

 -- Vanya Belyaev - 12 Jul 2007

Revision 32007-07-11 - VanyaBelyaev

Line: 1 to 1
 
META TOPICPARENT name="LoKi"

LoKi User Guide

Line: 15 to 15
 with various kinematic constrains and access to Monte Carlo truth information.
Changed:
<
<

User Guide

>
>

LoKi User Guide

 

Introduction

Line: 200 to 200
 Hugo Ruiz Perez, Jeroen van Tilburg and Benoit Viaud.
Changed:
<
<
It is a pleasure to thank the leaders of ITEP/Moscow, CERN-LBD,
>
>
It is the real pleasure to thank the leaders of ITEP/Moscow, CERN-LBD,
 LAPP/Annecy and Syracuse University teams for the kind support.
Added:
>
>

Who is LoKi?

  • Loki is a god of wit and mischief in Norse mythology
  • LoKi could be interpreted as Loops&Kinematics
 

LoKi ingredients

Line: 336 to 338
 
Added:
>
>
 

Selection of Monte Carlo Particles

Deleted:
<
<
 In a similar way one can select Monte Carlo particles (of C++ type LHCb::MCParticle), which satisfy the certain criteria:
Line: 359 to 361
  The differences with respect the previous case are
  • one needs to use the function mcselect instead of select
Changed:
<
<
  • the return value of this function has C++ type MCRange and behaves like container of const LHCb::MCParticle*
>
>
  • the return value of this function has C++ type MCRange and behaves like the container of const LHCb::MCParticle*
 
  • for selection one needs to use the special Monte Carlo variables & cuts, e.g. in this example MCID, MCPT and MC3Q.
Added:
>
>

Selection of Generator Particles

 
Added:
>
>
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:
<
<

Selection of Generator Particles

>
>
GRange kaons = gselect ( "AllGenKaons" , abs( GID ) == 321 && GPT > 100 * MeV ) ;

GRange k1 = gselect ( "genK+" , kaons , G3Q >= 1 ) ; GRange k2 = gselect ( "genK-" , kaons , G3Q <= -1 ) ;

// regular C++ loop: for ( GRange::iterator ik1 = k1.begin() ; k1.end() = ik1 ; ++ik1 ) { const HepMC::GenParticle* gen = *k1 ; /* do something with this raw C++ pointer */ }

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*
  • for selection one needs to use the special Generator variables & cuts, e.g. in this example GID, GPT and G3Q.

 

Selection of Vertices

Changed:
<
<

Selection of Monte Carlo Vertices

>
>
The similar approach is used for selection/filtering of vertices (of C++ type LHCb::VertexBase):
    
    VRange vs  = vselect( "GoodPVs" , 
                  PRIMARY && 5 < VTRACKS && VCHI2 / VDOF < 10 );
    
 
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) and with $\chi^2/{\mathrm{nDoF}}$ less than 10 (VCHI2/VDOF<10). This set of selected vertices is named as "GoodPVs".

Again PRIMARY, VTRACKS, VCHI2 and VDOF are predefined LoKi Vertex functions & cuts. It is internal convention of LoKi that all predefined functions, types and methods for vertices start their names from capital letter V. As an example one see type VRange for a light pseudo-container of const LHCb::VertexBase*, function vselect and all variables for vertices.

Also there exist the variants of vselect methods, which allow the subselection of vertices from already selected ranges of vertices (C++ type VRange), standard DaVinci containers (C++ types LHCb::VertexBase::Vector, LHCb::VertexBase::ConstVector, LHCb::VertexBase::Container, LHCb::Vertex::Vector, LHCb::Vertex::ConstVector, LHCb::Vertex::Container, LHCb::RecVertex::Vector, LHCb::RecVertex::ConstVector, LHCb::RecVertex::Container and from arbitary sequence of objects, convertible to const LHCb::VertexBase*:

    
    VRange vertices_1 = ... ;
    VRange vs1 = 
       vselect(  "GoodPVs1"  ,              // 'tag'
                 vertices_1  ,              // input vertices 
                 PRIMARY && 5 < VTRACKS  ); // cut 
    
    LHCb::VertexBase::ConstVector vertices_2 = ... ;
    VRange vs2 = 
       vselect(  "GoodPVs2"  ,              // 'tag'
                 vertices_2  ,              // input vertices 
                 PRIMARY && 5 < VTRACKS  ); // cut 
    
    /// arbitrary sequence of ojbects, implicitely convertible to 
    /// type LHCb::VertexBase*, e.g. std::vector<LHCb::VertexBase*>
    SEQUENCE vertices_3 = ... ; 
    VRange vs3 = 
      vselect(  "GoodPVs4"          ,      // 'tag'
                vertices_3.begin () ,      // begin of input sequence 
                vertices_3.end   () ,      // end of input sequence 
                PRIMARY && 5 < VTRACKS  ); // cut 
    

In summary, for selection of vertices:

  • one needs to use the function vselect
  • the return value of this function has C++ type VRange and behaves like the container of const LHCb::VertexBase*
  • for selection one needs to use the special Vertex variables & cuts, e.g. in this example PRIMARY, VTRACKS, VCHI2 and VDOF.

Selection of Monte Carlo Vertices and Generator Vertices

The selection of Monte Carlo Vertices and Generator Vertices is performed similar to the the selection of reconstructed Vertices with following difference:

  • one needs to use the functions mcvselect and gvselect for Monte Carlo Vertices and Generator Vertices respectively
  • the return value of this function has C++ type MCVRange (GVRange)and behaves like the container of const LHCb::MCVertex* (const HepMC::GenVertex*) for Monte Carlo Vertices and Generator Vertices respectively
  • for selection one needs to use the special Monte Carlo Vertex variables & cuts or Generator Vertex variables & cuts

Selection of minimal/maximal candidate

It is not unusual to select from some sequence or 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:


    // get all primary vertices 
    VRange vrtxs     = vselect( "GoodPVs" , PRIMARY ) ;

    const  LHCb::VertexBase* vertex  = select_max( vrtxs , VTRACKS ) ;
  
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.


    // get all primary vertices:
    VRange vrtxs           = vselect( "GoodPVs" , PRIMARY );
    
    // get B-candidate 
    const LHCb::Particle* B = ... 
    
    // find the primatry vertex with minimal B-impact parameter
    const LHCb::VertexBase* vertex  = select_min( vrtxs , VIP( B , geo() ) ) ;
    
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 the given particle (e.g. B-candidate) with respect to the vertex.

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

    
    Range kaons  = select( .... );

    const LHCb::Particle* kaon  = select_min( kaons  , abs( PY ) + sin( PX )   ) ;
    
 
Here from the container of preselected kaons the particle, which gives the minimal value of funny combination $\left|{\mathrm{p_y}}\right|+ \sin {\mathrm{p_x}}$ is selected.

The methods select_min_ and =select_max also allow the conditional selection of minimal/maximal candidate:


    MCRange kaons = mcselect( "kplus" , MCID == "K+" ) ;

    MCRange::iterator igood = select_max
                       ( kaons.begin() ,    // begin of the sequence 
                         kaons.end  () ,    // end of the sequence 
                         MCPT          ,    // function to be maximized
                         0 < MCPZ      ) ;  // condition/cut


    if ( kaons.end() != igood  ) 
      {
          const LHCb::MCParticle* good = *igood ;
         /* do something with this raw C++ pointer */    
       }


Here the maximum is searched only within the particles whcih satisfy the cut (0<MCPZ) - the z-component of particle momenta must be positive..

Access to the selected objects

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 string argument of the functions *select) and the function *selected:


    // get all previously selected particles, tagged as "MyGoodKaons":
    Range goodK = selected ( "MyGoodKaons" ) ;

    // get all previosly selected Monte Carlo particles, tagged as "TrueMCkaons":
    MCRange mcK = mcselected ( "TrueMCkaons" ) ;

    // get all previosly selected Generator particles, tagged as "My good b-quarks":
    GRange bquarks = mcselected ("My good b-quarks") ; 
 

Loops

Looping over the reconstructed particles

Simple one-particle loops

Above it has been already shown how to perform simple looping over the selected range of particles:

     
    Range kaons =  select( "AllKaons" , abs( ID ) == 321 && PT > 100 * MeV );

    for ( Range::iterator kaon = kaons.begin() ; kaons.end() != kaon ; ++kaon )
    { 
      const LHCb::Particle* k = *kaon ;
      /* do something with this raw C++ pointer */
    }

Equivalently one can use methods Range::operator(), Range::operator[] or Range::at():

 
    Range kaons =  select ( "AllKaons" , abs( ID ) == 321 && PT > 100 * MeV );

    for ( unsigned int index = 0 ; index < kaons.size() ; ++index ) 
      {
         const LHCb::Particle* k1 = kaons     ( index ) ;  // use Range::operator()
         const LHCb::Particle* k2 = kaons     [ index ] ;  // use Range::operator[]
         const LHCb::Particle* k3 = kaons .at ( index ) ; // use Range::at 
      }
    
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 effective loops over multi-particle combinations. But this gives no essential gain.

Loops over the multi-particle combinations

Looping over multi-particle combinations is performed using the special object Loop. All native C++ semantics for looping is supported by this object, e.g. for native C++ for -loop:

    
    // loop over all "kaon- kaon+ "combinations
    for  ( Loop phi = loop ( "kaon- kaon+" ) ; phi ; ++phi ) 
    {
       /* do something with the combination */  
    }
    
The while -form of the native C++ loop is also supported:
     
    Loop phi = loop( "kaon- kaon+" ) ;
    while ( phi ) 
      { 
         /* do something with the combination */  
      
         ++phi ; // go to the next valid combination
      }
    

The parameter of loop function is the selection formula (blank or comma separated list of particle tags). All items in the selection formula must be known for LoKi, e.g. previously selected using select functions.

LoKi takes care about the multiple counting within the loop over multiparticle combinations, e.g. for the following loop the given pair of two photons will appear only once:

    
    Loop pi0 = loop( "gamma gamma" ) ;
    while ( pi0 ) 
    { 
       /* do something with the combination */  
      
       ++pi0 ; // go to the next valid combination
    }
    
Internally LoKi eliminates such double counting through the discrimination of non-ordered combinations of the particles of the same type.

Access to the information inside the multi-particle loops

Inside the loop there are several ways to access the information about the properties of the combination.

Access to the daughter particles

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

    
    for ( Loop D0 = loop( "K- pi+ pi+ pi-" ) ; D0 ; ++D0 ) 
    {
      const LHCb::Particle* kaon = D0(1) ; // the first daughter particle 
      const LHCb::Particle* piP1 = D0(2) ; // the first positively charged pion 
      const LHCb::Particle* piP2 = D0(3) ; // the second positively charged pion
      const LHCb::Particle* pim  = D0(4) ; // the fourth daughter particle   
    }
    
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:
    
    for( Loop D0 = loop( "K- pi+ pi+ pi-" ) ; D0 ; ++D0 ) 
    {
      const LHCb::Particle* kaon = D0->daughter(1) ; // the first daughter  
      const LHCb::Particle* piP1 = D0->daughter(2) ; // the second daughter
      const LHCb::Particle* piP2 = D0->child(3)    ; // the third daughter 
      const LHCb::Particle* pim  = D0->particle(4) ; // the fourth daughter 
    }
    

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:

    
    for ( Loop D0 = loop( "K- pi+ pi+ pi-" ) ; D0 ; ++D0 ) 
    {
      const double PKaon = P ( D0(1) ) /GeV ; // Kaon momentum in GeV/c  
      const double PTpm  = PT( D0(4) )      ; // Momentum of  "pi-" 
    }
    

Plenty of methods exist for evaluation of different kinematic quantities of different combinations of daughter particles:

    
    for ( Loop D0 = loop( "K- pi+ pi+ pi-" ) ; D0 ; ++D0 ) 
    {  
      const LoKi::LorentzVector v   = D0->p()  ; // 4 vector of the whole combination
      const LoKi::LorentzVector v0  = D0->p(0) ; // 4 vector of the whole combination
      const LoKi::LorentzVector v1  = D0->p(1)    ; // 4-vector of K- 
      const LoKi::LorentzVector v14 = D0->p(1,4)  ; // 4-vector of K- and pi- 
      const LoKi::LorentzVector v123 = D0->momentum(1,2,3)  ; // 4-vector of K- and pi+ and pi+ 
      double m12  = D0->p(1,2).m()       ; // mass of K- and the first pi+
      double m234 = D0->p(2,3,4).m()     ; // mass of 3 pion sub-combination    
      doule  m24  = D0->mass(2,4)        ; // mass of 2nd and 4th particles
      doule  m13  = D0->m(1,3)            ; // mass of 1st and 3rd particles
    }
    
Alternatively to the convenient short-cut methods Loop::p, Loop::m one could use the equivalent methods Loop::momentum and Loop::mass respectively.

Access to the mother particle and its properties

Access to information on the effective mother particle of the combination requires the call of loop method 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:

    
    // particle name 
    for ( Loop D0 = loop( "K- pi+ pi+ pi-", "D0" ) ; D0 ; ++D0 ) { ... } 
 
    // particle ID 
    for ( Loop D0 = loop( "K- pi+ pi+ pi-", 241  ) ; D0 ; ++D0 ) { ... }
 
    // through ParticleProperty object:
    const ParticleProperty* pp = ... ;
    for ( Loop D0 = loop( "K- pi+ pi+ pi-", pp  ) ; D0 ; ++D0 ) { ... }

    // explicit set/reset
    Loop D0 = loop( "K- pi+ pi+ pi-" ) ;

    D0 -> setPID( 241 )      ;  // set/reset the partcle ID  
    // the same: 
    D0 -> setPID( "D0" )     ;  // set/reset the partcle ID  
    // the same: 
    D0 -> setPID( pp )       ;  // set/reset the partcle ID  

    // perform a loop:
    for ( ; D0 ; ++D0 )  { ... }
    

For properly instrumented looping construction one has an access to the information about the effective mother particle of the combination:

    
    for ( Loop D0 = loop ( "K- pi+ pi+ pi-", "D0" ) ; D0 ; ++D0 ) 
    {
      const LHCb::Particle*   d0_1 = D0   ;
      const LHCb::Particle*   d0_2 = D0( 0 )  ;
      const LHCb::Particle*   d0_3 = D0->particle()  ;
      const LHCb::Particle*   d0_4 = D0->particle( 0 )  ;
      const LHCb::Vertex*     v_1  = D0   ;
      const LHCb::Vertex*     v_2  = D0->vertex() ;
    } 
    

The example above shows several alternative ways for accessing information on "the effective particle" and "the effective vertex" of the combination.

The existence of the implicit conversion of the looping construction 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:


    for ( Loop D0 = loop( "K- pi+ pi+ pi-", "D0" ) ; D0 ; ++D0 ) {
      double mass  = M( D0 ) / GeV ; // mass in GeV 
      double chi2v = VCHI2( D0 )   ; // chi2 of vertex fit 
      double pt    = PT ( D0 ) ;  // transverse momentum 
      } 

Saving of the interesting combinations

Every interesting combination of particles could be saved for future reuse in LoKi and/or DaVinci:

    
    for ( Loop phi = loop( "kaon- kaon+" , "phi(1020)" ) ; phi ; ++phi ) 
    {
      if( M( phi )  < 1.050 * Gev ) { phi->save( "phi" ) ; }
    }
    

When particle is saved in internal LoKi storage, it is simultaneously saved into DaVinci's Desktop Tool. For each saved category of particles a new LoKi tag is assigned. In the above example the tag "phi" is assigned to all selected and saved combinations. One could reuse already existing tags to add the n ewly saved particles to existing LoKi containers/selections.

Patterns

Usage of kinematic constraints in LoKi

Access to Monte Carlo truth information

Monte Carlo truth matching

LoKi offers fast, easy, flexible and configurable access to Monte Carlo truth information. The helper utility MCMatch could be used to check if given reconstructed particle has the match with given Monte Carlo particle:


    MCMatch mcmatch = mcTruth ("My MC-truth matcher") ;

    const LHCb::MCParticle* MCD0 = ... ;

    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 ) ;}
    } 

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:


    // some 'sequence' or 'range' type
    typedef std::vector<const LHCb::MCParticle*> MCSEQ   ; 
    // some 'sequence' or 'range' type
    typedef std::vector<const   LHCb::Particle*> RECOSEQ ;
    
    MCSEQ                   mcps = ... ;
    RECOSEQ                   ps = ... ;
    const LHCb::MCParticle*  mcp = ... ;
    const   LHCb::Particle*    p = ... ; 
    
    MCMatch mcmatch = mcTruth() ;

    /// return the iterator to the first matched RECO particle
    RECOSEQ::const_iterator ip = 
       mcmatch->match( ps.begin () ,   // begin of sequence of Particles 
                       ps.end   () ,   // end   of sequence of Particles   
                       mcp         ) ; // Monte Carlo particle

    /// return the iterator to the first  matched MC particle
    MCSEQ::const_iterator imcp = 
       mcmatch->match( p              , // reconstructed particle    
                       mcps.begin ()  , // begin of MC sequence  
                       mcps.end   ()  );// end   of MC sequence  

    /// return true if *ALL* RECO particles are matched to MC 
    bool all = mcmatch->
        match(   ps.begin   () ,    // begin of sequence of reco particles     
                 ps.end     () ,    // end of sequence o=f reco particles 
                 mcps.begin () ,    // begin of MC sequence 
                 mcps.end   () ) ;  // end   of MC sequence
    
 

The methods described above are template, and therefore they could be applied to any type of sequence of pointers to LHCb::MCParticle and LHCb::Particle objects.

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:


    const LHCb::MCParticle* MCD0 = ... ;
    
    // create the predicate:
    Cut mc = MCTRUTH ( mcTruth() , MCD0 ) ;

    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 ) ;}
    } 

The latter way is especially convenient for analysis.

 
Added:
>
>

LoKi Reference Manual

 

Revision 22007-07-11 - VanyaBelyaev

Line: 1 to 1
 
META TOPICPARENT name="LoKi"

LoKi User Guide

Changed:
<
<

Abstract

>
>

Abstract

 LoKi is a package for the simple and user-friendly data analysis.
Changed:
<
<
LoKi is based on Gaudi architechture.
>
>
LoKi is based on Gaudi architecture.
 The current functionality of LoKi includes
Changed:
<
<
the selection of particles, manipulaton with predefined kinematical expressions, loops over combinations
>
>
the selection of particles, manipulations with predefined kinematic expressions, loops over combinations
 of selected particles, creation of composite particles from various combinations of particles, flexible manipulation
Changed:
<
<
with various kinematical constrains and
>
>
with various kinematic constrains and
 access to Monte Carlo truth information.

User Guide

Line: 24 to 24
 digitization, recontruction, vizualization and
Changed:
<
<
analysis, for LHCb~\cite{LHCbTP} collaboration
>
>
analysis, for LHCb collaboration
 is based on Gaudi framework. All software is written on C++, which is currently the best suited language for large scale OO software projects. It is worth to mention here that for the experts coding in C++ is like a real fun. The language itself
Changed:
<
<
and its embedded abilities to provide ``ready-to-use'' nontrivial,
>
>
and its embedded abilities to provide ready-to-use' nontrivial,
 brilliant and exiting solution for almost all ordinary, tedious and quite boring problems seems to be very attractive features for persons who has some knowledge and experience with OO programming.
Line: 39 to 39
 of acceptable quality. An essential static nature of the language itself requires the knowledge of compilation and linkage details.
Changed:
<
<
In addition quite often in the ``typical'' code fragments
>
>
In addition quite often in the "typical" code fragments
 for physical analysis the explicit C++ semantics
Changed:
<
<
and syntax hide the ``physical'' meaning
>
>
and syntax hide the "physical" meaning
 of the line and thus obscure the physical analysis algorithm.
Changed:
<
<
Often a simple operation corresponding to one ``physics'' statement results in an enormouse code with complicated
>
>
Often a simple operation corresponding to one "physics" statement results in an enormous code with complicated
 and probably non-obvious content:
    ParticleVector::const_iterator im;
Line: 70 to 69
 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
>
>
  • 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:
<
<
\item {\sc{Pattern}}~\cite{Pattern}\index{{\sc{Pattern}}} and {\sc{GCombiner}}~\cite{GCombiner}\index{{\sc{GCombiner}}} packages by Thorsten Glebe.
>
>
  These nice, powerful and friendly C++ components are used now for
Changed:
<
<
the physics analysis by HERA-B collaboration \item Some obsolete {\sc{Clhep}}~\cite{Clhep}\index{{\sc{Clhep}}} classes, like {\tt{HepChooser}} and {\tt{HepCombiner}} \index{{\sc{Clhep}}!{\tt{HepChooser}}} \index{{\sc{Clhep}}!{\tt{HepCombiner}}} \item {\sc{Loki}}~\cite{Loki}\index{{\sc{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
>
>
the physics analysis by HERA-B collaboration
  • 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:
<
<
\end{itemize}
>
>
The attractiveness of specialised, physics-oriented code for physics analysis could be demonstrated e.g. with "typical" code fragment in KAL:
    HYPOTH  E+  MU+  PI+ 5  K+  PROTON
    
    IDENT PI+     PI+
    IDENT K+      K+
    IDENT PROTON  PROTON
    IDENT E+      E+
    IDENT MU+     MU+
    
    SELECT K- PI+ 
     IF P > 2 THEN
      SAVEFITM D0 DMASS 0.045 CHI2 16  
     ENDIF 
    ENDSEL
     
    SELECT D0 PI+ 
     PLOT MASS L 2.0 H 2.100 NB 100 TEXT ' Mass of D0 pi+ '
    ENDSEL

    GO 1000000

This KAL pseudo-code gives an example of self-explanatory code. The physical content of selection of ${\mathrm{D}}^{*+}\rightarrow {\mathrm{D}}^0 \pi^+$, followed by ${\mathrm{D}}^0\rightarrow {\mathrm{K}}^-\pi^0$ decay is clear and unambigously visible between lines. Indeed no comments are needed for understanding the analysis within 2 minutes.

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 from T. Glebe's Pattern of ${\mathrm{K}}^0_{\mathrm{S}}\rightarrow \pi^+\pi^-$ reconstruction:

   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 ) ;

This code fragment is not so transparent as specialized 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 C++ package for physics analysis. Indeed the work has been started soon after I've seen these 5 lines.

Here it is a good moment to jump to the end of the whole story and present some LoKi fragment for illustration:

    select ( "Pi+" , ID =="pi+" && P > 5 * GeV ) ;
    select ( "K-"  , ID =="K-"  && P > 5 * GeV ) ;
    for ( Loop D0 = loop("K- pi+","D0") ; D0 ; ++D0 )
    {
      if ( P( D0 ) > 10 * GeV ){ D0->save("D0"); }
    }
    for ( Loop Dstar = loop( "D0 Pi+" , "D*+" ) ; Dstar ; ++Dstar )
    {
      plot ( M( Dstar ) / GeV , " Mass of D0 pi+ " , 2.0 , 2.1 , 100 );
    }

The physical content of these lines is quite transparent. Again I suppose that it is not obscured with C++ semantics. 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 developed withing DaVinci project.

Since LoKi is just a thin layer, all DaVinci tools are 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.

As a last line of this chapter I'd like to thank Galina Pakhlova, Andrey Tsaregorodtsev and Sergey Barsuk 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, Hans Dijkstra, Markus Frank, Jose Angel Hernando Morata, Jeroen van Hunen, Sander Klaus, Patrick Koppenburg, Pere Mato, Juan Palacios, Boleslav Pietrzyk, Gerhard Raven, Thomas Ruf, Hugo Ruiz Perez, Jeroen van Tilburg and Benoit Viaud.

It is a pleasure to thank the leaders of ITEP/Moscow, CERN-LBD, LAPP/Annecy and Syracuse University teams for the kind support.

LoKi ingredients

Typical analysis algorithm consists of quite complex combination of the following elementary actions:

  • selection/filtering with the criteria based on particle(s) kinematics, identification and topological properties, e.g. particle momenta, transverse momenta, confidence levels, impact parameters etc.
  • looping over the various combinations of selected particles and applying other criteria based on kinematic properties of the whole combination or any sub-combinations or some topology information (e.g. vertexing), including mass and/or vertex constrain fits.
  • saving of interesting combinations as "particles" which acquire all kinematic properties and could be further treated in the standard way.
  • for evaluation of efficiencies and resolutions the access for Monte Carlo truth information is needed.
  • also required is the filling of histograms and N-tuples.

LoKi has been designed to attack all these five major actions.

Selection

Selection of Particles

LoKi allows to select/filter a subset of reconstructed 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:

    
    select( "AllKaons" , abs( ID ) == 321 && PT > 100 * MeV ) ;

Here from all particles, loaded by DaVinci, the subset of particles identified as charged kaons (abs(ID)==321) with transverse momentum greater than 100 MeV/c (PT>100*MeV) is selected. These particles are copied into internal local LoKi storage and could be accessed later using the symbolic name "AllKaons".

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 the given particle. Cuts or predicates or selection criteria are constructed with the comparison operations '<', '<=', '==', '!=', '>=', '>' from variables. The arbitrary combinations of cuts with the boolean operations '&&' or '||' are allowed to be used as selection criteria.

LoKi defines many frequently used variables and set of the regular mathematical operation on them '+', '-', '*', '/' and all elementary functions, like sin, cos, log, atan, atan2, pow etc, which could be used for construction of variables of the arbitrary complexity. Cuts and variables are discussed in detail in subsequent chapters

Indeed the function select has a return value of type Range, which is essentially the light-weight container of selected particles. The returned value could be used for immediate access to the selected particles and in turn could be used for further sub-selections. The following example illustrates the idea: the selected sample of kaons is subdivided into samples of positive and negative kaons:


    Range kaons =  select( "AllKaons" , abs( ID ) == 321 && PT > 100 * MeV );
    select( "kaon+" , kaons , Q >   0.5 ) ;
    select( "kaon-" , kaons , Q < -0.5 ) ;

Here all positive kaons (Q>0.5) are selected into the subset named "kaon+" and all negative kaons (Q<-0.5) go to the subset named "kaon-". These subsets again could be subject to further selection/filtering in a similar way.

LoKi allows to perform selection of particles from standard DaVinci containers of particles LHCb::Particle::Vector, LHCb::Particle::ConstVector and LHCb::Particle::Container (also known as LHCb::Particles).

    
    const LHCb::Particle::ConstVector& particles = ... ;
    Range kaons_1 =  select( "Kaons_1" , particles , abs( ID ) == 321 ) ;
    
    const LHCb::Particle::Container* event = get<LHCb::Particle::Container>( "..." ) ; 
    Range kaons_2 =  select( "Kaons_2" , event     , 321 == abs( ID ) ) ;
    

Also any arbitrary sequnce of objects, implicitely convertible to the C++ type const LHCb::Particle* can be used as input for selection of particles:

    
    /// SEQUENCE is an arbitrary sequence of objects, 
    /// implicitely convertible to 
    /// type Particle*. e.q. std::vector<Particle*>, 
    /// ParticleVector, Particles, std::set<Particle*> etc. 
    SEQUENCE particles = ... ;

    Range kaons =  select( "AllKaons"          ,   // 'tag'
                                      particles.begin () ,   // begin of sequence
                                      particles.end   () ,   // end of sequence 
                                      abs( ID ) == 321   ) ; // cut 

The output of selection (object of type Range) could be directly inspected through the explicit loop over the content of the selected container:

 
    
    Range kaons =  select( "AllKaons" , abs( ID ) == 321 && PT > 100 * MeV ) ;

    // regular C++ loop:
    for( Range::iterator kaon = kaons.begin() ; kaons.end() != kaon ; ++kaon )
      { 
        const LHCb::Particle* k = *kaon ;
        /* do something with this raw C++ pointer */
      }

 

Selection of Monte Carlo Particles

In a similar way one can select Monte Carlo particles (of C++ type LHCb::MCParticle), which satisfy the certain criteria:


    MCRange kaons = mcselect ( "AllMCKaons" , abs( MCID ) == 321 && MCPT > 100 * MeV  ) ;

    MCRange k1 = mcselect ( "mcK+" , kaons , MC3Q >=  1 ) ;
    MCRange k2 = mcselect ( "mcK-"  , kaons , MC3Q <= -1 ) ; 

    // regular C++ loop:
    for ( MCRange::iterator ik1 = k1.begin() ; k1.end() != ik1 ; ++ik1 )
       {
          const LHCb::MCParticle* mc = *k1 ;
          /* do something with this raw C++ pointer */      
       }

The differences with respect the previous case are

  • one needs to use the function mcselect instead of select
  • the return value of this function has C++ type MCRange and behaves like container of const LHCb::MCParticle*
  • for selection one needs to use the special Monte Carlo variables & cuts, e.g. in this example MCID, MCPT and MC3Q.

Selection of Generator Particles

Selection of Vertices

Selection of Monte Carlo Vertices

 

Revision 12007-07-11 - VanyaBelyaev

Line: 1 to 1
Added:
>
>
META TOPICPARENT name="LoKi"

LoKi User Guide

Abstract

LoKi is a package for the simple and user-friendly data analysis. LoKi is based on Gaudi architechture. The current functionality of LoKi includes the selection of particles, manipulaton with predefined kinematical expressions, loops over combinations of selected particles, creation of composite particles from various combinations of particles, flexible manipulation with various kinematical constrains and access to Monte Carlo truth information.

User Guide

Introduction

All off-line OO software for simulation, digitization, recontruction, vizualization and analysis, for LHCb~\cite{LHCbTP} collaboration is based on Gaudi framework. All software is written on C++, which is currently the best suited language for large scale OO software projects. It is worth to mention here that for the experts coding in C++ is like a real fun. The language itself and its embedded abilities to provide ``ready-to-use'' nontrivial, brilliant and exiting solution for almost all ordinary, tedious and quite boring problems seems to be very attractive features for persons who has some knowledge and experience with OO programming. Unfortunately C++ requires significant amount of efforts from beginners to obtain some first results of acceptable quality. An essential static nature of the language itself requires the knowledge of compilation and linkage details. In addition quite often in the ``typical'' code fragments for physical analysis the explicit C++ semantics and syntax hide the ``physical'' meaning of the line and thus obscure the physical analysis algorithm. Often a simple operation corresponding to one ``physics'' statement results in an enormouse code with complicated and probably non-obvious content:

    ParticleVector::const_iterator im;
    for ( im = vDsK.begin(); im != vDsK.end(); im++ ) {
      if((*im)->particleID().pid() == m_DsPlusID||
      (*im)->particleID().pid() == m_DsMinusID) vDs.push_back(*im);
      else if((*im)->particleID().pid() == m_KPlusID||
      (*im)->particleID().pid() == m_KMinusID) vK.push_back(*im);
      else{
        log <<MSG::ERROR<< " some message here "<<endreq;
        return StatusCode::FAILURE;
        }
      }

The usage of comments becomes mandatory for understanding makes the code even longer and again results in additional complexity.

The idea of LoKi package is to provide the users with possibility to write the code, which does not obscure the 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:

  • 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 and executed by standard KAL executable. The package was very successfully used for physics analysis by ARGUS collaboration.
\item {\sc{Pattern}}~\cite{Pattern}\index{{\sc{Pattern}}} and {\sc{GCombiner}}~\cite{GCombiner}\index{{\sc{GCombiner}}} packages by Thorsten Glebe. These nice, powerful and friendly C++ components are used now for the physics analysis by HERA-B collaboration \item Some obsolete {\sc{Clhep}}~\cite{Clhep}\index{{\sc{Clhep}}} classes, like {\tt{HepChooser}} and {\tt{HepCombiner}} \index{{\sc{Clhep}}!{\tt{HepChooser}}} \index{{\sc{Clhep}}!{\tt{HepCombiner}}} \item {\sc{Loki}}~\cite{Loki}\index{{\sc{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. \end{itemize}

-- Main.ibelyaev - 11 Jul 2007

 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright & 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