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_rntuple 00005 #define inlib_rntuple 00006 00007 // interfaces to read ntuple. 00008 00009 #include "scast" 00010 00011 #include <string> 00012 #include <vector> 00013 00014 namespace inlib { 00015 namespace read { 00016 00017 class icol { 00018 public: 00019 virtual ~icol(){} 00020 public: 00021 virtual void* cast(cid) const = 0; 00022 virtual cid id_cls() const = 0; 00023 public: 00024 virtual const std::string& name() const = 0; 00025 public: 00026 virtual void stop() {} 00027 }; 00028 00029 template <class T> 00030 class icolumn : public virtual icol { 00031 public: 00032 static cid id_class() { 00033 static const T s_v = T(); //do that for T = std::string. 00034 return _cid(s_v); 00035 } 00036 public: //icol 00037 virtual void* cast(cid a_class) const { 00038 if(void* p = cmp_cast<icolumn>(this,a_class)) {return p;} 00039 else return 0; 00040 } 00041 virtual cid id_cls() const {return id_class();} 00042 public: 00043 virtual ~icolumn(){} 00044 public: 00045 virtual bool get_entry(T&) const = 0; 00046 }; 00047 00048 class intuple { 00049 public: 00050 virtual ~intuple(){} 00051 public: 00052 virtual void start() = 0; 00053 virtual bool next() = 0; 00054 virtual icol* find_icol(const std::string&) = 0; 00055 virtual const std::vector<icol*>& columns() const = 0; 00056 public: 00057 virtual void stop() {} 00058 public: 00059 template <class T> 00060 icolumn<T>* find_column(const std::string& a_name){ 00061 read::icol* col = find_icol(a_name); 00062 if(!col) return 0; 00063 return inlib::id_cast<read::icol, icolumn<T> >(*col); 00064 } 00065 }; 00066 00067 }} 00068 00069 #include "typedefs" 00070 #include "mnmx" 00071 00072 namespace inlib { 00073 namespace read { 00074 00075 template <class T> 00076 inline bool column_infos(intuple& a_ntu, 00077 const icolumn<T>& a_col, 00078 T& a_mn,T& a_mx, 00079 T& a_S,T& a_S2, 00080 inlib::uint64& a_count){ 00081 a_mn = T(); 00082 a_mx = T(); 00083 a_S = T(); 00084 a_S2 = T(); 00085 a_count = 0; 00086 00087 T v; 00088 00089 a_ntu.start(); 00090 if(a_ntu.next()){ 00091 if(!a_col.get_entry(v)) { 00092 a_mn = T(); 00093 a_mx = T(); 00094 a_S = T(); 00095 a_S2 = T(); 00096 a_count = 0; 00097 return false; 00098 } 00099 a_mn = v; 00100 a_mx = v; 00101 a_S = v; 00102 a_S2 = v*v; 00103 a_count++; 00104 } 00105 00106 while(a_ntu.next()){ 00107 if(!a_col.get_entry(v)) { 00108 a_mn = T(); 00109 a_mx = T(); 00110 a_S = T(); 00111 a_S2 = T(); 00112 a_count = 0; 00113 return false; 00114 } 00115 a_mn = inlib::mn<T>(a_mn,v); 00116 a_mx = inlib::mx<T>(a_mx,v); 00117 a_S += v; 00118 a_S2 += v*v; 00119 a_count++; 00120 } 00121 00122 return true; 00123 } 00124 00125 }} 00126 00127 #include <cmath> 00128 #include "cids" 00129 00130 namespace inlib { 00131 namespace read { 00132 00133 inline bool mean_rms(intuple& a_ntu, 00134 const icol& a_col, 00135 double& a_mean,double& a_rms){ 00136 a_mean = 0; 00137 a_rms = 0; 00138 typedef icolumn<int> icoli_t; 00139 typedef icolumn<float> icolf_t; 00140 typedef icolumn<double> icold_t; 00141 if(const icoli_t* ci = id_cast<icol, icoli_t >(a_col) ){ 00142 int mn,mx,S,S2; 00143 uint64 count; 00144 if(!column_infos<int>(a_ntu,*ci,mn,mx,S,S2,count)) return false; 00145 if(!count) return false; 00146 a_mean = S/double(count); 00147 a_rms = ::sqrt(::fabs(S2/double(count)-a_mean*a_mean)); 00148 return true; 00149 00150 } else if(const icolf_t* cf = id_cast<icol, icolf_t >(a_col) ){ 00151 float mn,mx,S,S2; 00152 uint64 count; 00153 if(!column_infos<float>(a_ntu,*cf,mn,mx,S,S2,count)) return false; 00154 if(!count) return false; 00155 a_mean = S/double(count); 00156 a_rms = ::sqrt(::fabs(S2/double(count)-a_mean*a_mean)); 00157 return true; 00158 00159 } else if(const icold_t* cd = id_cast<icol, icold_t >(a_col) ){ 00160 double mn,mx,S,S2; 00161 uint64 count; 00162 if(!column_infos<double>(a_ntu,*cd,mn,mx,S,S2,count)) return false; 00163 if(!count) return false; 00164 a_mean = S/double(count); 00165 a_rms = ::sqrt(::fabs(S2/double(count)-a_mean*a_mean)); 00166 return true; 00167 00168 } else { 00169 return false; 00170 } 00171 } 00172 00173 }} 00174 00175 #endif