//****************************************************************************** //** SCATMECH: Polarized Light Scattering C++ Class Library //** //** File: scattabl.cpp //** //** Thomas A. Germer //** Optical Technology Division, National Institute of Standards and Technology //** 100 Bureau Dr. Stop 8443; Gaithersburg, MD 20899-8443 //** Phone: (301) 975-2876; FAX: (301) 975-6991 //** Email: thomas.germer@nist.gov //** //** Version: 6.00 (February 2008) //** //****************************************************************************** #include #include #include #include #include #include #include #include "askuser.h" #include "scatmech.h" #include "scattabl.h" using namespace std; namespace SCATMECH { string getstrline(istream& is) { char c; string result; while ((c=is.get())!='\n') { if (is.eof()) return result; result += c; } return result; } TableFile:: TableFile(const string& filename) { vector > values; bool done; name = filename; string fname = find_file(filename); ifstream file(fname.c_str()); if (!file) throw SCATMECH_exception("Problem opening file " + fname); // Skip header. The end of the header is the beginning of any line // containing only numbers. ifstream::pos_type top; int ncol; for (done=false;!done;) { top = file.tellg(); string line = getstrline(file); if (file.fail()) throw SCATMECH_exception("No data in file " + fname); istringstream linestream(line); bool isheader=false; ncol=0; while (!linestream.fail()) { string s; linestream >> s; if (!linestream.fail()) { istringstream charstream(s); double x; charstream >> x; if (charstream.fail()) isheader=true; ncol++; } } if (!isheader) done=true; } file.seekg(top); // Size arrays... columns.resize(ncol); values.resize(ncol); int i; for (i=0;i> x; if (!linestream.fail()) { values[i].push_back(x); } else done = true; } } else done = true; } // Copy data into arrays... for (i=0;i TableFileMap; TableFileMap tablefiles; void ClearTableCache() { tablefiles.clear(); } Table:: Table() { clear(); last_lambda=-1234567e23; last_value=0; } Table:: Table(double singlevalue) { clear(); push_back(std::pair(0.,singlevalue)); last_value=singlevalue; last_lambda=1; } double Table:: value(double l) const { if (size()==1) return (*this)[0].second; if (last_lambda==l) return last_value; const_cast(last_lambda) = l; int bound1=0; int bound2=size()-1; if (l<(*this)[bound1].first) { const_cast(last_value) = (*this)[bound1].second; return last_value; } if (l>(*this)[bound2].first) { const_cast(last_value) = (*this)[bound2].second; return last_value; } while (bound2-bound1>1) { int split = (bound1+bound2)/2; if (l<(*this)[split].first) bound2=split; else bound1=split; } const_cast(last_value) = ((*this)[bound2].second-(*this)[bound1].second)/ ((*this)[bound2].first-(*this)[bound1].first)* (l-(*this)[bound1].first)+(*this)[bound1].second; return last_value; } Table:: Table(double *l,double *v,int nn) { clear(); for (int i=0;i(l[i],v[i])); std::sort(begin(),end()); last_lambda=(*this)[0].first; last_value=(*this)[0].second; name = "(internal array)"; } Table:: Table(const string& filename, int col) { clear(); read(filename,col); sort(begin(),end()); last_lambda=(*this)[0].first; last_value=(*this)[0].second; ostringstream str; str << filename; name = str.str(); } int Table:: read(const string& filename, int col) { TableFileMap::iterator it = tablefiles.find(filename); if (it==tablefiles.end()) { tablefiles[filename]=TableFile(filename); it = tablefiles.find(filename); } vector x = (it->second)[0]; vector y = (it->second)[col-1]; for (int i=0;i(x[i],y[i])); } sort(begin(),end()); last_lambda = (*this)[0].first; last_value = (*this)[0].second; ostringstream str; str << filename << " (col=" << col << ")"; name = str.str(); return 0; } int Table:: _AskUser(const string& query, const string& deflt) { string response = SCATMECH::AskUser(query + " (value or filename)",deflt); set_table(response); return 1; } int Table:: _AskUser(const string& query, double deflt) { ostringstream ww3; ww3 << deflt << ends; string response = SCATMECH::AskUser(query + " (value or filename)",ww3.str()); set_table(response); return 1; } Table Table:: AskUser(const std::string& prompt,const std::string& deflt) { Table result; bool success; do { try { result._AskUser(prompt,deflt); success = true; } catch (SCATMECH_exception& e) { SCATMECH_output << e.what() << endl; success = false; } } while (!success); return result; } Table Table:: AskUser(const std::string& prompt,double deflt) { Table result; bool success; do { try { result._AskUser(prompt,deflt); success = true; } catch (SCATMECH_exception& e) { SCATMECH_output << e.what() << endl; //instack_unwind(); success = false; } } while (!success); return result; } void Table:: set_table(const string& value) { last_lambda=-1234567e23; double result1; istringstream rr(value); rr >> result1; if (rr.fail()) { string filename; rr.clear(); rr >> filename; read(filename); } else { *this = result1; } name = value; } template <> void ModelParameterSet(Table& variable,const string& parameter,const string& value) { AssertNullParameter(parameter); variable.set_table(value); } template <> string ModelParameterGet(Table& variable,const string& parameter) { AssertNullParameter(parameter); ostringstream oss; oss << variable; return oss.str(); } template <> void ModelParameterAskUser(Table& value,const string& prompt) { value = Table::AskUser(prompt,value.value()); } } // namespace SCATMECH