Changeset 11913 for trunk


Ignore:
Timestamp:
08/25/11 16:22:13 (13 years ago)
Author:
lyard
Message:
added time display
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/src/fitsdump.cc

    r11912 r11913  
    1313#include <CCfits/CCfits>
    1414
     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
    1529using namespace std;
    1630
     
    2741};
    2842
     43#ifdef PLOTTING_PLEASE
     44class TimeScaleDraw: public QwtScaleDraw
     45{
     46public:
     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
    2960class FitsDumper
    3061{
     
    6596    void ListKeywords(ostream &);
    6697
     98    bool separateColumnsFromRanges(const vector<string>& list,
     99                                   vector<pair<int, int> >& ranges,
     100                                   vector<string>& listNamesOnly);
    67101    /// Perform the dumping, based on the current dump list
    68102    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);
    70105//    bool Plot(const vector<string> &list);
    71106
     
    482517}
    483518
    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;
     519bool FitsDumper::separateColumnsFromRanges(const vector<string>& list,
     520                               vector<pair<int, int> >& ranges,
     521                               vector<string>& listNamesOnly)
     522{
    495523    for (vector<string>::const_iterator it=list.begin(); it!=list.end(); it++)
    496524    {
     
    499527        unsigned long bracketIndex1 = columnNameOnly.find_first_of(']');
    500528        unsigned long colonIndex = columnNameOnly.find_first_of(':');
    501         cout << bracketIndex0 << " " << bracketIndex1 << " " << colonIndex << endl;
     529//        cout << bracketIndex0 << " " << bracketIndex1 << " " << colonIndex << endl;
    502530        int columnStart = -1;
    503531        int columnEnd = -1;
     
    549577        listNamesOnly.push_back(columnNameOnly);
    550578    }
     579    return true;
     580}
     581// --------------------------------------------------------------------------
     582//
     583//! Perform the actual dump, based on the current parameters
     584//
     585bool 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
    551598    // FIXME: Maybe do this when opening a table?
    552599    const vector<int> offsets = CalculateOffsets();
     
    604651    {
    605652        MyColumn *cCol = static_cast<MyColumn*>(fColMap.find(*it)->second);
    606         //CCfits::Column* cCol = fColMap.find(*it)->second;
    607653        columns.push_back(cCol);
    608 /*        int start, end;
    609         if (cCol->width() != 1)
    610         {//get the desired range of that column to output
    611             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         else
    630         {
    631             ranges.push_back(make_pair(0, cCol->width()));
    632         }*/
    633654    }
    634655    const int size = offsets[offsets.size()-1];
     
    741762    }
    742763
     764
    743765    if (conf.Get<bool>("list"))
    744766        List();
     
    749771            return -1;
    750772    }
     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
    751786
    752787    if (conf.Get<bool>("header"))
     
    768803            return -1;
    769804    }
     805
    770806
    771807    return 0;
     
    786822    //
    787823}
    788 
     824#ifdef PLOTTING_PLEASE
     825int 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
     1027int 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
    7891034void SetupConfiguration(Configuration& conf)
    7901035{
     
    8061051        ("list,l",      po_switch(),                "List all tables and columns in file")
    8071052        ("header,h",    po_switch(),                "Dump header of given table")
     1053        ("graph,g",      po_switch(),                "Plot the columns instead of dumping them")
    8081054        ;
    8091055
Note: See TracChangeset for help on using the changeset viewer.