1 // Dear emacs, this is -*- c++ -*-
 
    4   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 
    7 // $Id: TrigPassBits_v1.icc 773869 2016-09-19 15:27:05Z krasznaa $
 
    8 #ifndef XAODTRIGGER_VERSIONS_TRIGPASSBITS_V1_ICC
 
    9 #define XAODTRIGGER_VERSIONS_TRIGPASSBITS_V1_ICC
 
   15 #include "AthContainers/normalizedTypeinfoName.h"
 
   16 #include "xAODCore/CLASS_DEF.h"
 
   20    /// This function is used to initialise or reset the object, to describe
 
   21    /// a target container. It sets up all the internal variables of the object
 
   22    /// so that subsequent maskPassing/isPassing calls would succeed.
 
   24    /// @param container Pointer to the container that this object should
 
   26    /// @param containerKey A unique key describing the target container.
 
   27    ///                     (The sub-type index from the trigger navigation.)
 
   29    template< class CONT >
 
   30    void TrigPassBits_v1::reset( const CONT* container, uint32_t containerKey ) {
 
   32       // Set all internal variables:
 
   33       m_container = static_cast< const void* >( container );
 
   34       setSize( container->size() );
 
   35       if( container->size() == 0 ) {
 
   36          setPassBits( std::vector< uint32_t >() );
 
   38          setPassBits( std::vector< uint32_t >( ( ( container->size() - 1 ) /
 
   41       setContainerKey( containerKey );
 
   42       setContainerClid( ClassID_traits< CONT >::ID() );
 
   47    /// Tried to use const references in the arguments, but then the function
 
   48    /// overload broke. So instead of providing template and non-template
 
   49    /// functions with slightly different names, decided to use pointers in
 
   50    /// the interface instead.
 
   52    /// @param obj       The object whose state should be set
 
   53    /// @param container The container that the object is part of
 
   54    /// @param passed    The "passing state" of the specified object
 
   56    template< class OBJ, class CONT >
 
   57    void TrigPassBits_v1::markPassing( const OBJ* obj, const CONT* container,
 
   60       // Check if the CLID of the specified container is the same as the
 
   61       // container that the information was collected for originally:
 
   62       if( ClassID_traits< CONT >::ID() != containerClid() ) {
 
   63          throw std::runtime_error( "The CLID of the passed container does "
 
   64                                    "not match that of the original container" );
 
   67       // Check that we received the correct container:
 
   68       if( m_container && ( m_container != container ) ) {
 
   69          throw std::runtime_error( "Function called with a wrong container" );
 
   72       // Find the element in the container:
 
   73       auto itr = std::find( container->begin(), container->end(), obj );
 
   74       if( itr == container->end() ) {
 
   75          throw std::runtime_error( "Specified object is not part of the "
 
   76                                    "specified container" );
 
   79       // Call the non-templated function to set the bit:
 
   80       markPassing( itr - container->begin(), passed );
 
   85    /// The same comment applied as for the <code>markPassing</code> function.
 
   86    /// In order to avoid clashes with the non-template function, I had to use
 
   87    /// pointer arguments for the function.
 
   89    /// @param obj       The objects whose state we should check
 
   90    /// @param container The container that the object is part of
 
   91    /// @returns The "passing state" of the object
 
   93    template< class OBJ, class CONT >
 
   94    bool TrigPassBits_v1::isPassing( const OBJ* obj,
 
   95                                     const CONT* container ) const {
 
   97       // Check if the CLID of the specified container is the same as the
 
   98       // container that the information was collected for originally:
 
   99       if( ClassID_traits< CONT >::ID() != containerClid() ) {
 
  100          throw std::runtime_error( "The CLID of the passed container does "
 
  101                                    "not match that of the original container" );
 
  104       // Find the element in the container:
 
  105       auto itr = std::find( container->begin(), container->end(), obj );
 
  106       if( itr == container->end() ) {
 
  107          throw std::runtime_error( "Specified object is not part of the "
 
  108                                    "specified container" );
 
  111       // Call the non-templated function to check the status of the bit:
 
  112       return isPassing( itr - container->begin() );
 
  115    /// This function can be used to check whether an element of a container
 
  116    /// passed the hypothesis selections. While checking that we use the
 
  117    /// container with the right key.
 
  119    /// @param obj       The objects whose state we should check
 
  120    /// @param container The container that the object is part of
 
  121    /// @param key       The hashed key of the container we are checking
 
  122    /// @returns The "passing state" of the object
 
  124    template< class OBJ, class CONT >
 
  125    bool TrigPassBits_v1::isPassing( const OBJ* obj,
 
  126                                     const CONT* container,
 
  127                                     uint32_t key ) const {
 
  129       // Check if the key of the container matches the recorded one:
 
  130       if( key != containerKey() ) {
 
  131          throw std::runtime_error( "The specified key doesn't match the one "
 
  132                                    "stored in the object" );
 
  135       // Let the other function do the rest:
 
  136       return isPassing( obj, container );
 
  139    /// This function can be used to check whether an element of a container
 
  140    /// passed the hypothesis selections. While checking that we use the
 
  141    /// container with the right key.
 
  143    /// @param obj       The objects whose state we should check
 
  144    /// @param container The container that the object is part of
 
  145    /// @param key       The key of the container we are checking
 
  146    /// @returns The "passing state" of the object
 
  148    template< class OBJ, class CONT >
 
  149    bool TrigPassBits_v1::isPassing( const OBJ* obj,
 
  150                                     const CONT* container,
 
  151                                     const std::string& key ) const {
 
  153       // Let the other function do the heavy lifting:
 
  154       return isPassing( obj, container, hash( key ) );
 
  157    /// This function is an analogue of the HLT::makeTrigPassBits function,
 
  158    /// written for the original TrigPassBits type. It behaves much the
 
  159    /// same way, it just makes it clear in its interface that the user
 
  160    /// is supposed to take ownership of the received object.
 
  162    /// @param container Pointer to the container that this object should
 
  164    /// @param containerKey A unique key describing the target container.
 
  165    ///                     (The sub-type index from the trigger navigation.)
 
  167    template< class CONT >
 
  168    std::unique_ptr< TrigPassBits_v1 >
 
  169    makeTrigPassBits( const CONT* container, uint32_t containerKey ) {
 
  171       // Create the new object:
 
  172       std::unique_ptr< TrigPassBits_v1 > result( new TrigPassBits_v1() );
 
  173       // Give it a private auxiliary store:
 
  174       result->makePrivateStore();
 
  176       result->reset( container, containerKey );
 
  177       // And now return it:
 
  181    /// This function is an analogue of the HLT::makeTrigPassBits function,
 
  182    /// written for the original TrigPassBits type. It behaves much the
 
  183    /// same way, it just makes it clear in its interface that the user
 
  184    /// is supposed to take ownership of the received object.
 
  186    /// It's a more convenient way for hypo algorithm developers to specify
 
  187    /// a key/label for the container that this TrigPassBits object should
 
  190    /// @param container Pointer to the container that this object should
 
  192    /// @param containerKey A unique key describing the target container.
 
  193    ///                     (The label of the container in most cases.)
 
  195    template< class CONT >
 
  196    std::unique_ptr< TrigPassBits_v1 >
 
  197    makeTrigPassBits( const CONT* container, const std::string& containerKey ) {
 
  199       // Create the new object:
 
  200       std::unique_ptr< TrigPassBits_v1 > result( new TrigPassBits_v1() );
 
  201       // Give it a private auxiliary store:
 
  202       result->makePrivateStore();
 
  204       result->reset( container, xAOD::TrigPassBits_v1::hash( containerKey ) );
 
  205       // And now return it:
 
  211 #endif // XAODTRIGGER_VERSIONS_TRIGPASSBITS_V1_ICC