23 #ifndef O2SCL_TABLE_UNITS_H 24 #define O2SCL_TABLE_UNITS_H 30 #include <o2scl/table.h> 31 #include <o2scl/lib_settings.h> 38 #ifndef DOXYGEN_NO_O2NS 70 #ifndef DOXYGEN_NO_O2NS 84 template<
class vec_t=std::vector<
double> >
89 #ifdef O2SCL_NEVER_DEFINED 116 this->maxlines=this->nlines;
124 s.
dat.resize(this->nlines);
125 s.
index=this->atree.size();
126 this->atree.insert(make_pair(cname,s));
130 this->alist.push_back(it);
133 utree.insert(make_pair(cname,t.
get_unit(cname)));
137 it->second.dat[j]=t.
get(cname,j);
142 this->intp_set=
false;
153 for(
size_t i=0;i<nc;i++) {
157 this->constants.insert(make_pair(name,val));
165 this->maxlines=this->nlines;
173 s.
dat.resize(this->nlines);
174 s.
index=this->atree.size();
175 this->atree.insert(make_pair(cname,s));
179 this->alist.push_back(it);
183 it->second.dat[j]=t.
get(cname,j);
188 this->intp_set=
false;
201 this->constants.clear();
212 this->maxlines=this->nlines;
220 s.
dat.resize(this->nlines);
221 s.
index=this->atree.size();
222 this->atree.insert(make_pair(cname,s));
226 this->alist.push_back(it);
229 utree.insert(make_pair(cname,t.
get_unit(cname)));
233 it->second.dat[j]=t.
get(cname,j);
238 if (this->intp_set) {
239 this->intp_set=
false;
256 this->constants.clear();
261 for(
size_t i=0;i<nc;i++) {
265 this->constants.insert(make_pair(name,val));
273 this->maxlines=this->nlines;
281 s.
dat=
new vec_t(this->nlines);
282 s.
index=this->atree.size();
283 this->atree.insert(make_pair(cname,s));
287 this->alist.push_back(it);
291 (*it->second.dat)[j]=t.
get(cname,j);
296 if (this->intp_set) {
297 this->intp_set=
false;
319 template<
class vec2_t>
323 for(
size_t i=0;i<this->get_ncolumns();i++) {
324 std::string cname=this->get_column_name(i);
328 dest.
set_unit(cname,get_unit(cname));
332 for(
size_t i=0;i<this->get_nlines();i++) {
333 double val=this->row_function(func,i);
335 this->set_nlines_auto(new_lines+1);
336 for(
size_t j=0;j<this->get_ncolumns();j++) {
337 std::string cname=this->get_column_name(j);
338 dest.
set(cname,new_lines,this->
get(cname,i));
352 uciter it=utree.find(scol);
353 if (it==utree.end()) {
356 if (at==this->atree.
end()) {
357 O2SCL_ERR((((std::string)
"Column '")+scol+
358 "' not found in table_units::get_unit().").c_str(),
374 return get_unit(this->get_column_name(i));
380 uiter it=utree.find(scol);
381 if (it==utree.end()) {
382 O2SCL_ERR((((std::string)
"Column '")+scol+
383 "' not found in table_units::get_unit().").c_str(),
387 if (utree.size()==0) {
388 O2SCL_ERR(
"No units specified in table_units::remove_unit().",
397 void set_unit(std::string scol, std::string unit) {
399 uiter it=utree.find(scol);
400 if (it==utree.end()) {
402 if (at==this->atree.
end()) {
403 O2SCL_ERR((((std::string)
"Column '")+scol+
404 "' not found in table_units::set_unit().").c_str(),
407 utree.insert(make_pair(scol,unit));
417 bool err_on_fail=
true) {
420 uiter it=utree.find(scol);
421 if (it==utree.end()) {
423 O2SCL_ERR((((std::string)
"Column '")+scol+
"' not found in "+
424 "table_units::convert_to_unit().").c_str(),
432 if (it->second==unit)
return success;
436 if (at==this->atree.
end()) {
438 O2SCL_ERR((((std::string)
"Column '")+scol+
"' not found in "+
439 "table_units::convert_to_unit().").c_str(),
447 vec_t &vec=at->second.dat;
448 double conv=
cup->convert(it->second,unit,1.0);
450 for(
size_t i=0;i<this->get_nlines();i++) {
493 if (it==this->atree.
end()) {
494 O2SCL_ERR((((std::string)
"Column '")+scol+
495 " not found in table_units::delete_column().").c_str(),
501 if (get_unit(scol).length()>0) remove_unit(scol);
505 vit+=it->second.index;
510 this->alist[this->alist.size()-1]->second.index=it->second.index;
513 this->atree.erase(it);
514 this->alist.erase(vit);
526 std::string unit=get_unit(src);
533 virtual void summary(std::ostream *out,
size_t ncol=79)
const {
535 if (this->constants.size()==1) {
536 (*out) <<
"1 constant:" << std::endl;
538 (*out) << this->constants.size() <<
" constants:" << std::endl;
540 std::map<std::string,double>::const_iterator mit;
541 for(mit=this->constants.begin();mit!=this->constants.end();mit++) {
542 (*out) << mit->first <<
" " << mit->second << std::endl;
546 size_t nh=this->get_ncolumns(), nh2;
550 (*out) <<
"No columns." << std::endl;
555 (*out) <<
"1 column: " << std::endl;
557 (*out) << nh <<
" columns: " << std::endl;
559 std::string *h=
new std::string[nh];
560 for(
size_t i=0;i<nh;i++) {
561 h[i]=
szttos(i)+
". "+this->get_column_name(i)+
" ["+
562 get_unit(this->get_column_name(i))+
"]";
565 std::vector<std::string> h2;
571 for(
size_t i=0;i<nh2;i++) {
572 (*out) << h2[i] << std::endl;
579 if (this->get_nlines()==0) {
580 (*out) <<
"No lines of data." << std::endl;
581 }
else if (this->get_nlines()==1) {
582 (*out) <<
"One line of data." << std::endl;
584 (*out) << this->get_nlines() <<
" lines of data." << std::endl;
592 virtual const char *
type() {
return "table_units"; }
603 if (!this->is_column(dest)) this->new_column(dest);
605 typedef typename std::map<std::string,
608 aiter its=this->atree.find(src);
609 if (its==this->atree.end()) {
610 O2SCL_ERR((((std::string)
"Column '")+src+
611 " not found in table_units::copy_column().").c_str(),
615 aiter itd=this->atree.find(dest);
616 if (itd==this->atree.end()) {
617 O2SCL_ERR((((std::string)
"Destination column '")+dest+
618 " not found in table_units::copy_column().").c_str(),
622 this->set_unit(dest,this->get_unit(src));
623 for(
size_t i=0;i<this->nlines;i++) {
624 itd->second.dat[i]=its->second.dat[i];
635 std::istringstream *is;
638 std::vector<std::string> onames, nnames;
640 is=
new std::istringstream(line);
641 while ((*is) >> stemp) {
642 onames.push_back(stemp);
644 std::cout <<
"Read possible column name: " << stemp << std::endl;
651 for(
size_t i=0;i<onames.size();i++) {
657 if (n_nums==onames.size()) {
660 std::cout <<
"First row looks like it contains numerical values." 662 std::cout <<
"Creating generic column names: ";
665 for(
size_t i=0;i<onames.size();i++) {
666 nnames.push_back(((std::string)
"c")+
szttos(i+1));
667 if (verbose>0) std::cout << nnames[i] <<
" ";
670 if (verbose>0) std::cout << std::endl;
673 for(
size_t i=0;i<nnames.size();i++) {
674 this->new_column(nnames[i]);
678 for(
size_t i=0;i<onames.size();i++) {
686 for(
size_t i=0;i<onames.size();i++) {
687 std::string temps=onames[i];
688 this->make_fp_varname(temps);
689 this->make_unique_name(temps,nnames);
690 nnames.push_back(temps);
691 if (temps!=onames[i] && verbose>0) {
692 std::cout <<
"Converted column named '" << onames[i] <<
"' to '" 693 << temps <<
"'." << std::endl;
698 for(
size_t i=0;i<nnames.size();i++) {
699 this->new_column(nnames[i]);
703 std::vector<std::string> units;
705 is=
new std::istringstream(line);
707 while ((*is) >> stemp) {
708 units.push_back(stemp);
709 if (stemp[0]==
'[') num_units++;
711 std::cout <<
"Read word in second row: " << stemp << std::endl;
716 if (units.size()!=nnames.size()) {
717 std::cout <<
"Second row appears not to have same number of " 718 <<
"entries as the first." << std::endl;
719 std::cout <<
"Aborting." << std::endl;
723 if (num_units==((
int)units.size()) || num_units>2) {
725 std::cout <<
"Looks like second row contains units." << std::endl;
727 for(
size_t i=0;i<units.size();i++) {
730 if (stemp[0]==
'[') stemp=stemp.substr(1,stemp.length()-1);
731 if (stemp[stemp.length()-1]==
']') {
732 stemp=stemp.substr(0,stemp.length()-1);
735 set_unit(nnames[i],stemp);
737 std::cout <<
"Name,unit: " << nnames[i] <<
" [" << stemp <<
"]" 745 for(
size_t i=0;i<units.size();i++) {
755 while ((fin) >> data) {
756 this->
set(0,irow,data);
757 for(
size_t i=1;i<this->get_ncolumns();i++) {
759 this->
set(i,irow,data);
770 template<
class vec2_t>
772 bool allow_extrap=
true, std::string dest_index=
"") {
774 if (dest_index==
"") dest_index=src_index;
777 double min=source.
min(src_index);
778 double max=source.
max(src_index);
779 if (allow_extrap==
false) {
780 if (!std::isfinite(min) || !std::isfinite(max)) {
781 O2SCL_ERR2(
"Minimum or maximum of source index not finite ",
782 "in table_units::insert_table().",
exc_einval);
787 std::vector<std::string> col_list;
790 if (col!=src_index && col!=dest_index &&
791 this->is_column(col)==
false) {
792 col_list.push_back(col);
797 for(
size_t i=0;i<col_list.size();i++) {
798 this->new_column(col_list[i]);
799 set_unit(col_list[i],source.
get_unit(col_list[i]));
800 for(
size_t j=0;j<this->get_nlines();j++) {
801 double val=this->
get(dest_index,j);
802 if (allow_extrap || (val>=min && val<=max)) {
803 this->
set(col_list[i],j,source.
interp(src_index,val,col_list[i]));
813 friend void o2scl_hdf::hdf_output
819 friend void o2scl_hdf::hdf_output_data
827 #ifndef DOXYGEN_INTERNAL 837 typedef std::map<std::string,std::string,
838 std::greater<std::string> >::iterator uiter;
839 typedef std::map<std::string,std::string,
840 std::greater<std::string> >::const_iterator uciter;
844 std::map<std::string,std::string,std::greater<std::string> >
utree;
855 template<
class vec_t>
860 std::vector<double> dbuffer;
874 dbuffer.push_back(val);
877 ibuffer=cbuffer.length();
880 MPI_Send(&ibuffer,1,MPI_INT,dest_rank,
883 MPI_Send(&(cbuffer[0]),cbuffer.length(),MPI_CHAR,dest_rank,
886 MPI_Send(&(dbuffer[0]),dbuffer.size(),MPI_DOUBLE,dest_rank,
902 ibuffer=cbuffer.length();
904 MPI_Send(&ibuffer,1,MPI_INT,dest_rank,
907 MPI_Send(&(cbuffer[0]),cbuffer.length(),MPI_CHAR,dest_rank,
922 ibuffer=cbuffer.length();
924 MPI_Send(&ibuffer,1,MPI_INT,dest_rank,
927 MPI_Send(&(cbuffer[0]),cbuffer.length(),MPI_CHAR,dest_rank,
936 MPI_Send(&ibuffer,1,MPI_INT,dest_rank,
944 MPI_Send(&ibuffer,1,MPI_INT,dest_rank,
949 MPI_Send(&(t[i][0]),t.
get_nlines(),MPI_DOUBLE,dest_rank,
959 template<
class vec_t>
960 void o2scl_table_mpi_recv(
size_t src_rank,
965 std::vector<char> cbuffer;
966 std::vector<double> dbuffer;
968 std::vector<std::string> names;
976 MPI_Recv(&ibuffer,1,MPI_INT,src_rank,tag,MPI_COMM_WORLD,
978 cbuffer.resize(ibuffer);
980 MPI_Recv(&(cbuffer[0]),ibuffer,MPI_CHAR,src_rank,tag,MPI_COMM_WORLD,
984 for(
size_t i=0;i<cbuffer.size();i++) {
985 if (cbuffer[i]!=
' ') {
988 if (stemp.size()>0) {
989 names.push_back(stemp);
994 if (stemp.size()>0) {
995 names.push_back(stemp);
1000 dbuffer.resize(names.size());
1003 MPI_Recv(&(dbuffer[0]),dbuffer.size(),MPI_DOUBLE,
1004 src_rank,tag,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
1007 for(
size_t i=0;i<names.size();i++) {
1017 MPI_Recv(&ibuffer,1,MPI_INT,src_rank,tag,MPI_COMM_WORLD,
1019 cbuffer.resize(ibuffer);
1021 MPI_Recv(&(cbuffer[0]),ibuffer,MPI_CHAR,src_rank,tag,MPI_COMM_WORLD,
1025 for(
size_t i=0;i<cbuffer.size();i++) {
1026 if (cbuffer[i]!=
' ') {
1029 if (stemp.size()>0) {
1030 names.push_back(stemp);
1035 if (stemp.size()>0) {
1036 names.push_back(stemp);
1040 for(
size_t i=0;i<names.size();i++) {
1049 MPI_Recv(&ibuffer,1,MPI_INT,src_rank,tag,MPI_COMM_WORLD,
1051 cbuffer.resize(ibuffer);
1053 MPI_Recv(&(cbuffer[0]),ibuffer,MPI_CHAR,src_rank,tag,MPI_COMM_WORLD,
1057 for(
size_t i=0;i<cbuffer.size();i++) {
1058 if (cbuffer[i]!=
' ') {
1061 if (stemp.size()>0) {
1062 names.push_back(stemp);
1067 if (stemp.size()>0) {
1068 names.push_back(stemp);
1072 for(
size_t i=0;i<names.size();i++) {
1081 MPI_Recv(&ibuffer,1,MPI_INT,src_rank,tag,MPI_COMM_WORLD,
1089 MPI_Recv(&ibuffer,1,MPI_INT,src_rank,tag,MPI_COMM_WORLD,
1096 MPI_Recv(&(v[0]),ibuffer,MPI_DOUBLE,src_rank,
1097 tag,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
1106 #ifndef DOXYGEN_NO_O2NS table_units(int cmaxlines=0)
Create a new table_units with space for nlines<=cmaxlines.
double max(std::string scol) const
Return column maximum. Makes no assumptions about ordering, .
double get(std::string scol, size_t row) const
Get value from row row of column named col. .
void remove_unit(std::string scol)
Remove the unit for column scol.
The main O<span style='position: relative; top: 0.3em; font-size: 0.8em'>2</span>scl O$_2$scl names...
size_t get_nlines() const
Return the number of lines.
double min(std::string scol) const
Return column minimum. Makes no assumptions about ordering, .
void hdf_input_data(hdf_file &hf, o2scl::table< vec_t > &t)
Internal function for inputting a o2scl::table object.
void hdf_input(hdf_file &hf, o2scl::table_units< vec_t > &t, std::string name)
Input a o2scl::table_units object from a hdf_file.
virtual int read_generic(std::istream &fin, int verbose=0)
Clear the current table and read from a generic data file.
void set_nlines(size_t il)
Set the number of lines.
virtual void delete_column(std::string scol)
Delete column named scol.
virtual const char * type()
Return the type, "table_units".
sanity check failed - shouldn't happen
lib_settings_class o2scl_settings
The global library settings object.
invalid argument supplied by user
virtual size_t get_nconsts() const
Get the number of constants.
std::map< std::string, col, std::greater< std::string > >::const_iterator aciter
Const map iterator type.
Generic "not found" result.
int convert_to_unit(std::string scol, std::string unit, bool err_on_fail=true)
Convert the units of column scol to unit.
size_t get_interp_type() const
Get the interpolation type.
virtual double get_constant(std::string name) const
Get a constant.
virtual void summary(std::ostream *out, size_t ncol=79) const
Output a summary of the information stored.
void insert_table(table_units< vec2_t > &source, std::string src_index, bool allow_extrap=true, std::string dest_index="")
Insert columns from a source table into the new table by interpolation (or extrapolation) ...
virtual void rename_column(std::string src, std::string dest)
Rename column named src to dest .
std::map< std::string, double > constants
The list of constants.
void set_unit(std::string scol, std::string unit)
Set the unit for column scol to unit.
size_t get_maxlines()
Return the maximum number of lines before a reallocation is required.
double interp(std::string sx, double x0, std::string sy)
Interpolate value x0 from column named sx into column named sy.
convert_units * cup
The pointer to the convert units object.
size_t get_nunits()
Return the number of columns with units.
table_units & operator=(const table_units &t)
Copy with operator= from table_units.
#define O2SCL_ERR2(d, d2, n)
Set an error, two-string version.
Column structure for table [protected].
The O<span style='position: relative; top: 0.3em; font-size: 0.8em'>2</span>scl O$_2$scl namespace ...
void hdf_input_data(hdf_file &hf, o2scl::table_units< vec_t > &t)
Internal function for inputting a o2scl::table_units object.
std::map< std::string, std::string, std::greater< std::string > > utree
Unit map.
convert_units & get_convert_units()
Get the global convert_units object.
void screenify(size_t nin, const string_arr_t &in_cols, std::vector< std::string > &out_cols, size_t max_size=80)
Reformat the columns for output of width size.
#define O2SCL_ERR(d, n)
Set an error with message d and code n.
void copy_rows(std::string func, table_units< vec2_t > &dest)
Copy all rows matching a particular condition to a new table.
virtual void add_constant(std::string name, double val)
Add a constant, or if the constant already exists, change its value.
void set_interp_type(size_t interp_type)
Set the base interpolation objects.
bool is_number(std::string s)
Return true if the string s is likely a integral or floating point number.
size_t get_ncolumns() const
Return the number of columns.
double stod(std::string s)
Convert a string to a double.
Data table table class with units.
void new_column(std::string head)
Add a new column owned by the table table .
void clear()
Clear everything.
aiter end()
Return the end of the column tree.
bool is_column(std::string scol) const
Return true if scol is a column in the current table table .
table_units(const table< vec_t > &t)
Copy with constructor from table.
table_units & operator=(const table< vec_t > &t)
Copy with operator= from table.
std::map< std::string, col, std::greater< std::string > >::iterator aiter
Map iterator type.
virtual void copy_column(std::string src, std::string dest)
Copy data from column named src to column named dest, creating a new column if necessary ...
Store data in an O<span style='position: relative; top: 0.3em; font-size: 0.8em'>2</span>scl O$_2$sc...
std::string get_unit(std::string scol) const
Get the unit for column scol.
void set(std::string scol, size_t row, double val)
Set row row of column named col to value val . .
std::string get_unit(size_t i) const
Get the unit for column with index i.
std::string get_column_name(size_t icol) const
Returns the name of column col .
std::string szttos(size_t x)
Convert a size_t to a string.
void hdf_input(hdf_file &hf, o2scl::table< vec_t > &t, std::string name)
Input a o2scl::table object from a hdf_file.
vec_t dat
Pointer to column.
std::vector< aiter >::iterator aviter
Vector iterator type.
virtual void swap_column_data(std::string scol, vec_t &v)
Swap the data in column scol with that in vector v.
table_units(const table_units &t)
Copy with constructor from table_units.
virtual void rename_column(std::string src, std::string dest)
Rename column named src to dest .