Changeset 11913
- Timestamp:
- 08/25/11 16:22:13 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/fitsdump.cc
r11912 r11913 13 13 #include <CCfits/CCfits> 14 14 15 //#define PLOTTING_PLEASE 16 17 #ifdef PLOTTING_PLEASE 18 #include <qapplication.h> 19 #include <qlayout.h> 20 #include <qwt_plot.h> 21 #include <qwt-qt4/qwt_plot_grid.h> 22 #include <QPen> 23 #include <qwt-qt4/qwt_plot_curve.h> 24 #include <qwt-qt4/qwt_plot_zoomer.h> 25 #include <qwt-qt4/qwt_legend.h> 26 #include <qwt-qt4/qwt_scale_draw.h> 27 #include "Time.h" 28 #endif 15 29 using namespace std; 16 30 … … 27 41 }; 28 42 43 #ifdef PLOTTING_PLEASE 44 class TimeScaleDraw: public QwtScaleDraw 45 { 46 public: 47 virtual QwtText label(double v) const 48 { 49 Time t(v); 50 string time = t.GetAsStr("%H:%M:%S%F"); 51 while (time[time.size()-1] == '0' && time.size() > 2) 52 { 53 time = time.substr(0, time.size()-1); 54 } 55 return QwtText(time.c_str()); 56 } 57 }; 58 #endif 59 29 60 class FitsDumper 30 61 { … … 65 96 void ListKeywords(ostream &); 66 97 98 bool separateColumnsFromRanges(const vector<string>& list, 99 vector<pair<int, int> >& ranges, 100 vector<string>& listNamesOnly); 67 101 /// Perform the dumping, based on the current dump list 68 102 bool Dump(const string &, const vector<string> &list, int); 69 103 ///Display the selected columns values VS time 104 int doCurvesDisplay( const vector<string> &list, const string& tableName); 70 105 // bool Plot(const vector<string> &list); 71 106 … … 482 517 } 483 518 484 485 // -------------------------------------------------------------------------- 486 // 487 //! Perform the actual dump, based on the current parameters 488 // 489 bool FitsDumper::Dump(const string &filename, const vector<string> &list, int precision) 490 { 491 492 //first of all, let's separate the columns from their ranges and check that the requested columns are indeed part of the file 493 vector<pair<int, int> > ranges; 494 vector<string> listNamesOnly; 519 bool FitsDumper::separateColumnsFromRanges(const vector<string>& list, 520 vector<pair<int, int> >& ranges, 521 vector<string>& listNamesOnly) 522 { 495 523 for (vector<string>::const_iterator it=list.begin(); it!=list.end(); it++) 496 524 { … … 499 527 unsigned long bracketIndex1 = columnNameOnly.find_first_of(']'); 500 528 unsigned long colonIndex = columnNameOnly.find_first_of(':'); 501 cout << bracketIndex0 << " " << bracketIndex1 << " " << colonIndex << endl;529 // cout << bracketIndex0 << " " << bracketIndex1 << " " << colonIndex << endl; 502 530 int columnStart = -1; 503 531 int columnEnd = -1; … … 549 577 listNamesOnly.push_back(columnNameOnly); 550 578 } 579 return true; 580 } 581 // -------------------------------------------------------------------------- 582 // 583 //! Perform the actual dump, based on the current parameters 584 // 585 bool FitsDumper::Dump(const string &filename, const vector<string> &list, int precision) 586 { 587 588 //first of all, let's separate the columns from their ranges and check that the requested columns are indeed part of the file 589 vector<pair<int, int> > ranges; 590 vector<string> listNamesOnly; 591 592 if (!separateColumnsFromRanges(list, ranges, listNamesOnly)) 593 { 594 cerr << "Something went wrong while extracting the columns names from parameters. Aborting" << endl; 595 return false; 596 } 597 551 598 // FIXME: Maybe do this when opening a table? 552 599 const vector<int> offsets = CalculateOffsets(); … … 604 651 { 605 652 MyColumn *cCol = static_cast<MyColumn*>(fColMap.find(*it)->second); 606 //CCfits::Column* cCol = fColMap.find(*it)->second;607 653 columns.push_back(cCol); 608 /* int start, end;609 if (cCol->width() != 1)610 {//get the desired range of that column to output611 cout << "Column " << *it << " has " << cCol->width() << " entries. Please tell us which of them should be outputted. " << endl;612 cout << "Please enter the first value to dump (min 0, max " << cCol->width()-1 << "): ";613 cin >> start;614 while (start < 0 || start > cCol->width()-1)615 {616 cout << "value invalid. Please stick to the range 0-" << cCol->width()-1 << ": ";617 cin >> start;618 }619 cout << "Please enter the last value to dump (min " << start << ", max " << cCol->width()-1 << "): ";620 cin >> end;621 while (end < start || end > cCol->width()-1)622 {623 cout << "value invalid. Please stick to the range " << start << "-" << cCol->width()-1 << ": ";624 cin >> end;625 }626 end++;627 ranges.push_back(make_pair(start, end));628 }629 else630 {631 ranges.push_back(make_pair(0, cCol->width()));632 }*/633 654 } 634 655 const int size = offsets[offsets.size()-1]; … … 741 762 } 742 763 764 743 765 if (conf.Get<bool>("list")) 744 766 List(); … … 749 771 return -1; 750 772 } 773 774 if (conf.Get<bool>("graph")) 775 { 776 if (!conf.Has("col")) 777 { 778 cout << "Please specify the columns that should be dumped as arguments. Aborting" << endl; 779 return 0; 780 } 781 doCurvesDisplay(conf.Get<vector<string>>("col"), 782 conf.Get<string>("tablename")); 783 return 1; 784 } 785 751 786 752 787 if (conf.Get<bool>("header")) … … 768 803 return -1; 769 804 } 805 770 806 771 807 return 0; … … 786 822 // 787 823 } 788 824 #ifdef PLOTTING_PLEASE 825 int FitsDumper::doCurvesDisplay( const vector<string> &list, const string& tableName) 826 { 827 //first of all, let's separate the columns from their ranges and check that the requested columns are indeed part of the file 828 vector<pair<int, int> > ranges; 829 vector<string> listNamesOnly; 830 if (!separateColumnsFromRanges(list, ranges, listNamesOnly)) 831 { 832 cerr << "Something went wrong while extracting the columns names from parameters. Aborting" << endl; 833 return false; 834 } 835 vector<string> curvesNames; 836 stringstream str; 837 for (auto it=ranges.begin(), jt=listNamesOnly.begin(); it != ranges.end(); it++, jt++) 838 { 839 for (int i=it->first; i<it->second;i++) 840 { 841 str.str(""); 842 str << *jt << "[" << i << "]"; 843 curvesNames.push_back(str.str()); 844 } 845 } 846 char* handle = new char[17]; 847 sprintf(handle,"FitsDump Display"); 848 // Qt::HANDLE h = *handle;//NULL 849 int argc = 1; 850 char ** argv = &handle; 851 QApplication a(argc, argv); 852 853 854 855 QwtPlot* plot = new QwtPlot(); 856 QwtPlotGrid* grid = new QwtPlotGrid; 857 grid->enableX(false); 858 grid->enableY(true); 859 grid->enableXMin(false); 860 grid->enableYMin(false); 861 grid->setMajPen(QPen(Qt::black, 0, Qt::DotLine)); 862 grid->attach(plot); 863 plot->setAutoReplot(true); 864 string title = tableName; 865 plot->setAxisScaleDraw( QwtPlot::xBottom, new TimeScaleDraw()); 866 867 QWidget window; 868 QHBoxLayout* layout = new QHBoxLayout(&window); 869 layout->setContentsMargins(0,0,0,0); 870 layout->addWidget(plot); 871 872 QwtPlotZoomer zoom(plot->canvas()); 873 zoom.setRubberBandPen(QPen(Qt::gray, 2, Qt::DotLine)); 874 zoom.setTrackerPen(QPen(Qt::gray)); 875 int totalSize = 0; 876 for (unsigned int i=0;i<list.size();i++) 877 totalSize += ranges[i].second - ranges[i].first; 878 cout << "Total size: " << totalSize << endl; 879 vector<QwtPlotCurve*> curves(totalSize); 880 int ii=0; 881 for (auto it = curves.begin(), jt=curvesNames.begin(); it != curves.end(); it++, jt++) 882 { 883 *it = new QwtPlotCurve(jt->c_str()); 884 switch (ii%6) 885 { 886 case 0: 887 (*it)->setPen(QColor(255,0,0)); 888 break; 889 case 1: 890 (*it)->setPen(QColor(0,255,0)); 891 break; 892 case 2: 893 (*it)->setPen(QColor(0,0,255)); 894 break; 895 case 3: 896 (*it)->setPen(QColor(255,255,0)); 897 break; 898 case 4: 899 (*it)->setPen(QColor(0,255,255)); 900 break; 901 case 5: 902 (*it)->setPen(QColor(255,0,255)); 903 break; 904 default: 905 (*it)->setPen(QColor(0,0,0)); 906 }; 907 ii++; 908 (*it)->setStyle(QwtPlotCurve::Lines); 909 (*it)->attach(plot); 910 } 911 plot->insertLegend(new QwtLegend(), QwtPlot::RightLegend); 912 913 const vector<int> offsets = CalculateOffsets(); 914 if (offsets.size()==0) 915 return false; 916 917 918 // Loop over all columns in our list of requested columns 919 vector<MyColumn*> columns; 920 for (vector<string>::const_iterator it=listNamesOnly.begin(); it!=listNamesOnly.end(); it++) 921 { 922 MyColumn *cCol = static_cast<MyColumn*>(fColMap.find(*it)->second); 923 columns.push_back(cCol); 924 } 925 //add the time column to the given columns 926 MyColumn* timeCol = static_cast<MyColumn*>(fColMap.find("Time")->second); 927 if (!timeCol) 928 { 929 cerr << "Error: time column could not be found in given table. Aborting" << endl; 930 return false; 931 } 932 columns.push_back(timeCol); 933 ranges.push_back(make_pair(0,1)); 934 ///// 935 const int size = offsets[offsets.size()-1]; 936 unsigned char* fitsBuffer = new unsigned char[size]; 937 938 // stringstream str; 939 str.str(""); 940 int status = 0; 941 942 vector<double*> xValues(totalSize); 943 double* yValues; 944 cout.precision(10); 945 str.precision(20); 946 for (auto it=xValues.begin(); it!=xValues.end(); it++) 947 *it = new double[fTable->rows()]; 948 949 yValues = new double[fTable->rows()]; 950 951 for (int i=1; i<=fTable->rows(); i++) 952 { 953 fits_read_tblbytes(fFile->fitsPointer(), i, 1, size, fitsBuffer, &status); 954 if (status) 955 { 956 cerr << "An error occurred while reading fits row #" << i << " error code: " << status << endl; 957 break; 958 } 959 if (WriteRow(str, columns, offsets, fitsBuffer, ranges)<0) 960 { 961 status=1; 962 cerr << "An Error occured while reading the fits row " << i << endl; 963 return -1; 964 } 965 // yValues[i-1] = i; 966 for (auto it=xValues.begin(); it!= xValues.end(); it++) 967 { 968 str >> (*it)[i-1]; 969 cout << (*it)[i-1] << " "; 970 } 971 str >> yValues[i-1]; 972 if (i==1) 973 { 974 Time t(yValues[0]); 975 title += " - " + t.GetAsStr("%Y-%m-%d"); 976 plot->setTitle(title.c_str()); 977 } 978 cout << yValues[i-1] << " "; 979 cout << endl; 980 } 981 //set the actual data. 982 auto jt = xValues.begin(); 983 for (auto it=curves.begin(); it != curves.end(); it++, jt++) 984 (*it)->setRawData(yValues, *jt, fTable->rows()); 985 986 QStack<QRectF> stack; 987 double minX, minY, maxX, maxY; 988 minX = minY = 1e10; 989 maxX = maxY = -1e10; 990 QRectF rect; 991 QPointF point; 992 for (auto it=curves.begin(); it!= curves.end(); it++) 993 { 994 rect = (*it)->boundingRect(); 995 point = rect.bottomRight(); 996 if (point.x() < minX) minX = point.x(); 997 if (point.y() < minY) minY = point.y(); 998 if (point.x() > maxX) maxX = point.x(); 999 if (point.y() > maxY) maxY = point.y(); 1000 point = rect.topLeft(); 1001 if (point.x() < minX) minX = point.x(); 1002 if (point.y() < minY) minY = point.y(); 1003 if (point.x() > maxX) maxX = point.x(); 1004 if (point.y() > maxY) maxY = point.y(); 1005 } 1006 QPointF bottomRight(maxX, minY); 1007 QPointF topLeft(minX, maxY); 1008 QPointF center((bottomRight+topLeft)/2.f); 1009 stack.push(QRectF(topLeft + (topLeft-center)*(.5f),bottomRight + (bottomRight-center)*(.5f))); 1010 zoom.setZoomStack(stack); 1011 1012 delete[] fitsBuffer; 1013 window.resize(600, 400); 1014 window.show(); 1015 1016 a.exec(); 1017 1018 for (auto it = curves.begin(); it != curves.end(); it++) 1019 delete *it; 1020 for (auto it = xValues.begin(); it != xValues.end(); it++) 1021 delete[] *it; 1022 delete[] yValues; 1023 delete[] handle; 1024 return 0; 1025 } 1026 #else 1027 int FitsDumper::doCurvesDisplay( const vector<string> &list, const string& tableName) 1028 { 1029 cerr << "Sorry, but plotting features seem to have been disabled at compilation time." << endl; 1030 cerr << "Please recompile with PLOTTING_PLEASE defined and try again." << endl; 1031 return 0; 1032 } 1033 #endif 789 1034 void SetupConfiguration(Configuration& conf) 790 1035 { … … 806 1051 ("list,l", po_switch(), "List all tables and columns in file") 807 1052 ("header,h", po_switch(), "Dump header of given table") 1053 ("graph,g", po_switch(), "Plot the columns instead of dumping them") 808 1054 ; 809 1055
Note:
See TracChangeset
for help on using the changeset viewer.