// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. #ifndef tools_aida_ntuple #define tools_aida_ntuple // An in memory ntuple able to have "sub ntuple" on a column. // It is used in ioda to read ntuples in XML/AIDA files. #include "vmanip" #include "typedefs" #include "scast" #include "forit" #include "ntuple_binding" #include "mnmx" #include #include #include namespace tools { namespace aida { class base_col { public: static const std::string& s_class() { static const std::string s_v("tools::aida::base_col"); return s_v; } virtual void* cast(const std::string& a_class) const { if(void* p = cmp_cast(this,a_class)) {return p;} return 0; } public: virtual base_col* copy() const = 0; virtual uint64 num_elems() const = 0; virtual bool add() = 0; virtual bool reset() = 0; //binded column reading API : virtual bool fetch_entry() const = 0; virtual void set_user_variable(void*) = 0; protected: base_col(std::ostream& a_out,const std::string& a_name) :m_out(a_out) ,m_name(a_name),m_index(0){ } public: virtual ~base_col(){ } protected: base_col(const base_col& a_from) :m_out(a_from.m_out) ,m_name(a_from.m_name) ,m_index(a_from.m_index){ } base_col& operator=(const base_col& a_from){ m_name = a_from.m_name; m_index = a_from.m_index; return *this; } public: const std::string& name() const {return m_name;} void set_index(uint64 a_index){m_index = a_index;} protected: std::ostream& m_out; std::string m_name; uint64 m_index; }; class base_ntu { public: static const std::string& s_class() { static const std::string s_v("tools::aida::base_ntu"); return s_v; } virtual void* cast(const std::string& a_class) const { if(void* p = cmp_cast(this,a_class)) {return p;} return 0; } protected: base_ntu(std::ostream& a_out,const std::string& a_title) :m_out(a_out),m_title(a_title),m_index(-1){ } virtual ~base_ntu() { clear(); } protected: base_ntu(const base_ntu& a_from) :m_out(a_from.m_out) ,m_title(a_from.m_title),m_index(a_from.m_index) { tools_vforcit(base_col*,a_from.m_cols,it) { base_col* column = (*it)->copy(); if(!column) { m_out << s_class() << "::cstor :" << " can't copy column." << std::endl; safe_clear(m_cols); m_index = -1; return; //throw } m_cols.push_back(column); } } base_ntu& operator=(const base_ntu& a_from){ if(&a_from==this) return *this; safe_clear(m_cols); m_index = a_from.m_index; m_title = a_from.m_title; tools_vforcit(base_col*,a_from.m_cols,it) { base_col* column = (*it)->copy(); if(!column) { m_out << s_class() << "::operator=() :" << " can't copy column." << std::endl; safe_clear(m_cols); m_index = -1; return *this; } m_cols.push_back(column); } return *this; } public: std::ostream& out() const {return m_out;} const std::vector& columns() const {return m_cols;} size_t number_of_columns() const {return m_cols.size();} void column_names(std::vector& a_names) const { a_names.clear(); tools_vforcit(base_col*,m_cols,it) a_names.push_back((*it)->name()); } const std::string& title() const {return m_title;} void set_title(const std::string& a_title) {m_title = a_title;} uint64 rows() const { if(m_cols.empty()) return 0; return m_cols.front()->num_elems(); } bool number_of_entries(uint64& a_value) const { if(m_cols.empty()) {a_value = 0;return false;} a_value = m_cols.front()->num_elems(); return true; } void clear() { //must not be confused with reset(). safe_clear(m_cols); m_index = -1; } bool reset() { //clear data in columns (but not the column set) bool status = true; tools_vforit(base_col*,m_cols,it) { if(!(*it)->reset()) status = false; } m_index = -1; return status; } // reading : void start() {m_index = -1;set_columns_index(0);} bool next() { // a tuple loop is of the form : // tuple.start(); // while(tuple.next()) { // ... // double v; // if(!col->get_entry(v)) {} // ... // } if((m_index+1)>=(int64)rows()) return false; m_index++; set_columns_index(m_index); return true; } int64 row_index() const {return m_index;} // filling : bool add_row() { bool status = true; tools_vforit(base_col*,m_cols,it) { if(!(*it)->add()) status = false; } return status; } public: base_col* find_column(const std::string& a_name){ return find_named(m_cols,a_name); } void add_column(base_col* a_col) { //we take ownership. m_cols.push_back(a_col); } protected: void set_columns_index(uint64 a_index) { tools_vforit(base_col*,m_cols,it) { (*it)->set_index(a_index); } } protected: std::ostream& m_out; std::string m_title; int64 m_index; std::vector m_cols; }; }} #include "tos" #include "sto" #include "columns" #include "stype" namespace tools { namespace aida { inline const std::string& s_aida_type(short) { static const std::string s_v("short"); return s_v; } inline const std::string& s_aida_type(int) { static const std::string s_v("int"); return s_v; } inline const std::string& s_aida_type(float) { static const std::string s_v("float"); return s_v; } inline const std::string& s_aida_type(double) { static const std::string s_v("double"); return s_v; } inline const std::string& s_aida_type(bool) { static const std::string s_v("boolean"); return s_v; } inline const std::string& s_aida_type(const std::string&) { static const std::string s_v("string"); return s_v; } inline const std::string& s_aida_type(int64) { static const std::string s_v("long"); return s_v; } inline const std::string& s_aida_type_ituple() { static const std::string s_v("ITuple"); return s_v; } ///////////////////////////////////////// /// not AIDA ! ////////////////////////// ///////////////////////////////////////// inline const std::string& s_aida_type(unsigned short) { static const std::string s_v("ushort"); return s_v; } inline const std::string& s_aida_type(unsigned int) { static const std::string s_v("uint"); return s_v; } inline const std::string& s_aida_type(uint64) { static const std::string s_v("ulong"); return s_v; } class aida_base_col : public base_col { public: static const std::string& s_class() { static const std::string s_v("tools::aida::aida_base_col"); return s_v; } virtual void* cast(const std::string& a_class) const { if(void* p = cmp_cast(this,a_class)) {return p;} return base_col::cast(a_class); } public: virtual const std::string& aida_type() const = 0; virtual bool s_default_value(std::string&) const = 0; virtual bool s_value(std::string&) const = 0; virtual bool s_fill(const std::string&) = 0; public: aida_base_col(std::ostream& a_out,const std::string& a_name) :base_col(a_out,a_name){} public: virtual ~aida_base_col(){} public: aida_base_col(const aida_base_col& a_from) :base_col(a_from) {} aida_base_col& operator=(const aida_base_col& a_from){ base_col::operator=(a_from); return *this; } }; inline bool s__fill(const std::string& a_s,std::string& a_v) { a_v = a_s; return true; } inline bool s__fill(const std::string& a_s,char& a_v) { //for exlib/cbk/aida_ntu if(a_s.empty()) return false; a_v = a_s[0]; return true; } inline bool s__fill(const std::string& a_s,unsigned char& a_v) { //for exlib/cbk/aida_ntu if(a_s.empty()) return false; a_v = a_s[0]; return true; } inline bool s__fill(const std::string& a_s,bool& a_v) { return to(a_s,a_v); } inline bool s__fill(const std::string& a_s,short& a_v) { return to(a_s,a_v); } inline bool s__fill(const std::string& a_s,unsigned short& a_v) { return to(a_s,a_v); } inline bool s__fill(const std::string& a_s,int& a_v) { return to(a_s,a_v); } inline bool s__fill(const std::string& a_s,unsigned int& a_v) { return to(a_s,a_v); } inline bool s__fill(const std::string& a_s,int64& a_v) { return to(a_s,a_v); } inline bool s__fill(const std::string& a_s,uint64& a_v) { return to(a_s,a_v); } inline bool s__fill(const std::string& a_s,float& a_v) { return to(a_s,a_v); } inline bool s__fill(const std::string& a_s,double& a_v) { return to(a_s,a_v); } template class aida_col : public aida_base_col { public: typedef T entry_t; public: static const std::string& s_class() { static const std::string s_v("tools::aida::aida_col<"+stype(T())+">"); return s_v; } virtual void* cast(const std::string& a_class) const { if(void* p = cmp_cast< aida_col >(this,a_class)) {return p;} return aida_base_col::cast(a_class); } public: virtual base_col* copy() const {return new aida_col(*this);} virtual bool add() {m_data.push_back(m_tmp);m_tmp = m_default;return true;} virtual bool reset() { m_data.clear(); m_index = 0; m_tmp = m_default; return true; } virtual uint64 num_elems() const {return m_data.size();} public: virtual const std::string& aida_type() const {return s_aida_type(T());} virtual bool s_default_value(std::string& a_s) const { a_s = tos(m_default); return true; } virtual bool s_value(std::string& a_s) const { typedef typename std::vector::size_type sz_t; a_s = tos(m_data[sz_t(m_index)]); return true; } // for exlib/raxml/tuple : virtual bool s_fill(const std::string& a_s) { //if(!to(a_s,m_tmp)) { if(!s__fill(a_s,m_tmp)) { m_out << s_class() << "::fill :" << " can't convert " << sout(a_s) << "." << std::endl; return false; } return true; } virtual void set_user_variable(void* a_user_var) {m_user_var = (T*)a_user_var;} //not owner. public: aida_col(std::ostream& a_out,const std::string& a_name,const T& a_def) :aida_base_col(a_out,a_name) ,m_default(a_def) ,m_tmp(a_def) ,m_user_var(0) //not owner {} public: virtual ~aida_col(){} public: aida_col(const aida_col& a_from) :aida_base_col(a_from) ,m_data(a_from.m_data) ,m_default(a_from.m_default) ,m_tmp(a_from.m_tmp) ,m_user_var(a_from.m_user_var) {} aida_col& operator=(const aida_col& a_from){ aida_base_col::operator=(a_from); if(&a_from==this) return *this; m_data = a_from.m_data; m_default = a_from.m_default; m_tmp = a_from.m_tmp; m_user_var = a_from.m_user_var; return *this; } public: bool fill(const T& a_value) {m_tmp = a_value;return true;} bool get_entry(T& a_v) const { if(m_index>=m_data.size()) { m_out << s_class() << "::get_entry :" << " bad index " << m_index << ". Vec size is " << m_data.size() << "." << "." << std::endl; a_v = T(); return false; } typedef typename std::vector::size_type sz_t; a_v = m_data[sz_t(m_index)]; return true; } virtual bool fetch_entry() const { //NOTE : it is ok to have a NULL m_user_var. if(m_index>=m_data.size()) { m_out << s_class() << "::get_entry :" << " bad index " << m_index << ". Vec size is " << m_data.size() << "." << "." << std::endl; if(m_user_var) *m_user_var = T(); return false; } typedef typename std::vector::size_type sz_t; if(m_user_var) *m_user_var = m_data[sz_t(m_index)]; return true; } protected: std::vector m_data; T m_default; T m_tmp; T* m_user_var; }; class ntuple : public base_ntu { public: static cid id_class() {return 2000;} //for ntuple_binding. public: static const std::string& s_class() { static const std::string s_v("tools::aida::ntuple"); return s_v; } virtual void* cast(const std::string& a_class) const { if(void* p = cmp_cast(this,a_class)) {return p;} return base_ntu::cast(a_class); } virtual const std::string& s_cls() const {return s_class();} public: ntuple(std::ostream& a_out,const std::string& a_title) :base_ntu(a_out,a_title) {} virtual ~ntuple() {} public: ntuple(const ntuple& a_from): base_ntu(a_from){} ntuple& operator=(const ntuple& a_from){ base_ntu::operator=(a_from); return *this; } public: template aida_col* create_col(const std::string& a_name,const T& a_def = T()) { if(find_named(m_cols,a_name)) { m_out << s_class() << "::create_col :" << " a column with name " << sout(a_name) << " already exists." << std::endl; return 0; } aida_col* col = new aida_col(m_out,a_name,a_def); if(!col) { m_out << s_class() << "::create_col :" << " can't create aida_col " << sout(a_name) << "." << std::endl; return 0; } m_cols.push_back(col); return col; } template aida_col* find_column(const std::string& a_name){ base_col* col = find_named(m_cols,a_name); if(!col) return 0; return safe_cast >(*col); } template bool find_column(const std::string& a_name,aida_col*& a_col,bool a_case_sensitive = true) { //for exlib::evaluator. base_col* col = a_case_sensitive ? find_named(m_cols,a_name) : find_named_case_insensitive(m_cols,a_name); if(!col) {a_col = 0;return false;} a_col = safe_cast >(*col); return a_col?true:false; } aida_base_col* find_aida_base_column(const std::string& a_name,bool a_case_sensitive = true){ //for opaw/panntu. base_col* col = a_case_sensitive ? find_named(m_cols,a_name) : find_named_case_insensitive(m_cols,a_name); if(!col) return 0; return safe_cast(*col); } bool get_row() const { bool status = true; tools_vforcit(base_col*,m_cols,it) { if(!(*it)->fetch_entry()) status = false; } return status; } bool set_binding(std::ostream& a_out,const ntuple_binding& a_bd = ntuple_binding()) { tools_vforcit(column_binding,a_bd.columns(),itb) { bool found = false; tools_vforcit(base_col*,m_cols,itc) { if((*itc)->name()==(*itb).name()) { (*itc)->set_user_variable((*itb).user_obj()); found = true; } } if(!found) { a_out << "tools::aida::ntuple :" << " binding name " << sout((*itb).name()) << " does not match any ntuple column." << std::endl; return false; } } return true; } template bool column_min(unsigned int a_col,T& a_value) { a_value = T(); if(m_cols.empty()) return false; if(a_col>=m_cols.size()) return false; base_col* _base_col = m_cols[a_col]; aida_col* _col = safe_cast >(*_base_col); if(!_col) return false; start(); uint64 _rows = rows(); T v; {for(uint64 row=0;row<_rows;row++) { if(!next()) {a_value = T();return false;} if(!_col->get_entry(v)) {} if(!row) { a_value = v; } else { a_value = min_of(a_value,v); } }} return true; } template bool column_max(unsigned int a_col,T& a_value) { a_value = T(); if(m_cols.empty()) return false; if(a_col>=m_cols.size()) return false; base_col* _base_col = m_cols[a_col]; aida_col* _col = safe_cast >(*_base_col); if(!_col) return false; start(); uint64 _rows = rows(); T v; {for(uint64 row=0;row<_rows;row++) { if(!next()) {a_value = T();return false;} if(!_col->get_entry(v)) {} if(!row) { a_value = v; } else { a_value = max_of(a_value,v); } }} return true; } }; //////////////////////////////////////////////////////////// /// some special column that can't be done with aida_col //// //////////////////////////////////////////////////////////// class aida_col_ntu : public base_col { public: static const std::string& s_class() { static const std::string s_v("tools::aida::aida_col_ntu"); return s_v; } virtual void* cast(const std::string& a_class) const { if(void* p = cmp_cast(this,a_class)) {return p;} return base_col::cast(a_class); } public: virtual base_col* copy() const {return new aida_col_ntu(*this);} virtual bool add() {m_data.push_back(m_tmp);m_tmp.reset();return true;} virtual bool reset() {m_data.clear();m_index = 0;return true;} virtual uint64 num_elems() const {return m_data.size();} public: base_ntu* get_entry() { if(m_index>=m_data.size()) { m_out << s_class() << "::get_entry :" << " bad index " << m_index << ". Vec size is " << m_data.size() << "." << "." << std::endl; return 0; } typedef std::vector::size_type sz_t; return &(m_data[sz_t(m_index)]); } virtual void set_user_variable(void* a_user_var) {m_user_var = (ntuple*)a_user_var;} //not owner. virtual bool fetch_entry() const { if(m_index>=m_data.size()) { m_out << s_class() << "::fetch_entry :" << " bad index " << m_index << ". Vec size is " << m_data.size() << "." << "." << std::endl; if(m_user_var) *m_user_var = ntuple(m_out,""); return false; } typedef std::vector::size_type sz_t; if(m_user_var) *m_user_var = m_data[sz_t(m_index)]; return true; } virtual base_ntu* get_to_fill() {return &m_tmp;} public: aida_col_ntu(std::ostream& a_out,const std::string& a_name) :base_col(a_out,a_name) ,m_tmp(a_out,"tmp") ,m_user_var(0) //not owner {} public: virtual ~aida_col_ntu(){} public: aida_col_ntu(const aida_col_ntu& a_from) :base_col(a_from) ,m_data(a_from.m_data) ,m_tmp(a_from.m_tmp) ,m_user_var(a_from.m_user_var) {} aida_col_ntu& operator=(const aida_col_ntu& a_from){ base_col::operator=(a_from); if(&a_from==this) return *this; m_data = a_from.m_data; m_tmp = a_from.m_tmp; m_user_var = a_from.m_user_var; return *this; } protected: std::vector m_data; ntuple m_tmp; ntuple* m_user_var; }; inline bool create_cols_from_vals(ntuple& a_ntu, const std::vector& a_vars, bool a_verbose = false){ tools_vforcit(value,a_vars,it) { if((*it).type()==value::VOID_STAR) { if(a_verbose){ a_ntu.out() << "tools::aida::create_cols_from_vals :" << " ITuple : " << (*it).label() << " : begin " << std::endl; } std::vector* vars = (std::vector*)(*it).get_void_star(); aida_col_ntu* col_ntu = new aida_col_ntu(a_ntu.out(),(*it).label()); // create sub columns on the "fillable" of col_ntu : base_ntu* sub_base_ntu = col_ntu->get_to_fill(); if(!sub_base_ntu) { delete col_ntu; return false; } ntuple* sub_aida = safe_cast(*sub_base_ntu); if(!sub_aida) { delete col_ntu; return false; } if(!create_cols_from_vals(*sub_aida,*vars,a_verbose)) { delete col_ntu; return false; } a_ntu.add_column(col_ntu); } else { if(a_verbose){ std::string stype; (*it).s_type(stype); std::string sval; (*it).tos(sval); a_ntu.out() << "tools::aida::create_cols_from_vals :" << " " << stype << " : " << (*it).label() << " : " << sval << std::endl; } // char,short,int,float,double // byte,boolean,string,long(for int64) // double[] base_col* col = 0; if((*it).type()==value::SHORT) { col = a_ntu.create_col((*it).label(),(*it).get_short()); } else if((*it).type()==value::INT) { col = a_ntu.create_col((*it).label(),(*it).get_int()); } else if((*it).type()==value::INT64) { col = a_ntu.create_col((*it).label(),(*it).get_int64()); } else if((*it).type()==value::FLOAT) { col = a_ntu.create_col((*it).label(),(*it).get_float()); } else if((*it).type()==value::DOUBLE) { col = a_ntu.create_col((*it).label(),(*it).get_double()); } else if((*it).type()==value::UNSIGNED_SHORT) { col = a_ntu.create_col((*it).label(),(*it).get_unsigned_short()); } else if((*it).type()==value::UNSIGNED_INT) { col = a_ntu.create_col((*it).label(),(*it).get_unsigned_int()); } else if((*it).type()==value::UNSIGNED_INT64) { col = a_ntu.create_col((*it).label(),(*it).get_unsigned_int64()); } else if((*it).type()==value::BOOL) { col = a_ntu.create_col((*it).label(),(*it).get_bool()); } else if((*it).type()==value::STRING) { col = a_ntu.create_col((*it).label(),(*it).get_string()); } else if((*it).type()==value::INT64) { col = a_ntu.create_col((*it).label(),(*it).get_int64()); } if(!col) { std::string stype; (*it).s_type(stype); std::string sval; (*it).tos(sval); a_ntu.out() << "tools::aida::create_cols_from_vals :" << " failed for " << stype << " : " << (*it).label() << " : " << sval << std::endl; return false; } } } return true; } // for raxml : inline bool create_col(ntuple& a_ntu, const std::string& a_type, const std::string& a_name, const std::string& a_s, //def or booking. bool a_is_ntu){ if(a_type==s_aida_type((short)0)) { short v = 0; if(a_s.size()&&!to(a_s,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't convert def " << sout(a_s) << " to a " << a_type << std::endl; return false; } if(!a_ntu.create_col(a_name,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't create column of type " << sout(a_type) << std::endl; return false; } } else if(a_type==s_aida_type((int)0)) { int v = 0; if(a_s.size()&&!to(a_s,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't convert def " << sout(a_s) << " to a " << a_type << std::endl; return false; } if(!a_ntu.create_col(a_name,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't create column of type " << sout(a_type) << std::endl; return false; } } else if(a_type==s_aida_type((int64)0)) { int64 v = 0; if(a_s.size()&&!to(a_s,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't convert def " << sout(a_s) << " to a " << a_type << std::endl; return false; } if(!a_ntu.create_col(a_name,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't create column of type " << sout(a_type) << std::endl; return false; } } else if(a_type==s_aida_type((float)0)) { float v = 0; if(a_s.size()&&!to(a_s,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't convert def " << sout(a_s) << " to a " << a_type << std::endl; return false; } if(!a_ntu.create_col(a_name,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't create column of type " << sout(a_type) << std::endl; return false; } } else if(a_type==s_aida_type((double)0)) { double v = 0; if(a_s.size()&&!to(a_s,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't convert def " << sout(a_s) << " to a " << a_type << std::endl; return false; } if(!a_ntu.create_col(a_name,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't create column of type " << sout(a_type) << std::endl; return false; } } else if(a_type==s_aida_type((unsigned short)0)) { unsigned short v = 0; if(a_s.size()&&!to(a_s,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't convert def " << sout(a_s) << " to a " << a_type << std::endl; return false; } if(!a_ntu.create_col(a_name,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't create column of type " << sout(a_type) << std::endl; return false; } } else if(a_type==s_aida_type((unsigned int)0)) { unsigned int v = 0; if(a_s.size()&&!to(a_s,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't convert def " << sout(a_s) << " to a " << a_type << std::endl; return false; } if(!a_ntu.create_col(a_name,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't create column of type " << sout(a_type) << std::endl; return false; } } else if(a_type==s_aida_type((uint64)0)) { uint64 v = 0; if(a_s.size()&&!to(a_s,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't convert def " << sout(a_s) << " to a " << a_type << std::endl; return false; } if(!a_ntu.create_col(a_name,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't create column of type " << sout(a_type) << std::endl; return false; } ///////////////////////////////////////// ///////////////////////////////////////// } else if(a_type==s_aida_type((bool)true)) { bool v = false; if(a_s.size()&&!to(a_s,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't convert def " << sout(a_s) << " to a " << a_type << std::endl; return false; } if(!a_ntu.create_col(a_name,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't create column of type " << sout(a_type) << std::endl; return false; } } else if(a_type==s_aida_type(std::string())) { if(!a_ntu.create_col(a_name,a_s)) { a_ntu.out() << "tools::aida::create_col :" << " can't create column of type " << sout(a_type) << std::endl; return false; } } else if(a_type==s_aida_type((int64)0)) { int64 v = 0; if(a_s.size()&&!to(a_s,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't convert def " << sout(a_s) << " to a " << a_type << std::endl; return false; } if(!a_ntu.create_col(a_name,v)) { a_ntu.out() << "tools::aida::create_col :" << " can't create column of type " << sout(a_type) << std::endl; return false; } } else if(a_type==s_aida_type_ituple()) { // we expect a booking string on a_s. if(!a_is_ntu) { a_ntu.out() << "tools::aida::create_col :" << " mismatch a_is_ntu/a_type." << std::endl; return false; } if(a_s.empty()) { a_ntu.out() << "tools::aida::create_col :" << " empty booking string." << std::endl; return false; } columns::finder f(a_ntu.out(),a_s); if(!f.find_variables()) { a_ntu.out() << "tools::aida::create_col :" << " find_variables() failed for " << sout(a_s) << "." << std::endl; return false; } aida_col_ntu* col_ntu = new aida_col_ntu(a_ntu.out(),a_name); //create columns on the fillable. base_ntu* sub_base_ntu = col_ntu->get_to_fill(); if(!sub_base_ntu) {delete col_ntu;return false;} ntuple* sub_aida = safe_cast(*sub_base_ntu); if(!sub_aida) {delete col_ntu;return false;} std::vector vars;f.result(vars); if(!create_cols_from_vals(*sub_aida,vars)) { columns::delete_columns(vars); delete col_ntu; return false; } columns::delete_columns(vars); a_ntu.add_column(col_ntu); //FIXME : double[] } else { a_ntu.out() << "tools::aida::create_col :" << " col type " << sout(a_type) << " not yet handled." << std::endl; return false; } return true; } }} #endif