Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

Tuple.cxx

Go to the documentation of this file.
00001 // $Id: Tuple.cxx,v 1.2 2001/03/24 00:04:37 burnett Exp $
00002 //
00003 #include "analysis/Tuple.h"
00004 
00005 #include <algorithm> // for count
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     // assume first line is title
00030     infile.getline(buffer, sizeof(buffer) );
00031     m_title = buffer;
00032     if( std::count(m_title.begin(), m_title.end(), '\t')>2 ) {
00033         // no, has column names
00034         m_title = "";
00035     } else {
00036         // and second line is a list of space or tab-delimited names
00037         infile.getline(buffer, sizeof(buffer) );
00038     }
00039     char* token = strtok( buffer, " \t" );
00040     while( token != NULL )   {
00041         new TupleItem(token);  // note that there is no logic to delete these
00042         token = strtok( 0, " \t" );
00043     }
00044 }
00045 void Tuple::nextStream(std::istream& infile)
00046 {
00047     char buffer[2000];
00048 
00049     // assume first line is title
00050     infile.getline(buffer, sizeof(buffer) );
00051     if( std::count(m_title.begin(), m_title.end(), '\t')>2 ) {
00052         // no, has column names
00053         m_title = "";
00054     } else {
00055         // and second line is a list of space or tab-delimited names
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 //## begin Tuple::find%-650323776.body preserve=yes
00094     const_iterator it=begin();
00095     for(;  it !=end(); ++it) {
00096         if( nam==(*it)->name() )break;
00097     }
00098     return it;
00099 //## end Tuple::find%-650323776.body
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() ){  // protect against 1.#INF!
00144             if( in.eof() ) break;
00145             in.clear();
00146             char temp[200];
00147 
00148             if( it == t.begin()) {
00149                 do {
00150                     // non-numeric at beginning of line. just read until OK
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]=='#') { // what we get on the PC
00161                     --it; //back up because stopped at the #
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                 }  // maybe it is 'NaN' or 'Infinity' (gcc)
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     // replace one blank with an underscore
00191     std::string::size_type i = name().find(' ');
00192     if( i != std::string::npos){
00193         m_name[i] = '_';
00194     }
00195     // die if another
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 }

Generated at Wed Nov 21 12:20:52 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000