Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-07-03 08:36:34

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 <Gaudi/Decays/Decay.h>
0014 #include <Gaudi/Decays/iNode.h>
0015 #include <Gaudi/ParticleID.h>
0016 #include <GaudiKernel/Kernel.h>
0017 #include <GaudiKernel/SmartIF.h>
0018 #include <GaudiKernel/StatusCode.h>
0019 #include <algorithm>
0020 
0021 /** @file Decays/Nodes.h
0022  *  Helper general purpose utilities to deal with decay nodes
0023  *  @see Decays::iNode
0024  *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0025  *  @date 2008-04-21
0026  */
0027 namespace Gaudi::Decays {
0028   /** check the validness of the trees or nodes
0029    *  @param begin begin-iterator for the sequence of trees/nodes
0030    *  @param end end-iterator for the sequence of trees/nodes
0031    *  @return true of no invalid trees are found
0032    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0033    *  @date 2008-04-21
0034    */
0035   template <typename Iterator>
0036   bool valid( Iterator begin, Iterator end ) {
0037     return std::all_of( begin, end, []( const auto& i ) { return i.valid(); } );
0038   }
0039   template <typename Container>
0040   bool valid( Container const& c ) {
0041     return valid( c.begin(), c.end() );
0042   }
0043 
0044   /** validate trees/nodes
0045    *  @param begin begin-iterator for the sequence of trees/nodes
0046    *  @param end end-iterator for the sequence of trees/nodes
0047    *  @param svc the Particle Property Service for validation
0048    *  @return statuis code
0049    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0050    *  @date 2008-04-21
0051    */
0052   template <class Iterator>
0053   StatusCode validate( Iterator begin, Iterator end, const Gaudi::Interfaces::IParticlePropertySvc* svc ) {
0054     for ( ; begin != end; ++begin ) {
0055       StatusCode sc = begin->validate( svc );
0056       if ( sc.isFailure() ) { return sc; }
0057     }
0058     return StatusCode::SUCCESS;
0059   }
0060   template <class TREE>
0061   StatusCode validate( TREE const& tree, const Gaudi::Interfaces::IParticlePropertySvc* svc ) {
0062     return validate( tree.begin(), tree.end(), svc );
0063   }
0064 
0065   class NodeList;
0066 
0067   namespace Nodes {
0068     /** @class Invalid
0069      *  the most simple node to represent the invalid node
0070      *  it matches to all valid the Gaudi::Particles
0071      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0072      *  @date 2008-04-12
0073      */
0074     class GAUDI_API Invalid : public Decays::iNode {
0075     public:
0076       /// MANDATORY: default constructor
0077       Invalid() = default;
0078       /// MANDATORY: clone method ("virtual constructor")
0079       Invalid* clone() const override;
0080       /// MANDATORY: the only one essential method
0081       bool operator()( const Gaudi::ParticleID& /* p */ ) const override;
0082       /// MANDATORY: the specific printout
0083       std::ostream& fillStream( std::ostream& s ) const override;
0084       /// MANDATORY: check the validity
0085       bool valid() const override;
0086       /// MANDATORY: the proper validation of the node
0087       StatusCode validate( const Gaudi::Interfaces::IParticlePropertySvc* svc ) const override;
0088     };
0089 
0090     /** @class _Node
0091      *  Helper structure (especially it is light version node-holder
0092      *  the default constructor
0093      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0094      *  @date 2008-04-12
0095      */
0096     class GAUDI_API _Node {
0097     public:
0098       /// the default constructor
0099       _Node();
0100       /// the constructor from iNode
0101       _Node( const iNode& node ) : m_node( node ) {}
0102       /// the constructor from  Node
0103       _Node( const Node& node ) : m_node( node ) {}
0104       // default copy constructor
0105       _Node( const _Node& node ) = default;
0106       /// Check the validity
0107       inline bool valid() const { return m_node.node().valid(); }
0108       /// The proper validation of the node
0109       inline StatusCode validate( const Gaudi::Interfaces::IParticlePropertySvc* svc ) const {
0110         return m_node.node().validate( svc );
0111       }
0112       /// The major method
0113       inline bool operator()( const Gaudi::ParticleID& pid ) const { return m_node.node( pid ); }
0114 
0115       inline bool operator==( const Gaudi::ParticleID& pid ) const { return m_node.node( pid ); }
0116 
0117       inline bool operator!=( const Gaudi::ParticleID& pid ) const { return !m_node.node( pid ); }
0118 
0119       /// pseudo-assignment operator:
0120       _Node& operator=( const Node& right ) {
0121         m_node = right;
0122         return *this;
0123       }
0124       /// pseudo-assignment from arbitrary node
0125       _Node& operator=( const iNode& right ) {
0126         m_node = right;
0127         return *this;
0128       }
0129       /// pseudo-assignment from arbitrary node
0130       _Node& operator=( const _Node& right ) {
0131         m_node = right.m_node;
0132         return *this;
0133       }
0134 
0135       _Node& operator|=( const iNode& right ) {
0136         m_node |= right;
0137         return *this;
0138       }
0139       _Node& operator&=( const iNode& right ) {
0140         m_node &= right;
0141         return *this;
0142       }
0143 
0144       _Node& operator|=( const NodeList& right ) { return op_or( right ); }
0145       _Node& operator&=( const NodeList& right ) { return op_and( right ); }
0146 
0147       _Node& operator|=( const _Node& right ) {
0148         m_node |= right;
0149         return *this;
0150       }
0151       _Node& operator&=( const _Node& right ) {
0152         m_node &= right;
0153         return *this;
0154       }
0155 
0156       /// the accessor to the node
0157       const Decays::iNode& node() const { return m_node.node(); }
0158       /// the cast operator to the actual list of nodes
0159       operator const Decays::iNode&() const { return node(); }
0160 
0161     private:
0162       _Node& op_or( const NodeList& right );
0163       _Node& op_and( const NodeList& right );
0164       /// the node holder itself
0165       Decays::Node m_node;
0166     };
0167   } // namespace Nodes
0168 
0169   class GAUDI_API NodeList {
0170   public:
0171     /// the actual type of the sequence of nodes
0172     typedef std::vector<Decays::Nodes::_Node> Nodes_;
0173     typedef Nodes_::const_iterator            const_iterator;
0174     typedef Nodes_::iterator                  iterator;
0175     typedef Nodes_::value_type                value_type;
0176 
0177     /// constructor from the list of Nodes
0178     NodeList( const Nodes_& nodes = Nodes_() );
0179 
0180     void push_back( const Decays::Nodes::_Node& node );
0181     void push_back( const Decays::iNode& node );
0182     void push_back( const Nodes_& nodes );
0183     void push_back( const NodeList& nodes );
0184     void clear() { m_nodes.clear(); }
0185 
0186     NodeList& operator=( const Decays::Nodes::_Node& node );
0187     NodeList& operator=( const Decays::iNode& node );
0188 
0189     NodeList& operator+=( const Decays::Nodes::_Node& node ) {
0190       push_back( node );
0191       return *this;
0192     }
0193     NodeList& operator+=( const Decays::iNode& node ) {
0194       push_back( node );
0195       return *this;
0196     }
0197     NodeList& operator+=( const Nodes_& nodes ) {
0198       push_back( nodes );
0199       return *this;
0200     }
0201     NodeList& operator+=( const NodeList& nodes ) {
0202       push_back( nodes );
0203       return *this;
0204     }
0205 
0206     size_t         size() const { return m_nodes.size(); }
0207     bool           empty() const { return m_nodes.empty(); }
0208     iterator       begin() { return m_nodes.begin(); }
0209     iterator       end() { return m_nodes.end(); }
0210     const_iterator begin() const { return m_nodes.begin(); }
0211     const_iterator end() const { return m_nodes.end(); }
0212 
0213     operator const Nodes_&() const { return m_nodes; }
0214 
0215   private:
0216     /// the actual list of nodes
0217     Nodes_ m_nodes;
0218   };
0219 
0220   namespace Nodes {
0221     /** @class Or
0222      *  the rather simple (but powerful) node in the decay tree:
0223      *  it matches .OR. for sub-nodes
0224      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0225      *  @date 2008-04-12
0226      */
0227     class GAUDI_API Or : public Decays::iNode {
0228     public:
0229       /// constructor from two nodes
0230       Or( const Decays::iNode& n1, const Decays::iNode& n2 );
0231       /// constructor from three nodes
0232       Or( const Decays::iNode& n1, const Decays::iNode& n2, const Decays::iNode& n3 );
0233       /// constructor from four nodes
0234       Or( const Decays::iNode& n1, const Decays::iNode& n2, const Decays::iNode& n3, const Decays::iNode& n4 );
0235       /// constructor from list of nodes
0236       Or( const Decays::NodeList& nodes );
0237       /// MANDATORY: clone method ("virtual constructor")
0238       Or* clone() const override;
0239       /// MANDATORY: the only one essential method
0240       bool operator()( const Gaudi::ParticleID& pid ) const override;
0241       /// MANDATORY: the specific printout
0242       std::ostream& fillStream( std::ostream& s ) const override;
0243       /// MANDATORY: check the validity
0244       bool valid() const override;
0245       /// MANDATORY: the proper validation of the node
0246       StatusCode validate( const Gaudi::Interfaces::IParticlePropertySvc* svc ) const override;
0247 
0248     protected:
0249       size_t add( const Decays::iNode& node );
0250       size_t add( const Decays::NodeList& nodes );
0251 
0252     public:
0253       Or& operator+=( const Decays::iNode& node );
0254       Or& operator+=( const Decays::NodeList& node );
0255 
0256     private:
0257       /// the default constructor is disabled
0258       Or(); // the default constructor is disabled
0259 
0260       /// the sub-nodes
0261       Decays::NodeList m_nodes;
0262     };
0263 
0264     /** @class And
0265      *  the rather simple (but powerful) node in the decay tree:
0266      *  it matches .AND. for sub-nodes
0267      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0268      *  @date 2008-04-12
0269      */
0270     class GAUDI_API And : public Decays::iNode {
0271     public:
0272       /// constructor from two nodes
0273       And( const Decays::iNode& n1, const Decays::iNode& n2 );
0274       /// constructor from three nodes
0275       And( const Decays::iNode& n1, const Decays::iNode& n2, const Decays::iNode& n3 );
0276       /// constructor from four nodes
0277       And( const Decays::iNode& n1, const Decays::iNode& n2, const Decays::iNode& n3, const Decays::iNode& n4 );
0278       /// constructor from list of nodes
0279       And( const Decays::NodeList& nodes );
0280       /// MANDATORY: clone method ("virtual constructor")
0281       And* clone() const override;
0282       /// MANDATORY: the only one essential method
0283       bool operator()( const Gaudi::ParticleID& p ) const override;
0284       /// MANDATORY: the specific printout
0285       std::ostream& fillStream( std::ostream& s ) const override;
0286       /// MANDATORY: check the validity
0287       bool valid() const override;
0288       /// MANDATORY: the proper validation of the node
0289       StatusCode validate( const Gaudi::Interfaces::IParticlePropertySvc* svc ) const override;
0290 
0291     protected:
0292       size_t add( const Decays::iNode& node );
0293       size_t add( const Decays::NodeList& nodes );
0294 
0295     public:
0296       And& operator+=( const Decays::iNode& node );
0297       And& operator+=( const Decays::NodeList& nodes );
0298 
0299     private:
0300       /// the sub-nodes
0301       NodeList m_nodes;
0302     };
0303 
0304     /** @class Not
0305      *  Simple node which match "NOT" for the subnode
0306      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0307      *  @date 2008-04-12
0308      */
0309     class GAUDI_API Not : public Decays::iNode {
0310     public:
0311       /// constructor from the node
0312       Not( const Decays::iNode& node );
0313       /// MANDATORY: clone method ("virtual constructor")
0314       Not* clone() const override;
0315       /// MANDATORY: the only one essential method
0316       bool operator()( const Gaudi::ParticleID& pid ) const override;
0317       /// MANDATORY: the specific printout
0318       std::ostream& fillStream( std::ostream& s ) const override;
0319       /// MANDATORY: check the validity
0320       bool valid() const override;
0321       /// MANDATORY: the proper validation of the node
0322       StatusCode validate( const Gaudi::Interfaces::IParticlePropertySvc* svc ) const override;
0323 
0324     public:
0325       /// get the underlying node
0326       const Decays::iNode& node() const { return m_node.node(); }
0327 
0328     private:
0329       /// the node itself
0330       Decays::Node m_node;
0331     };
0332 
0333     /** Create the "NOT" for the node
0334      *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0335      *  @date 2008-04-12
0336      */
0337     inline Decays::Nodes::Not operator!( const Decays::Nodes::Not& o ) { return Decays::Node( o.node() ); }
0338 
0339     /// output operator
0340     inline std::ostream& operator<<( std::ostream& s, const Decays::Nodes::_Node& n ) { return s << n.node(); }
0341   } // namespace Nodes
0342 
0343   /** Create the "OR" of two nodes
0344    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0345    *  @date 2008-04-12
0346    */
0347   inline Decays::Nodes::Or operator||( const Decays::iNode& o1, const Decays::iNode& o2 ) {
0348     return Decays::Nodes::Or( o1, o2 );
0349   }
0350 
0351   /** Create the "OR" of two nodes
0352    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0353    *  @date 2008-04-12
0354    */
0355   inline Decays::Nodes::Or operator|( const Decays::iNode& o1, const Decays::iNode& o2 ) {
0356     return Decays::Nodes::Or( o1, o2 );
0357   }
0358 
0359   /** Create the "AND" of two nodes
0360    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0361    *  @date 2008-04-12
0362    */
0363   inline Decays::Nodes::And operator&&( const Decays::iNode& o1, const Decays::iNode& o2 ) {
0364     return Decays::Nodes::And( o1, o2 );
0365   }
0366 
0367   /** Create the "AND" of two nodes
0368    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0369    *  @date 2008-04-12
0370    */
0371   inline Decays::Nodes::And operator&( const Decays::iNode& o1, const Decays::iNode& o2 ) {
0372     return Decays::Nodes::And( o1, o2 );
0373   }
0374 
0375   /** Create the "NOT" for the node
0376    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0377    *  @date 2008-04-12
0378    */
0379   inline Decays::Nodes::Not operator~( const Decays::iNode& o ) { return Decays::Nodes::Not( o ); }
0380 
0381   /** Create the "OR" of two nodes
0382    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0383    *  @date 2008-04-12
0384    */
0385   GAUDI_API
0386   Decays::Nodes::Or operator||( const Decays::iNode& o1, const std::string& o2 );
0387 
0388   /** Create the "OR" of two nodes
0389    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0390    *  @date 2008-04-12
0391    */
0392   GAUDI_API
0393   Decays::Nodes::Or operator||( const Decays::iNode& o1, const Gaudi::ParticleID& o2 );
0394 
0395   /** Create the "OR" of two nodes
0396    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0397    *  @date 2008-04-12
0398    */
0399   GAUDI_API
0400   Decays::Nodes::Or operator||( const Decays::iNode& o1, const Decays::Decay::Item& o2 );
0401 
0402   /** Create the "OR" of two nodes
0403    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0404    *  @date 2008-04-12
0405    */
0406   GAUDI_API
0407   Decays::Nodes::Or operator||( const Decays::iNode& o1, const Gaudi::ParticleProperty* o2 );
0408 
0409   /** Create the "OR" of two nodes
0410    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0411    *  @date 2008-04-12
0412    */
0413   GAUDI_API
0414   Decays::Nodes::Or operator||( const std::string& o2, const Decays::iNode& o1 );
0415 
0416   /** Create the "OR" of two nodes
0417    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0418    *  @date 2008-04-12
0419    */
0420   GAUDI_API
0421   Decays::Nodes::Or operator||( const Gaudi::ParticleID& o2, const Decays::iNode& o1 );
0422 
0423   /** Create the "OR" of two nodes
0424    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0425    *  @date 2008-04-12
0426    */
0427   GAUDI_API
0428   Decays::Nodes::Or operator||( const Decays::Decay::Item& o2, const Decays::iNode& o1 );
0429 
0430   /** Create the "OR" of two nodes
0431    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0432    *  @date 2008-04-12
0433    */
0434   GAUDI_API
0435   Decays::Nodes::Or operator||( const Gaudi::ParticleProperty* o2, const Decays::iNode& o1 );
0436 
0437   /** Create the "AND" of two nodes
0438    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0439    *  @date 2008-04-12
0440    */
0441   GAUDI_API
0442   Decays::Nodes::And operator&&( const Decays::iNode& o1, const std::string& o2 );
0443 
0444   /** Create the "AND" of two nodes
0445    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0446    *  @date 2008-04-12
0447    */
0448   GAUDI_API
0449   Decays::Nodes::And operator&&( const Decays::iNode& o1, const Gaudi::ParticleID& o2 );
0450 
0451   /** Create the "AND" of two nodes
0452    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0453    *  @date 2008-04-12
0454    */
0455   GAUDI_API
0456   Decays::Nodes::And operator&&( const Decays::iNode& o1, const Decays::Decay::Item& o2 );
0457 
0458   /** Create the "AND" of two nodes
0459    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0460    *  @date 2008-04-12
0461    */
0462   GAUDI_API
0463   Decays::Nodes::And operator&&( const Decays::iNode& o1, const Gaudi::ParticleProperty* o2 );
0464 
0465   /** Create the "AND" of two nodes
0466    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0467    *  @date 2008-04-12
0468    */
0469   GAUDI_API
0470   Decays::Nodes::And operator&&( const std::string& o2, const Decays::iNode& o1 );
0471 
0472   /** Create the "AND" of two nodes
0473    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0474    *  @date 2008-04-12
0475    */
0476   GAUDI_API
0477   Decays::Nodes::And operator&&( const Gaudi::ParticleID& o2, const Decays::iNode& o1 );
0478 
0479   /** Create the "AND" of two nodes
0480    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0481    *  @date 2008-04-12
0482    */
0483   GAUDI_API
0484   Decays::Nodes::And operator&&( const Decays::Decay::Item& o2, const Decays::iNode& o1 );
0485 
0486   /** Create the "AND" of two nodes
0487    *  @author Vanya BELYAEV Ivan.Belyaev@nikhef.nl
0488    *  @date 2008-04-12
0489    */
0490   GAUDI_API
0491   Decays::Nodes::And operator&&( const Gaudi::ParticleProperty* o2, const Decays::iNode& o1 );
0492 
0493 } // namespace Gaudi::Decays