Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:07:17

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2019 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 #ifndef GAUDIKERNEL_NTUPLE_H
0012 #define GAUDIKERNEL_NTUPLE_H
0013 // ============================================================================
0014 // Framework include files
0015 // ============================================================================
0016 #include "GaudiKernel/DataObject.h"
0017 #include "GaudiKernel/DataTypeInfo.h"
0018 #include "GaudiKernel/INTuple.h"
0019 #include "GaudiKernel/IOpaqueAddress.h"
0020 #include "GaudiKernel/SmartDataPtr.h"
0021 // ============================================================================
0022 // STL include files
0023 // ============================================================================
0024 #include <algorithm>
0025 #include <cfloat>
0026 #include <limits>
0027 #include <stdexcept>
0028 #include <string>
0029 // ============================================================================
0030 // Forward declarations
0031 // ============================================================================
0032 class NTupleFile;
0033 class NTupleDirectory;
0034 // ============================================================================
0035 /**
0036  * NTuple name space
0037  *
0038  *  Definition of helpers to access N tuple implementations
0039  *
0040  * @author Markus Frank
0041  * @author Sebastien Ponce
0042  */
0043 namespace NTuple {
0044   // local forward declarations
0045   template <class TYP>
0046   class Range;
0047   template <class TYP>
0048   class _Data;
0049   template <class TYP>
0050   class _Item;
0051   template <class TYP>
0052   class _Array;
0053   template <class TYP>
0054   class _Matrix;
0055   template <class TYP>
0056   class _Accessor;
0057   template <class TYP>
0058   class Item;
0059   template <class TYP>
0060   class Array;
0061   template <class TYP>
0062   class Matrix;
0063   // ==========================================================================
0064   /// Class defining a range
0065   template <class TYP>
0066   class Range {
0067     /// Lower boundary of range
0068     /*const*/ TYP m_lower;
0069     /// Upper boundary of range
0070     /*const*/ TYP m_upper;
0071 
0072   public:
0073     /// Standard constructor
0074     Range( TYP low, TYP upper ) : m_lower( std::move( low ) ), m_upper( std::move( upper ) ) {}
0075     /// Copy constructor
0076     Range( const Range<TYP>& copy ) : m_lower( copy.m_lower ), m_upper( copy.m_upper ) {}
0077     /// Adjust ranges
0078     Range& operator=( const Range<TYP>& copy ) {
0079       m_lower = copy.m_lower;
0080       m_upper = copy.m_upper;
0081       return *this;
0082     }
0083     /// Destructor
0084     virtual ~Range() = default;
0085     /// Lower boundary of range
0086     TYP lower() const { return m_lower; }
0087     /// Upper boundary of range
0088     TYP upper() const { return m_upper; }
0089     /// Distance between lower and upper range
0090     TYP distance() const { return m_upper - m_lower; }
0091     /// Minimal number of data
0092     static TYP min() { return std::numeric_limits<TYP>::min(); }
0093     /// Maximal number of data
0094     static TYP max() { return std::numeric_limits<TYP>::max(); }
0095   };
0096   // ==========================================================================
0097   template <>
0098   class Range<bool> {
0099   public:
0100     /// Standard constructor
0101     Range( const bool /* low */, const bool /* upper */ ) {}
0102     /// Copy constructor
0103     Range( const Range<bool>& /* copy */ ) {}
0104     /// Destructor
0105     virtual ~Range() = default;
0106     /// Lower boundary of range
0107     bool lower() const { return false; }
0108     /// Upper boundary of range
0109     bool upper() const { return true; }
0110     /// Distance between lower and upper range
0111     bool distance() const { return true; }
0112     /// Minimal number of data
0113     static bool min() { return false; }
0114     /// Maximal number of data
0115     static bool max() { return true; }
0116   };
0117   // ==========================================================================
0118   template <>
0119   inline IOpaqueAddress* Range<IOpaqueAddress*>::min() {
0120     return (IOpaqueAddress*)0x0;
0121   }
0122   template <>
0123   inline IOpaqueAddress* Range<IOpaqueAddress*>::max() {
0124     return (IOpaqueAddress*)0xffffffff;
0125   }
0126   // ==========================================================================
0127   /** Abstract class describing basic data in an Ntuple.
0128    */
0129   template <class TYP>
0130   class GAUDI_API _Data : virtual public INTupleItem {
0131   protected:
0132     /// Pointer to data buffer
0133     TYP* m_buffer = nullptr;
0134 
0135   public:
0136     /// Set type definition to make life more easy easy
0137     typedef Range<TYP> ItemRange;
0138     /// Set default value
0139     virtual void setDefault( const TYP d ) = 0;
0140     /// Access the range if specified
0141     virtual const ItemRange& range() const = 0;
0142   };
0143   // ==========================================================================
0144   /** Abstract class describing a column in a N tuple.
0145    */
0146   template <class TYP>
0147   class GAUDI_API _Item : virtual public _Data<TYP> {
0148   public:
0149     /// Create instance
0150     static _Item* create( INTuple* tup, const std::string& name, const std::type_info& info, TYP min, TYP max,
0151                           TYP def );
0152     /// Assignment operator
0153     template <class T>
0154     _Item<TYP>& operator=( const _Item<T>& copy ) {
0155       *this->m_buffer = copy.get();
0156       return *this;
0157     }
0158     /// Access to data by reference
0159     void set( const TYP& item ) { *this->m_buffer = item; }
0160     /// Access to data by reference (CONST)
0161     virtual TYP get() const { return *this->m_buffer; }
0162   };
0163   // ==========================================================================
0164   /** Abstract class describing a column-array in a N tuple.
0165    */
0166   template <class TYP>
0167   class GAUDI_API _Array : virtual public _Data<TYP> {
0168   public:
0169     /// Create instance
0170     static _Array* create( INTuple* tup, const std::string& name, const std::type_info& info, const std::string& index,
0171                            long len, TYP min, TYP max, TYP def );
0172     /// Assignment operator
0173     template <class T>
0174     _Array<TYP>& operator=( const _Array<T>& copy ) {
0175       long len = this->length();
0176       if ( len == copy.length() ) {
0177         const T* source = (const T*)copy.buffer();
0178         std::copy_n( source, len, this->m_buffer );
0179         return *this;
0180       }
0181       throw std::out_of_range( "N-tuple matrix cannot be copied! The index range does not match!" );
0182       return *this;
0183     }
0184     /// Access to data by reference (CONST)
0185     const TYP& data( long i ) const { return this->m_buffer[i]; }
0186     /// Access to data by reference (CONST)
0187     TYP& data( long i ) { return this->m_buffer[i]; }
0188 
0189     TYP* begin() { return this->m_buffer; }
0190     TYP* end() { return this->m_buffer + this->length(); }
0191   };
0192   // ==========================================================================
0193   /** Abstract class describing a matrix column in a N tuple.
0194    */
0195   template <class TYP>
0196   class GAUDI_API _Matrix : virtual public _Data<TYP> {
0197   protected:
0198     /// Number of rows per column
0199     long m_rows;
0200 
0201   public:
0202     /// Create instance
0203     static _Matrix* create( INTuple* tup, const std::string& name, const std::type_info& info, const std::string& index,
0204                             long ncol, long nrow, TYP min, TYP max, TYP def );
0205     /// Assignment operator
0206     template <class T>
0207     _Matrix<TYP>& operator=( const _Matrix<T>& copy ) {
0208       long len = this->length();
0209       if ( len == copy.length() ) {
0210         const T* source = (const T*)copy.buffer();
0211         std::copy_n( source, len, this->m_buffer );
0212         return *this;
0213       }
0214       throw std::out_of_range( "N-tuple matrix cannot be copied! The index range does not match!" );
0215       return *this;
0216     }
0217     /// Access to data by reference
0218     TYP* column( long i ) { return this->m_buffer + i * m_rows; }
0219     /// Access to data by reference (CONST)
0220     const TYP* column( long i ) const { return this->m_buffer + i * m_rows; }
0221   };
0222   // ==========================================================================
0223   /** Class acting as a smart pointer holding a N tuple entry.
0224    */
0225   template <class TYP>
0226   class _Accessor {
0227     friend class Tuple;
0228 
0229   private:
0230     _Accessor<TYP>& operator=( const _Accessor<TYP>& ) { return *this; }
0231 
0232   protected:
0233     /// Pointer to instance
0234     mutable TYP* m_ptr = nullptr;
0235 
0236   public:
0237     /// Standard Constructor
0238     _Accessor() = default;
0239     /// Standard Destructor
0240     virtual ~_Accessor() = default;
0241     /// Default copy constructor.
0242     _Accessor( const _Accessor& ) = default;
0243     /// Check if column is present
0244     bool operator!() const { return m_ptr != 0; }
0245     /// Check if column is present
0246     operator const void*() const { return m_ptr; }
0247     /// Dereference operator
0248     TYP* operator->() { return m_ptr; }
0249     /// Dereference operator (CONST)
0250     const TYP* operator->() const { return m_ptr; }
0251     /// Access the range
0252     const Range<TYP>& range() const { return m_ptr->range(); }
0253   };
0254   // ==========================================================================
0255   /** Class acting as a smart pointer holding a N tuple _Item.
0256    */
0257   template <class TYP>
0258   class Item : virtual public _Accessor<_Item<TYP>> {
0259     typedef Item<TYP> _My;
0260 
0261   public:
0262     /// Standard Constructor
0263     Item() = default;
0264     /// Automatic type conversion
0265     operator const TYP() const { return this->m_ptr->get(); }
0266     /// Dereference operator for pointers
0267     TYP operator*() { return this->m_ptr->get(); }
0268     /// Dereference operator for pointers(CONST)
0269     const TYP operator*() const { return this->m_ptr->get(); }
0270     // Arithmetic operators defined on NTuple column entries
0271     Item& operator++() { return *this += TYP( 1 ); }
0272     Item& operator++( int ) { return *this += TYP( 1 ); }
0273     Item& operator--() { return *this -= TYP( 1 ); }
0274     Item& operator--( int ) { return *this -= TYP( 1 ); }
0275     /// Assignment operator
0276     Item& operator=( const TYP data ) {
0277       this->m_ptr->set( data );
0278       return *this;
0279     }
0280     /// Assignment operator
0281     template <class T>
0282     Item& operator=( const Item<T>& data ) {
0283       this->m_ptr->set( data->get() );
0284       return *this;
0285     }
0286     Item<TYP>& operator+=( const TYP data ) {
0287       this->m_ptr->set( this->m_ptr->get() + data );
0288       return *this;
0289     }
0290     Item<TYP>& operator-=( const TYP data ) {
0291       this->m_ptr->set( this->m_ptr->get() - data );
0292       return *this;
0293     }
0294     Item<TYP>& operator*=( const TYP data ) {
0295       this->m_ptr->set( this->m_ptr->get() * data );
0296       return *this;
0297     }
0298     Item<TYP>& operator/=( const TYP data ) {
0299       this->m_ptr->set( this->m_ptr->get() / data );
0300       return *this;
0301     }
0302   };
0303   // ==========================================================================
0304   /** Specialization acting as a smart pointer holding a N tuple _Item.
0305    */
0306   template <>
0307   class Item<bool> : virtual public _Accessor<_Item<bool>> {
0308     typedef Item<bool> _My;
0309 
0310   public:
0311     /// Standard Constructor
0312     Item() = default;
0313     /// Automatic type conversion
0314     operator bool() const { return this->m_ptr->get(); }
0315     /// Assignment operator
0316     Item& operator=( const bool data ) {
0317       this->m_ptr->set( data );
0318       return *this;
0319     }
0320     /// Assignment operator
0321     template <class T>
0322     Item& operator=( const Item<T>& data ) {
0323       this->m_ptr->set( data->get() );
0324       return *this;
0325     }
0326   };
0327   // ==========================================================================
0328   /** Class acting as a smart pointer holding a N tuple _Item.
0329    */
0330   template <class TYP>
0331   class Array : virtual public _Accessor<_Array<TYP>> {
0332   public:
0333     /// Standard Constructor
0334     Array() = default;
0335     /// Assignment operator
0336     template <class T>
0337     Array& operator=( const Array<T>& copy ) {
0338       *( this->m_ptr ) = *( copy.operator->() );
0339       return *this;
0340     }
0341     /// Array operator
0342     template <class T>
0343     TYP& operator[]( const T i ) {
0344       return this->m_ptr->data( i );
0345     }
0346     /// Array operator
0347     template <class T>
0348     const TYP& operator[]( const T i ) const {
0349       return this->m_ptr->data( i );
0350     }
0351 
0352     TYP* begin() { return this->m_ptr->begin(); }
0353     TYP* end() { return this->m_ptr->end(); }
0354   };
0355   // =========================================================================
0356   /** Class acting as a smart pointer holding a N tuple _Item.
0357    */
0358   template <class TYP>
0359   class Matrix : virtual public _Accessor<_Matrix<TYP>> {
0360   public:
0361     /// Standard Constructor
0362     Matrix() = default;
0363     /// Assignment operator
0364     template <class T>
0365     Matrix& operator=( const Matrix<T>& copy ) {
0366       *( this->m_ptr ) = *( copy.operator->() );
0367       return *this;
0368     }
0369     /// Array operator
0370     template <class T>
0371     TYP* operator[]( const T i ) {
0372       return this->m_ptr->column( i );
0373     }
0374     /// Array operator
0375     template <class T>
0376     const TYP* operator[]( const T i ) const {
0377       return this->m_ptr->column( i );
0378     }
0379   };
0380   // =========================================================================
0381   /** Abstract base class which allows the user to interact with the
0382       actual N tuple implementation.
0383       The class is abstract, because the template methods must
0384       be instantiated by the compiler at compile time. Otherwise the
0385       references would be unresolved.
0386   */
0387   class Tuple : public DataObject, virtual public INTuple {
0388 
0389   protected:
0390     /// Locate a _Column of data to the N tuple type safe
0391     template <class TYPE>
0392     StatusCode i_item( const std::string& name, _Item<TYPE>*& result ) const {
0393       try {
0394         result = dynamic_cast<_Item<TYPE>*>( i_find( name ) );
0395       } catch ( ... ) { result = nullptr; }
0396       return result ? StatusCode::SUCCESS : StatusCode::FAILURE;
0397     }
0398     /// Locate a _Column of data to the N tuple type unsafe for objects
0399     template <class TYPE>
0400     StatusCode i_item( const std::string& name, _Item<TYPE*>*& result ) const {
0401       try {
0402         _Item<void*>* p = dynamic_cast<_Item<void*>*>( i_find( name ) );
0403         result          = (_Item<TYPE*>*)p;
0404       } catch ( ... ) { result = nullptr; }
0405       return result ? StatusCode::SUCCESS : StatusCode::FAILURE;
0406     }
0407     /// Locate a _Column of data to the N tuple type safe
0408     StatusCode i_item( const std::string& name, _Item<IOpaqueAddress*>*& result ) const {
0409       try {
0410         result = dynamic_cast<_Item<IOpaqueAddress*>*>( i_find( name ) );
0411       } catch ( ... ) { result = nullptr; }
0412       return result ? StatusCode::SUCCESS : StatusCode::FAILURE;
0413     }
0414     /// Locate a _Array of data to the N tuple type safe
0415     template <class TYPE>
0416     StatusCode i_item( const std::string& name, _Array<TYPE>*& result ) const {
0417       try {
0418         if ( clID() == CLID_ColumnWiseTuple ) { result = dynamic_cast<_Array<TYPE>*>( i_find( name ) ); }
0419       } catch ( ... ) { result = nullptr; }
0420       return result ? StatusCode::SUCCESS : StatusCode::FAILURE;
0421     }
0422     /// Locate a _Matrix of data to the N tuple type safe
0423     template <class TYPE>
0424     StatusCode i_item( const std::string& name, _Matrix<TYPE>*& result ) const {
0425       try {
0426         if ( clID() == CLID_ColumnWiseTuple ) { result = dynamic_cast<_Matrix<TYPE>*>( i_find( name ) ); }
0427       } catch ( ... ) { result = nullptr; }
0428       return result ? StatusCode::SUCCESS : StatusCode::FAILURE;
0429     }
0430     /// Add a _Item of data to the N tuple
0431     template <class TYPE>
0432     StatusCode i_addItem( const std::string& name, long, const std::string&, TYPE low, TYPE high,
0433                           _Item<TYPE>*& result ) {
0434       if ( !i_find( name ) ) {
0435         TYPE nil;
0436         nil = 0;
0437         return add( result = _Item<TYPE>::create( this, name, typeid( TYPE ), low, high, nil ) );
0438       }
0439       return StatusCode::FAILURE;
0440     }
0441     /// Add a _Item of data to the N tuple
0442     template <class TYPE>
0443     StatusCode i_addItem( const std::string& name, long dim, const std::string& index, TYPE low, TYPE high,
0444                           _Array<TYPE>*& result ) {
0445       if ( !i_find( name ) && clID() == CLID_ColumnWiseTuple ) {
0446         return add( result = _Array<TYPE>::create( this, name, typeid( TYPE ), index, dim, low, high, TYPE( 0 ) ) );
0447       }
0448       return StatusCode::FAILURE;
0449     }
0450     /// Add a _Item of data to the N tuple
0451     template <class TYPE>
0452     StatusCode i_addItem( const std::string& name, long dim1, long dim2, const std::string& index, TYPE low, TYPE high,
0453                           _Matrix<TYPE>*& result ) {
0454       if ( !i_find( name ) && clID() == CLID_ColumnWiseTuple ) {
0455         return add( result =
0456                         _Matrix<TYPE>::create( this, name, typeid( TYPE ), index, dim1, dim2, low, high, TYPE( 0 ) ) );
0457       }
0458       return StatusCode::FAILURE;
0459     }
0460     template <class TYPE>
0461     StatusCode i_addObject( const std::string& name, _Item<TYPE*>*& result, const std::type_info& /* typ */ ) {
0462       if ( !i_find( name ) && clID() == CLID_ColumnWiseTuple ) {
0463         return add( result = (_Item<TYPE*>*)_Item<void*>::create( this, name, typeid( TYPE ), 0, 0, 0 ) );
0464       }
0465       return StatusCode::FAILURE;
0466     }
0467 
0468   public:
0469     /// Locate a scalar Item of data to the N tuple type safe
0470     template <class TYPE>
0471     StatusCode item( const std::string& name, Item<TYPE>& result ) {
0472       return i_item( name, result.m_ptr );
0473     }
0474     /// Locate a scalar Item of data to the N tuple type safe (CONST)
0475     template <class TYPE>
0476     StatusCode item( const std::string& name, const Item<TYPE>& result ) const {
0477       return i_item( name, result.m_ptr );
0478     }
0479     /// Locate a Array of data to the N tuple type safe
0480     template <class TYPE>
0481     StatusCode item( const std::string& name, Array<TYPE>& result ) {
0482       return i_item( name, result.m_ptr );
0483     }
0484     /// Locate a Array of data to the N tuple type safe (CONST)
0485     template <class TYPE>
0486     StatusCode item( const std::string& name, const Array<TYPE>& result ) const {
0487       return i_item( name, result.m_ptr );
0488     }
0489     /// Locate a Matrix of data to the N tuple type safe
0490     template <class TYPE>
0491     StatusCode item( const std::string& name, Matrix<TYPE>& result ) {
0492       return i_item( name, result.m_ptr );
0493     }
0494 
0495     /// Locate a Matrix of data to the N tuple type safe (CONST)
0496     template <class TYPE>
0497     StatusCode item( const std::string& name, const Matrix<TYPE>& result ) const {
0498       return i_item( name, result.m_ptr );
0499     }
0500 
0501     /** Add a scalar data item a N tuple.
0502 
0503         Use this entry point to connect any allowed scalar data type
0504         to an N-tuple. The value filled, may have any range.
0505         Do NOT use this entry point to specify an index
0506         column in a column wise N-tuple.
0507 
0508         @param  name       Name of the column in the column wise N-tuple
0509         @param  itm        Reference to the Item<TYPE> datatype, which
0510                            should be connected to the N-tuple.
0511 
0512         @return StatusCode indicating success or failure.
0513     */
0514     template <class TYPE>
0515     StatusCode addItem( const std::string& name, Item<TYPE>& itm ) {
0516       typedef Range<TYPE> _R;
0517       return i_addItem( name, 1, "", _R::min(), _R::max(), itm.m_ptr );
0518     }
0519 
0520     /** Add an simple object item to an N tuple.
0521 
0522         @param  name       Name of the column in the column wise N-tuple
0523         @param  itm        Reference to the Item<TYPE> datatype, which
0524                            should be connected to the N-tuple.
0525 
0526         @return StatusCode indicating success or failure.
0527     */
0528     template <class TYPE>
0529     StatusCode addItem( const std::string& name, Item<TYPE*>& itm ) {
0530       return i_addObject( name, itm.m_ptr, typeid( TYPE ) );
0531     }
0532 
0533     /** Add an address object item to an N tuple: specialized call
0534 
0535         @param  name       Name of the column in the column wise N-tuple
0536         @param  itm        Reference to the Item<TYPE> datatype, which
0537                            should be connected to the N-tuple.
0538 
0539         @return StatusCode indicating success or failure.
0540     */
0541     StatusCode addItem( const std::string& name, Item<IOpaqueAddress*>& itm ) {
0542       typedef Range<IOpaqueAddress*> _R;
0543       return i_addItem( name, 1, "", _R::min(), _R::max(), itm.m_ptr );
0544     }
0545 
0546     /** Add a scalar data item a N tuple with a range.
0547 
0548         Typically this entry point is used to specuify
0549         index column with a fixed data range for a column wise N-tuple.
0550 
0551         Note: Checks on the data range are not implemented!
0552 
0553         @param  name       Name of the column in the column wise N-tuple
0554         @param  itm        Reference to the Item<TYPE> datatype, which
0555                            should be connected to the N-tuple.
0556         @param  low        Lower edge of client data values allowed
0557                            to fill into the N-tuple array.
0558         @param  high       Upper edge of client data values allowed
0559                            to fill into the N-tuple array.
0560 
0561         @return StatusCode indicating success or failure.
0562     */
0563     template <class TYPE, class RANGE>
0564     StatusCode addItem( const std::string& name, Item<TYPE>& itm, const RANGE low, const RANGE high ) {
0565       return i_addItem( name, 1, "", TYPE( low ), TYPE( high ), itm.m_ptr );
0566     }
0567 
0568     /** Add an fixed-size Array of data to a column wise N tuple.
0569 
0570         You should use this entry point to add a FIXED SIZE ARRAY
0571         to a column wise N-tuple. The dimension of the array must
0572         be specified.
0573 
0574         @param  name       Name of the column in the column wise N-tuple
0575         @param  dim        Length of the array to be added to the N-tuple
0576         @param  array      Reference to the Array<TYPE> datatype, which
0577                            should be connected to the N-tuple.
0578 
0579         @return StatusCode indicating success or failure.
0580     */
0581     template <class TYPE>
0582     StatusCode addItem( const std::string& name, long dim, Array<TYPE>& array ) {
0583       return i_addItem( name, dim, "", Range<TYPE>::min(), Range<TYPE>::max(), array.m_ptr );
0584     }
0585 
0586     /** Add an fixed-size Array of data to a column wise N tuple with a range.
0587 
0588         You should use this entry point to add a FIXED SIZE ARRAY
0589         to a column wise N-tuple. The dimension of the array must
0590         be specified.
0591 
0592         Note: Checks on the data range are not implemented!
0593 
0594         @param  name       Name of the column in the column wise N-tuple
0595         @param  dim        Length of the array to be added to the N-tuple
0596         @param  array      Reference to the Array<TYPE> datatype, which
0597                            should be connected to the N-tuple.
0598         @param  low        Lower edge of client data values allowed
0599                            to fill into the N-tuple array.
0600         @param  high       Upper edge of client data values allowed
0601                            to fill into the N-tuple array.
0602 
0603         @return StatusCode indicating success or failure.
0604     */
0605     template <class TYPE, class RANGE>
0606     StatusCode addItem( const std::string& name, long dim, Array<TYPE>& array, const RANGE low, const RANGE high ) {
0607       return i_addItem( name, dim, "", TYPE( low ), TYPE( high ), array.m_ptr );
0608     }
0609 
0610     /** Add an indexed Array of data to a column wise N tuple with a range.
0611 
0612         You should use this entry point to add a VARIABLE SIZE ARRAY
0613         to a column wise N-tuple. The dimension of the array is
0614         unspecified and depends on the data range, which you allowed
0615         for the index column.
0616 
0617         Hence you have to be careful on the allowed data range of the
0618         index column, because the index column determines the total
0619         allocated memory.
0620 
0621         Note: Checks on the data range are not implemented!
0622 
0623         Note: Due to confusion with the entry point to connecting
0624               a fixed size array the use of this function is
0625                   *** DEPRECATED ***
0626               please use addIndexedItem(...) instead.
0627 
0628         @param  name       Name of the column in the column wise N-tuple
0629         @param  index      Reference to the scalar index column used to
0630                            determine the size of the array.
0631         @param  array      Reference to the Array<TYPE> datatype, which
0632                            should be connected to the N-tuple.
0633         @param  low        Lower edge of client data values allowed
0634                            to fill into the N-tuple array.
0635         @param  high       Upper edge of client data values allowed
0636                            to fill into the N-tuple array.
0637 
0638         @return StatusCode indicating success or failure.
0639     */
0640     template <class TYPE, class INDEX, class RANGE>
0641     StatusCode addItem( const std::string& name, Item<INDEX>& index, Array<TYPE>& array, const RANGE low,
0642                         const RANGE high ) {
0643       return i_addItem( name, index->range().distance(), index->name(), TYPE( low ), TYPE( high ), array.m_ptr );
0644     }
0645 
0646     /** Add an indexed Array of data to a column wise N tuple with a range.
0647 
0648         You should use this entry point to add a VARIABLE SIZE ARRAY
0649         to a column wise N-tuple. The dimension of the array is
0650         unspecified and depends on the data range, which you allowed
0651         for the index column.
0652 
0653         Hence you have to be careful on the allowed data range of the
0654         index column, because the index column determines the total
0655         allocated memory.
0656 
0657         Note: Checks on the data range are not implemented!
0658 
0659         @param  name       Name of the column in the column wise N-tuple
0660         @param  index      Reference to the scalar index column used to
0661                            determine the size of the array.
0662         @param  array      Reference to the Array<TYPE> datatype, which
0663                            should be connected to the N-tuple.
0664         @param  low        Lower edge of client data values allowed
0665                            to fill into the N-tuple array.
0666         @param  high       Upper edge of client data values allowed
0667                            to fill into the N-tuple array.
0668 
0669         @return StatusCode indicating success or failure.
0670     */
0671     template <class TYPE, class INDEX, class RANGE>
0672     StatusCode addIndexedItem( const std::string& name, Item<INDEX>& index, Array<TYPE>& array, const RANGE low,
0673                                const RANGE high ) {
0674       return i_addItem( name, index->range().distance(), index->name(), TYPE( low ), TYPE( high ), array.m_ptr );
0675     }
0676 
0677     /** Add an indexed Array of data to a column wise N tuple.
0678 
0679         You should use this entry point to add a VARIABLE SIZE ARRAY
0680         to a column wise N-tuple. The dimension of the array is
0681         unspecified and depends on the data range, which you allowed
0682         for the index column.
0683 
0684         Hence, you have to be careful on the allowed data range of the
0685         index column, because the index column determines the total
0686         allocated memory.
0687 
0688         Note: Due to confusion with the entry point to connecting
0689               a fixed size array the use of this member function is
0690                   *** DEPRECATED ***
0691               please use addIndexedItem(...) instead.
0692 
0693         @param  name       Name of the column in the column wise N-tuple
0694         @param  index      Reference to the scalar index column used to
0695                            determine the size of the array.
0696         @param  array      Reference to the Array<TYPE> datatype, which
0697                            should be connected to the N-tuple.
0698 
0699         @return StatusCode indicating success or failure.
0700     */
0701     template <class TYPE, class INDEX>
0702     StatusCode addItem( const std::string& name, Item<INDEX>& index, Array<TYPE>& array ) {
0703       return i_addItem( name, index->range().distance(), index->name(), Range<TYPE>::min(), Range<TYPE>::max(),
0704                         array.m_ptr );
0705     }
0706 
0707     /** Add an indexed Array of data to a column wise N tuple.
0708 
0709         You should use this entry point to add a VARIABLE SIZE ARRAY
0710         to a column wise N-tuple. The dimension of the array is
0711         unspecified and depends on the data range, which you allowed
0712         for the index column.
0713 
0714         Hence, you have to be careful on the allowed data range of the
0715         index column, because the index column determines the total
0716         allocated memory.
0717 
0718         @param  name       Name of the column in the column wise N-tuple
0719         @param  index      Reference to the scalar index column used to
0720                            determine the size of the array.
0721         @param  array      Reference to the Array<TYPE> datatype, which
0722                            should be connected to the N-tuple.
0723 
0724         @return StatusCode indicating success or failure.
0725     */
0726     template <class TYPE, class INDEX>
0727     StatusCode addIndexedItem( const std::string& name, Item<INDEX>& index, Array<TYPE>& array ) {
0728       return i_addItem( name, index->range().distance(), index->name(), Range<TYPE>::min(), Range<TYPE>::max(),
0729                         array.m_ptr );
0730     }
0731 
0732     /** Add an fixed size Matrix of data to a column wise N tuple.
0733 
0734         You should use this entry point to add a FIXED SIZE MATRIX
0735         to a column wise N-tuple. The dimension of the matrix must
0736         be specified.
0737 
0738         Attention: Do not confuse with entry point to add a
0739                    VARIABLE SIZE MATRIX!
0740 
0741         @param  name       Name of the column in the column wise N-tuple
0742         @param  cols       Number of data columns in the Matrix.
0743         @param  rows       Number of data rows in the Matrix.
0744         @param  matrix     Reference to the Matrix<TYPE> datatype, which
0745                            should be connected to the N-tuple.
0746 
0747         @return StatusCode indicating success or failure.
0748     */
0749     template <class TYPE>
0750     StatusCode addItem( const std::string& name, long cols, long rows, Matrix<TYPE>& matrix ) {
0751       return i_addItem( name, cols, rows, "", Range<TYPE>::min(), Range<TYPE>::max(), matrix.m_ptr );
0752     }
0753 
0754     /** Add an fixed size Matrix of data to a column wise N tuple.
0755 
0756         You should use this entry point to add a FIXED SIZE MATRIX
0757         to a column wise N-tuple. The dimension of the matrix must
0758         be specified.
0759 
0760         Note: Checks on the data range are not implemented!
0761         Attention: Do not confuse with entry point to add a
0762                    VARIABLE SIZE MATRIX!
0763 
0764         @param  name       Name of the column in the column wise N-tuple
0765         @param  cols       Number of data columns in the Matrix.
0766         @param  rows       Number of data rows in the Matrix.
0767         @param  matrix     Reference to the Matrix<TYPE> datatype, which
0768                            should be connected to the N-tuple.
0769         @param  low        Lower edge of client data values allowed
0770                            to fill into the N-tuple matrix.
0771         @param  high       Upper edge of client data values allowed
0772                            to fill into the N-tuple matrix.
0773 
0774         @return StatusCode indicating success or failure.
0775     */
0776     template <class TYPE, class RANGE>
0777     StatusCode addItem( const std::string& name, long cols, long rows, Matrix<TYPE>& result, const RANGE low,
0778                         const RANGE high ) {
0779       return i_addItem( name, cols, rows, "", TYPE( low ), TYPE( high ), result.m_ptr );
0780     }
0781 
0782     /** Add an variable size Matrix of data to a column wise N tuple.
0783 
0784         You should use this entry point to add a VARIABLE SIZE MATRIX
0785         to a column wise N-tuple. The number of columns of the
0786         matrix is given by the allowed data range of the index column.
0787         The number of rows however, which are allowed in the matrix
0788         must be specified explicitly and cannot be variable.
0789 
0790         Attention: Do not confuse with entry point to add a
0791                    FIXED SIZE MATRIX.
0792 
0793         Note: Due to confusion with the entry point to connecting
0794               a fixed size matrix the use of this member function is
0795                   *** DEPRECATED ***
0796               please use addIndexedItem(...) instead.
0797 
0798         @param  name       Name of the column in the column wise N-tuple
0799         @param  index      Reference to the scalar index column used to
0800                            determine the number of data columns in the matrix
0801         @param  matrix     Reference to the Matrix<TYPE> datatype, which
0802                            should be connected to the N-tuple.
0803         @param  rows       Number of data rows in the Matrix.
0804 
0805         @return StatusCode indicating success or failure.
0806     */
0807     template <class TYPE, class INDEX>
0808     StatusCode addItem( const std::string& name, Item<INDEX>& index, Matrix<TYPE>& matrix, long rows ) {
0809       return i_addItem( name, index->range().distance(), rows, index->name(), Range<TYPE>::min(), Range<TYPE>::max(),
0810                         matrix.m_ptr );
0811     }
0812 
0813     /** Add an variable size Matrix of data to a column wise N tuple.
0814 
0815         You should use this entry point to add a VARIABLE SIZE MATRIX
0816         to a column wise N-tuple. The number of columns of the
0817         matrix is given by the allowed data range of the index column.
0818         The number of rows however, which are allowed in the matrix
0819         must be specified explicitly and cannot be variable.
0820 
0821         Attention: Do not confuse with entry point to add a
0822                    FIXED SIZE MATRIX.
0823 
0824         @param  name       Name of the column in the column wise N-tuple
0825         @param  index      Reference to the scalar index column used to
0826                            determine the number of data columns in the matrix
0827         @param  rows       Number of data rows in the Matrix.
0828         @param  matrix     Reference to the Matrix<TYPE> datatype, which
0829                            should be connected to the N-tuple.
0830 
0831         @return StatusCode indicating success or failure.
0832     */
0833     template <class TYPE, class INDEX>
0834     StatusCode addIndexedItem( const std::string& name, Item<INDEX>& col_index, long rows, Matrix<TYPE>& matrix ) {
0835       return i_addItem( name, col_index->range().distance(), rows, col_index->name(), Range<TYPE>::min(),
0836                         Range<TYPE>::max(), matrix.m_ptr );
0837     }
0838 
0839     /** Add an variable size Matrix of data to a column wise N tuple.
0840 
0841         You should use this entry point to add a VARIABLE SIZE MATRIX
0842         to a column wise N-tuple. The number of columns of the
0843         matrix is given by the allowed data range of the index column.
0844         The number of rows however, which are allowed in the matrix
0845         must be specified explicitly and cannot be variable. Also the
0846         range of allowed data values to be filled into the data area
0847         of the matrix can be specified.
0848 
0849         Note: Checks on the data range are not implemented!
0850         Attention: Do not confuse with entry point to add a
0851                    FIXED SIZE MATRIX.
0852 
0853         Note: Due to confusion with the entry point to connecting
0854               a fixed size matrix the use of this member function is
0855                   *** DEPRECATED ***
0856               please use addIndexedItem(...) instead.
0857 
0858         @param  name       Name of the column in the column wise N-tuple
0859         @param  index      Reference to the scalar index column used to
0860                            determine the number of data columns in the matrix
0861         @param  matrix     Reference to the Matrix<TYPE> datatype, which
0862                            should be connected to the N-tuple.
0863         @param  rows       Number of data rows in the Matrix.
0864         @param  low        Lower edge of client data values allowed
0865                            to fill into the N-tuple matrix.
0866         @param  high       Upper edge of client data values allowed
0867                            to fill into the N-tuple matrix.
0868 
0869         @return StatusCode indicating success or failure.
0870     */
0871     template <class TYPE, class INDEX, class RANGE>
0872     StatusCode addItem( const std::string& name, Item<INDEX>& index, Matrix<TYPE>& matrix, long rows, const RANGE low,
0873                         const RANGE high ) {
0874       return i_addItem( name, index->range().distance(), rows, index->name(), TYPE( low ), TYPE( high ), matrix.m_ptr );
0875     }
0876 
0877     /** Add an variable size Matrix of data to a column wise N tuple.
0878 
0879         You should use this entry point to add a VARIABLE SIZE MATRIX
0880         to a column wise N-tuple. The number of columns of the
0881         matrix is given by the allowed data range of the index column.
0882         The number of rows however, which are allowed in the matrix
0883         must be specified explicitly and cannot be variable. Also the
0884         range of allowed data values to be filled into the data area
0885         of the matrix can be specified.
0886 
0887         Note: Checks on the data range are not implemented!
0888         Attention: Do not confuse with entry point to add a
0889                    FIXED SIZE MATRIX.
0890 
0891         @param  name       Name of the column in the column wise N-tuple
0892         @param  index      Reference to the scalar index column used to
0893                            determine the number of data columns in the matrix
0894         @param  rows       Number of data rows in the Matrix.
0895         @param  matrix     Reference to the Matrix<TYPE> datatype, which
0896                            should be connected to the N-tuple.
0897         @param  low        Lower edge of client data values allowed
0898                            to fill into the N-tuple matrix.
0899         @param  high       Upper edge of client data values allowed
0900                            to fill into the N-tuple matrix.
0901 
0902         @return StatusCode indicating success or failure.
0903     */
0904     template <class TYPE, class INDEX, class RANGE>
0905     StatusCode addIndexedItem( const std::string& name, Item<INDEX>& index, long rows, Matrix<TYPE>& matrix,
0906                                const RANGE low, const RANGE high ) {
0907       return i_addItem( name, index->range().distance(), rows, index->name(), TYPE( low ), TYPE( high ), matrix.m_ptr );
0908     }
0909   };
0910 
0911   /** Small class representing an N tuple directory in the transient store
0912    */
0913   struct Directory : DataObject {
0914     /// class ID of the object
0915     static const CLID& classID() { return CLID_NTupleDirectory; }
0916     /// class ID of the object
0917     const CLID& clID() const override { return classID(); }
0918   };
0919 
0920   /** Small class representing an N tuple file in the transient store
0921    */
0922   class File : public Directory {
0923   protected:
0924     /// Physical file name
0925     std::string m_name;
0926     /// Logical file name
0927     std::string m_logName;
0928     /// Access type
0929     long m_type = 0;
0930     /// Flag to indicate wether the file was opened already
0931     bool m_isOpen = false;
0932 
0933   public:
0934     File() = default;
0935     /// Standard constructor
0936     File( long type, std::string name, std::string logName )
0937         : m_name( std::move( name ) ), m_logName( std::move( logName ) ), m_type( type ) {}
0938 
0939     /// class ID of the object
0940     static const CLID& classID() { return CLID_NTupleFile; }
0941     /// class ID of the object
0942     const CLID& clID() const override { return classID(); }
0943     /// Set access type
0944     void setType( const long typ ) { m_type = typ; }
0945     /// Return access type
0946     long type() const { return m_type; }
0947     /// Retrun physical file name
0948     const std::string& name() const { return m_name; }
0949     /// Set access type
0950     void setName( std::string nam ) { m_name = std::move( nam ); }
0951     //// Return logical file name
0952     const std::string& logicalName() const { return m_logName; }
0953     //// Return logical file name
0954     void setLogicalName( std::string l ) { m_logName = std::move( l ); }
0955     /// Set "open" flag
0956     void setOpen( bool flag ) { m_isOpen = flag; }
0957     /// Access "open" flag
0958     bool isOpen() const { return m_isOpen; }
0959   };
0960   // =========================================================================
0961   // inhibit certain types by defining specialized templates which do not
0962   // allow for construction.
0963   template <>
0964   class Array<IOpaqueAddress*> {
0965     Array() = delete;
0966 
0967   public:
0968     virtual ~Array()     = default;
0969     virtual void dummy() = 0;
0970   };
0971   template <>
0972   class Matrix<IOpaqueAddress*> {
0973     Matrix() = delete;
0974 
0975   public:
0976     virtual ~Matrix()    = default;
0977     virtual void dummy() = 0;
0978   };
0979 // =========================================================================
0980 #ifndef ALLOW_ALL_TYPES
0981 #else
0982   typedef Item<bool>               BoolItem;
0983   typedef Item<char>               CharItem;
0984   typedef Item<unsigned char>      UCharItem;
0985   typedef Item<short>              ShortItem;
0986   typedef Item<unsigned short>     UShortItem;
0987   typedef Item<long>               LongItem;
0988   typedef Item<long long>          LongLongItem;
0989   typedef Item<unsigned long>      ULongItem;
0990   typedef Item<unsigned long long> ULongLongItem;
0991   typedef Item<int>                IntItem;
0992   typedef Item<unsigned int>       UIntItem;
0993   typedef Item<float>              FloatItem;
0994   typedef Item<double>             DoubleItem;
0995   typedef Array<bool>              BoolArray;
0996   typedef Array<char>              CharArray;
0997   typedef Array<unsigned char>     UCharArray;
0998   typedef Array<short>             ShortArray;
0999   typedef Array<unsigned short>    UShortArray;
1000   typedef Array<long>              LongArray;
1001   typedef Array<unsigned long>     ULongArray;
1002   typedef Array<int>               IntArray;
1003   typedef Array<unsigned int>      UIntArray;
1004   typedef Array<float>             FloatArray;
1005   typedef Array<double>            DoubleArray;
1006   typedef Matrix<bool>             BoolMatrix;
1007   typedef Matrix<char>             CharMatrix;
1008   typedef Matrix<unsigned char>    UCharMatrix;
1009   typedef Matrix<short>            ShortMatrix;
1010   typedef Matrix<unsigned short>   UShortMatrix;
1011   typedef Matrix<long>             LongMatrix;
1012   typedef Matrix<unsigned long>    ULongMatrix;
1013   typedef Matrix<int>              IntMatrix;
1014   typedef Matrix<unsigned int>     UIntMatrix;
1015   typedef Matrix<float>            FloatMatrix;
1016   typedef Matrix<double>           DoubleMatrix;
1017 #endif
1018 
1019   template <class T>
1020   inline std::ostream& operator<<( std::ostream& s, const Item<T>& obj ) {
1021     return s << T( obj );
1022   }
1023 } // end of namespace NTuple
1024 
1025 // Useful:
1026 typedef SmartDataPtr<NTuple::Tuple>     NTuplePtr;
1027 typedef SmartDataPtr<NTuple::Directory> NTupleDirPtr;
1028 typedef SmartDataPtr<NTuple::File>      NTupleFilePtr;
1029 
1030 #endif // GAUDIKERNEL_NTUPLE_H