Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 2 // See the file tools.license for terms. 3 3 4 #ifndef tools_rcsv_ntuple 4 #ifndef tools_rcsv_ntuple 5 #define tools_rcsv_ntuple 5 #define tools_rcsv_ntuple 6 6 7 // A simple ntuple class to read at the csv fo 7 // A simple ntuple class to read at the csv format. 8 // (csv = comma separated value). 8 // (csv = comma separated value). 9 9 10 // This reader can be use to read file at the 10 // This reader can be use to read file at the hippodraw format 11 // which is : 11 // which is : 12 // - one header line for the ntuple title. 12 // - one header line for the ntuple title. 13 // - one csv line for column names. 13 // - one csv line for column names. 14 // - data at csv format. 14 // - data at csv format. 15 15 16 #include "rntuple" 16 #include "rntuple" 17 17 18 #include <istream> 18 #include <istream> 19 #include <sstream> 19 #include <sstream> 20 20 21 #include "vfind" 21 #include "vfind" 22 #include "vmanip" 22 #include "vmanip" 23 #include "words" 23 #include "words" 24 #include "snums" 24 #include "snums" 25 #include "sto" 25 #include "sto" 26 #include "s2time" 26 #include "s2time" 27 #include "chars" 27 #include "chars" 28 #include "strip" 28 #include "strip" 29 #include "cids" 29 #include "cids" 30 #include "ntuple_binding" 30 #include "ntuple_binding" 31 #include "sout" 31 #include "sout" 32 #include "num2s" 32 #include "num2s" 33 //#include "srep" 33 //#include "srep" 34 34 35 #ifdef TOOLS_MEM 35 #ifdef TOOLS_MEM 36 #include "mem" 36 #include "mem" 37 #endif 37 #endif 38 38 39 #include <utility> << 40 << 41 namespace tools { 39 namespace tools { 42 namespace rcsv { 40 namespace rcsv { 43 41 44 class ntuple : public virtual read::intuple { 42 class ntuple : public virtual read::intuple { 45 typedef read::intuple parent; 43 typedef read::intuple parent; 46 public: //read::intuple 44 public: //read::intuple 47 virtual void start() { 45 virtual void start() { 48 m_reader.clear(); 46 m_reader.clear(); 49 m_reader.seekg(0,std::ios::beg); 47 m_reader.seekg(0,std::ios::beg); 50 if(m_hippo) { 48 if(m_hippo) { 51 skip_line(m_reader,m_sz); 49 skip_line(m_reader,m_sz); 52 skip_line(m_reader,m_sz); 50 skip_line(m_reader,m_sz); 53 } 51 } 54 } 52 } 55 virtual bool next() { 53 virtual bool next() { 56 if(!m_sep) return false; //not inited. 54 if(!m_sep) return false; //not inited. 57 if(m_reader.tellg()>=m_sz) return false; 55 if(m_reader.tellg()>=m_sz) return false; 58 // first time we are at bol but else we ar 56 // first time we are at bol but else we are at eol. 59 char c; 57 char c; 60 m_reader.get(c); 58 m_reader.get(c); 61 if(c==LF()){ 59 if(c==LF()){ 62 if(m_reader.tellg()>=m_sz) { 60 if(m_reader.tellg()>=m_sz) { 63 //eof. Tell caller to stop looping on 61 //eof. Tell caller to stop looping on ntuple rows. 64 return false; 62 return false; 65 } 63 } 66 //eol. Next char read is going to be at 64 //eol. Next char read is going to be at bol. 67 } else { 65 } else { 68 m_reader.putback(c); 66 m_reader.putback(c); 69 //bol 67 //bol 70 } 68 } 71 // ready for a new row : 69 // ready for a new row : 72 70 73 while(skip_comment(m_reader,m_sz)){} 71 while(skip_comment(m_reader,m_sz)){} 74 if(m_reader.tellg()>=m_sz) return false; 72 if(m_reader.tellg()>=m_sz) return false; 75 73 76 return _read_line(); 74 return _read_line(); 77 } 75 } 78 76 79 virtual read::icol* find_icol(const std::str 77 virtual read::icol* find_icol(const std::string& a_name){ 80 return find_named<read::icol>(m_cols,a_nam 78 return find_named<read::icol>(m_cols,a_name); 81 } 79 } 82 80 83 virtual const std::vector<read::icol*>& colu 81 virtual const std::vector<read::icol*>& columns() const {return m_cols;} 84 82 85 virtual const std::string& title() const {re 83 virtual const std::string& title() const {return m_title;} 86 84 87 virtual bool number_of_entries(tools::uint64 85 virtual bool number_of_entries(tools::uint64 & a_value) const { 88 if(!m_sep) {a_value = 0;return false;} //n 86 if(!m_sep) {a_value = 0;return false;} //not inited. 89 ntuple& self = const_cast<ntuple&>(*this); 87 ntuple& self = const_cast<ntuple&>(*this); 90 if(m_rows==(-1)) { 88 if(m_rows==(-1)) { 91 self.m_rows = 0; 89 self.m_rows = 0; 92 self.start(); 90 self.start(); 93 while(self.next()) {self.m_rows++;} 91 while(self.next()) {self.m_rows++;} 94 } 92 } 95 a_value = (uint64)m_rows; 93 a_value = (uint64)m_rows; 96 return true; 94 return true; 97 } 95 } 98 public: 96 public: 99 template <class T> 97 template <class T> 100 class column : public virtual read::icolumn< 98 class column : public virtual read::icolumn<T> { 101 typedef read::icolumn<T> parent; 99 typedef read::icolumn<T> parent; 102 public: 100 public: 103 static cid id_class() { 101 static cid id_class() { 104 static const T s_v = T(); //do that for 102 static const T s_v = T(); //do that for T = std::string. 105 return 200+_cid(s_v); 103 return 200+_cid(s_v); 106 } 104 } 107 public: //icol 105 public: //icol 108 virtual void* cast(cid a_class) const { 106 virtual void* cast(cid a_class) const { 109 if(void* p = cmp_cast<column>(this,a_cla 107 if(void* p = cmp_cast<column>(this,a_class)) {return p;} 110 return parent::cast(a_class); 108 return parent::cast(a_class); 111 } 109 } 112 virtual cid id_cls() const {return id_clas 110 virtual cid id_cls() const {return id_class();} 113 public: //icol 111 public: //icol 114 virtual const std::string& name() const {r 112 virtual const std::string& name() const {return m_name;} 115 virtual bool fetch_entry() const { 113 virtual bool fetch_entry() const { 116 if(m_user_var) *m_user_var = m_tmp; 114 if(m_user_var) *m_user_var = m_tmp; 117 return true; 115 return true; 118 } 116 } 119 public: //icolumn<T> 117 public: //icolumn<T> 120 virtual bool get_entry(T& a_v) const { 118 virtual bool get_entry(T& a_v) const { 121 a_v = m_tmp; 119 a_v = m_tmp; 122 return true; 120 return true; 123 } 121 } 124 public: 122 public: 125 column(const std::string& a_name,T* a_user 123 column(const std::string& a_name,T* a_user_var = 0) 126 :m_name(a_name) 124 :m_name(a_name) 127 ,m_tmp(T()) 125 ,m_tmp(T()) 128 ,m_user_var(a_user_var) //not owner 126 ,m_user_var(a_user_var) //not owner 129 {} 127 {} 130 virtual ~column(){} 128 virtual ~column(){} 131 protected: 129 protected: 132 column(const column& a_from) 130 column(const column& a_from) 133 :read::icol(a_from) 131 :read::icol(a_from) 134 ,parent(a_from) 132 ,parent(a_from) 135 ,m_name(a_from.m_name) 133 ,m_name(a_from.m_name) 136 ,m_tmp(a_from.m_tmp) 134 ,m_tmp(a_from.m_tmp) 137 ,m_user_var(a_from.m_user_var) 135 ,m_user_var(a_from.m_user_var) 138 {} 136 {} 139 column& operator=(const column& a_from){ 137 column& operator=(const column& a_from){ 140 m_name = a_from.m_name; 138 m_name = a_from.m_name; 141 m_tmp = a_from.m_tmp; 139 m_tmp = a_from.m_tmp; 142 m_user_var = a_from.m_user_var; 140 m_user_var = a_from.m_user_var; 143 return *this; 141 return *this; 144 } 142 } 145 public: 143 public: 146 // should be used in ntuple _read_line onl 144 // should be used in ntuple _read_line only : 147 void set_value(const T& a_v){m_tmp = a_v;} 145 void set_value(const T& a_v){m_tmp = a_v;} 148 protected: 146 protected: 149 std::string m_name; 147 std::string m_name; 150 T m_tmp; 148 T m_tmp; 151 T* m_user_var; 149 T* m_user_var; 152 }; 150 }; 153 151 154 #ifdef TOOLS_MEM 152 #ifdef TOOLS_MEM 155 public: 153 public: 156 static const std::string& s_class() { 154 static const std::string& s_class() { 157 static const std::string s_v("tools::rcsv: 155 static const std::string s_v("tools::rcsv::ntuple"); 158 return s_v; 156 return s_v; 159 } 157 } 160 #endif 158 #endif 161 public: 159 public: 162 ntuple(std::istream& a_reader) 160 ntuple(std::istream& a_reader) 163 :m_reader(a_reader) 161 :m_reader(a_reader) 164 ,m_title() 162 ,m_title() 165 ,m_sep(0) 163 ,m_sep(0) 166 ,m_vec_sep(';') 164 ,m_vec_sep(';') 167 ,m_sz(0) 165 ,m_sz(0) 168 ,m_rows(-1) 166 ,m_rows(-1) 169 ,m_hippo(false) 167 ,m_hippo(false) 170 { 168 { 171 #ifdef TOOLS_MEM 169 #ifdef TOOLS_MEM 172 mem::increment(s_class().c_str()); 170 mem::increment(s_class().c_str()); 173 #endif 171 #endif 174 } 172 } 175 virtual ~ntuple() { 173 virtual ~ntuple() { 176 safe_clear<read::icol>(m_cols); 174 safe_clear<read::icol>(m_cols); 177 #ifdef TOOLS_MEM 175 #ifdef TOOLS_MEM 178 mem::decrement(s_class().c_str()); 176 mem::decrement(s_class().c_str()); 179 #endif 177 #endif 180 } 178 } 181 protected: 179 protected: 182 ntuple(const ntuple& a_from) 180 ntuple(const ntuple& a_from) 183 :parent(a_from) 181 :parent(a_from) 184 ,m_reader(a_from.m_reader) 182 ,m_reader(a_from.m_reader) 185 ,m_title(a_from.m_title) 183 ,m_title(a_from.m_title) 186 ,m_sep(a_from.m_sep) 184 ,m_sep(a_from.m_sep) 187 ,m_vec_sep(a_from.m_vec_sep) 185 ,m_vec_sep(a_from.m_vec_sep) 188 ,m_sz(a_from.m_sz) 186 ,m_sz(a_from.m_sz) 189 ,m_rows(-1) 187 ,m_rows(-1) 190 ,m_hippo(a_from.m_hippo) 188 ,m_hippo(a_from.m_hippo) 191 { 189 { 192 #ifdef TOOLS_MEM 190 #ifdef TOOLS_MEM 193 mem::increment(s_class().c_str()); 191 mem::increment(s_class().c_str()); 194 #endif 192 #endif 195 } 193 } 196 ntuple& operator=(const ntuple& a_from){ 194 ntuple& operator=(const ntuple& a_from){ 197 m_title = a_from.m_title; 195 m_title = a_from.m_title; 198 m_sep = a_from.m_sep; 196 m_sep = a_from.m_sep; 199 m_vec_sep = a_from.m_vec_sep; 197 m_vec_sep = a_from.m_vec_sep; 200 m_hippo = a_from.m_hippo; 198 m_hippo = a_from.m_hippo; 201 m_rows = a_from.m_rows; 199 m_rows = a_from.m_rows; 202 return *this; 200 return *this; 203 } 201 } 204 public: 202 public: 205 void set_vec_sep(char a_c) {m_vec_sep = a_c; 203 void set_vec_sep(char a_c) {m_vec_sep = a_c;} 206 void set_sep(char a_c) {m_sep = a_c;} 204 void set_sep(char a_c) {m_sep = a_c;} 207 void set_hippo(bool a_hippo) {m_hippo = a_hi 205 void set_hippo(bool a_hippo) {m_hippo = a_hippo;} 208 206 209 std::istream& istrm() {return m_reader;} 207 std::istream& istrm() {return m_reader;} 210 208 211 /* use file::is_hippo for that. 209 /* use file::is_hippo for that. 212 static bool is_hippo(std::ostream& a_out,std 210 static bool is_hippo(std::ostream& a_out,std::istream& a_reader) { 213 // analyse two first data line. 211 // analyse two first data line. 214 212 215 a_reader.clear(); 213 a_reader.clear(); 216 a_reader.seekg(0,std::ios::end); 214 a_reader.seekg(0,std::ios::end); 217 std::streampos sz = a_reader.tellg(); 215 std::streampos sz = a_reader.tellg(); 218 a_reader.seekg(0,std::ios::beg); 216 a_reader.seekg(0,std::ios::beg); 219 if(!sz) { 217 if(!sz) { 220 a_out << "tools::rcsv::ntuple::is_hippo 218 a_out << "tools::rcsv::ntuple::is_hippo :" 221 << " stream is empty." 219 << " stream is empty." 222 << std::endl; 220 << std::endl; 223 return false; 221 return false; 224 } //file empty. 222 } //file empty. 225 223 226 std::string _title; 224 std::string _title; 227 if(!read_line(a_reader,sz,_title)) return 225 if(!read_line(a_reader,sz,_title)) return false; 228 std::string _s; 226 std::string _s; 229 if(!read_line(a_reader,sz,_s)) return fals 227 if(!read_line(a_reader,sz,_s)) return false; 230 if(_s.find('\t')==std::string::npos) retur 228 if(_s.find('\t')==std::string::npos) return false; 231 229 232 //std::vector<std::string> labels; 230 //std::vector<std::string> labels; 233 //words(s,"\t",false,labels); 231 //words(s,"\t",false,labels); 234 //return labels.size()?true:false; 232 //return labels.size()?true:false; 235 233 236 return true; 234 return true; 237 } 235 } 238 */ 236 */ 239 static bool find_sep(std::ostream& a_out, 237 static bool find_sep(std::ostream& a_out, 240 std::istream& a_reader, 238 std::istream& a_reader,bool a_hippo, 241 bool a_verbose, 239 bool a_verbose, 242 char& a_sep){ 240 char& a_sep){ 243 // analyse first data line to find the cha 241 // analyse first data line to find the char separator. 244 242 245 a_reader.clear(); 243 a_reader.clear(); 246 a_reader.seekg(0,std::ios::end); 244 a_reader.seekg(0,std::ios::end); 247 std::streampos sz = a_reader.tellg(); 245 std::streampos sz = a_reader.tellg(); 248 a_reader.seekg(0,std::ios::beg); 246 a_reader.seekg(0,std::ios::beg); 249 if(!sz) { 247 if(!sz) { 250 a_out << "tools::rcsv::ntuple::find_sep 248 a_out << "tools::rcsv::ntuple::find_sep :" 251 << " stream is empty." 249 << " stream is empty." 252 << std::endl; 250 << std::endl; 253 a_sep = 0; 251 a_sep = 0; 254 return false; 252 return false; 255 } //file empty. 253 } //file empty. 256 if(a_verbose) a_out << "file size " << sz 254 if(a_verbose) a_out << "file size " << sz << std::endl; 257 255 258 if(a_hippo) { //skip first two lines : 256 if(a_hippo) { //skip first two lines : 259 if(!skip_line(a_reader,sz)) {a_sep = 0;r 257 if(!skip_line(a_reader,sz)) {a_sep = 0;return false;} 260 if(!skip_line(a_reader,sz)) {a_sep = 0;r 258 if(!skip_line(a_reader,sz)) {a_sep = 0;return false;} 261 } else { 259 } else { 262 while(skip_comment(a_reader,sz)){} 260 while(skip_comment(a_reader,sz)){} 263 } 261 } 264 if(a_reader.tellg()>=sz) {a_sep=0;return f 262 if(a_reader.tellg()>=sz) {a_sep=0;return false;} //no data line. 265 263 266 // get first data line : 264 // get first data line : 267 std::string sfirst; 265 std::string sfirst; 268 {char c; 266 {char c; 269 while(true) { 267 while(true) { 270 if(a_reader.tellg()>=sz) break; 268 if(a_reader.tellg()>=sz) break; 271 a_reader.get(c); 269 a_reader.get(c); 272 if((c==CR())||(c==LF())) break; 270 if((c==CR())||(c==LF())) break; 273 sfirst += c; 271 sfirst += c; 274 }} 272 }} 275 if(sfirst.empty()) { 273 if(sfirst.empty()) { 276 a_out << "tools::rcsv::ntuple::find_set 274 a_out << "tools::rcsv::ntuple::find_set :" 277 << " first datat line is empty." 275 << " first datat line is empty." 278 << std::endl; 276 << std::endl; 279 a_sep = 0; 277 a_sep = 0; 280 return false; 278 return false; 281 } 279 } 282 if(a_verbose) a_out << "first data line \" 280 if(a_verbose) a_out << "first data line \"" << sfirst << "\"" << std::endl; 283 281 284 //guess sep from first data line : 282 //guess sep from first data line : 285 std::istringstream strm(sfirst.c_str()); 283 std::istringstream strm(sfirst.c_str()); 286 double d; 284 double d; 287 strm >> d; 285 strm >> d; 288 std::streampos pos = strm.tellg(); 286 std::streampos pos = strm.tellg(); 289 if(pos==std::streampos(-1)) { 287 if(pos==std::streampos(-1)) { 290 a_out << "tools::rcsv::ntuple::find_sep 288 a_out << "tools::rcsv::ntuple::find_sep :" 291 << " first line does not start wit 289 << " first line does not start with a number." 292 << std::endl; 290 << std::endl; 293 a_sep = 0; 291 a_sep = 0; 294 return false; 292 return false; 295 } //not a number. 293 } //not a number. 296 if(a_verbose) a_out << "first number " << 294 if(a_verbose) a_out << "first number " << d 297 << " ending at pos " < 295 << " ending at pos " << pos << std::endl; 298 if(pos>=(std::streampos)sfirst.size()) { 296 if(pos>=(std::streampos)sfirst.size()) { 299 a_out << "tools::rcsv::ntuple::find_sep 297 a_out << "tools::rcsv::ntuple::find_sep :" 300 << " no separator found in first l 298 << " no separator found in first line." 301 << " pos " << pos 299 << " pos " << pos 302 << " sfirst.size() " << sfirst.siz 300 << " sfirst.size() " << sfirst.size() 303 << std::endl; 301 << std::endl; 304 a_sep = 0; 302 a_sep = 0; 305 return false; 303 return false; 306 } //no sep. 304 } //no sep. 307 305 308 strm.get(a_sep); 306 strm.get(a_sep); 309 307 310 return true; 308 return true; 311 } 309 } 312 310 313 public: 311 public: 314 bool initialize(std::ostream& a_out, 312 bool initialize(std::ostream& a_out, 315 char a_sep = 0, //guessed 313 char a_sep = 0, //guessed 316 const std::string& a_suffix 314 const std::string& a_suffix = "x", //col suffix 317 bool a_verbose = false) { 315 bool a_verbose = false) { 318 safe_clear<read::icol>(m_cols); 316 safe_clear<read::icol>(m_cols); 319 m_sep = 0; 317 m_sep = 0; 320 m_sz = 0; 318 m_sz = 0; 321 m_rows = -1; 319 m_rows = -1; 322 320 323 if(a_suffix.empty()) { 321 if(a_suffix.empty()) { 324 a_out << "tools::rcsv::ntuple::initializ 322 a_out << "tools::rcsv::ntuple::initialize : expect a column suffix." << std::endl; 325 return false; 323 return false; 326 } 324 } 327 325 328 m_reader.clear(); 326 m_reader.clear(); 329 m_reader.seekg(0,std::ios::end); 327 m_reader.seekg(0,std::ios::end); 330 m_sz = m_reader.tellg(); 328 m_sz = m_reader.tellg(); 331 m_reader.seekg(0,std::ios::beg); 329 m_reader.seekg(0,std::ios::beg); 332 if(!m_sz) { 330 if(!m_sz) { 333 a_out << "tools::rcsv::ntuple::initializ 331 a_out << "tools::rcsv::ntuple::initialize :" 334 << " stream is empty." 332 << " stream is empty." 335 << std::endl; 333 << std::endl; 336 return false; //file empty. 334 return false; //file empty. 337 } 335 } 338 if(a_verbose) a_out << "file size " << m_s 336 if(a_verbose) a_out << "file size " << m_sz << std::endl; 339 337 340 std::vector<std::string> labels; 338 std::vector<std::string> labels; 341 if(m_hippo) { //skip first two lines : 339 if(m_hippo) { //skip first two lines : 342 std::string _title; 340 std::string _title; 343 if(!read_line(m_reader,m_sz,_title)) { 341 if(!read_line(m_reader,m_sz,_title)) { 344 a_out << "tools::rcsv::ntuple::initial 342 a_out << "tools::rcsv::ntuple::initialize : read_line() failed." << std::endl; 345 m_sz = 0; 343 m_sz = 0; 346 m_rows = -1; 344 m_rows = -1; 347 return false; 345 return false; 348 } 346 } 349 std::string _s; 347 std::string _s; 350 if(!read_line(m_reader,m_sz,_s)) { 348 if(!read_line(m_reader,m_sz,_s)) { 351 a_out << "tools::rcsv::ntuple::initial 349 a_out << "tools::rcsv::ntuple::initialize : (2) read_line() failed." << std::endl; 352 m_sz = 0; 350 m_sz = 0; 353 m_rows = -1; 351 m_rows = -1; 354 return false; 352 return false; 355 } 353 } 356 words(_s,"\t",false,labels); //false for 354 words(_s,"\t",false,labels); //false for glast.tnt that has a trailing \t. 357 } else { 355 } else { 358 while(skip_comment(m_reader,m_sz)){} 356 while(skip_comment(m_reader,m_sz)){} 359 } 357 } 360 if(m_reader.tellg()>=m_sz) { 358 if(m_reader.tellg()>=m_sz) { 361 a_out << "tools::rcsv::ntuple::initializ 359 a_out << "tools::rcsv::ntuple::initialize : tellg() >= sz." << std::endl; 362 m_sz = 0; 360 m_sz = 0; 363 m_rows = -1; 361 m_rows = -1; 364 return false; 362 return false; 365 } 363 } 366 364 367 // get first data line : 365 // get first data line : 368 std::string sfirst; 366 std::string sfirst; 369 {{char c; 367 {{char c; 370 while(true) { 368 while(true) { 371 if(m_reader.tellg()>=m_sz) break; 369 if(m_reader.tellg()>=m_sz) break; 372 m_reader.get(c); 370 m_reader.get(c); 373 if((c==CR())||(c==LF())) break; 371 if((c==CR())||(c==LF())) break; 374 sfirst += c; 372 sfirst += c; 375 }} 373 }} 376 if(sfirst.empty()) { 374 if(sfirst.empty()) { 377 a_out << "tools::rcsv::ntuple::initializ 375 a_out << "tools::rcsv::ntuple::initialize :" 378 << " first datat line is empty." 376 << " first datat line is empty." 379 << std::endl; 377 << std::endl; 380 m_sz = 0; 378 m_sz = 0; 381 m_rows = -1; 379 m_rows = -1; 382 return false; 380 return false; 383 }} 381 }} 384 if(a_verbose) a_out << "first data line \" 382 if(a_verbose) a_out << "first data line \"" << sfirst << "\"" << std::endl; 385 383 386 if(a_sep) { 384 if(a_sep) { 387 m_sep = a_sep; 385 m_sep = a_sep; 388 } else { 386 } else { 389 //guess sep from first data line : 387 //guess sep from first data line : 390 std::istringstream strm(sfirst.c_str()); 388 std::istringstream strm(sfirst.c_str()); 391 double d; 389 double d; 392 strm >> d; 390 strm >> d; 393 std::streampos pos = strm.tellg(); 391 std::streampos pos = strm.tellg(); 394 if(pos==std::streampos(-1)) { 392 if(pos==std::streampos(-1)) { 395 a_out << "tools::rcsv::ntuple::initial 393 a_out << "tools::rcsv::ntuple::initialize :" 396 << " first line does not start w 394 << " first line does not start with a number." 397 << std::endl; 395 << std::endl; 398 m_sz = 0; 396 m_sz = 0; 399 m_rows = -1; 397 m_rows = -1; 400 return false; 398 return false; 401 } 399 } 402 if(a_verbose) a_out << "first number " < 400 if(a_verbose) a_out << "first number " << d << " ending at pos " << pos << std::endl; 403 if(pos>=(std::streampos)sfirst.size()) { 401 if(pos>=(std::streampos)sfirst.size()) { 404 a_out << "tools::rcsv::ntuple::initial 402 a_out << "tools::rcsv::ntuple::initialize :" 405 << " no separator found in first 403 << " no separator found in first line." 406 << std::endl; 404 << std::endl; 407 m_sz = 0; 405 m_sz = 0; 408 m_rows = -1; 406 m_rows = -1; 409 return false; 407 return false; 410 } 408 } 411 strm.get(m_sep); 409 strm.get(m_sep); 412 } 410 } 413 if(a_verbose) a_out << "sep " << (int)m_se 411 if(a_verbose) a_out << "sep " << (int)m_sep << std::endl; 414 412 415 // in case sep is ' ', there is an ambigui 413 // in case sep is ' ', there is an ambiguity with some leading 416 // space in front of first number. 414 // space in front of first number. 417 if(m_sep==' ') strip(sfirst,leading,' '); 415 if(m_sep==' ') strip(sfirst,leading,' '); 418 416 419 std::vector<std::string> ws; 417 std::vector<std::string> ws; 420 {std::string sep; 418 {std::string sep; 421 sep += m_sep; 419 sep += m_sep; 422 words(sfirst,sep,m_hippo?false:true,ws);} 420 words(sfirst,sep,m_hippo?false:true,ws);} 423 421 424 // look if words are numbers : 422 // look if words are numbers : 425 if(a_verbose) a_out << "words " << ws.size 423 if(a_verbose) a_out << "words " << ws.size() << std::endl; 426 unsigned int index = 0; 424 unsigned int index = 0; 427 std::vector<std::string>::iterator it; 425 std::vector<std::string>::iterator it; 428 for(it=ws.begin();it!=ws.end();++it,index+ 426 for(it=ws.begin();it!=ws.end();++it,index++) { 429 if(a_verbose) a_out << "word " << sout(* 427 if(a_verbose) a_out << "word " << sout(*it) << "" << std::endl; 430 /* with glast.tnt there is trailing \t that wi 428 /* with glast.tnt there is trailing \t that will induce an extra empty column. 431 if((*it).empty()) { 429 if((*it).empty()) { 432 // do not accept : 430 // do not accept : 433 // <num><sep><num><sep><sep><num>... 431 // <num><sep><num><sep><sep><num>... 434 // but accept a trailing <sep> (glast. 432 // but accept a trailing <sep> (glast.tnt) : 435 // <num><sep><num>....<sep><num><sep 433 // <num><sep><num>....<sep><num><sep> 436 if(index==(ws.size()-1)) { 434 if(index==(ws.size()-1)) { 437 break; 435 break; 438 } else { 436 } else { 439 a_out << "tools::rcsv::ntuple::initi 437 a_out << "tools::rcsv::ntuple::initialize :" 440 << " empty word." 438 << " empty word." 441 << std::endl; 439 << std::endl; 442 safe_clear<read::icol>(m_cols); 440 safe_clear<read::icol>(m_cols); 443 m_sep = 0; 441 m_sep = 0; 444 m_sz = 0; 442 m_sz = 0; 445 m_rows = -1; 443 m_rows = -1; 446 return false; 444 return false; 447 } 445 } 448 } 446 } 449 */ 447 */ 450 std::string name = a_suffix; 448 std::string name = a_suffix; 451 if(!numas<uint64>(m_cols.size(),name)){} 449 if(!numas<uint64>(m_cols.size(),name)){} 452 if(m_hippo) { 450 if(m_hippo) { 453 if(index>=labels.size()) { 451 if(index>=labels.size()) { 454 a_out << "tools::rcsv::ntuple::initi 452 a_out << "tools::rcsv::ntuple::initialize :" 455 << " warning : not enough labe 453 << " warning : not enough labels." 456 << std::endl; 454 << std::endl; 457 } else { 455 } else { 458 name = labels[index]; 456 name = labels[index]; 459 } 457 } 460 } 458 } 461 double d; 459 double d; 462 if(to<double>(*it,d)) { 460 if(to<double>(*it,d)) { 463 if(a_verbose) a_out << "number " << d 461 if(a_verbose) a_out << "number " << d << std::endl; 464 create_column<double>(name); 462 create_column<double>(name); 465 } else { 463 } else { 466 time_t time; 464 time_t time; 467 if(s2time(*it,time)) { 465 if(s2time(*it,time)) { 468 create_column<csv_time>(name); 466 create_column<csv_time>(name); 469 } else { 467 } else { 470 std::vector<double> v; 468 std::vector<double> v; 471 std::string vec_sep;vec_sep += m_vec 469 std::string vec_sep;vec_sep += m_vec_sep; 472 if(snums<double>(*it,vec_sep,v)&&v.s 470 if(snums<double>(*it,vec_sep,v)&&v.size()) { 473 create_column< std::vector<double> 471 create_column< std::vector<double> >(name); 474 } else { 472 } else { 475 create_column<std::string>(name); 473 create_column<std::string>(name); 476 } 474 } 477 } 475 } 478 } 476 } 479 } 477 } 480 size_t num = m_cols.size(); 478 size_t num = m_cols.size(); 481 if(!num) { 479 if(!num) { 482 a_out << "tools::rcsv::ntuple::initializ 480 a_out << "tools::rcsv::ntuple::initialize :" 483 << " zero columns." 481 << " zero columns." 484 << std::endl; 482 << std::endl; 485 m_sep = 0; 483 m_sep = 0; 486 m_sz = 0; 484 m_sz = 0; 487 m_rows = -1; 485 m_rows = -1; 488 return false; 486 return false; 489 } 487 } 490 488 491 return true; 489 return true; 492 } 490 } 493 491 494 static const std::string& s_cid(cid a_id) { 492 static const std::string& s_cid(cid a_id) { 495 493 496 #define TOOLS_RCSV_NTUPLE_IF_CID(a__name,a__ty 494 #define TOOLS_RCSV_NTUPLE_IF_CID(a__name,a__type) \ 497 if(a_id==column<a__type>::id_class()) {\ 495 if(a_id==column<a__type>::id_class()) {\ 498 static const std::string s_v(#a__name);\ 496 static const std::string s_v(#a__name);\ 499 return s_v;\ 497 return s_v;\ 500 } 498 } 501 499 502 #define TOOLS_RCSV_NTUPLE_IF_VEC_CID(a__name,a 500 #define TOOLS_RCSV_NTUPLE_IF_VEC_CID(a__name,a__type) \ 503 if(a_id==column< std::vector<a__type> >::i 501 if(a_id==column< std::vector<a__type> >::id_class()) {\ 504 static const std::string s_v(#a__name+st 502 static const std::string s_v(#a__name+std::string("[]"));\ 505 return s_v;\ 503 return s_v;\ 506 } 504 } 507 505 508 TOOLS_RCSV_NTUPLE_IF_CID(char,char) 506 TOOLS_RCSV_NTUPLE_IF_CID(char,char) 509 else TOOLS_RCSV_NTUPLE_IF_CID(short,short) 507 else TOOLS_RCSV_NTUPLE_IF_CID(short,short) 510 else TOOLS_RCSV_NTUPLE_IF_CID(int,int) 508 else TOOLS_RCSV_NTUPLE_IF_CID(int,int) 511 else TOOLS_RCSV_NTUPLE_IF_CID(int64,int64) 509 else TOOLS_RCSV_NTUPLE_IF_CID(int64,int64) 512 510 513 else TOOLS_RCSV_NTUPLE_IF_CID(float,float) 511 else TOOLS_RCSV_NTUPLE_IF_CID(float,float) 514 else TOOLS_RCSV_NTUPLE_IF_CID(double,doubl 512 else TOOLS_RCSV_NTUPLE_IF_CID(double,double) 515 513 516 else TOOLS_RCSV_NTUPLE_IF_CID(uchar,uchar) 514 else TOOLS_RCSV_NTUPLE_IF_CID(uchar,uchar) 517 else TOOLS_RCSV_NTUPLE_IF_CID(ushort,ushor 515 else TOOLS_RCSV_NTUPLE_IF_CID(ushort,ushort) 518 else TOOLS_RCSV_NTUPLE_IF_CID(uint,uint32) 516 else TOOLS_RCSV_NTUPLE_IF_CID(uint,uint32) //WARNING 519 else TOOLS_RCSV_NTUPLE_IF_CID(uint64,uint6 517 else TOOLS_RCSV_NTUPLE_IF_CID(uint64,uint64) 520 518 521 else TOOLS_RCSV_NTUPLE_IF_CID(bool,bool) 519 else TOOLS_RCSV_NTUPLE_IF_CID(bool,bool) 522 else if(a_id==column<std::string>::id_clas 520 else if(a_id==column<std::string>::id_class()) { 523 static const std::string s_v("string"); 521 static const std::string s_v("string"); 524 return s_v; 522 return s_v; 525 } 523 } 526 524 527 else if(a_id==column<csv_time>::id_class() 525 else if(a_id==column<csv_time>::id_class()) { 528 static const std::string s_v("time"); 526 static const std::string s_v("time"); 529 return s_v; 527 return s_v; 530 } 528 } 531 529 532 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(char,cha 530 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(char,char) 533 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(short,sh 531 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(short,short) 534 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(int,int) 532 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(int,int) 535 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(int64,in 533 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(int64,int64) 536 534 537 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(float,fl 535 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(float,float) 538 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(double,d 536 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(double,double) 539 537 540 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(uchar,uc 538 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(uchar,uchar) 541 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(ushort,u 539 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(ushort,ushort) 542 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(uint,uin 540 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(uint,uint32) //WARNING 543 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(uint64,u 541 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(uint64,uint64) 544 542 545 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(bool,boo 543 else TOOLS_RCSV_NTUPLE_IF_VEC_CID(bool,bool) 546 else if(a_id==column< std::vector<std::str 544 else if(a_id==column< std::vector<std::string> >::id_class()) { 547 static const std::string s_v("string[]") 545 static const std::string s_v("string[]"); 548 return s_v; 546 return s_v; 549 } 547 } 550 548 551 #undef TOOLS_RCSV_NTUPLE_IF_CID 549 #undef TOOLS_RCSV_NTUPLE_IF_CID 552 #undef TOOLS_RCSV_NTUPLE_IF_VEC_CID 550 #undef TOOLS_RCSV_NTUPLE_IF_VEC_CID 553 551 554 else { 552 else { 555 static const std::string s_v("unknown"); 553 static const std::string s_v("unknown"); 556 return s_v; 554 return s_v; 557 } 555 } 558 } 556 } 559 557 560 void dump_columns(std::ostream& a_out) const 558 void dump_columns(std::ostream& a_out) const { 561 if((m_sep>=32)&&(m_sep<=126)) { //printabl 559 if((m_sep>=32)&&(m_sep<=126)) { //printable 562 a_out << "separator is '" << m_sep << "' 560 a_out << "separator is '" << m_sep << "'" << std::endl; 563 } else { 561 } else { 564 a_out << "separator is " << (unsigned in 562 a_out << "separator is " << (unsigned int)m_sep << std::endl; 565 } 563 } 566 a_out << "number of columns " << m_cols.si 564 a_out << "number of columns " << m_cols.size() << std::endl; 567 std::vector<read::icol*>::const_iterator i 565 std::vector<read::icol*>::const_iterator it; 568 for(it=m_cols.begin();it!=m_cols.end();++i 566 for(it=m_cols.begin();it!=m_cols.end();++it) { 569 a_out << sout((*it)->name()) 567 a_out << sout((*it)->name()) 570 << " " << s_cid((*it)->id_cls()) 568 << " " << s_cid((*it)->id_cls()) 571 << std::endl; 569 << std::endl; 572 } 570 } 573 } 571 } 574 public: 572 public: 575 typedef std::pair<std::string,std::string> c 573 typedef std::pair<std::string,std::string> col_desc; 576 574 577 bool initialize(std::ostream& a_out,const nt 575 bool initialize(std::ostream& a_out,const ntuple_binding& a_bd = ntuple_binding()) { 578 // it assumes a "commented header". 576 // it assumes a "commented header". 579 577 580 safe_clear<read::icol>(m_cols); 578 safe_clear<read::icol>(m_cols); 581 m_sep = 0; 579 m_sep = 0; 582 m_sz = 0; 580 m_sz = 0; 583 m_rows = -1; 581 m_rows = -1; 584 m_hippo = false; 582 m_hippo = false; 585 583 586 m_reader.clear(); 584 m_reader.clear(); 587 m_reader.seekg(0,std::ios::end); 585 m_reader.seekg(0,std::ios::end); 588 m_sz = m_reader.tellg(); 586 m_sz = m_reader.tellg(); 589 m_reader.seekg(0,std::ios::beg); 587 m_reader.seekg(0,std::ios::beg); 590 if(!m_sz) { 588 if(!m_sz) { 591 a_out << "tools::rcsv::ntuple::initializ 589 a_out << "tools::rcsv::ntuple::initialize(booking) :" 592 << " stream is empty." 590 << " stream is empty." 593 << std::endl; 591 << std::endl; 594 return false; //file empty. 592 return false; //file empty. 595 } 593 } 596 //if(a_verbose) a_out << "file size " << m 594 //if(a_verbose) a_out << "file size " << m_sz << std::endl; 597 595 598 std::string _title; 596 std::string _title; 599 char _sep,_vec_sep; 597 char _sep,_vec_sep; 600 std::vector<col_desc> _cols; 598 std::vector<col_desc> _cols; 601 if(!read_commented_header(a_out,m_reader,_ 599 if(!read_commented_header(a_out,m_reader,_title,_sep,_vec_sep,_cols)) return false; 602 600 603 m_sep = _sep; 601 m_sep = _sep; 604 m_title = std::move(_title); << 602 m_title = _title; 605 603 606 tools_vforcit(col_desc,_cols,it) { 604 tools_vforcit(col_desc,_cols,it) { 607 const std::string& type = (*it).first; 605 const std::string& type = (*it).first; 608 const std::string& name = (*it).second; 606 const std::string& name = (*it).second; 609 607 610 #define TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(a__na 608 #define TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(a__name,a__type) \ 611 if(type==(std::string(#a__name)+"[]")) { 609 if(type==(std::string(#a__name)+"[]")) {\ 612 create_column< std::vector<a__type> >( 610 create_column< std::vector<a__type> >(name,a_bd.find_variable< std::vector<a__type> >(name));\ 613 } 611 } 614 612 615 // see cid2s() for string types. 613 // see cid2s() for string types. 616 614 617 if(type=="char") create_column<ch 615 if(type=="char") create_column<char>(name,a_bd.find_variable<char>(name)); 618 else if(type=="short") create_column<sh 616 else if(type=="short") create_column<short>(name,a_bd.find_variable<short>(name)); 619 else if(type=="int") create_column<in 617 else if(type=="int") create_column<int>(name,a_bd.find_variable<int>(name)); 620 else if(type=="float") create_column<fl 618 else if(type=="float") create_column<float>(name,a_bd.find_variable<float>(name)); 621 else if(type=="double") create_column<do 619 else if(type=="double") create_column<double>(name,a_bd.find_variable<double>(name)); 622 else if(type=="string") create_column<st 620 else if(type=="string") create_column<std::string>(name,a_bd.find_variable<std::string>(name)); 623 621 624 else if(type=="uchar") create_column<un 622 else if(type=="uchar") create_column<unsigned char>(name,a_bd.find_variable<unsigned char>(name)); 625 else if(type=="ushort") create_column<un 623 else if(type=="ushort") create_column<unsigned short>(name,a_bd.find_variable<unsigned short>(name)); 626 else if(type=="uint") create_column<ui 624 else if(type=="uint") create_column<uint32>(name,a_bd.find_variable<uint32>(name)); //WARNING 627 else if(type=="bool") create_column<bo 625 else if(type=="bool") create_column<bool>(name,a_bd.find_variable<bool>(name)); 628 else if(type=="int64") create_column<in 626 else if(type=="int64") create_column<int64>(name,a_bd.find_variable<int64>(name)); 629 else if(type=="uint64") create_column<ui 627 else if(type=="uint64") create_column<uint64>(name,a_bd.find_variable<uint64>(name)); 630 628 631 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(ch 629 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(char,char) 632 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(sh 630 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(short,short) 633 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(in 631 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(int,int) 634 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(fl 632 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(float,float) 635 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(do 633 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(double,double) 636 634 637 else if(type=="string[]") create_column< 635 else if(type=="string[]") create_column< std::vector<std::string> >(name,a_bd.find_variable< std::vector<std::string> >(name)); 638 636 639 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(uc 637 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(uchar,uchar) 640 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(us 638 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(ushort,ushort) 641 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(ui 639 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(uint,uint32) //WARNING 642 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(bo 640 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(bool,bool) 643 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(in 641 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(int64,int64) 644 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(ui 642 else TOOLS_RCSV_NTUPLE_CREATE_VEC_COL(uint64,uint64) 645 643 646 else { 644 else { 647 a_out << "tools::rcsv::ntuple::initial 645 a_out << "tools::rcsv::ntuple::initialize(booking) :" 648 << " unhandled column type " << 646 << " unhandled column type " << sout(type) 649 << std::endl; 647 << std::endl; 650 safe_clear<read::icol>(m_cols); 648 safe_clear<read::icol>(m_cols); 651 m_sep = 0; 649 m_sep = 0; 652 m_sz = 0; 650 m_sz = 0; 653 m_rows = -1; 651 m_rows = -1; 654 m_hippo = false; 652 m_hippo = false; 655 return false; 653 return false; 656 } 654 } 657 655 658 #undef TOOLS_RCSV_NTUPLE_CREATE_VEC_COL 656 #undef TOOLS_RCSV_NTUPLE_CREATE_VEC_COL 659 657 660 } 658 } 661 659 662 size_t num = m_cols.size(); 660 size_t num = m_cols.size(); 663 if(!num) { 661 if(!num) { 664 a_out << "tools::rcsv::ntuple::initializ 662 a_out << "tools::rcsv::ntuple::initialize(booking) :" 665 << " zero columns." 663 << " zero columns." 666 << std::endl; 664 << std::endl; 667 return false; 665 return false; 668 } 666 } 669 667 670 //a_out << "tools::rroot::ntuple::initiali 668 //a_out << "tools::rroot::ntuple::initialize :" 671 // << " number of columns " << num << 669 // << " number of columns " << num << "." 672 // << std::endl; 670 // << std::endl; 673 671 674 return true; 672 return true; 675 } 673 } 676 674 677 bool initialize_from_commented_header(std::o 675 bool initialize_from_commented_header(std::ostream& a_out) { // it assumes a "commented header". 678 std::string _title; 676 std::string _title; 679 char _sep,_vec_sep; 677 char _sep,_vec_sep; 680 std::vector<col_desc> _cols; 678 std::vector<col_desc> _cols; 681 if(!read_commented_header(a_out,m_reader,_ 679 if(!read_commented_header(a_out,m_reader,_title,_sep,_vec_sep,_cols)) return false; 682 ntuple_binding nbd; 680 ntuple_binding nbd; 683 {tools_vforcit(col_desc,_cols,it) nbd.add_c 681 {tools_vforcit(col_desc,_cols,it) nbd.add_column_no_var((*it).second);} //user_var is 0. 684 return initialize(a_out,nbd); 682 return initialize(a_out,nbd); 685 } 683 } 686 684 687 bool get_row() const { 685 bool get_row() const { 688 bool status = true; 686 bool status = true; 689 tools_vforcit(read::icol*,m_cols,it) { 687 tools_vforcit(read::icol*,m_cols,it) { 690 if(!(*it)->fetch_entry()) status = false 688 if(!(*it)->fetch_entry()) status = false; 691 } 689 } 692 return status; 690 return status; 693 } 691 } 694 692 695 protected: 693 protected: 696 bool read_commented_header(std::ostream& a_o 694 bool read_commented_header(std::ostream& a_out,std::istream& a_reader, 697 std::string& a_ti 695 std::string& a_title,char& a_sep,char& a_vec_sep,std::vector<col_desc>& a_cols) { 698 // analyse first lines starting with '#'. 696 // analyse first lines starting with '#'. 699 a_title.clear(); 697 a_title.clear(); 700 a_sep = 0; 698 a_sep = 0; 701 a_cols.clear(); 699 a_cols.clear(); 702 700 703 a_reader.clear(); 701 a_reader.clear(); 704 a_reader.seekg(0,std::ios::end); 702 a_reader.seekg(0,std::ios::end); 705 std::streampos sz = a_reader.tellg(); 703 std::streampos sz = a_reader.tellg(); 706 a_reader.seekg(0,std::ios::beg); 704 a_reader.seekg(0,std::ios::beg); 707 if(!sz) { 705 if(!sz) { 708 a_out << "tools::rcsv::ntuple::read_comm 706 a_out << "tools::rcsv::ntuple::read_commented_header :" 709 << " stream is empty." 707 << " stream is empty." 710 << std::endl; 708 << std::endl; 711 return false; 709 return false; 712 } //file empty. 710 } //file empty. 713 711 714 712 715 std::string _class; 713 std::string _class; 716 714 717 while(true) { 715 while(true) { 718 if(a_reader.tellg()>=sz) break; 716 if(a_reader.tellg()>=sz) break; 719 //we should be at bol : 717 //we should be at bol : 720 char c; 718 char c; 721 a_reader.get(c); 719 a_reader.get(c); 722 a_reader.putback(c); 720 a_reader.putback(c); 723 if(c!='#') break; //finished, probably a 721 if(c!='#') break; //finished, probably a data line now. 724 std::string line; 722 std::string line; 725 if(!read_line(a_reader,sz,line)) break; 723 if(!read_line(a_reader,sz,line)) break; //or return false ? 726 724 727 std::vector<std::string> _words; 725 std::vector<std::string> _words; 728 words(line," ",false,_words); 726 words(line," ",false,_words); 729 if(!_words.size()) { 727 if(!_words.size()) { 730 a_out << "tools::rcsv::ntuple::read_co 728 a_out << "tools::rcsv::ntuple::read_commented_header :" 731 << " syntax error : empty header 729 << " syntax error : empty header line." 732 << std::endl; 730 << std::endl; 733 return false; 731 return false; 734 } 732 } 735 if((_words[0]=="#class")) { 733 if((_words[0]=="#class")) { 736 if(_words.size()!=2) { 734 if(_words.size()!=2) { 737 a_out << "tools::rcsv::ntuple::read_ 735 a_out << "tools::rcsv::ntuple::read_commented_header :" 738 << " syntax error in " << sout 736 << " syntax error in " << sout(line) 739 << std::endl; 737 << std::endl; 740 return false; 738 return false; 741 } 739 } 742 _class = _words[1]; 740 _class = _words[1]; 743 } else if(_words[0]=="#title") { 741 } else if(_words[0]=="#title") { 744 if(_words.size()<1) { 742 if(_words.size()<1) { 745 a_out << "tools::rcsv::ntuple::read_ 743 a_out << "tools::rcsv::ntuple::read_commented_header :" 746 << " syntax error in " << sout 744 << " syntax error in " << sout(line) 747 << std::endl; 745 << std::endl; 748 return false; 746 return false; 749 } 747 } 750 if(_words.size()==1) { 748 if(_words.size()==1) { 751 a_title.clear(); 749 a_title.clear(); 752 } else { 750 } else { 753 std::string::size_type pos = line.fi 751 std::string::size_type pos = line.find(_words[0]); 754 pos += _words[0].size()+1; 752 pos += _words[0].size()+1; 755 a_title = line.substr(pos,line.size( 753 a_title = line.substr(pos,line.size()-pos); 756 } 754 } 757 } else if((_words[0]=="#separator")) { 755 } else if((_words[0]=="#separator")) { 758 if(_words.size()!=2) { 756 if(_words.size()!=2) { 759 a_out << "tools::rcsv::ntuple::read_ 757 a_out << "tools::rcsv::ntuple::read_commented_header :" 760 << " syntax error in " << sout 758 << " syntax error in " << sout(line) 761 << std::endl; 759 << std::endl; 762 return false; 760 return false; 763 } 761 } 764 unsigned int uisep; 762 unsigned int uisep; 765 if(!to(_words[1],uisep)) { 763 if(!to(_words[1],uisep)) { 766 a_out << "tools::rcsv::ntuple::read_ 764 a_out << "tools::rcsv::ntuple::read_commented_header :" 767 << " syntax error in " << sout 765 << " syntax error in " << sout(line) 768 << std::endl; 766 << std::endl; 769 return false; 767 return false; 770 } 768 } 771 a_sep = (char)uisep; 769 a_sep = (char)uisep; 772 } else if((_words[0]=="#vector_separator 770 } else if((_words[0]=="#vector_separator")) { 773 if(_words.size()!=2) { 771 if(_words.size()!=2) { 774 a_out << "tools::rcsv::ntuple::read_ 772 a_out << "tools::rcsv::ntuple::read_commented_header :" 775 << " syntax error in " << sout 773 << " syntax error in " << sout(line) 776 << std::endl; 774 << std::endl; 777 return false; 775 return false; 778 } 776 } 779 unsigned int uisep; 777 unsigned int uisep; 780 if(!to(_words[1],uisep)) { 778 if(!to(_words[1],uisep)) { 781 a_out << "tools::rcsv::ntuple::read_ 779 a_out << "tools::rcsv::ntuple::read_commented_header :" 782 << " syntax error in " << sout 780 << " syntax error in " << sout(line) 783 << std::endl; 781 << std::endl; 784 return false; 782 return false; 785 } 783 } 786 a_vec_sep = (char)uisep; 784 a_vec_sep = (char)uisep; 787 } else if((_words[0]=="#column")) { 785 } else if((_words[0]=="#column")) { 788 if(_words.size()<2) { 786 if(_words.size()<2) { 789 a_out << "tools::rcsv::ntuple::read_ 787 a_out << "tools::rcsv::ntuple::read_commented_header :" 790 << " syntax error in " << sout 788 << " syntax error in " << sout(line) 791 << std::endl; 789 << std::endl; 792 return false; 790 return false; 793 } 791 } 794 std::string stype = _words[1]; 792 std::string stype = _words[1]; 795 std::string label; 793 std::string label; 796 if(_words.size()==2) { 794 if(_words.size()==2) { 797 label.clear(); 795 label.clear(); 798 } else { 796 } else { 799 std::string::size_type pos = line.fi 797 std::string::size_type pos = line.find(_words[1]); 800 pos += _words[1].size()+1; 798 pos += _words[1].size()+1; 801 label = line.substr(pos,line.size()- 799 label = line.substr(pos,line.size()-pos); 802 } 800 } 803 //a_out << "column " << stype << " " < 801 //a_out << "column " << stype << " " << sout(label) << std::endl; 804 a_cols.push_back(col_desc(stype,label) 802 a_cols.push_back(col_desc(stype,label)); 805 } else { 803 } else { 806 a_out << "tools::rcsv::ntuple::read_co 804 a_out << "tools::rcsv::ntuple::read_commented_header :" 807 << " syntax error in " << sout(l 805 << " syntax error in " << sout(line) 808 << ", unknown keyword " << sout( 806 << ", unknown keyword " << sout(_words[0]) 809 << std::endl; 807 << std::endl; 810 //return false; 808 //return false; 811 } 809 } 812 } 810 } 813 811 814 /* 812 /* 815 a_out << "class " << _class << std::endl; 813 a_out << "class " << _class << std::endl; 816 a_out << "title " << _title << std::endl; 814 a_out << "title " << _title << std::endl; 817 a_out << "separator " << _separator << std 815 a_out << "separator " << _separator << std::endl; 818 */ 816 */ 819 817 820 return true; 818 return true; 821 } 819 } 822 820 823 protected: 821 protected: 824 template <class T> 822 template <class T> 825 column<T>* create_column(const std::string& 823 column<T>* create_column(const std::string& a_name,T* a_user_var = 0){ 826 if(find_named<read::icol>(m_cols,a_name)) 824 if(find_named<read::icol>(m_cols,a_name)) return 0; 827 column<T>* col = new column<T>(a_name,a_us 825 column<T>* col = new column<T>(a_name,a_user_var); 828 if(!col) return 0; 826 if(!col) return 0; 829 m_cols.push_back(col); 827 m_cols.push_back(col); 830 return col; 828 return col; 831 } 829 } 832 830 833 protected: 831 protected: 834 static bool read_line(std::istream& a_reader 832 static bool read_line(std::istream& a_reader,std::streampos a_sz,std::string& a_s){ 835 a_s.clear(); 833 a_s.clear(); 836 char c; 834 char c; 837 while(true) { 835 while(true) { 838 if(a_reader.tellg()>=a_sz) {a_s.clear(); 836 if(a_reader.tellg()>=a_sz) {a_s.clear();return false;} 839 a_reader.get(c); 837 a_reader.get(c); 840 if(c==CR()) continue; 838 if(c==CR()) continue; 841 if(c==LF()) break; //eol. 839 if(c==LF()) break; //eol. 842 a_s += c; 840 a_s += c; 843 } 841 } 844 return true; 842 return true; 845 } 843 } 846 844 847 static bool skip_line(std::istream& a_reader 845 static bool skip_line(std::istream& a_reader,std::streampos a_sz){ 848 char c; 846 char c; 849 while(true) { 847 while(true) { 850 if(a_reader.tellg()>=a_sz) return false; 848 if(a_reader.tellg()>=a_sz) return false; 851 a_reader.get(c); 849 a_reader.get(c); 852 if(c==LF()) break; 850 if(c==LF()) break; 853 } 851 } 854 return true; 852 return true; 855 } 853 } 856 854 857 static bool skip_comment(std::istream& a_rea 855 static bool skip_comment(std::istream& a_reader,std::streampos a_sz){ 858 //ret true = we had a commented line, fals 856 //ret true = we had a commented line, false : a data line or nothing. 859 if(a_reader.tellg()>=a_sz) return false; 857 if(a_reader.tellg()>=a_sz) return false; 860 //we should be at bol : 858 //we should be at bol : 861 char c; 859 char c; 862 a_reader.get(c); 860 a_reader.get(c); 863 if(c=='#') { 861 if(c=='#') { 864 return skip_line(a_reader,a_sz); 862 return skip_line(a_reader,a_sz); 865 //eol. Next char should be bol. 863 //eol. Next char should be bol. 866 } else { 864 } else { 867 a_reader.putback(c); 865 a_reader.putback(c); 868 return false; 866 return false; 869 } 867 } 870 } 868 } 871 869 872 template <class T> 870 template <class T> 873 static bool _read(std::istream& a_reader,std 871 static bool _read(std::istream& a_reader,std::streampos,char,T& a_v) { 874 a_reader >> a_v; 872 a_reader >> a_v; 875 if(a_reader.tellg()==std::streampos(-1)) { 873 if(a_reader.tellg()==std::streampos(-1)) {a_v = 0;return false;} 876 //std::cout << "debug : _read(double) " << 874 //std::cout << "debug : _read(double) " << a_v << std::endl; 877 return true; 875 return true; 878 } 876 } 879 static bool _read_time(std::istream& a_reade 877 static bool _read_time(std::istream& a_reader,std::streampos a_sz,char a_sep,time_t& a_v) { 880 std::string _s; 878 std::string _s; 881 char c; 879 char c; 882 while(true){ 880 while(true){ 883 if(a_reader.tellg()>=a_sz) break; 881 if(a_reader.tellg()>=a_sz) break; 884 a_reader.get(c); 882 a_reader.get(c); 885 if((c==a_sep)||(c==CR())||(c==LF())) { 883 if((c==a_sep)||(c==CR())||(c==LF())) { 886 a_reader.putback(c); 884 a_reader.putback(c); 887 break; 885 break; 888 } 886 } 889 _s += c; 887 _s += c; 890 } 888 } 891 if(!s2time(_s,a_v)) return false; 889 if(!s2time(_s,a_v)) return false; 892 return true; 890 return true; 893 } 891 } 894 static bool _read(std::istream& a_reader,std 892 static bool _read(std::istream& a_reader,std::streampos a_sz,char a_sep,std::string& a_v) { 895 a_v.clear(); 893 a_v.clear(); 896 char c; 894 char c; 897 while(true){ 895 while(true){ 898 if(a_reader.tellg()>=a_sz) break; 896 if(a_reader.tellg()>=a_sz) break; 899 a_reader.get(c); 897 a_reader.get(c); 900 if((c==a_sep)||(c==CR())||(c==LF())) { 898 if((c==a_sep)||(c==CR())||(c==LF())) { 901 a_reader.putback(c); 899 a_reader.putback(c); 902 break; 900 break; 903 } 901 } 904 a_v += c; 902 a_v += c; 905 } 903 } 906 return true; 904 return true; 907 } 905 } 908 906 909 static bool _vec_read(std::istream& a_reader 907 static bool _vec_read(std::istream& a_reader,std::streampos a_sz, 910 std::istringstream&,st 908 std::istringstream&,std::vector<std::string>&, 911 char a_sep,const std:: 909 char a_sep,const std::string& a_vec_sep, 912 std::vector<std::strin 910 std::vector<std::string>& a_v) { 913 std::string _s; 911 std::string _s; 914 if(!_read(a_reader,a_sz,a_sep,_s)) return 912 if(!_read(a_reader,a_sz,a_sep,_s)) return false; 915 //replace(_s,"\\"+a_vec_sep,"@@"); 913 //replace(_s,"\\"+a_vec_sep,"@@"); 916 words(_s,a_vec_sep,true,a_v); 914 words(_s,a_vec_sep,true,a_v); 917 //tools_vforit(std::string,a_v,it) replace 915 //tools_vforit(std::string,a_v,it) replace(*it,"@@",a_vec_sep); 918 return true; 916 return true; 919 } 917 } 920 918 921 template <class T> 919 template <class T> 922 static bool _vec_read(std::istream& a_reader 920 static bool _vec_read(std::istream& a_reader,std::streampos a_sz, 923 std::istringstream& a_ 921 std::istringstream& a_iss,std::vector<std::string>& a_tmp, 924 char a_sep,const std:: 922 char a_sep,const std::string& a_vec_sep, 925 std::vector<T>& a_v) { 923 std::vector<T>& a_v) { 926 std::string _s; 924 std::string _s; 927 if(!_read(a_reader,a_sz,a_sep,_s)) return 925 if(!_read(a_reader,a_sz,a_sep,_s)) return false; 928 if(!snums<T>(_s,a_iss,a_tmp,a_vec_sep,a_v) 926 if(!snums<T>(_s,a_iss,a_tmp,a_vec_sep,a_v)) return false; 929 return true; 927 return true; 930 } 928 } 931 929 932 protected: 930 protected: 933 bool _read_line() { 931 bool _read_line() { 934 // have to loop on all columns ! 932 // have to loop on all columns ! 935 typedef read::icol icol_t; 933 typedef read::icol icol_t; 936 934 937 typedef ntuple::column<char> col_char; 935 typedef ntuple::column<char> col_char; 938 typedef ntuple::column<short> col_short; 936 typedef ntuple::column<short> col_short; 939 typedef ntuple::column<int> col_int; 937 typedef ntuple::column<int> col_int; 940 typedef ntuple::column<float> col_float; 938 typedef ntuple::column<float> col_float; 941 typedef ntuple::column<double> col_double; 939 typedef ntuple::column<double> col_double; 942 typedef std::string string_t; 940 typedef std::string string_t; 943 typedef ntuple::column<string_t> col_strin 941 typedef ntuple::column<string_t> col_string_t; 944 942 945 typedef ntuple::column<uchar> col_uchar; 943 typedef ntuple::column<uchar> col_uchar; 946 typedef ntuple::column<ushort> col_ushort; 944 typedef ntuple::column<ushort> col_ushort; 947 typedef ntuple::column<uint32> col_uint32; 945 typedef ntuple::column<uint32> col_uint32; 948 typedef ntuple::column<bool> col_bool; 946 typedef ntuple::column<bool> col_bool; 949 typedef ntuple::column<int64> col_int64; 947 typedef ntuple::column<int64> col_int64; 950 typedef ntuple::column<uint64> col_uint64; 948 typedef ntuple::column<uint64> col_uint64; 951 949 952 typedef ntuple::column<csv_time> col_time; 950 typedef ntuple::column<csv_time> col_time; 953 951 954 typedef ntuple::column< std::vector<char> 952 typedef ntuple::column< std::vector<char> > col_vec_char; 955 typedef ntuple::column< std::vector<short> 953 typedef ntuple::column< std::vector<short> > col_vec_short; 956 typedef ntuple::column< std::vector<int32> 954 typedef ntuple::column< std::vector<int32> > col_vec_int; 957 typedef ntuple::column< std::vector<float> 955 typedef ntuple::column< std::vector<float> > col_vec_float; 958 typedef ntuple::column< std::vector<double 956 typedef ntuple::column< std::vector<double> > col_vec_double; 959 typedef ntuple::column< std::vector<std::s 957 typedef ntuple::column< std::vector<std::string> > col_vec_string_t; 960 958 961 typedef ntuple::column< std::vector<uchar> 959 typedef ntuple::column< std::vector<uchar> > col_vec_uchar; 962 typedef ntuple::column< std::vector<ushort 960 typedef ntuple::column< std::vector<ushort> > col_vec_ushort; 963 typedef ntuple::column< std::vector<uint32 961 typedef ntuple::column< std::vector<uint32> > col_vec_uint32; 964 typedef ntuple::column< std::vector<bool> 962 typedef ntuple::column< std::vector<bool> > col_vec_bool; 965 typedef ntuple::column< std::vector<int64> 963 typedef ntuple::column< std::vector<int64> > col_vec_int64; 966 typedef ntuple::column< std::vector<uint64 964 typedef ntuple::column< std::vector<uint64> > col_vec_uint64; 967 965 968 std::string vec_sep;vec_sep += m_vec_sep; 966 std::string vec_sep;vec_sep += m_vec_sep; 969 std::istringstream iss; 967 std::istringstream iss; 970 std::vector<std::string> tmp; 968 std::vector<std::string> tmp; 971 969 972 size_t index = 0; 970 size_t index = 0; 973 size_t num = m_cols.size(); 971 size_t num = m_cols.size(); 974 std::vector<icol_t*>::const_iterator it; 972 std::vector<icol_t*>::const_iterator it; 975 for(it=m_cols.begin();it!=m_cols.end();++i 973 for(it=m_cols.begin();it!=m_cols.end();++it,index++) { 976 974 977 #define TOOLS_RCSV_NTUPLE_IF_COL(a__type) \ 975 #define TOOLS_RCSV_NTUPLE_IF_COL(a__type) \ 978 if(col_##a__type* _col_##a__type = id_ca 976 if(col_##a__type* _col_##a__type = id_cast<icol_t,col_##a__type>(*(*it))) {\ 979 a__type v;\ 977 a__type v;\ 980 if(!_read(m_reader,m_sz,m_sep,v)) retu 978 if(!_read(m_reader,m_sz,m_sep,v)) return false;\ 981 _col_##a__type->set_value(v);\ 979 _col_##a__type->set_value(v);\ 982 } 980 } 983 981 984 #define TOOLS_RCSV_NTUPLE_IF_VEC_COL(a__type) 982 #define TOOLS_RCSV_NTUPLE_IF_VEC_COL(a__type) \ 985 if(col_vec_##a__type* _col_vec_##a__type 983 if(col_vec_##a__type* _col_vec_##a__type = id_cast<icol_t,col_vec_##a__type>(*(*it))) {\ 986 std::vector<a__type> v;\ 984 std::vector<a__type> v;\ 987 if(!_vec_read(m_reader,m_sz,iss,tmp,m_ 985 if(!_vec_read(m_reader,m_sz,iss,tmp,m_sep,vec_sep,v)) return false;\ 988 _col_vec_##a__type->set_value(v);\ 986 _col_vec_##a__type->set_value(v);\ 989 } 987 } 990 988 991 TOOLS_RCSV_NTUPLE_IF_COL(char) 989 TOOLS_RCSV_NTUPLE_IF_COL(char) 992 else TOOLS_RCSV_NTUPLE_IF_COL(short) 990 else TOOLS_RCSV_NTUPLE_IF_COL(short) 993 else TOOLS_RCSV_NTUPLE_IF_COL(int) 991 else TOOLS_RCSV_NTUPLE_IF_COL(int) 994 else TOOLS_RCSV_NTUPLE_IF_COL(float) 992 else TOOLS_RCSV_NTUPLE_IF_COL(float) 995 else TOOLS_RCSV_NTUPLE_IF_COL(double) 993 else TOOLS_RCSV_NTUPLE_IF_COL(double) 996 else TOOLS_RCSV_NTUPLE_IF_COL(string_t) 994 else TOOLS_RCSV_NTUPLE_IF_COL(string_t) 997 995 998 else TOOLS_RCSV_NTUPLE_IF_COL(uchar) 996 else TOOLS_RCSV_NTUPLE_IF_COL(uchar) 999 else TOOLS_RCSV_NTUPLE_IF_COL(ushort) 997 else TOOLS_RCSV_NTUPLE_IF_COL(ushort) 1000 else TOOLS_RCSV_NTUPLE_IF_COL(uint32) 998 else TOOLS_RCSV_NTUPLE_IF_COL(uint32) 1001 else TOOLS_RCSV_NTUPLE_IF_COL(bool) 999 else TOOLS_RCSV_NTUPLE_IF_COL(bool) 1002 else TOOLS_RCSV_NTUPLE_IF_COL(int64) 1000 else TOOLS_RCSV_NTUPLE_IF_COL(int64) 1003 else TOOLS_RCSV_NTUPLE_IF_COL(uint64) 1001 else TOOLS_RCSV_NTUPLE_IF_COL(uint64) 1004 1002 1005 else if(col_time* _col_time = id_cast<i 1003 else if(col_time* _col_time = id_cast<icol_t,col_time>(*(*it))) { 1006 time_t v; 1004 time_t v; 1007 if(!_read_time(m_reader,m_sz,m_sep,v) 1005 if(!_read_time(m_reader,m_sz,m_sep,v)) return false; 1008 csv_time ct;ct.m_l = long(v); 1006 csv_time ct;ct.m_l = long(v); 1009 _col_time->set_value(ct); 1007 _col_time->set_value(ct); 1010 } 1008 } 1011 1009 1012 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(char) 1010 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(char) 1013 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(short 1011 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(short) 1014 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(int) 1012 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(int) 1015 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(float 1013 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(float) 1016 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(doubl 1014 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(double) 1017 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(strin 1015 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(string_t) 1018 1016 1019 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(uchar 1017 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(uchar) 1020 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(ushor 1018 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(ushort) 1021 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(uint3 1019 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(uint32) 1022 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(bool) 1020 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(bool) 1023 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(int64 1021 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(int64) 1024 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(uint6 1022 else TOOLS_RCSV_NTUPLE_IF_VEC_COL(uint64) 1025 1023 1026 #undef TOOLS_RCSV_NTUPLE_IF_COL 1024 #undef TOOLS_RCSV_NTUPLE_IF_COL 1027 #undef TOOLS_RCSV_NTUPLE_IF_VEC_COL 1025 #undef TOOLS_RCSV_NTUPLE_IF_VEC_COL 1028 1026 1029 else { 1027 else { 1030 //std::cout << "column cast failed." 1028 //std::cout << "column cast failed." << std::endl; 1031 return false; 1029 return false; 1032 } 1030 } 1033 1031 1034 if(index==(num-1)) { //read up to LF() 1032 if(index==(num-1)) { //read up to LF() 1035 char c; 1033 char c; 1036 while(true){ 1034 while(true){ 1037 if(m_reader.tellg()>=m_sz) break; 1035 if(m_reader.tellg()>=m_sz) break; 1038 m_reader.get(c); 1036 m_reader.get(c); 1039 if(c==LF()) break; 1037 if(c==LF()) break; 1040 } 1038 } 1041 } else { //read sep : 1039 } else { //read sep : 1042 char sep; 1040 char sep; 1043 m_reader.get(sep); 1041 m_reader.get(sep); 1044 } 1042 } 1045 } 1043 } 1046 return true; 1044 return true; 1047 } 1045 } 1048 protected: 1046 protected: 1049 std::istream& m_reader; 1047 std::istream& m_reader; 1050 std::string m_title; 1048 std::string m_title; 1051 char m_sep; 1049 char m_sep; 1052 char m_vec_sep; 1050 char m_vec_sep; 1053 std::vector<read::icol*> m_cols; 1051 std::vector<read::icol*> m_cols; 1054 std::streampos m_sz; 1052 std::streampos m_sz; 1055 int m_rows; //to optimize number_of_entries 1053 int m_rows; //to optimize number_of_entries(). 1056 bool m_hippo; 1054 bool m_hippo; 1057 }; 1055 }; 1058 1056 1059 }} 1057 }} 1060 1058 1061 1059 1062 #include <fstream> 1060 #include <fstream> 1063 1061 1064 namespace tools { 1062 namespace tools { 1065 namespace rcsv { 1063 namespace rcsv { 1066 1064 1067 class fntuple : public ntuple { 1065 class fntuple : public ntuple { 1068 typedef ntuple parent; 1066 typedef ntuple parent; 1069 public: 1067 public: 1070 static const std::string& s_class() { 1068 static const std::string& s_class() { 1071 static const std::string s_v("tools::rcsv 1069 static const std::string s_v("tools::rcsv::fntuple"); 1072 return s_v; 1070 return s_v; 1073 } 1071 } 1074 public: 1072 public: 1075 fntuple(const std::string& a_file) 1073 fntuple(const std::string& a_file) 1076 :parent(m_freader) 1074 :parent(m_freader) 1077 ,m_file(a_file) 1075 ,m_file(a_file) 1078 {} 1076 {} 1079 virtual ~fntuple() {m_freader.close();} 1077 virtual ~fntuple() {m_freader.close();} 1080 protected: 1078 protected: 1081 fntuple(const fntuple& a_from) 1079 fntuple(const fntuple& a_from) 1082 :read::intuple(a_from) 1080 :read::intuple(a_from) 1083 ,parent(a_from) 1081 ,parent(a_from) 1084 ,m_file(a_from.m_file) 1082 ,m_file(a_from.m_file) 1085 {} 1083 {} 1086 fntuple& operator=(const fntuple& a_from){ 1084 fntuple& operator=(const fntuple& a_from){ 1087 parent::operator=(a_from); 1085 parent::operator=(a_from); 1088 m_file = a_from.m_file; 1086 m_file = a_from.m_file; 1089 return *this; 1087 return *this; 1090 } 1088 } 1091 public: 1089 public: 1092 bool open(){ 1090 bool open(){ 1093 m_freader.open(m_file.c_str()); 1091 m_freader.open(m_file.c_str()); 1094 return m_freader.fail()?false:true; 1092 return m_freader.fail()?false:true; 1095 } 1093 } 1096 bool initialize(std::ostream& a_out, 1094 bool initialize(std::ostream& a_out, 1097 char a_sep = 0, //guessed 1095 char a_sep = 0, //guessed 1098 const std::string& a_suffix 1096 const std::string& a_suffix = "x", //col suffix 1099 bool a_verbose = false) { 1097 bool a_verbose = false) { 1100 if(!m_freader.is_open()) { 1098 if(!m_freader.is_open()) { 1101 m_freader.open(m_file.c_str()); 1099 m_freader.open(m_file.c_str()); 1102 if(m_freader.fail()) { 1100 if(m_freader.fail()) { 1103 a_out << "tools::rcsv::fntuple::initi 1101 a_out << "tools::rcsv::fntuple::initialize :" 1104 << " can't open " << m_file << 1102 << " can't open " << m_file << "." 1105 << std::endl; 1103 << std::endl; 1106 return false; 1104 return false; 1107 } 1105 } 1108 } 1106 } 1109 return parent::initialize(a_out,a_sep,a_s 1107 return parent::initialize(a_out,a_sep,a_suffix,a_verbose); 1110 } 1108 } 1111 protected: 1109 protected: 1112 std::string m_file; 1110 std::string m_file; 1113 std::ifstream m_freader; 1111 std::ifstream m_freader; 1114 }; 1112 }; 1115 1113 1116 }} 1114 }} 1117 1115 1118 #endif 1116 #endif