// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_wroot_ntuple #define tools_wroot_ntuple // An ntuple class to write at the ROOT format. // It inherits wroot::tree and each column is mapped // on a wroot::branch. Each add_row() does a tree::fill(). #include "tree" #include "../vfind" #include "../vmanip" namespace tools { namespace wroot { class ntuple : public tree { protected: class icol { public: virtual ~icol(){} public: virtual void add() = 0; virtual const std::string& name() const = 0; virtual void set_basket_size(uint32) = 0; }; public: template class column : public virtual icol { public: //icol virtual void add() {m_leaf->fill(m_tmp);m_tmp = m_def;} virtual const std::string& name() const {return m_leaf->name();} virtual void set_basket_size(uint32 a_size) { m_leaf->branch().set_basket_size(a_size); } public: column(tree& a_tree, const std::string& a_name, const T& a_def) :m_tree(a_tree),m_leaf(0) ,m_def(a_def),m_tmp(a_def) { branch* br = m_tree.create_branch(a_name); m_leaf = br->create_leaf(a_name,a_name); } virtual ~column(){} protected: column(const column& a_from) :icol(a_from) ,m_tree(a_from.m_tree) ,m_leaf(0) ,m_def(a_from.m_def) ,m_tmp(a_from.m_tmp) {} column& operator=(const column& a_from){ m_leaf = 0; m_def = a_from.m_def; m_tmp = a_from.m_tmp; return *this; } public: bool fill(const T& a_value) {m_tmp = a_value;return true;} protected: tree& m_tree; leaf* m_leaf; T m_def; T m_tmp; }; public: ntuple(idir& a_dir, const std::string& a_name,const std::string& a_title) : tree(a_dir,a_name,a_title){} virtual ~ntuple() {} protected: ntuple(const ntuple& a_from) :iobject(a_from),itree(a_from),tree(a_from) {} ntuple& operator=(const ntuple&){return *this;} public: const std::vector& columns() const {return m_cols;} template column* create_column(const std::string& a_name, const T& a_def = T()) { if(find_named(m_cols,a_name)) return 0; column* col = new column(*this,a_name,a_def); if(!col) return 0; m_cols.push_back(col); return col; } bool add_row() { if(m_cols.empty()) return false; {std::vector::iterator it; for(it=m_cols.begin();it!=m_cols.end();++it) (*it)->add();} uint32 n; return tree::fill(n); } void set_basket_size(uint32 a_size) { std::vector::iterator it; for(it=m_cols.begin();it!=m_cols.end();++it) { (*it)->set_basket_size(a_size); } } protected: std::vector m_cols; }; }} #endif