inlib
1.2.0
|
00001 // Copyright (C) 2010, Guy Barrand. All rights reserved. 00002 // See the file inlib.license for terms. 00003 00004 #ifndef inlib_rroot_ntuple 00005 #define inlib_rroot_ntuple 00006 00007 // to have same API than rcsv::ntuple. 00008 00009 #include "../rntuple" 00010 00011 #include "tree" 00012 #include "leaf" 00013 00014 #include "../cids" 00015 #include "../vfind" 00016 #include "../vmanip" 00017 00018 #ifdef INLIB_MEM 00019 #include "../mem" 00020 #endif 00021 00022 namespace inlib { 00023 namespace rroot { 00024 00025 class ntuple : public virtual read::intuple { 00026 public: //intuple 00027 virtual void start() {m_index = -1;} 00028 virtual bool next() { 00029 m_index++; 00030 if((uint64)m_index>=m_tree.entries()) return false; 00031 return true; 00032 } 00033 virtual read::icol* find_icol(const std::string& a_name){ 00034 return find_named<read::icol>(m_cols,a_name); 00035 } 00036 virtual const std::vector<read::icol*>& columns() const {return m_cols;} 00037 public: 00038 template <class T> 00039 class column : public virtual read::icolumn<T> { 00040 public: //icol 00041 virtual const std::string& name() const {return m_leaf.name();} 00042 public: //icolumn<T> 00043 virtual bool get_entry(T& a_v) const { 00044 unsigned int n; 00045 if(!m_leaf.branch().find_entry(uint32(m_index),n)) { 00046 a_v = T(); 00047 return false; 00048 } 00049 a_v = m_leaf.value(); 00050 return true; 00051 } 00052 public: 00053 column(leaf<T>& a_leaf,int64& a_index) 00054 :m_leaf(a_leaf) 00055 ,m_index(a_index) //WARNING : we keep the ref ! 00056 {} 00057 virtual ~column(){} 00058 protected: 00059 column(const column& a_from) 00060 :read::intuple(a_from),read::icolumn<T>(a_from) 00061 ,m_leaf(a_from.m_leaf) 00062 ,m_index(a_from.m_index) 00063 {} 00064 column& operator=(const column&){return *this;} 00065 protected: 00066 leaf<T>& m_leaf; 00067 int64& m_index; //WARNING : a ref. 00068 }; 00069 00070 class column_string : public virtual read::icol { 00071 public: 00072 static cid id_class() { 00073 static const std::string s_v; 00074 return _cid(s_v); 00075 } 00076 public: //icol 00077 virtual void* cast(cid a_class) const { 00078 if(void* p = cmp_cast<column_string>(this,a_class)) {return p;} 00079 else return 0; 00080 } 00081 virtual cid id_cls() const {return id_class();} 00082 virtual const std::string& name() const {return m_leaf.name();} 00083 public: 00084 column_string(leaf_string& a_leaf,int64& a_index) 00085 :m_leaf(a_leaf) 00086 ,m_index(a_index) //WARNING : we keep the ref ! 00087 {} 00088 virtual ~column_string(){} 00089 protected: 00090 column_string(const column_string& a_from) 00091 : read::icol(a_from) 00092 ,m_leaf(a_from.m_leaf) 00093 ,m_index(a_from.m_index) 00094 {} 00095 column_string& operator=(const column_string&){return *this;} 00096 protected: 00097 leaf_string& m_leaf; 00098 int64& m_index; //WARNING : a ref. 00099 }; 00100 00101 #ifdef INLIB_MEM 00102 public: 00103 static const std::string& s_class() { 00104 static const std::string s_v("inlib::rroot::ntuple"); 00105 return s_v; 00106 } 00107 #endif 00108 public: 00109 ntuple(tree& a_tree):m_tree(a_tree),m_index(-1){ 00110 #ifdef INLIB_MEM 00111 mem::increment(s_class().c_str()); 00112 #endif 00113 } 00114 virtual ~ntuple() { 00115 inlib::clear<read::icol>(m_cols); 00116 #ifdef INLIB_MEM 00117 mem::decrement(s_class().c_str()); 00118 #endif 00119 } 00120 protected: 00121 ntuple(const ntuple& a_from) 00122 :read::intuple(a_from),m_tree(a_from.m_tree){ 00123 #ifdef INLIB_MEM 00124 mem::increment(s_class().c_str()); 00125 #endif 00126 } 00127 ntuple& operator=(const ntuple&){return *this;} 00128 public: 00129 bool initialize(std::ostream& a_out) { 00130 inlib::clear<read::icol>(m_cols); 00131 00132 std::vector<base_leaf*> leaves = m_tree.find_leaves(); 00133 {std::vector<base_leaf*>::const_iterator it; 00134 for(it=leaves.begin();it!=leaves.end();++it) { 00135 base_leaf* bl = (*it); 00136 if(find_named<read::icol>(m_cols,bl->name())) { 00137 a_out << "inlib::rroot::ntuple::initialize :" 00138 << " column with name " << sout(bl->name()) 00139 << " already exists." 00140 << std::endl; 00141 inlib::clear<read::icol>(m_cols); 00142 return false; 00143 } 00144 00145 if(leaf<float>* lf = cast<base_leaf, leaf<float> >(*bl) ){ 00146 00147 column<float>* col = new column<float>(*lf,m_index); 00148 m_cols.push_back(col); 00149 00150 } else if(leaf<double>* ld = cast<base_leaf, leaf<double> >(*bl) ){ 00151 00152 column<double>* col = new column<double>(*ld,m_index); 00153 m_cols.push_back(col); 00154 00155 } else if(leaf<int>* li = cast<base_leaf, leaf<int> >(*bl) ){ 00156 00157 column<int>* col = new column<int>(*li,m_index); 00158 m_cols.push_back(col); 00159 00160 } else if(leaf_string* ls = cast<base_leaf, leaf_string >(*bl) ){ 00161 00162 column_string* col = new column_string(*ls,m_index); 00163 m_cols.push_back(col); 00164 00165 } else { 00166 a_out << "inlib::rroot::ntuple::initialize :" 00167 << " column type not yet handled." 00168 << std::endl; 00169 inlib::clear<read::icol>(m_cols); 00170 return false; 00171 } 00172 00173 }} 00174 00175 unsigned int num = m_cols.size(); 00176 if(!num) { 00177 a_out << "inlib::rroot::ntuple::initialize :" 00178 << " zero columns." 00179 << std::endl; 00180 return false; 00181 } 00182 00183 return true; 00184 } 00185 protected: 00186 tree& m_tree; 00187 std::vector<read::icol*> m_cols; 00188 int64 m_index; 00189 }; 00190 00191 }} 00192 00193 #endif