Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-06-30 08:36:23

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2024 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; } // cppcheck-suppress CastIntegerToAddressAtReturn
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     /// Needs to be implemented in derived classes
0231     _Accessor<TYP>& operator=( const _Accessor<TYP>& ) = delete;
0232 
0233   protected:
0234     /// Pointer to instance
0235     mutable TYP* m_ptr = nullptr;
0236 
0237   public:
0238     /// Standard Constructor
0239     _Accessor() = default;
0240     /// Standard Destructor
0241     virtual ~_Accessor() = default;
0242     /// Default copy constructor.
0243     _Accessor( const _Accessor& ) = default;
0244     /// Check if column is present
0245     bool operator!() const { return m_ptr != 0; }
0246     /// Check if column is present
0247     operator const void*() const { return m_ptr; }
0248     /// Dereference operator
0249     TYP* operator->() { return m_ptr; }
0250     /// Dereference operator (CONST)
0251     const TYP* operator->() const { return m_ptr; }
0252     /// Access the range
0253     const Range<TYP>& range() const { return m_ptr->range(); }
0254   };
0255   // ==========================================================================
0256   /** Class acting as a smart pointer holding a N tuple _Item.
0257    */
0258   template <class TYP>
0259   class Item : virtual public _Accessor<_Item<TYP>> {
0260     typedef Item<TYP> _My;
0261 
0262   public:
0263     /// Standard Constructor
0264     Item() = default;
0265     /// Automatic type conversion
0266     operator const TYP() const { return this->m_ptr->get(); }
0267     /// Dereference operator for pointers
0268     TYP operator*() { return this->m_ptr->get(); }
0269     /// Dereference operator for pointers(CONST)
0270     const TYP operator*() const { return this->m_ptr->get(); }
0271     // Arithmetic operators defined on NTuple column entries
0272     Item& operator++() { return *this += TYP( 1 ); }
0273     Item& operator++( int ) { return *this += TYP( 1 ); }
0274     Item& operator--() { return *this -= TYP( 1 ); }
0275     Item& operator--( int ) { return *this -= TYP( 1 ); }
0276     /// Assignment operator
0277     Item& operator=( const TYP data ) {
0278       this->m_ptr->set( data );
0279       return *this;
0280     }
0281     /// Assignment operator
0282     template <class T>
0283     Item& operator=( const Item<T>& data ) {
0284       this->m_ptr->set( data->get() );
0285       return *this;
0286     }
0287     Item<TYP>& operator+=( const TYP data ) {
0288       this->m_ptr->set( this->m_ptr->get() + data );
0289       return *this;
0290     }
0291     Item<TYP>& operator-=( const TYP data ) {
0292       this->m_ptr->set( this->m_ptr->get() - data );
0293       return *this;
0294     }
0295     Item<TYP>& operator*=( const TYP data ) {
0296       this->m_ptr->set( this->m_ptr->get() * data );
0297       return *this;
0298     }
0299     Item<TYP>& operator/=( const TYP data ) {
0300       this->m_ptr->set( this->m_ptr->get() / data );
0301       return *this;
0302     }
0303   };
0304   // ==========================================================================
0305   /** Specialization acting as a smart pointer holding a N tuple _Item.
0306    */
0307   template <>
0308   class Item<bool> : virtual public _Accessor<_Item<bool>> {
0309     typedef Item<bool> _My;
0310 
0311   public:
0312     /// Standard Constructor
0313     Item() = default;
0314     /// Automatic type conversion
0315     operator bool() const { return this->m_ptr->get(); }
0316     /// Assignment operator
0317     Item& operator=( const bool data ) {
0318       this->m_ptr->set( data );
0319       return *this;
0320     }
0321     /// Assignment operator
0322     template <class T>
0323     Item& operator=( const Item<T>& data ) {
0324       this->m_ptr->set( data->get() );
0325       return *this;
0326     }
0327   };
0328   // ==========================================================================
0329   /** Class acting as a smart pointer holding a N tuple _Item.
0330    */
0331   template <class TYP>
0332   class Array : virtual public _Accessor<_Array<TYP>> {
0333   public:
0334     /// Standard Constructor
0335     Array() = default;
0336     /// Assignment operator
0337     template <class T>
0338     Array& operator=( const Array<T>& copy ) {
0339       *( this->m_ptr ) = *( copy.operator->() );
0340       return *this;
0341     }
0342     /// Array operator
0343     template <class T>
0344     TYP& operator[]( const T i ) {
0345       return this->m_ptr->data( i );
0346     }
0347     /// Array operator
0348     template <class T>
0349     const TYP& operator[]( const T i ) const {
0350       return this->m_ptr->data( i );
0351     }
0352 
0353     TYP* begin() { return this->m_ptr->begin(); }
0354     TYP* end() { return this->m_ptr->end(); }
0355   };
0356   // =========================================================================
0357   /** Class acting as a smart pointer holding a N tuple _Item.
0358    */
0359   template <class TYP>
0360   class Matrix : virtual public _Accessor<_Matrix<TYP>> {
0361   public:
0362     /// Standard Constructor
0363     Matrix() = default;
0364     /// Assignment operator
0365     template <class T>
0366     Matrix& operator=( const Matrix<T>& copy ) {
0367       *( this->m_ptr ) = *( copy.operator->() );
0368       return *this;
0369     }
0370     /// Array operator
0371     template <class T>
0372     TYP* operator[]( const T i ) {
0373       return this->m_ptr->column( i );
0374     }
0375     /// Array operator
0376     template <class T>
0377     const TYP* operator[]( const T i ) const {
0378       return this->m_ptr->column( i );
0379     }
0380   };
0381   // =========================================================================
0382   /** Abstract base class which allows the user to interact with the
0383       actual N tuple implementation.
0384       The class is abstract, because the template methods must
0385       be instantiated by the compiler at compile time. Otherwise the
0386       references would be unresolved.
0387   */
0388   class Tuple : public DataObject, virtual public INTuple {
0389 
0390   protected:
0391     /// Locate a _Column of data to the N tuple type safe
0392     template <class TYPE>
0393     StatusCode i_item( const std::string& name, _Item<TYPE>*& result ) const {
0394       try {
0395         result = dynamic_cast<_Item<TYPE>*>( i_find( name ) );
0396       } catch ( ... ) { result = nullptr; }
0397       return result ? StatusCode::SUCCESS : StatusCode::FAILURE;
0398     }
0399     /// Locate a _Column of data to the N tuple type unsafe for objects
0400     template <class TYPE>
0401     StatusCode i_item( const std::string& name, _Item<TYPE*>*& result ) const {
0402       try {
0403         _Item<void*>* p = dynamic_cast<_Item<void*>*>( i_find( name ) );
0404         result          = (_Item<TYPE*>*)p;
0405       } catch ( ... ) { result = nullptr; }
0406       return result ? StatusCode::SUCCESS : StatusCode::FAILURE;
0407     }
0408     /// Locate a _Column of data to the N tuple type safe
0409     StatusCode i_item( const std::string& name, _Item<IOpaqueAddress*>*& result ) const {
0410       try {
0411         result = dynamic_cast<_Item<IOpaqueAddress*>*>( i_find( name ) );
0412       } catch ( ... ) { result = nullptr; }
0413       return result ? StatusCode::SUCCESS : StatusCode::FAILURE;
0414     }
0415     /// Locate a _Array of data to the N tuple type safe
0416     template <class TYPE>
0417     StatusCode i_item( const std::string& name, _Array<TYPE>*& result ) const {
0418       try {
0419         if ( clID() == CLID_ColumnWiseTuple ) { result = dynamic_cast<_Array<TYPE>*>( i_find( name ) ); }
0420       } catch ( ... ) { result = nullptr; }
0421       return result ? StatusCode::SUCCESS : StatusCode::FAILURE;
0422     }
0423     /// Locate a _Matrix of data to the N tuple type safe
0424     template <class TYPE>
0425     StatusCode i_item( const std::string& name, _Matrix<TYPE>*& result ) const {
0426       try {
0427         if ( clID() == CLID_ColumnWiseTuple ) { result = dynamic_cast<_Matrix<TYPE>*>( i_find( name ) ); }
0428       } catch ( ... ) { result = nullptr; }
0429       return result ? StatusCode::SUCCESS : StatusCode::FAILURE;
0430     }
0431     /// Add a _Item of data to the N tuple
0432     template <class TYPE>
0433     StatusCode i_addItem( const std::string& name, long, const std::string&, TYPE low, TYPE high,
0434                           _Item<TYPE>*& result ) {
0435       if ( !i_find( name ) ) {
0436         TYPE nil;
0437         nil = 0;
0438         return add( result = _Item<TYPE>::create( this, name, typeid( TYPE ), low, high, nil ) );
0439       }
0440       return StatusCode::FAILURE;
0441     }
0442     /// Add a _Item of data to the N tuple
0443     template <class TYPE>
0444     StatusCode i_addItem( const std::string& name, long dim, const std::string& index, TYPE low, TYPE high,
0445                           _Array<TYPE>*& result ) {
0446       if ( !i_find( name ) && clID() == CLID_ColumnWiseTuple ) {
0447         return add( result = _Array<TYPE>::create( this, name, typeid( TYPE ), index, dim, low, high, TYPE( 0 ) ) );
0448       }
0449       return StatusCode::FAILURE;
0450     }
0451     /// Add a _Item of data to the N tuple
0452     template <class TYPE>
0453     StatusCode i_addItem( const std::string& name, long dim1, long dim2, const std::string& index, TYPE low, TYPE high,
0454                           _Matrix<TYPE>*& result ) {
0455       if ( !i_find( name ) && clID() == CLID_ColumnWiseTuple ) {
0456         return add( result =
0457                         _Matrix<TYPE>::create( this, name, typeid( TYPE ), index, dim1, dim2, low, high, TYPE( 0 ) ) );
0458       }
0459       return StatusCode::FAILURE;
0460     }
0461     template <class TYPE>
0462     StatusCode i_addObject( const std::string& name, _Item<TYPE*>*& result, const std::type_info& /* typ */ ) {
0463       if ( !i_find( name ) && clID() == CLID_ColumnWiseTuple ) {
0464         return add( result = (_Item<TYPE*>*)_Item<void*>::create( this, name, typeid( TYPE ), 0, 0, 0 ) );
0465       }
0466       return StatusCode::FAILURE;
0467     }
0468 
0469   public:
0470     /// Locate a scalar Item of data to the N tuple type safe
0471     template <class TYPE>
0472     StatusCode item( const std::string& name, Item<TYPE>& result ) {
0473       return i_item( name, result.m_ptr );
0474     }
0475     /// Locate a scalar Item of data to the N tuple type safe (CONST)
0476     template <class TYPE>
0477     StatusCode item( const std::string& name, const Item<TYPE>& result ) const {
0478       return i_item( name, result.m_ptr );
0479     }
0480     /// Locate a Array of data to the N tuple type safe
0481     template <class TYPE>
0482     StatusCode item( const std::string& name, Array<TYPE>& result ) {
0483       return i_item( name, result.m_ptr );
0484     }
0485     /// Locate a Array of data to the N tuple type safe (CONST)
0486     template <class TYPE>
0487     StatusCode item( const std::string& name, const Array<TYPE>& result ) const {
0488       return i_item( name, result.m_ptr );
0489     }
0490     /// Locate a Matrix of data to the N tuple type safe
0491     template <class TYPE>
0492     StatusCode item( const std::string& name, Matrix<TYPE>& result ) {
0493       return i_item( name, result.m_ptr );
0494     }
0495 
0496     /// Locate a Matrix of data to the N tuple type safe (CONST)
0497     template <class TYPE>
0498     StatusCode item( const std::string& name, const Matrix<TYPE>& result ) const {
0499       return i_item( name, result.m_ptr );
0500     }
0501 
0502     /** Add a scalar data item a N tuple.
0503 
0504         Use this entry point to connect any allowed scalar data type
0505         to an N-tuple. The value filled, may have any range.
0506         Do NOT use this entry point to specify an index
0507         column in a column wise N-tuple.
0508 
0509         @param  name       Name of the column in the column wise N-tuple
0510         @param  itm        Reference to the Item<TYPE> datatype, which
0511                            should be connected to the N-tuple.
0512 
0513         @return StatusCode indicating success or failure.
0514     */
0515     template <class TYPE>
0516     StatusCode addItem( const std::string& name, Item<TYPE>& itm ) {
0517       typedef Range<TYPE> _R;
0518       return i_addItem( name, 1, "", _R::min(), _R::max(), itm.m_ptr );
0519     }
0520 
0521     /** Add an simple object item to an N tuple.
0522 
0523         @param  name       Name of the column in the column wise N-tuple
0524         @param  itm        Reference to the Item<TYPE> datatype, which
0525                            should be connected to the N-tuple.
0526 
0527         @return StatusCode indicating success or failure.
0528     */
0529     template <class TYPE>
0530     StatusCode addItem( const std::string& name, Item<TYPE*>& itm ) {
0531       return i_addObject( name, itm.m_ptr, typeid( TYPE ) );
0532     }
0533 
0534     /** Add an address object item to an N tuple: specialized call
0535 
0536         @param  name       Name of the column in the column wise N-tuple
0537         @param  itm        Reference to the Item<TYPE> datatype, which
0538                            should be connected to the N-tuple.
0539 
0540         @return StatusCode indicating success or failure.
0541     */
0542     StatusCode addItem( const std::string& name, Item<IOpaqueAddress*>& itm ) {
0543       typedef Range<IOpaqueAddress*> _R;
0544       return i_addItem( name, 1, "", _R::min(), _R::max(), itm.m_ptr );
0545     }
0546 
0547     /** Add a scalar data item a N tuple with a range.
0548 
0549         Typically this entry point is used to specuify
0550         index column with a fixed data range for a column wise N-tuple.
0551 
0552         Note: Checks on the data range are not implemented!
0553 
0554         @param  name       Name of the column in the column wise N-tuple
0555         @param  itm        Reference to the Item<TYPE> datatype, which
0556                            should be connected to the N-tuple.
0557         @param  low        Lower edge of client data values allowed
0558                            to fill into the N-tuple array.
0559         @param  high       Upper edge of client data values allowed
0560                            to fill into the N-tuple array.
0561 
0562         @return StatusCode indicating success or failure.
0563     */
0564     template <class TYPE, class RANGE>
0565     StatusCode addItem( const std::string& name, Item<TYPE>& itm, const RANGE low, const RANGE high ) {
0566       return i_addItem( name, 1, "", TYPE( low ), TYPE( high ), itm.m_ptr );
0567     }
0568 
0569     /** Add an fixed-size Array of data to a column wise N tuple.
0570 
0571         You should use this entry point to add a FIXED SIZE ARRAY
0572         to a column wise N-tuple. The dimension of the array must
0573         be specified.
0574 
0575         @param  name       Name of the column in the column wise N-tuple
0576         @param  dim        Length of the array to be added to the N-tuple
0577         @param  array      Reference to the Array<TYPE> datatype, which
0578                            should be connected to the N-tuple.
0579 
0580         @return StatusCode indicating success or failure.
0581     */
0582     template <class TYPE>
0583     StatusCode addItem( const std::string& name, long dim, Array<TYPE>& array ) {
0584       return i_addItem( name, dim, "", Range<TYPE>::min(), Range<TYPE>::max(), array.m_ptr );
0585     }
0586 
0587     /** Add an fixed-size Array of data to a column wise N tuple with a range.
0588 
0589         You should use this entry point to add a FIXED SIZE ARRAY
0590         to a column wise N-tuple. The dimension of the array must
0591         be specified.
0592 
0593         Note: Checks on the data range are not implemented!
0594 
0595         @param  name       Name of the column in the column wise N-tuple
0596         @param  dim        Length of the array to be added to the N-tuple
0597         @param  array      Reference to the Array<TYPE> datatype, which
0598                            should be connected to the N-tuple.
0599         @param  low        Lower edge of client data values allowed
0600                            to fill into the N-tuple array.
0601         @param  high       Upper edge of client data values allowed
0602                            to fill into the N-tuple array.
0603 
0604         @return StatusCode indicating success or failure.
0605     */
0606     template <class TYPE, class RANGE>
0607     StatusCode addItem( const std::string& name, long dim, Array<TYPE>& array, const RANGE low, const RANGE high ) {
0608       return i_addItem( name, dim, "", TYPE( low ), TYPE( high ), array.m_ptr );
0609     }
0610 
0611     /** Add an indexed Array of data to a column wise N tuple with a range.
0612 
0613         You should use this entry point to add a VARIABLE SIZE ARRAY
0614         to a column wise N-tuple. The dimension of the array is
0615         unspecified and depends on the data range, which you allowed
0616         for the index column.
0617 
0618         Hence you have to be careful on the allowed data range of the
0619         index column, because the index column determines the total
0620         allocated memory.
0621 
0622         Note: Checks on the data range are not implemented!
0623 
0624         Note: Due to confusion with the entry point to connecting
0625               a fixed size array the use of this function is
0626                   *** DEPRECATED ***
0627               please use addIndexedItem(...) instead.
0628 
0629         @param  name       Name of the column in the column wise N-tuple
0630         @param  index      Reference to the scalar index column used to
0631                            determine the size of the array.
0632         @param  array      Reference to the Array<TYPE> datatype, which
0633                            should be connected to the N-tuple.
0634         @param  low        Lower edge of client data values allowed
0635                            to fill into the N-tuple array.
0636         @param  high       Upper edge of client data values allowed
0637                            to fill into the N-tuple array.
0638 
0639         @return StatusCode indicating success or failure.
0640     */
0641     template <class TYPE, class INDEX, class RANGE>
0642     StatusCode addItem( const std::string& name, Item<INDEX>& index, Array<TYPE>& array, const RANGE low,
0643                         const RANGE high ) {
0644       return i_addItem( name, index->range().distance(), index->name(), TYPE( low ), TYPE( high ), array.m_ptr );
0645     }
0646 
0647     /** Add an indexed Array of data to a column wise N tuple with a range.
0648 
0649         You should use this entry point to add a VARIABLE SIZE ARRAY
0650         to a column wise N-tuple. The dimension of the array is
0651         unspecified and depends on the data range, which you allowed
0652         for the index column.
0653 
0654         Hence you have to be careful on the allowed data range of the
0655         index column, because the index column determines the total
0656         allocated memory.
0657 
0658         Note: Checks on the data range are not implemented!
0659 
0660         @param  name       Name of the column in the column wise N-tuple
0661         @param  index      Reference to the scalar index column used to
0662                            determine the size of the array.
0663         @param  array      Reference to the Array<TYPE> datatype, which
0664                            should be connected to the N-tuple.
0665         @param  low        Lower edge of client data values allowed
0666                            to fill into the N-tuple array.
0667         @param  high       Upper edge of client data values allowed
0668                            to fill into the N-tuple array.
0669 
0670         @return StatusCode indicating success or failure.
0671     */
0672     template <class TYPE, class INDEX, class RANGE>
0673     StatusCode addIndexedItem( const std::string& name, Item<INDEX>& index, Array<TYPE>& array, const RANGE low,
0674                                const RANGE high ) {
0675       return i_addItem( name, index->range().distance(), index->name(), TYPE( low ), TYPE( high ), array.m_ptr );
0676     }
0677 
0678     /** Add an indexed Array of data to a column wise N tuple.
0679 
0680         You should use this entry point to add a VARIABLE SIZE ARRAY
0681         to a column wise N-tuple. The dimension of the array is
0682         unspecified and depends on the data range, which you allowed
0683         for the index column.
0684 
0685         Hence, you have to be careful on the allowed data range of the
0686         index column, because the index column determines the total
0687         allocated memory.
0688 
0689         Note: Due to confusion with the entry point to connecting
0690               a fixed size array the use of this member function is
0691                   *** DEPRECATED ***
0692               please use addIndexedItem(...) instead.
0693 
0694         @param  name       Name of the column in the column wise N-tuple
0695         @param  index      Reference to the scalar index column used to
0696                            determine the size of the array.
0697         @param  array      Reference to the Array<TYPE> datatype, which
0698                            should be connected to the N-tuple.
0699 
0700         @return StatusCode indicating success or failure.
0701     */
0702     template <class TYPE, class INDEX>
0703     StatusCode addItem( const std::string& name, Item<INDEX>& index, Array<TYPE>& array ) {
0704       return i_addItem( name, index->range().distance(), index->name(), Range<TYPE>::min(), Range<TYPE>::max(),
0705                         array.m_ptr );
0706     }
0707 
0708     /** Add an indexed Array of data to a column wise N tuple.
0709 
0710         You should use this entry point to add a VARIABLE SIZE ARRAY
0711         to a column wise N-tuple. The dimension of the array is
0712         unspecified and depends on the data range, which you allowed
0713         for the index column.
0714 
0715         Hence, you have to be careful on the allowed data range of the
0716         index column, because the index column determines the total
0717         allocated memory.
0718 
0719         @param  name       Name of the column in the column wise N-tuple
0720         @param  index      Reference to the scalar index column used to
0721                            determine the size of the array.
0722         @param  array      Reference to the Array<TYPE> datatype, which
0723                            should be connected to the N-tuple.
0724 
0725         @return StatusCode indicating success or failure.
0726     */
0727     template <class TYPE, class INDEX>
0728     StatusCode addIndexedItem( const std::string& name, Item<INDEX>& index, Array<TYPE>& array ) {
0729       return i_addItem( name, index->range().distance(), index->name(), Range<TYPE>::min(), Range<TYPE>::max(),
0730                         array.m_ptr );
0731     }
0732 
0733     /** Add an fixed size Matrix of data to a column wise N tuple.
0734 
0735         You should use this entry point to add a FIXED SIZE MATRIX
0736         to a column wise N-tuple. The dimension of the matrix must
0737         be specified.
0738 
0739         Attention: Do not confuse with entry point to add a
0740                    VARIABLE SIZE MATRIX!
0741 
0742         @param  name       Name of the column in the column wise N-tuple
0743         @param  cols       Number of data columns in the Matrix.
0744         @param  rows       Number of data rows in the Matrix.
0745         @param  matrix     Reference to the Matrix<TYPE> datatype, which
0746                            should be connected to the N-tuple.
0747 
0748         @return StatusCode indicating success or failure.
0749     */
0750     template <class TYPE>
0751     StatusCode addItem( const std::string& name, long cols, long rows, Matrix<TYPE>& matrix ) {
0752       return i_addItem( name, cols, rows, "", Range<TYPE>::min(), Range<TYPE>::max(), matrix.m_ptr );
0753     }
0754 
0755     /** Add an fixed size Matrix of data to a column wise N tuple.
0756 
0757         You should use this entry point to add a FIXED SIZE MATRIX
0758         to a column wise N-tuple. The dimension of the matrix must
0759         be specified.
0760 
0761         Note: Checks on the data range are not implemented!
0762         Attention: Do not confuse with entry point to add a
0763                    VARIABLE SIZE MATRIX!
0764 
0765         @param  name       Name of the column in the column wise N-tuple
0766         @param  cols       Number of data columns in the Matrix.
0767         @param  rows       Number of data rows in the Matrix.
0768         @param  matrix     Reference to the Matrix<TYPE> datatype, which
0769                            should be connected to the N-tuple.
0770         @param  low        Lower edge of client data values allowed
0771                            to fill into the N-tuple matrix.
0772         @param  high       Upper edge of client data values allowed
0773                            to fill into the N-tuple matrix.
0774 
0775         @return StatusCode indicating success or failure.
0776     */
0777     template <class TYPE, class RANGE>
0778     StatusCode addItem( const std::string& name, long cols, long rows, Matrix<TYPE>& result, const RANGE low,
0779                         const RANGE high ) {
0780       return i_addItem( name, cols, rows, "", TYPE( low ), TYPE( high ), result.m_ptr );
0781     }
0782 
0783     /** Add an variable size Matrix of data to a column wise N tuple.
0784 
0785         You should use this entry point to add a VARIABLE SIZE MATRIX
0786         to a column wise N-tuple. The number of columns of the
0787         matrix is given by the allowed data range of the index column.
0788         The number of rows however, which are allowed in the matrix
0789         must be specified explicitly and cannot be variable.
0790 
0791         Attention: Do not confuse with entry point to add a
0792                    FIXED SIZE MATRIX.
0793 
0794         Note: Due to confusion with the entry point to connecting
0795               a fixed size matrix the use of this member function is
0796                   *** DEPRECATED ***
0797               please use addIndexedItem(...) instead.
0798 
0799         @param  name       Name of the column in the column wise N-tuple
0800         @param  index      Reference to the scalar index column used to
0801                            determine the number of data columns in the matrix
0802         @param  matrix     Reference to the Matrix<TYPE> datatype, which
0803                            should be connected to the N-tuple.
0804         @param  rows       Number of data rows in the Matrix.
0805 
0806         @return StatusCode indicating success or failure.
0807     */
0808     template <class TYPE, class INDEX>
0809     StatusCode addItem( const std::string& name, Item<INDEX>& index, Matrix<TYPE>& matrix, long rows ) {
0810       return i_addItem( name, index->range().distance(), rows, index->name(), Range<TYPE>::min(), Range<TYPE>::max(),
0811                         matrix.m_ptr );
0812     }
0813 
0814     /** Add an variable size Matrix of data to a column wise N tuple.
0815 
0816         You should use this entry point to add a VARIABLE SIZE MATRIX
0817         to a column wise N-tuple. The number of columns of the
0818         matrix is given by the allowed data range of the index column.
0819         The number of rows however, which are allowed in the matrix
0820         must be specified explicitly and cannot be variable.
0821 
0822         Attention: Do not confuse with entry point to add a
0823                    FIXED SIZE MATRIX.
0824 
0825         @param  name       Name of the column in the column wise N-tuple
0826         @param  index      Reference to the scalar index column used to
0827                            determine the number of data columns in the matrix
0828         @param  rows       Number of data rows in the Matrix.
0829         @param  matrix     Reference to the Matrix<TYPE> datatype, which
0830                            should be connected to the N-tuple.
0831 
0832         @return StatusCode indicating success or failure.
0833     */
0834     template <class TYPE, class INDEX>
0835     StatusCode addIndexedItem( const std::string& name, Item<INDEX>& col_index, long rows, Matrix<TYPE>& matrix ) {
0836       return i_addItem( name, col_index->range().distance(), rows, col_index->name(), Range<TYPE>::min(),
0837                         Range<TYPE>::max(), matrix.m_ptr );
0838     }
0839 
0840     /** Add an variable size Matrix of data to a column wise N tuple.
0841 
0842         You should use this entry point to add a VARIABLE SIZE MATRIX
0843         to a column wise N-tuple. The number of columns of the
0844         matrix is given by the allowed data range of the index column.
0845         The number of rows however, which are allowed in the matrix
0846         must be specified explicitly and cannot be variable. Also the
0847         range of allowed data values to be filled into the data area
0848         of the matrix can be specified.
0849 
0850         Note: Checks on the data range are not implemented!
0851         Attention: Do not confuse with entry point to add a
0852                    FIXED SIZE MATRIX.
0853 
0854         Note: Due to confusion with the entry point to connecting
0855               a fixed size matrix the use of this member function is
0856                   *** DEPRECATED ***
0857               please use addIndexedItem(...) instead.
0858 
0859         @param  name       Name of the column in the column wise N-tuple
0860         @param  index      Reference to the scalar index column used to
0861                            determine the number of data columns in the matrix
0862         @param  matrix     Reference to the Matrix<TYPE> datatype, which
0863                            should be connected to the N-tuple.
0864         @param  rows       Number of data rows in the Matrix.
0865         @param  low        Lower edge of client data values allowed
0866                            to fill into the N-tuple matrix.
0867         @param  high       Upper edge of client data values allowed
0868                            to fill into the N-tuple matrix.
0869 
0870         @return StatusCode indicating success or failure.
0871     */
0872     template <class TYPE, class INDEX, class RANGE>
0873     StatusCode addItem( const std::string& name, Item<INDEX>& index, Matrix<TYPE>& matrix, long rows, const RANGE low,
0874                         const RANGE high ) {
0875       return i_addItem( name, index->range().distance(), rows, index->name(), TYPE( low ), TYPE( high ), matrix.m_ptr );
0876     }
0877 
0878     /** Add an variable size Matrix of data to a column wise N tuple.
0879 
0880         You should use this entry point to add a VARIABLE SIZE MATRIX
0881         to a column wise N-tuple. The number of columns of the
0882         matrix is given by the allowed data range of the index column.
0883         The number of rows however, which are allowed in the matrix
0884         must be specified explicitly and cannot be variable. Also the
0885         range of allowed data values to be filled into the data area
0886         of the matrix can be specified.
0887 
0888         Note: Checks on the data range are not implemented!
0889         Attention: Do not confuse with entry point to add a
0890                    FIXED SIZE MATRIX.
0891 
0892         @param  name       Name of the column in the column wise N-tuple
0893         @param  index      Reference to the scalar index column used to
0894                            determine the number of data columns in the matrix
0895         @param  rows       Number of data rows in the Matrix.
0896         @param  matrix     Reference to the Matrix<TYPE> datatype, which
0897                            should be connected to the N-tuple.
0898         @param  low        Lower edge of client data values allowed
0899                            to fill into the N-tuple matrix.
0900         @param  high       Upper edge of client data values allowed
0901                            to fill into the N-tuple matrix.
0902 
0903         @return StatusCode indicating success or failure.
0904     */
0905     template <class TYPE, class INDEX, class RANGE>
0906     StatusCode addIndexedItem( const std::string& name, Item<INDEX>& index, long rows, Matrix<TYPE>& matrix,
0907                                const RANGE low, const RANGE high ) {
0908       return i_addItem( name, index->range().distance(), rows, index->name(), TYPE( low ), TYPE( high ), matrix.m_ptr );
0909     }
0910   };
0911 
0912   /** Small class representing an N tuple directory in the transient store
0913    */
0914   struct Directory : DataObject {
0915     /// class ID of the object
0916     static const CLID& classID() { return CLID_NTupleDirectory; }
0917     /// class ID of the object
0918     const CLID& clID() const override { return classID(); }
0919   };
0920 
0921   /** Small class representing an N tuple file in the transient store
0922    */
0923   class File : public Directory {
0924   protected:
0925     /// Physical file name
0926     std::string m_name;
0927     /// Logical file name
0928     std::string m_logName;
0929     /// Access type
0930     long m_type = 0;
0931     /// Flag to indicate wether the file was opened already
0932     bool m_isOpen = false;
0933 
0934   public:
0935     File() = default;
0936     /// Standard constructor
0937     File( long type, std::string name, std::string logName )
0938         : m_name( std::move( name ) ), m_logName( std::move( logName ) ), m_type( type ) {}
0939 
0940     /// class ID of the object
0941     static const CLID& classID() { return CLID_NTupleFile; }
0942     /// class ID of the object
0943     const CLID& clID() const override { return classID(); }
0944     /// Set access type
0945     void setType( const long typ ) { m_type = typ; }
0946     /// Return access type
0947     long type() const { return m_type; }
0948     /// Retrun physical file name
0949     const std::string& name() const { return m_name; }
0950     /// Set access type
0951     void setName( std::string nam ) { m_name = std::move( nam ); }
0952     //// Return logical file name
0953     const std::string& logicalName() const { return m_logName; }
0954     //// Return logical file name
0955     void setLogicalName( std::string l ) { m_logName = std::move( l ); }
0956     /// Set "open" flag
0957     void setOpen( bool flag ) { m_isOpen = flag; }
0958     /// Access "open" flag
0959     bool isOpen() const { return m_isOpen; }
0960   };
0961   // =========================================================================
0962   // inhibit certain types by defining specialized templates which do not
0963   // allow for construction.
0964   template <>
0965   class Array<IOpaqueAddress*> {
0966     Array() = delete;
0967 
0968   public:
0969     virtual ~Array()     = default;
0970     virtual void dummy() = 0;
0971   };
0972   template <>
0973   class Matrix<IOpaqueAddress*> {
0974     Matrix() = delete;
0975 
0976   public:
0977     virtual ~Matrix()    = default;
0978     virtual void dummy() = 0;
0979   };
0980 // =========================================================================
0981 #ifndef ALLOW_ALL_TYPES
0982 #else
0983   typedef Item<bool>               BoolItem;
0984   typedef Item<char>               CharItem;
0985   typedef Item<unsigned char>      UCharItem;
0986   typedef Item<short>              ShortItem;
0987   typedef Item<unsigned short>     UShortItem;
0988   typedef Item<long>               LongItem;
0989   typedef Item<long long>          LongLongItem;
0990   typedef Item<unsigned long>      ULongItem;
0991   typedef Item<unsigned long long> ULongLongItem;
0992   typedef Item<int>                IntItem;
0993   typedef Item<unsigned int>       UIntItem;
0994   typedef Item<float>              FloatItem;
0995   typedef Item<double>             DoubleItem;
0996   typedef Array<bool>              BoolArray;
0997   typedef Array<char>              CharArray;
0998   typedef Array<unsigned char>     UCharArray;
0999   typedef Array<short>             ShortArray;
1000   typedef Array<unsigned short>    UShortArray;
1001   typedef Array<long>              LongArray;
1002   typedef Array<unsigned long>     ULongArray;
1003   typedef Array<int>               IntArray;
1004   typedef Array<unsigned int>      UIntArray;
1005   typedef Array<float>             FloatArray;
1006   typedef Array<double>            DoubleArray;
1007   typedef Matrix<bool>             BoolMatrix;
1008   typedef Matrix<char>             CharMatrix;
1009   typedef Matrix<unsigned char>    UCharMatrix;
1010   typedef Matrix<short>            ShortMatrix;
1011   typedef Matrix<unsigned short>   UShortMatrix;
1012   typedef Matrix<long>             LongMatrix;
1013   typedef Matrix<unsigned long>    ULongMatrix;
1014   typedef Matrix<int>              IntMatrix;
1015   typedef Matrix<unsigned int>     UIntMatrix;
1016   typedef Matrix<float>            FloatMatrix;
1017   typedef Matrix<double>           DoubleMatrix;
1018 #endif
1019 
1020   template <class T>
1021   inline std::ostream& operator<<( std::ostream& s, const Item<T>& obj ) {
1022     return s << T( obj );
1023   }
1024 } // end of namespace NTuple
1025 
1026 // Useful:
1027 typedef SmartDataPtr<NTuple::Tuple>     NTuplePtr;
1028 typedef SmartDataPtr<NTuple::Directory> NTupleDirPtr;
1029 typedef SmartDataPtr<NTuple::File>      NTupleFilePtr;
1030 
1031 #endif // GAUDIKERNEL_NTUPLE_H