Back to home page

EIC code displayed by LXR

 
 

    


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

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