Changeset 17147
- Timestamp:
- 09/08/13 21:20:17 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/fitsdump.cc
r17000 r17147 15 15 #include <boost/regex.hpp> 16 16 17 #include "tools.h" 17 18 #include "Time.h" 18 19 #include "externals/factfits.h" … … 45 46 minMaxStruct() : min(FLT_MAX), max(-FLT_MAX), average(0), squared(0), numValues(0) { } 46 47 47 void add( double val)48 void add(long double val) 48 49 { 49 50 average += val; … … 78 79 79 80 double GetDouble(const MyColumn &, size_t) const; 81 int64_t GetInteger(const MyColumn &, size_t) const; 82 string Format(const string &fmt, const double &val) const; 83 string Format(const string &fmt, const MyColumn &, size_t) const; 80 84 81 85 ///Display the selected columns values VS time 82 void Dump(ofstream &, const vector< MyColumn> &, const string &, size_t, size_t, const string &);86 void Dump(ofstream &, const vector<string> &, const vector<MyColumn> &, const string &, size_t, size_t, const string &); 83 87 void DumpRoot(ofstream &, const vector<string> &, const string &, size_t, size_t, const string &); 84 88 void DumpMinMax(ofstream &, const vector<MyColumn> &, size_t, size_t, bool); 85 void DumpStats(ofstream &, const vector<MyColumn> &, size_t, size_t);89 void DumpStats(ofstream &, const vector<MyColumn> &, const string &, size_t, size_t); 86 90 87 91 public: … … 284 288 } 285 289 290 int64_t FitsDumper::GetInteger(const MyColumn &it, size_t i) const 291 { 292 switch (it.col.type) 293 { 294 case 'A': 295 return reinterpret_cast<const char*>(it.ptr)[i]; 296 297 case 'L': 298 return reinterpret_cast<const bool*>(it.ptr)[i]; 299 300 case 'B': 301 return (unsigned int)reinterpret_cast<const uint8_t*>(it.ptr)[i]; 302 303 case 'I': 304 return reinterpret_cast<const int16_t*>(it.ptr)[i]; 305 306 case 'J': 307 return reinterpret_cast<const int32_t*>(it.ptr)[i]; 308 309 case 'K': 310 return reinterpret_cast<const int64_t*>(it.ptr)[i]; 311 312 case 'E': 313 return reinterpret_cast<const float*>(it.ptr)[i]; 314 315 case 'D': 316 return reinterpret_cast<const double*>(it.ptr)[i]; 317 } 318 319 return 0; 320 } 321 322 string FitsDumper::Format(const string &format, const MyColumn &col, size_t i) const 323 { 324 switch (*format.rbegin()) 325 { 326 case 'd': 327 case 'i': 328 case 'o': 329 case 'u': 330 case 'x': 331 case 'X': 332 return Tools::Form(format.c_str(), GetDouble(col, i)); 333 334 case 'e': 335 case 'E': 336 case 'f': 337 case 'F': 338 case 'g': 339 case 'G': 340 case 'a': 341 case 'A': 342 return Tools::Form(format.c_str(), GetInteger(col, i)); 343 344 case 'h': 345 { 346 string rc = Tools::Scientific(GetDouble(col, i)); 347 *remove_if(rc.begin(), rc.end(), ::isspace)=0; 348 return rc; 349 } 350 } 351 352 return ""; 353 } 354 355 string FitsDumper::Format(const string &format, const double &val) const 356 { 357 switch (*format.rbegin()) 358 { 359 case 'd': 360 case 'i': 361 case 'o': 362 case 'u': 363 case 'x': 364 case 'X': 365 return Tools::Form(format.c_str(), int64_t(val)); 366 367 case 'e': 368 case 'E': 369 case 'f': 370 case 'F': 371 case 'g': 372 case 'G': 373 case 'a': 374 case 'A': 375 return Tools::Form(format.c_str(), val); 376 377 case 'h': 378 { 379 string rc = Tools::Scientific(val); 380 *remove_if(rc.begin(), rc.end(), ::isspace)=0; 381 return rc; 382 } 383 } 384 385 return ""; 386 } 387 388 286 389 // -------------------------------------------------------------------------- 287 390 // 288 391 //! Perform the actual dump, based on the current parameters 289 392 // 290 void FitsDumper::Dump(ofstream &fout, const vector< MyColumn> &cols, const string &filter, size_t first, size_t limit, const string &filename)393 void FitsDumper::Dump(ofstream &fout, const vector<string> &format, const vector<MyColumn> &cols, const string &filter, size_t first, size_t limit, const string &filename) 291 394 { 292 395 const fits::Table::Keys &fKeyMap = GetKeys(); … … 357 460 ostringstream sout; 358 461 sout.precision(fout.precision()); 359 for (auto it=cols.begin(); it!=cols.end(); it++) 462 sout.flags(fout.flags()); 463 464 uint32_t col = 0; 465 for (auto it=cols.begin(); it!=cols.end(); it++, col++) 360 466 { 361 467 string msg; 362 468 for (uint32_t i=it->first; i<=it->last; i++, p++) 363 469 { 364 switch (it->col.type) 470 if (col<format.size()) 471 sout << Format("%"+format[col], *it, i) << " "; 472 else 365 473 { 366 case 'A': 367 msg += reinterpret_cast<const char*>(it->ptr)[i]; 368 break; 369 case 'B': 370 sout << (unsigned int)reinterpret_cast<const unsigned char*>(it->ptr)[i] << " "; 371 break; 372 case 'L': 373 sout << reinterpret_cast<const bool*>(it->ptr)[i] << " "; 374 break; 375 case 'I': 376 sout << reinterpret_cast<const int16_t*>(it->ptr)[i] << " "; 377 break; 378 case 'J': 379 sout << reinterpret_cast<const int32_t*>(it->ptr)[i] << " "; 380 break; 381 case 'K': 382 sout << reinterpret_cast<const int64_t*>(it->ptr)[i] << " "; 383 break; 384 case 'E': 385 sout << reinterpret_cast<const float*>(it->ptr)[i] << " "; 386 break; 387 case 'D': 388 sout << reinterpret_cast<const double*>(it->ptr)[i] << " "; 389 break; 390 default: 391 ; 474 switch (it->col.type) 475 { 476 case 'A': 477 msg += reinterpret_cast<const char*>(it->ptr)[i]; 478 break; 479 case 'B': 480 sout << (unsigned int)reinterpret_cast<const unsigned char*>(it->ptr)[i] << " "; 481 break; 482 case 'L': 483 sout << reinterpret_cast<const bool*>(it->ptr)[i] << " "; 484 break; 485 case 'I': 486 sout << reinterpret_cast<const int16_t*>(it->ptr)[i] << " "; 487 break; 488 case 'J': 489 sout << reinterpret_cast<const int32_t*>(it->ptr)[i] << " "; 490 break; 491 case 'K': 492 sout << reinterpret_cast<const int64_t*>(it->ptr)[i] << " "; 493 break; 494 case 'E': 495 sout << reinterpret_cast<const float*>(it->ptr)[i] << " "; 496 break; 497 case 'D': 498 sout << reinterpret_cast<const double*>(it->ptr)[i] << " "; 499 break; 500 default: 501 ; 502 } 392 503 } 393 394 504 #ifdef HAVE_ROOT 395 505 if (!filter.empty()) … … 680 790 out << "Max: " << double(val[numElems-1]) << '\n'; 681 791 682 if (numElems>2) 683 { 684 if (numElems%2 == 0) 685 out << "Med: " << (double(val[numElems/2]) + double(val[numElems/2+1]))/2 << '\n'; 686 else 687 out << "Med: " << double(val[numElems/2+1]) << '\n'; 688 } 792 if (numElems%2 == 0) 793 out << "Med: " << (double(val[numElems/2-1]) + double(val[numElems/2]))/2 << '\n'; 794 else 795 out << "Med: " << double(val[numElems/2]) << '\n'; 689 796 690 797 long double avg = 0; … … 692 799 for (uint32_t i=0;i<numElems;i++) 693 800 { 694 avg += double(val[i]); 695 rms += double(val[i])*double(val[i]); 801 const long double v = val[i]; 802 avg += v; 803 rms += v*v; 696 804 } 697 805 … … 704 812 } 705 813 706 void FitsDumper::DumpStats(ofstream &fout, const vector<MyColumn> &cols, size_t first, size_t limit) 707 { 814 void FitsDumper::DumpStats(ofstream &fout, const vector<MyColumn> &cols, const string &filter, size_t first, size_t limit) 815 { 816 #ifdef HAVE_ROOT 817 TFormula select; 818 if (!filter.empty() && select.Compile(filter.c_str())) 819 throw runtime_error("Syntax Error: TFormula::Compile failed for '"+filter+"'"); 820 #endif 821 708 822 // Loop over all columns in our list of requested columns 709 823 vector<vector<char>> statData; … … 712 826 713 827 for (auto it=cols.begin(); it!=cols.end(); it++) 714 statData.push_back(vector<char>(it->col.size*num*(it->last-it->first+1))); 828 statData.emplace_back(vector<char>(it->col.size*num*(it->last-it->first+1))); 829 830 #ifdef HAVE_ROOT 831 vector<Double_t> data(num+1); 832 #endif 715 833 716 834 // Loop over all columns in our list of requested columns 717 835 const size_t last = limit ? first + limit : size_t(-1); 836 837 uint64_t counter = 0; 718 838 719 839 while (GetRow(first++)) … … 723 843 break; 724 844 845 #ifdef HAVE_ROOT 846 if (!filter.empty()) 847 { 848 size_t p = 0; 849 850 data[p++] = first-1; 851 852 for (auto it=cols.begin(); it!=cols.end(); it++) 853 for (uint32_t i=it->first; i<=it->last; i++, p++) 854 data[p] = GetDouble(*it, i); 855 856 if (select.EvalPar(0, data.data())<0.5) 857 continue; 858 } 859 #endif 725 860 726 861 auto statsIt = statData.begin(); … … 729 864 const char *src = reinterpret_cast<const char*>(it->ptr); 730 865 const size_t sz = (it->last-it->first+1)*it->col.size; 731 memcpy(statsIt->data()+row*sz, src+it->first*it->col.size, sz); 732 } 866 memcpy(statsIt->data()+counter*sz, src+it->first*it->col.size, sz); 867 } 868 869 counter++; 733 870 } 734 871 … … 740 877 fout << ':' << it->last; 741 878 fout << "]\n"; 879 880 const size_t sz = (it->last-it->first+1)*it->col.size; 881 statsIt->resize(counter*sz); 742 882 743 883 switch (it->col.type) … … 792 932 if (conf.Get<bool>("minmax") && conf.Get<bool>("stat")) 793 933 { 794 cerr << "Invalid combination of options: cannot do stats and minmax. Aborting" << endl;934 cerr << "Invalid combination of options: cannot do stats and minmax." << endl; 795 935 return -1; 796 936 } 797 937 if (conf.Get<bool>("stat") && conf.Get<bool>("nozero")) 798 938 { 799 cerr << "Invalid combination of options: nozero only works with minmax. Aborting" << endl; 939 cerr << "Invalid combination of options: nozero only works with minmax." << endl; 940 return -1; 941 } 942 943 if (conf.Get<bool>("scientific") && conf.Get<bool>("fixed")) 944 { 945 cerr << "Switched --scientific and --fixed are mutually exclusive." << endl; 946 return -1; 947 } 948 949 if (conf.Has("%") && conf.Has("%%")) 950 { 951 cerr << "Switched --% and --%% are mutually exclusive." << endl; 800 952 return -1; 801 953 } … … 812 964 } 813 965 fout.precision(conf.Get<int>("precision")); 966 if (conf.Get<bool>("fixed")) 967 fout << fixed; 968 if (conf.Get<bool>("scientific")) 969 fout << scientific; 814 970 815 971 const string filter = conf.Has("filter") ? conf.Get<string>("filter") : ""; 816 817 972 const size_t first = conf.Get<size_t>("first"); 818 973 const size_t limit = conf.Get<size_t>("limit"); … … 825 980 } 826 981 #endif 982 983 const vector<string> format = conf.Vec<string>("%"); 984 for (auto it=format.begin(); it<format.end(); it++) 985 { 986 static const boost::regex expr("-?[0-9]*[.]?[0-9]*[diouxXeEfFgGaAh]"); 987 988 boost::smatch what; 989 if (!boost::regex_match(*it, what, expr, boost::match_extra)) 990 { 991 cerr << "Format '" << *it << "' not supported." << endl; 992 return -1; 993 } 994 } 827 995 828 996 const vector<MyColumn> cols = InitColumns(conf.Vec<string>("col")); … … 830 998 return false; 831 999 832 833 1000 if (conf.Get<bool>("minmax")) 834 1001 { … … 839 1006 if (conf.Get<bool>("stat")) 840 1007 { 841 DumpStats(fout, cols, fi rst, limit);1008 DumpStats(fout, cols, filter, first, limit); 842 1009 return 0; 843 1010 } 844 1011 845 Dump(fout, cols, filter, first, limit, filename);1012 Dump(fout, format, cols, filter, first, limit, filename); 846 1013 847 1014 return 0; … … 897 1064 "\n" 898 1065 " fitsdump -r \"#\" --filter=\"#>10 && #<100\"\n" 1066 "\n" 1067 "To format a single column you can do\n" 1068 "\n" 1069 " fitsdump col1 -%.1f col2 -%d\n" 1070 "\n" 1071 "A special format is provided converting to 'human readable format'\n" 1072 "\n" 1073 " fitsdump col1 -%h\n" 899 1074 "\n"; 900 1075 cout << endl; … … 920 1095 ("minmax,m", po_switch(), "Calculates min and max of data") 921 1096 ("nozero,z", po_switch(), "skip 0 values for stats") 1097 ("fixed", po_switch(), "Switch output stream to floating point values in fixed-point notation") 1098 ("scientific", po_switch(), "Switch output stream to floating point values in scientific notation") 1099 ("%,%", vars<string>(), "Format for the output (currently not available in root-mode)") 922 1100 ("force", po_switch(), "Force reading the fits file even if END key is missing") 923 ("first", var<size_t>( size_t(0)),"First number of row to read")924 ("limit", var<size_t>( size_t(0)),"Limit for the maximum number of rows to read (0=unlimited)")1101 ("first", var<size_t>(0), "First number of row to read") 1102 ("limit", var<size_t>(0), "Limit for the maximum number of rows to read (0=unlimited)") 925 1103 ("tablename,t", var<string>(""), "Name of the table to open. If not specified, first binary table is opened") 926 1104 #ifdef HAVE_ROOT
Note:
See TracChangeset
for help on using the changeset viewer.