Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:57:31

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2023 CERN for the benefit of the LHCb and ATLAS collaborations *
0003 *                                                                                   *
0004 * This software is distributed under the terms of the Apache version 2 licence,     *
0005 * copied verbatim in the file "LICENSE".                                            *
0006 *                                                                                   *
0007 * In applying this licence, CERN does not waive the privileges and immunities       *
0008 * granted to it by virtue of its status as an Intergovernmental Organization        *
0009 * or submit itself to any jurisdiction.                                             *
0010 \***********************************************************************************/
0011 #pragma once
0012 
0013 #include <GaudiKernel/IInterface.h>
0014 #include <GaudiKernel/Kernel.h>
0015 #include <vector>
0016 
0017 namespace Gaudi {
0018   class ParticleID;
0019   class ParticleProperty;
0020 } // namespace Gaudi
0021 
0022 namespace Gaudi::Interfaces {
0023   /** @class IParticlePropertySvc Kernel/IParticlePropertySvc.h
0024    *  The abstract interface to Particle Property Service
0025    *  @author Iain Last
0026    *  @author G.Corti
0027    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0028    */
0029   class GAUDI_API IParticlePropertySvc : public extend_interfaces<IInterface> {
0030   public:
0031     DeclareInterfaceID( Gaudi::Interfaces::IParticlePropertySvc, 2, 0 );
0032 
0033     /// the actual type of (ordered) container of particle properties
0034     typedef std::vector<const Gaudi::ParticleProperty*> ParticleProperties;
0035     /// the actual type of iterator over the (ordered) container of properties
0036     typedef ParticleProperties::const_iterator iterator;
0037 
0038     /** get the begin-iterator for the container of particle properties
0039      *  It is assumed that the container is properly ordered
0040      *  @return begin-iterator for the container of particle properties
0041      */
0042     virtual iterator begin() const = 0;
0043     /** get the end-iterator for the container of particle properties
0044      *  It is assumed that the container is properly ordered
0045      *  @return end-iterator for the container of particle properties
0046      */
0047     virtual iterator end() const = 0;
0048     /// get the container size.
0049     virtual size_t size() const = 0;
0050     /** Retrieve an object by name:
0051      *
0052      *  @code
0053      *
0054      *   Gaudi::Interfaces::IParticlePropertySvc* svc = ... ;
0055      *
0056      *   const std::string& name = ... ;
0057      *
0058      *   const Gaudi::ParticleProperty*  pp = svc -> find ( name ) ;
0059      *
0060      *  @endcode
0061      *  @param name the particle name
0062      *  @return pointer to particle property object
0063      */
0064     virtual const ParticleProperty* find( const std::string& name ) const = 0; // find by particle name
0065     /** Retrieve an object by Gaudi::ParticleID:
0066      *
0067      *  @code
0068      *
0069      *   Gaudi::Interfaces::IParticlePropertySvc* svc = ... ;
0070      *
0071      *   const Gaudi::ParticleID& pid = ... ;
0072      *
0073      *   const Gaudi::ParticleProperty*  pp = svc -> find ( pid ) ;
0074      *
0075      *  @endcode
0076      *  @param  pid     the particle's Gaudi::ParticleID
0077      *  @return pointer to particle property object
0078      */
0079     virtual const ParticleProperty* find( const Gaudi::ParticleID& pid ) const = 0; // find by Gaudi::ParticleID
0080 
0081     /** get the properties according to some criteria
0082      *
0083      *  e.g. get all leptons:
0084      *
0085      *  @code
0086      *
0087      *  #include "boost/lambda/lambda.hpp"
0088      *  #include "boost/lambda/bind.hpp"
0089      *  ...
0090      *  using namespace boost::lambda ;
0091      *  ...
0092      *
0093      *  const Gaudi::Interfaces::IParticlePropertySvc* svc = ... ;
0094      *
0095      *  typedef Gaudi::Interfaces::IParticlePropertySvc::ParticleProperties Vector ;
0096      *
0097      *  // create the output vector:
0098      *  Vector leptons ;
0099      *  // use the service
0100      *  svc -> get
0101      *    ( bind ( &Gaudi::ParticleID::isLepton ,
0102      *             bind ( &Gaudi::ParticleProperty::particleID , _1 ) ) ,
0103      *      std::back_inserter ( lepton ) ) ; // output
0104      *
0105      *  @endcode
0106      *
0107      *  Essentially it is just <c>std::copy_if</c> STL-algorithm
0108      *
0109      *  @param cut the predicate
0110      *  @param output the output iterator
0111      *  @return the updated position of output iterator
0112      */
0113     template <class PREDICATE, class OUTPUT>
0114     OUTPUT get( const PREDICATE& cut, OUTPUT output ) const;
0115 
0116     /** make the charge conjugation for the string/decay descriptor
0117      *
0118      *  @code
0119      *
0120      *   std::string decay = "B0 -> pi+ pi-" ;
0121      *
0122      *   Gaudi::IParticlePropertySvc* svc = ... ;
0123      *
0124      *   std::string cc = svc -> cc ( decay ) ;
0125      *
0126      *  @endcode
0127      *
0128      *  @param decay the decay descriptor
0129      *  @return the charge conjugation for the decay descriptor
0130      */
0131     virtual std::string cc( const std::string& decay ) const = 0;
0132   };
0133 } // namespace Gaudi::Interfaces
0134 
0135 namespace Gaudi {
0136   namespace ParticleProperties {
0137     /** helper utility for mapping of Gaudi::ParticleProperty object into
0138      *  non-negative integral sequential identifier
0139      *  @code
0140      *
0141      *  const Gaudi::ParticlePropertySvc* svc = ... ;
0142      *
0143      *  const Gaudi::ParticleProperty* pp = ... ;
0144      *
0145      *   size_t index = index ( pp , svc ) ;
0146      *
0147      *   if ( !index )
0148      *   {
0149      *     // error here: conversion is not possible
0150      *   }
0151      *
0152      *  @endcode
0153      *  This appears to be useful operation, but since it is
0154      *  "pure technical" it does not appear as interface method.
0155      *
0156      *  For invalid/missing property and/or  service
0157      *  <c>0</c> is returned. The valid result is always
0158      *  satisfy the condition: <c> index <= service->size() </c>
0159      *
0160      *  @param property the property to be mapped
0161      *  @param service the service
0162      *  @return the sequential non-negative index
0163      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0164      *  @date   2008-08-03
0165      */
0166     size_t index( const Gaudi::ParticleProperty* property, const Gaudi::Interfaces::IParticlePropertySvc* service );
0167 
0168     /** helper utility for mapping of Gaudi::ParticleID object into
0169      *  non-negative integral sequential identifier
0170      *  @code
0171      *
0172      *  const Gaudi::ParticlePropertySvc* svc = ... ;
0173      *
0174      *  const Gaudi::ParticleID& pid = ... ;
0175      *
0176      *  size_t index = index ( pid , svc ) ;
0177      *
0178      *  if ( !index )
0179      *   {
0180      *     // error here: conversion is not possible
0181      *   }
0182      *
0183      *  @endcode
0184      *  This appears to be useful operation, but since it is
0185      *  "pure technical" it does not appear as interface method.
0186      *
0187      *  For invalid/missing PID and/or  service
0188      *  <c>0</c> is returned. The valid result is always
0189      *  satisfy the condition: <c> index <= service->size() </c>
0190      *
0191      *  @param pid the object to be mapped
0192      *  @param service the service
0193      *  @return the sequential non-negative index
0194      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0195      *  @date   2008-08-03
0196      */
0197     size_t index( const Gaudi::ParticleID& pid, const Gaudi::Interfaces::IParticlePropertySvc* service );
0198 
0199     /** the inverse mapping of the integer sequential number onto
0200      *  Gaudi::ParticleID object
0201      *  @code
0202      *
0203      *  const Gaudi::ParticlePropertySvc* svc = ... ;
0204      *
0205      *  const size_t index = ...
0206      *
0207      *  const Gaudi::ParticleProperty* pp = particle ( index , svc ) ;
0208      *
0209      *  if ( !pp )
0210      *   {
0211      *     // error here: conversion is not possible
0212      *   }
0213      *
0214      *  @endcode
0215      *  This appears to be useful operation, but since it is
0216      *  "pure technical" it does not appear as interface method.
0217      *
0218      *  For invalid/missing PID and/or  service
0219      *  <c>NULL</c> is returned.
0220      *
0221      *  @param pid the object to be mapped
0222      *  @param service the service
0223      *  @return the sequential non-negative index
0224      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0225      *  @date   2008-08-03
0226      */
0227     const Gaudi::ParticleProperty* particle( const size_t                                   index,
0228                                              const Gaudi::Interfaces::IParticlePropertySvc* service );
0229 
0230     /** the inverse mapping of the integer sequential number onto
0231      *  Gaudi::ParticleID object
0232      *  @code
0233      *
0234      *  const Gaudi::ParticlePropertySvc* svc = ... ;
0235      *
0236      *  const size_t index = ...
0237      *
0238      *  const Gaudi::ParticleID pid = particleID ( index , svc ) ;
0239      *
0240      *  if ( Gaudi::ParticleID() == pid )
0241      *   {
0242      *     // error here: conversion is not possible
0243      *   }
0244      *
0245      *  @endcode
0246      *  This appears to be useful operation, but since it is
0247      *  "pure technical" it does not appear as interface method.
0248      *
0249      *  For invalid/missing index and/or  service
0250      *  <c>Gaudi::ParticleID()</c> is returned.
0251      *
0252      *  @param pid the object to be mapped
0253      *  @param service the service
0254      *  @return the sequential non-negative index
0255      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0256      *  @date   2008-08-03
0257      */
0258     const Gaudi::ParticleID particleID( const size_t index, const Gaudi::Interfaces::IParticlePropertySvc* service );
0259 
0260     /** mapping by pythiaID
0261      *
0262      *  @code
0263      *
0264      *   const int pythiaID = ... ;
0265      *
0266      *   const Gaudi::Interfaces::IParticlePropertySvc* svc = ... ;
0267      *
0268      *   const Gaudi::ParticleProeprty* pp = byPythiaID( pythiaID , svc ) ;
0269      *
0270      *  @endcode
0271      *
0272      *  @attention the method is not very efficient and should not be abused
0273      *  @see Gaudi::ParticleProperties::particle
0274      *  @param pythia pythia identifier
0275      *  @param svc    pointer to particle property service
0276      *  @return the particle property for the given pythia ID
0277      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0278      *  @date   2008-08-03
0279      */
0280     const Gaudi::ParticleProperty* byPythiaID( const int pythia, const Gaudi::Interfaces::IParticlePropertySvc* svc );
0281 
0282     /** mapping by EvtGen-name
0283      *
0284      *  @code
0285      *
0286      *   const std::string& evtGen
0287      *
0288      *   const Gaudi::Interfaces::IParticlePropertySvc* svc = ... ;
0289      *
0290      *   const Gaudi::ParticleProperty* pp = byEvtGenName ( pythiaID , svc ) ;
0291      *
0292      *  @endcode
0293      *
0294      *  @attention the method is not very efficient and should not be abused
0295      *  @see Gaudi::ParticleProperties::particle
0296      *  @param evtGen the particle naem in EvtGen-generator
0297      *  @param svc    pointer to particle property service
0298      *  @return the particle property for the given EvtGen-name
0299      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0300      *  @date   2008-08-03
0301      */
0302     const Gaudi::ParticleProperty* byEvtGenName( const std::string&                             evtGen,
0303                                                  const Gaudi::Interfaces::IParticlePropertySvc* svc );
0304 
0305     /** get all particle properties which satisfy the certain criteria
0306      *
0307      *  e.g. select all particles with 'invalid' Pythia ID = 0 :
0308      *
0309      *  @code
0310      *
0311      *  #include "boost/lambda/lambda.hpp"
0312      *  #include "boost/lambda/bind.hpp"
0313      *
0314      *  typedef Gaudi::Interfaces::IParticlePropertySvc::ParticleProperties Vector ;
0315      *  using namespace boost::lambda ;
0316      *
0317      *  const Gaudi::Interfaces::IParticlePropertySvc* svc = ... ;
0318      *
0319      *  // create the output vector:
0320      *  Vector output ;
0321      *  // use the function
0322      *  Gaudi::ParticleProperties::get
0323      *         ( svc->begin() ,  // begin-sequence
0324      *           svc->end  () ,  // end-sequence
0325      *           bind ( &Gaudi::ParticleProperty::pythiaID , _1 ) == 0 , // predicate
0326      *           std::back_inserter( output ) ) ; // output
0327      *
0328      *  @endcode
0329      *
0330      *  or select all particles with 'invalid' EvtGen  = "unknown" :
0331      *
0332      *  @code
0333      *
0334      *  #include "boost/lambda/lambda.hpp"
0335      *  #include "boost/lambda/bind.hpp"
0336      *
0337      *  typedef Gaudi::Interfaces::IParticlePropertySvc::ParticleProperties Vector ;
0338      *  using namespace boost::lambda ;
0339      *
0340      *  const Gaudi::Interfaces::IParticlePropertySvc* svc = ... ;
0341      *
0342      *  // create the output vector:
0343      *  Vector output ;
0344      *  // use the function
0345      *  Gaudi::ParticleProperties::get
0346      *         ( svc->begin() ,  // begin-sequence
0347      *           svc->end  () ,  // end-sequence
0348      *           bind ( &Gaudi::ParticleProperty::evtGen , _1 ) == "unknown" , // predicate
0349      *           std::back_inserter( output ) ) ; // output
0350      *
0351      *  @endcode
0352      *
0353      *  select leptons:
0354      *
0355      *  @code
0356      *
0357      *  #include "boost/lambda/lambda.hpp"
0358      *  #include "boost/lambda/bind.hpp"
0359      *  ...
0360      *  ...
0361      *  const Gaudi::Interfaces::IParticlePropertySvc* svc = ... ;
0362      *
0363      *  typedef Gaudi::Interfaces::IParticlePropertySvc::ParticleProperties Vector ;
0364      *  using namespace boost::lambda ;
0365      *
0366      *  // create the output vector:
0367      *  Vector leptons ;
0368      *  // use the function
0369      *  Gaudi::ParticleProperties::get
0370      *         ( svc->begin() ,  // begin-sequence
0371      *           svc->end  () ,  // end-sequence
0372      *           bind ( &Gaudi::ParticleID::isLepton , bind ( &Gaudi::ParticleProperty::particleID ,_1 ) ) ,
0373      *           std::back_inserter ( lepton ) ) ; // output
0374      *
0375      *  @endcode
0376      *
0377      *  Essentially it is just a missing <c>std::copy_if</c> STL-algorithm
0378      *
0379      *  @param first begin-iterator of input sequence of particle properties
0380      *  @param last  end-iterator of input sequence of particle properties
0381      *  @param cut the predicate
0382      *  @param output the output iterator
0383      *  @return the updated position of output iterator
0384      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0385      *  @date   2008-08-03
0386      */
0387     template <class INPUT, class PREDICATE, class OUTPUT>
0388     OUTPUT get( INPUT first, INPUT last, const PREDICATE& cut, OUTPUT output ) {
0389       for ( ; first != last; ++first ) {
0390         if ( cut( *first ) ) {
0391           *output = *first;
0392           ++output;
0393         }
0394       }
0395       return output;
0396     }
0397 
0398     /** get all particle properties which satisfy the certain criteria
0399      *
0400      *  e.g. select all particles with 'invalid' Pythia ID = 0 :
0401      *
0402      *  @code
0403      *
0404      *  #include "boost/lambda/lambda.hpp"
0405      *  #include "boost/lambda/bind.hpp"
0406      *
0407      *  typedef Gaudi::Interfaces::IParticlePropertySvc::ParticleProperties Vector ;
0408      *  using namespace boost::lambda ;
0409      *
0410      *  const Gaudi::Interfaces::IParticlePropertySvc* svc = ... ;
0411      *
0412      *  // create the output vector:
0413      *  Vector output ;
0414      *  // use the function
0415      *  Gaudi::ParticleProperties::get
0416      *    ( svc ,
0417      *      bind ( &Gaudi::ParticleProperty::pythiaID , _1 ) == 0 , // predicate
0418      *      std::back_inserter( output ) ) ; // output
0419      *
0420      *  @endcode
0421      *
0422      *  or select all particles with 'invalid' EvtGen  = "unknown" :
0423      *
0424      *  @code
0425      *
0426      *  #include "boost/lambda/lambda.hpp"
0427      *  #include "boost/lambda/bind.hpp"
0428      *
0429      *  typedef Gaudi::Interfaces::IParticlePropertySvc::ParticleProperties Vector ;
0430      *  using namespace boost::lambda ;
0431      *
0432      *  const Gaudi::Interfaces::IParticlePropertySvc* svc = ... ;
0433      *
0434      *  // create the output vector:
0435      *  Vector output ;
0436      *  // use the function
0437      *  Gaudi::ParticleProperties::get
0438      *    ( svc ,
0439      *      bind ( &Gaudi::ParticleProperty::evtGen , _1 ) == "unknown" , // predicate
0440      *      std::back_inserter( output ) ) ; // output
0441      *
0442      *  @endcode
0443      *
0444      *  Select all leptons:
0445      *
0446      *  @code
0447      *
0448      *  #include "boost/lambda/lambda.hpp"
0449      *  #include "boost/lambda/bind.hpp"
0450      *
0451      *  typedef Gaudi::Interfaces::IParticlePropertySvc::ParticleProperties Vector ;
0452      *  using namespace boost::lambda ;
0453      *
0454      *  const Gaudi::Interfaces::IParticlePropertySvc* svc = ... ;
0455      *
0456      *  // create the output vector:
0457      *  Vector leptons ;
0458      *  // use the function
0459      *  Gaudi::ParticleProperties::get
0460      *    ( svc ,
0461      *      bind ( &Gaudi::ParticleID::isLepton ,
0462      *      bind ( &Gaudi::ParticleProperty::particleID , _1 ) ) ,
0463      *      std::back_inserter ( leptons ) ) ; // output
0464      *
0465      *  @endcode
0466      *
0467      *  @param first begin-iterator of input sequence of particle properties
0468      *  @param end   end-iterator of input sequence of particle properties
0469      *  @param cut the predicate
0470      *  @param output the output iterator
0471      *  @return the updated position of output iterator
0472      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0473      *  @date   2008-08-03
0474      */
0475     template <class PREDICATE, class OUTPUT>
0476     OUTPUT get( const Gaudi::Interfaces::IParticlePropertySvc* service, const PREDICATE& cut, OUTPUT output ) {
0477       if ( 0 == service ) { return output; }
0478       return service->get( cut, output );
0479     }
0480 
0481     /** get all the properties at once
0482      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0483      *  @date   2008-08-03
0484      */
0485     Gaudi::Interfaces::IParticlePropertySvc::ParticleProperties
0486     allProperties( const Gaudi::Interfaces::IParticlePropertySvc* service );
0487   } // namespace ParticleProperties
0488 
0489   namespace Interfaces {
0490     // get the properties according to some criteria
0491     template <class PREDICATE, class OUTPUT>
0492     OUTPUT IParticlePropertySvc::get( const PREDICATE& cut, OUTPUT output ) const {
0493       iterator first = this->begin();
0494       iterator last  = this->end();
0495       return Gaudi::ParticleProperties::get( first, last, cut, output );
0496     }
0497   } // namespace Interfaces
0498 } // namespace Gaudi