00001
00002
00003 #include "analysis/Tuple.h"
00004
00005 #include <algorithm>
00006 #include <cassert>
00007 #include <cmath>
00008 #include <cfloat>
00009
00010 static inline void WARNING(const char* text){ std::cerr << text;}
00011 static inline void FATAL(const char* text) {std::cerr << text; exit(-1);}
00012
00013 Tuple::Tuple(const std::string& tname)
00014 : m_title(tname)
00015 {
00016
00017 s_currentTuple = this;
00018 }
00019 void Tuple::setTitle(const std::string& name)
00020 {
00021 m_title = name;
00022 }
00023
00024 Tuple::Tuple(std::istream& infile)
00025 {
00026 s_currentTuple = this;
00027 char buffer[2000];
00028
00029
00030 infile.getline(buffer, sizeof(buffer) );
00031 m_title = buffer;
00032 if( std::count(m_title.begin(), m_title.end(), '\t')>2 ) {
00033
00034 m_title = "";
00035 } else {
00036
00037 infile.getline(buffer, sizeof(buffer) );
00038 }
00039 char* token = strtok( buffer, " \t" );
00040 while( token != NULL ) {
00041 new TupleItem(token);
00042 token = strtok( 0, " \t" );
00043 }
00044 }
00045 void Tuple::nextStream(std::istream& infile)
00046 {
00047 char buffer[2000];
00048
00049
00050 infile.getline(buffer, sizeof(buffer) );
00051 if( std::count(m_title.begin(), m_title.end(), '\t')>2 ) {
00052
00053 m_title = "";
00054 } else {
00055
00056 m_title =std::string(buffer);
00057 infile.getline(buffer, sizeof(buffer) );
00058 }
00059 char* token = strtok( buffer, " \t" );
00060 int i=0;
00061
00062 while( token != NULL ) {
00063 if( std::string(token) != name(i++) ){
00064 FATAL( "new tuple not identical to last");
00065 }
00066 token = strtok( 0, " \t" );
00067 }
00068
00069 }
00070 Tuple*
00071 Tuple::s_currentTuple=0;
00072
00073 float
00074 Tuple::operator[](unsigned i)const
00075 {
00076 return (*(begin()+i))->datum;
00077 }
00078 const char*
00079 Tuple::name(unsigned i)const
00080 {
00081 return (*(begin()+i))->name().c_str();
00082 }
00083 int
00084 Tuple::index(const std::string& nam)const
00085 {
00086 const_iterator look;
00087 if ((look=find(nam)) == end() ) return -1;
00088 return look-begin();
00089 }
00090 Tuple::const_iterator
00091 Tuple::find(const std::string& nam)const
00092 {
00093
00094 const_iterator it=begin();
00095 for(; it !=end(); ++it) {
00096 if( nam==(*it)->name() )break;
00097 }
00098 return it;
00099
00100 }
00101 void
00102 Tuple::fillArray(float array[])const
00103 {
00104 for( const_iterator it=begin(); it !=end(); ++it)
00105 *array++ = (*it)->datum;
00106 }
00107
00108 void
00109 Tuple::writeHeader(std::ostream& os)const
00110 {
00111
00112 os << m_title << '\n';
00113 if( !size() ){
00114 WARNING("Tuple::writeHeader--no items in tuple!");
00115 return;
00116 }
00117 for( const_iterator it=begin(); it !=end(); ++it) {
00118 os << (*it)->name() << " \t";
00119 }
00120 os << '\n';
00121 }
00122
00123 std::ostream& operator << (std::ostream& out, const Tuple& t)
00124 {
00125 unsigned len = t.size();
00126 if( !len) {
00127 WARNING("Attempt to write empty tuple!");
00128
00129 }else {
00130
00131 for( Tuple::const_iterator it=t.begin(); it !=t.end(); ++it)
00132 out << float(**it) << '\t';
00133 }
00134 out << '\n';
00135 return out;
00136 }
00137
00138 std::istream& operator >> (std::istream& in, Tuple& t)
00139 {
00140 float x;
00141 for( Tuple::iterator it = t.begin(); it != t.end(); ++it) {
00142 in >> x;
00143 if( in.fail() ){
00144 if( in.eof() ) break;
00145 in.clear();
00146 char temp[200];
00147
00148 if( it == t.begin()) {
00149 do {
00150
00151 in.clear();
00152 in.getline(temp, sizeof(temp) , '\n');
00153 std::cerr << "Text found & skipped: \""
00154 << temp << "\"" << std::endl;
00155 in >> x;
00156 } while ( in.fail() && ! in.eof() );
00157 } else {
00158
00159 in.getline(temp, sizeof(temp), '\t');
00160 if( fabs(x)==1 && temp[0]=='#') {
00161 --it;
00162 std::cerr << "Bad value for \"" <<
00163 (*it)->name() << "\": " << temp << std::endl;
00164 x= FLT_MAX;
00165 }
00166 else if( temp[0]=='N' || temp[0]=='I' ||
00167 (temp[0] =='-' && temp[1] == 'N') ){
00168 x = FLT_MAX;
00169 }
00170 else {
00171 std::cerr << "Error message found: \"" << temp
00172 << "\"" << std::endl;
00173 std::cerr << "Can't recover, exiting" << std::endl;
00174 exit(-1);
00175 }
00176 }
00177 }
00178 (*it)->datum = x;
00179 }
00180 return in;
00181 }
00182
00183 TupleItem::TupleItem(const std::string& iname, float x)
00184 : m_name(iname), m_pdatum(&datum), datum(x)
00185 {
00186
00187 if( Tuple::s_currentTuple==0 )
00188 FATAL("TupleItem, but no Tuple defined");
00189
00190
00191 std::string::size_type i = name().find(' ');
00192 if( i != std::string::npos){
00193 m_name[i] = '_';
00194 }
00195
00196 i = m_name.find(' ');
00197
00198 if( i != std::string::npos){
00199 std::string fatal("TupleItem: bad item name, \"");
00200 FATAL((fatal+iname+"\" ").c_str());
00201 }
00202 Tuple::s_currentTuple->push_back(this);
00203 }
00204
00205 TupleItem::TupleItem(const std::string& iname, float* px)
00206 : m_name(iname), m_pdatum(px)
00207 {
00208 Tuple::s_currentTuple->push_back(this);
00209 }
00210
00211
00212 float &
00213 TupleItem::operator()(){
00214 return *m_pdatum;
00215 }
00216
00217
00218 std::ostream& operator<< (std::ostream& out, const TupleItem& t)
00219 {
00220 out << t.name() << '=' << *t.m_pdatum;
00221 return out;
00222 }
00223
00224
00225 const TupleItem*
00226 Tuple::tupleItem(const std::string& name)const
00227 {
00228 Tuple::const_iterator it = find(name);
00229 if( it != end() ) return *it;
00230 std::cerr << "Sorry, did not find '" << name << "' in the tuple\n";
00231 exit(-1);
00232 return *it;
00233 }
00234
00235 Tuple::~Tuple()
00236 {
00237 iterator it = begin();
00238 while( it != end() )
00239 delete *it++;
00240 }