00001
00002 #ifndef GAUDIKERNEL_NTUPLE_H
00003 #define GAUDIKERNEL_NTUPLE_H
00004
00005
00006 #include <string>
00007 #include <climits>
00008 #include <cfloat>
00009
00010
00011 #include "GaudiKernel/DataTypeInfo.h"
00012 #include "GaudiKernel/DataObject.h"
00013 #include "GaudiKernel/INTuple.h"
00014
00015
00016 class IOpaqueAddress;
00017 class NTupleFile;
00018 class NTupleDirectory;
00019 template <class TYPE> class SmartDataPtr;
00020
00021
00022 static const CLID CLID_NTupleFile = 40;
00023 static const CLID CLID_NTupleDirectory = 41;
00024 static const CLID CLID_RowWiseTuple = 42;
00025 static const CLID CLID_ColumnWiseTuple = 43;
00026
00027
00028
00035 namespace NTuple {
00036
00037 template <class TYP> class Range;
00038 template <class TYP> class _Data;
00039 template <class TYP> class _Item;
00040 template <class TYP> class _Array;
00041 template <class TYP> class _Matrix;
00042 template <class TYP> class _Accessor;
00043 template <class TYP> class Item;
00044 template <class TYP> class Array;
00045 template <class TYP> class Matrix;
00046
00048 template <class TYP> class Range {
00050 TYP m_lower;
00052 TYP m_upper;
00053 public:
00055 Range(const TYP low, const TYP upper) : m_lower(low), m_upper(upper) {
00056 }
00058 Range(const Range<TYP>& copy) : m_lower(copy.m_lower), m_upper(copy.m_upper) {
00059 }
00061 Range& operator=(const Range<TYP>& copy) {
00062 m_lower = copy.m_lower;
00063 m_upper = copy.m_upper;
00064 return *this;
00065 }
00067 virtual ~Range() { }
00069 const TYP lower() const { return m_lower; }
00071 const TYP upper() const { return m_upper; }
00073 const TYP distance() const { return m_upper-m_lower; }
00075 static const TYP min();
00077 static const TYP max();
00078 };
00079 template <> class Range<bool> {
00080 public:
00082 Range(const bool , const bool ) {
00083 }
00085 Range(const Range<bool>& ) {
00086 }
00088 virtual ~Range() { }
00090 const bool lower() const { return false; }
00092 const bool upper() const { return true; }
00094 const bool distance() const { return true; }
00096 static const bool min() { return false; }
00098 static const bool max() { return true; }
00099 };
00101 #define DECL_MINMAX(true_typ,minimum,maximum) \
00102 template <> inline const true_typ Range<true_typ>::min() { \
00103 return minimum; \
00104 } \
00105 template <> inline const true_typ Range<true_typ>::max() { \
00106 return maximum; \
00107 }
00108 template <> inline const float Range<float>::min() {
00109 return -FLT_MAX;
00110 }
00111 template <> inline const float Range<float>::max() {
00112 return FLT_MAX;
00113 }
00114 template <> inline const double Range<double>::min() {
00115 return -DBL_MAX;
00116 }
00117 template <> inline const double Range<double>::max() {
00118 return DBL_MAX;
00119 }
00120 template <> inline const unsigned char Range<unsigned char>::min() {
00121 return 0;
00122 }
00123 template <> inline const unsigned char Range<unsigned char>::max() {
00124 return UCHAR_MAX;
00125 }
00126 template <> inline const char Range<char>::min() {
00127 return CHAR_MIN;
00128 }
00129 template <> inline const char Range<char>::max() {
00130 return CHAR_MAX;
00131 }
00132 template <> inline const unsigned short Range<unsigned short>::min() {
00133 return 0;
00134 }
00135 template <> inline const unsigned short Range<unsigned short>::max() {
00136 return USHRT_MAX;
00137 }
00138 template <> inline const short Range<short>::min() {
00139 return SHRT_MIN;
00140 }
00141 template <> inline const short Range<short>::max() {
00142 return SHRT_MAX;
00143 }
00144 template <> inline const unsigned int Range<unsigned int>::min() {
00145 return 0;
00146 }
00147 template <> inline const unsigned int Range<unsigned int>::max() {
00148 return UINT_MAX;
00149 }
00150 template <> inline const int Range<int>::min() {
00151 return INT_MIN;
00152 }
00153 template <> inline const int Range<int>::max() {
00154 return USHRT_MAX;
00155 }
00156 template <> inline const unsigned long Range<unsigned long>::min() {
00157 return 0;
00158 }
00159 template <> inline const unsigned long Range<unsigned long>::max() {
00160 return ULONG_MAX;
00161 }
00162 template <> inline const long Range<long>::min() {
00163 return LONG_MIN;
00164 }
00165 template <> inline const long Range<long>::max() {
00166 return LONG_MAX;
00167 }
00168 template <> inline IOpaqueAddress* const Range<IOpaqueAddress* >::min() {
00169 return (IOpaqueAddress*)0x0;
00170 }
00171 template <> inline IOpaqueAddress* const Range<IOpaqueAddress* >::max() {
00172 return (IOpaqueAddress*)0xffffffff;
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00191 template <class TYP> class _Data : virtual public INTupleItem {
00192 protected:
00194 TYP* m_buffer;
00195 public:
00197 typedef Range<TYP> ItemRange;
00199 virtual void setDefault(const TYP d) = 0;
00201 virtual const ItemRange& range() const = 0;
00202 };
00203
00206 template <class TYP> class _Item : virtual public _Data<TYP> {
00207 public:
00209 static _Item* create(INTuple* tup, const std::string& name, TYP min, TYP max, TYP def);
00211 void set(const TYP& item) { *m_buffer = item; }
00213 virtual const TYP get() const { return *m_buffer; }
00214 };
00215
00218 template <class TYP> class _Array : virtual public _Data<TYP> {
00219 public:
00221 static _Array* create(INTuple* tup, const std::string& name, const std::string& index, long len, TYP min, TYP max, TYP def);
00223 const TYP& data(long i) const { return *(m_buffer + i); }
00225 TYP& data(long i) { return *(m_buffer + i); }
00226 };
00227
00230 template <class TYP> class _Matrix : virtual public _Data<TYP> {
00231 protected:
00233 long m_rows;
00234 public:
00236 static _Matrix* create(INTuple* tup, const std::string& name, const std::string& index, long ncol, long nrow, TYP min, TYP max, TYP def);
00238 TYP* column(long i) { return (m_buffer + i*m_rows); }
00240 const TYP* column(long i) const { return (m_buffer + i*m_rows); }
00241 };
00242
00245 template <class TYP> class _Accessor {
00246 friend class Tuple;
00247 protected:
00249 mutable TYP* m_ptr;
00250 public:
00252 _Accessor() : m_ptr(0) { }
00254 virtual ~_Accessor() { }
00256 bool operator !() const { return m_ptr != 0; }
00258 operator const void*() const { return m_ptr; }
00260 TYP* operator->() { return m_ptr; }
00262 const TYP* operator->() const { return m_ptr; }
00264 const Range<TYP>& range() const { return m_ptr->range(); }
00265 };
00266
00269 template <class TYP> class Item : virtual public _Accessor< _Item<TYP> > {
00270 typedef Item<TYP> _My;
00271 public:
00273 Item() { }
00275 operator const TYP () const { return m_ptr->get(); }
00276
00277 Item& operator ++ () { return *this += TYP(1); }
00278 Item& operator ++ (int) { return *this += TYP(1); }
00279 Item& operator -- () { return *this -= TYP(1); }
00280 Item& operator -- (int) { return *this -= TYP(1); }
00282 Item& operator=(const TYP data) {
00283 m_ptr->set( data );
00284 return *this;
00285 }
00286 Item<TYP>& operator += (const TYP data) {
00287 m_ptr->set ( m_ptr->get() + data );
00288 return *this;
00289 }
00290 Item<TYP>& operator -= (const TYP data) {
00291 m_ptr->set ( m_ptr->get() - data );
00292 return *this;
00293 }
00294 Item<TYP>& operator *= (const TYP data) {
00295 m_ptr->set ( m_ptr->get() * data );
00296 return *this;
00297 }
00298 Item<TYP>& operator /= (const TYP data) {
00299 m_ptr->set ( m_ptr->get() / data );
00300 return *this;
00301 }
00302 };
00303
00306 template <class TYP> class Array : virtual public _Accessor < _Array<TYP> > {
00307 public:
00309 Array() { }
00311 template <class T>
00312 TYP& operator[] (const T i) { return m_ptr->data(i); }
00314 template <class T>
00315 const TYP& operator[] (const T i) const { return m_ptr->data(i); }
00316 };
00317
00320 template <class TYP> class Matrix : virtual public _Accessor< _Matrix<TYP> > {
00321 public:
00323 Matrix() { }
00325 template <class T>
00326 TYP* operator[] (const T i) { return m_ptr->column(i); }
00328 template <class T>
00329 const TYP* operator[] (const T i) const { return m_ptr->column(i); }
00330 };
00331
00338 class Tuple : public DataObject, virtual public INTuple {
00339
00340 protected:
00342 template <class TYPE> StatusCode i_item(const std::string& name, _Item<TYPE>*& result) const {
00343 try {
00344 result = dynamic_cast< _Item<TYPE>* > (i_find(name));
00345 }
00346 catch (...) {
00347 result = 0;
00348 }
00349 return (0==result) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00350 }
00352 template <class TYPE> StatusCode i_item(const std::string& name, _Array<TYPE>*& result) const {
00353 try {
00354 if ( clID() == CLID_ColumnWiseTuple ) {
00355 result = dynamic_cast< _Array<TYPE>* > (i_find(name));
00356 }
00357 }
00358 catch (...) {
00359 result = 0;
00360 }
00361 return (0==result) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00362 }
00364 template <class TYPE> StatusCode i_item(const std::string& name, _Matrix<TYPE>*& result) const {
00365 try {
00366 if ( clID() == CLID_ColumnWiseTuple ) {
00367 result = dynamic_cast< _Matrix<TYPE>* > (i_find(name));
00368 }
00369 }
00370 catch (...) {
00371 result = 0;
00372 }
00373 return (0==result) ? StatusCode::FAILURE : StatusCode::SUCCESS;
00374 }
00376 template <class TYPE>
00377 StatusCode i_addItem(const std::string& name, long, const std::string&, TYPE low, TYPE high, _Item<TYPE>*& result) {
00378 if ( !i_find(name) ) {
00379 TYPE nil;
00380 nil = 0;
00381 return add( result = _Item<TYPE>::create(this, name, low, high, nil) );
00382 }
00383 return StatusCode::FAILURE;
00384 }
00386 template <class TYPE>
00387 StatusCode i_addItem(const std::string& name, long dim, const std::string& index, TYPE low, TYPE high, _Array<TYPE>*& result) {
00388 if ( !i_find(name) && clID() == CLID_ColumnWiseTuple ) {
00389 return add( result = _Array<TYPE>::create(this, name, index, dim, low, high, TYPE(0)) );
00390 }
00391 return StatusCode::FAILURE;
00392 }
00394 template <class TYPE>
00395 StatusCode i_addItem(const std::string& name, long dim1, long dim2, const std::string& index, TYPE low, TYPE high, _Matrix<TYPE>*& result) {
00396 if ( !i_find(name) && clID() == CLID_ColumnWiseTuple ) {
00397 return add( result = _Matrix<TYPE>::create(this, name, index, dim1, dim2, low, high, TYPE(0)) );
00398 }
00399 return StatusCode::FAILURE;
00400 }
00401 public:
00403 virtual ~Tuple() {
00404 }
00406 template <class TYPE> StatusCode item(const std::string& name, Item<TYPE>& result) {
00407 return i_item(name, result.m_ptr);
00408 }
00410 template <class TYPE> StatusCode item(const std::string& name, const Item<TYPE>& result) const {
00411 return i_item(name, result.m_ptr);
00412 }
00414 template <class TYPE> StatusCode item(const std::string& name, Array<TYPE>& result) {
00415 return i_item(name, result.m_ptr);
00416 }
00418 template <class TYPE> StatusCode item(const std::string& name, const Array<TYPE>& result) const {
00419 return i_item(name, result.m_ptr);
00420 }
00422 template <class TYPE> StatusCode item(const std::string& name, Matrix<TYPE>& result) {
00423 return i_item(name, result.m_ptr);
00424 }
00426 template <class TYPE> StatusCode item(const std::string& name, const Matrix<TYPE>& result) const {
00427 return i_item(name, result.m_ptr);
00428 }
00430 template <class TYPE> StatusCode addItem(const std::string& name, Item<TYPE>& result) {
00431 return i_addItem(name, 1, "", Range<TYPE>::min(), Range<TYPE>::max(), result.m_ptr);
00432 }
00434 template <class TYPE, class RANGE> StatusCode addItem(const std::string& name, Item<TYPE>& result, const RANGE low, const RANGE high) {
00435 return i_addItem(name, 1, "", TYPE(low), TYPE(high), result.m_ptr);
00436 }
00438 template <class TYPE> StatusCode addItem(const std::string& name, long dim, Array<TYPE>& result) {
00439 return i_addItem(name, dim, "", Range<TYPE>::min(), Range<TYPE>::max(), result.m_ptr);
00440 }
00442 template <class TYPE, class RANGE> StatusCode addItem(const std::string& name, long dim, Array<TYPE>& result, const RANGE low, const RANGE high) {
00443 return i_addItem(name, dim, "", TYPE(low), TYPE(high), result.m_ptr);
00444 }
00448 template <class TYPE, class INDEX, class RANGE> StatusCode addItem(const std::string& name,
00449 Item<INDEX>& index,Array<TYPE>& result, const RANGE low, const RANGE high) {
00450 return i_addItem(name, index->range().distance(), index->name(), TYPE(low), TYPE(high), result.m_ptr);
00451 }
00453 template <class TYPE, class INDEX> StatusCode addItem(const std::string& name, Item<INDEX>& index, Array<TYPE>& result) {
00454 return i_addItem(name, index->range().distance(), index->name(), Range<TYPE>::min(), Range<TYPE>::max(), result.m_ptr);
00455 }
00457 template <class TYPE> StatusCode addItem(const std::string& name, long dim, long rows, Matrix<TYPE>& result) {
00458 return i_addItem(name, dim, rows, "", Range<TYPE>::min(), Range<TYPE>::max(), result.m_ptr);
00459 }
00461 template <class TYPE, class RANGE> StatusCode addItem(const std::string& name, long dim, long rows, Matrix<TYPE>& result, const RANGE low, const RANGE high) {
00462 return i_addItem(name, dim, rows, "", TYPE(low), TYPE(high), result.m_ptr);
00463 }
00465 template <class TYPE, class INDEX> StatusCode addItem(const std::string& name, Item<INDEX>& index, Matrix<TYPE>& result, long rows) {
00466 return i_addItem(name, index->range().distance(), rows, index->name(), Range<TYPE>::min(), Range<TYPE>::max(), result.m_ptr);
00467 }
00469 template <class TYPE, class INDEX, class RANGE> StatusCode addItem(const std::string& name, Item<INDEX>& index, Matrix<TYPE>& result, long rows, const RANGE low, const RANGE high) {
00470 return i_addItem(name, index->range().distance(), rows, index->name(), TYPE(low), TYPE(high), result.m_ptr);
00471 }
00472 };
00473
00476 class Directory : public DataObject {
00477 public:
00479 Directory() {
00480 }
00482 virtual ~Directory() {
00483 }
00485 static const CLID& classID() {
00486 return CLID_NTupleDirectory;
00487 }
00489 virtual const CLID& clID() const {
00490 return Directory::classID();
00491 }
00492 };
00493
00496 class File : public Directory {
00497 protected:
00499 std::string m_name;
00501 std::string m_logName;
00503 unsigned char m_type;
00505 bool m_isOpen;
00506 public:
00507 File() : m_type(0), m_isOpen(false) {
00508 }
00510 File(unsigned char type, const std::string name, const std::string& logName)
00511 : m_name(name), m_logName(logName), m_type(type), m_isOpen(false) {
00512 }
00514 virtual ~File() {
00515 }
00517 static const CLID& classID() {
00518 return CLID_NTupleFile;
00519 }
00521 virtual const CLID& clID() const {
00522 return File::classID();
00523 }
00525 void setType(const unsigned char typ) {
00526 m_type = typ;
00527 }
00529 const unsigned char type() const {
00530 return m_type;
00531 }
00533 const std::string& name() const {
00534 return m_name;
00535 }
00537 void setName(const std::string& nam) {
00538 m_name = nam;
00539 }
00541 const std::string& logicalName() const {
00542 return m_logName;
00543 }
00545 void setLogicalName( const std::string& l) {
00546 m_logName = l;
00547 }
00549 void setOpen(bool flag) {
00550 m_isOpen = flag;
00551 }
00553 bool isOpen() const {
00554 return m_isOpen;
00555 }
00556 };
00557
00558
00559
00560 template <> class Array <IOpaqueAddress*> {private: Array(){} public: virtual void dummy() = 0; };
00561 template <> class Matrix<IOpaqueAddress*> {private: Matrix(){} public: virtual void dummy() = 0; };
00562 #ifndef ALLOW_ALL_TYPES
00563 template <> class Item<unsigned char> {private: Item(){} public: virtual void dummy() = 0; };
00564 template <> class Array <unsigned char> {private: Array(){} public: virtual void dummy() = 0; };
00565 template <> class Matrix<unsigned char> {private: Matrix(){} public: virtual void dummy() = 0; };
00566 template <> class Item<char> {private: Item(){} public: virtual void dummy() = 0; };
00567 template <> class Array <char> {private: Array(){} public: virtual void dummy() = 0; };
00568 template <> class Matrix<char> {private: Matrix(){} public: virtual void dummy() = 0; };
00569 template <> class Item<unsigned short> {private: Item(){} public: virtual void dummy() = 0; };
00570 template <> class Array <unsigned short> {private: Array(){} public: virtual void dummy() = 0; };
00571 template <> class Matrix<unsigned short> {private: Matrix(){} public: virtual void dummy() = 0; };
00572 template <> class Item<short> {private: Item(){} public: virtual void dummy() = 0; };
00573 template <> class Array <short> {private: Array(){} public: virtual void dummy() = 0; };
00574 template <> class Matrix<short> {private: Matrix(){} public: virtual void dummy() = 0; };
00575 template <> class Item<unsigned int> {private: Item(){} public: virtual void dummy() = 0; };
00576 template <> class Array <unsigned int> {private: Array(){} public: virtual void dummy() = 0; };
00577 template <> class Matrix<unsigned int> {private: Matrix(){} public: virtual void dummy() = 0; };
00578 template <> class Item<int> {private: Item(){} public: virtual void dummy() = 0; };
00579 template <> class Array <int> {private: Array(){} public: virtual void dummy() = 0; };
00580 template <> class Matrix<int> {private: Matrix(){} public: virtual void dummy() = 0; };
00581 #else
00582 typedef Item<bool> BoolItem;
00583 typedef Item<char> CharItem;
00584 typedef Item<unsigned char> UCharItem;
00585 typedef Item<short> ShortItem;
00586 typedef Item<unsigned short> UShortItem;
00587 typedef Item<long> LongItem;
00588 typedef Item<unsigned long> ULongItem;
00589 typedef Item<int> IntItem;
00590 typedef Item<unsigned int> UIntItem;
00591 typedef Item<float> FloatItem;
00592 typedef Item<double> DoubleItem;
00593 typedef Array<bool> BoolArray;
00594 typedef Array<char> CharArray;
00595 typedef Array<unsigned char> UCharArray;
00596 typedef Array<short> ShortArray;
00597 typedef Array<unsigned short> UShortArray;
00598 typedef Array<long> LongArray;
00599 typedef Array<unsigned long> ULongArray;
00600 typedef Array<int> IntArray;
00601 typedef Array<unsigned int> UIntArray;
00602 typedef Array<float> FloatArray;
00603 typedef Array<double> DoubleArray;
00604 typedef Matrix<bool> BoolMatrix;
00605 typedef Matrix<char> CharMatrix;
00606 typedef Matrix<unsigned char> UCharMatrix;
00607 typedef Matrix<short> ShortMatrix;
00608 typedef Matrix<unsigned short> UShortMatrix;
00609 typedef Matrix<long> LongMatrix;
00610 typedef Matrix<unsigned long> ULongMatrix;
00611 typedef Matrix<int> IntMatrix;
00612 typedef Matrix<unsigned int> UIntMatrix;
00613 typedef Matrix<float> FloatMatrix;
00614 typedef Matrix<double> DoubleMatrix;
00615 #endif
00616 #undef DECL_MINMAX
00617 };
00618
00619
00620 typedef SmartDataPtr<NTuple::Tuple> NTuplePtr;
00621 typedef SmartDataPtr<NTuple::Directory> NTupleDirPtr;
00622 typedef SmartDataPtr<NTuple::File> NTupleFilePtr;
00623
00624 #include "GaudiKernel/MsgStream.h"
00625 template <class T>
00626 MsgStream& operator<<(MsgStream& s, const NTuple::Item<T>& obj) {
00627 return s << T(obj);
00628 }
00629
00630 template <class T>
00631 std::ostream& operator<<(std::ostream& s, const NTuple::Item<T>& obj) {
00632 return s << T(obj);
00633 }
00634
00635 #endif // GAUDIKERNEL_NTUPLE_H