summaryrefslogtreecommitdiff
path: root/gr-qtgui/src/lib/Waterfall3DDisplayPlot.h
blob: dcdbf380c820235952b4edd708795d2772eec186 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#ifndef WATERFALL_3D_DISPLAY_PLOT_HPP
#define WATERFALL_3D_DISPLAY_PLOT_HPP

#include <highResTimeFunctions.h>

#include <waterfallGlobalData.h>
#include <qwt3d_surfaceplot.h>

#include <qwt3d_color.h>
#include <qwt_color_map.h>

class Waterfall3DColorMap:public Qwt3D::Color, public QwtLinearColorMap{
public:
  Waterfall3DColorMap();
  virtual ~Waterfall3DColorMap();

  virtual Qwt3D::RGBA operator()(double x, double y, double z)const;
  virtual Qwt3D::ColorVector& createVector(Qwt3D::ColorVector& vec);

  virtual void SetInterval(const double minValue, const double maxValue);

protected:
  
private:
  QwtDoubleInterval _interval;
};

class Waterfall3DDisplayPlot:public Qwt3D::SurfacePlot{
  Q_OBJECT

  protected:
  class IntensityScale:public Qwt3D::LinearScale{

  friend class Qwt3D::Axis;
  friend class Qwt3D::qwt3d_ptr<Qwt3D::Scale>;

  private:
    double _floor;

  public:
    explicit IntensityScale(const double newFloor):_floor(newFloor){ }
    virtual ~IntensityScale(){}

    virtual QString ticLabel(unsigned int idx) const{
      if (idx<majors_p.size())
	{
	  return QString("%1").arg( majors_p[idx] + GetFloorValue(), 0, 'f', 0 );
	}
      return QString("");
    }

    virtual double GetFloorValue()const{ return _floor; }
    virtual void SetFloorValue(const double newFloor){ _floor = newFloor; }

    //! Returns a new heap based object utilized from qwt3d_ptr
    Scale* clone() const {return new IntensityScale(*this);} 
  };
  
  class TimeScale:public Qwt3D::LinearScale{

    friend class Qwt3D::Axis;
    friend class Qwt3D::qwt3d_ptr<Qwt3D::Scale>;
    friend class Waterfall3DDisplayPlot;

  private:
    Waterfall3DDisplayPlot* _plot;

  public:
    TimeScale(Waterfall3DDisplayPlot* plot ):_plot(plot){
    }
    virtual ~TimeScale(){
    }

    virtual QString ticLabel(unsigned int idx) const{
      if (idx<majors_p.size())
	{
	  const timespec markerTime = timespec_add(_plot->_dataTimestamp, -(_plot->_timePerFFT) * majors_p[idx]);
	  struct tm timeTm;
	  gmtime_r(&markerTime.tv_sec, &timeTm);
	  
	  char* timeBuffer = new char[128];
	  snprintf(timeBuffer, 128, "%02d:%02d:%02d.%03ld", timeTm.tm_hour, timeTm.tm_min, timeTm.tm_sec, (markerTime.tv_nsec / 1000000));
	  QString returnBuffer(timeBuffer);
	  delete[] timeBuffer;
	  return returnBuffer;
	}
      return QString("");
    }

    //! Returns a new heap based object utilized from qwt3d_ptr
    Scale* clone() const {return new TimeScale(*this);}
  };

  class FrequencyScale: public Qwt3D::LinearScale{

    friend class Qwt3D::Axis;
    friend class Qwt3D::qwt3d_ptr<Qwt3D::Scale>;
  private:
    double _centerFrequency;
    bool _useCenterFrequencyFlag;
  public:
    FrequencyScale(bool useCenterFrequencyFlag, double centerFrequency):_centerFrequency(centerFrequency),_useCenterFrequencyFlag(useCenterFrequencyFlag){}
    virtual ~FrequencyScale(){}

    virtual QString ticLabel(unsigned int idx) const{
      if (idx<majors_p.size())
	{
	  if(!_useCenterFrequencyFlag){
	    return QString("%1").arg(  majors_p[idx], 0, 'f', 0 );

	  }
	  else{
	    return QString("%1").arg(  (majors_p[idx] + _centerFrequency)/1000.0, 0, 'f', 3 );
	  }
	}
      return QString("");
    }

    //! Returns a new heap based object utilized from qwt3d_ptr
    Scale* clone() const {return new FrequencyScale(*this);}
  };

public:
  Waterfall3DDisplayPlot(QWidget*);
  virtual ~Waterfall3DDisplayPlot();
						
  void Init();
  void Reset();

  bool loadFromData(double** data, unsigned int columns, unsigned int rows
		    ,double minx, double maxx, double miny, double maxy);

  void SetFrequencyRange(const double, const double, const double, const bool);
  double GetStartFrequency()const;
  double GetStopFrequency()const;

  void PlotNewData(const double* dataPoints, const int64_t numDataPoints, const double timePerFFT, const timespec timestamp, const int droppedFrames);

  void SetIntensityRange(const double minIntensity, const double maxIntensity);

  virtual void replot(void);

  int GetIntensityColorMapType()const;
  void SetIntensityColorMapType( const int, const QColor, const QColor, const bool forceFlag = false, const bool noReplotFlag = false );
  const QColor GetUserDefinedLowIntensityColor()const;
  const QColor GetUserDefinedHighIntensityColor()const;

  static const int INTENSITY_COLOR_MAP_TYPE_MULTI_COLOR = 0;
  static const int INTENSITY_COLOR_MAP_TYPE_WHITE_HOT = 1;
  static const int INTENSITY_COLOR_MAP_TYPE_BLACK_HOT = 2;
  static const int INTENSITY_COLOR_MAP_TYPE_INCANDESCENT = 3;
  static const int INTENSITY_COLOR_MAP_TYPE_USER_DEFINED = 4;

signals:
  void UpdatedLowerIntensityLevel(const double);
  void UpdatedUpperIntensityLevel(const double);

protected:

  double _startFrequency;
  double _stopFrequency;

  Waterfall3DData* _waterfallData;

  timespec _lastReplot;

  int64_t _numPoints;

  double _displayIntervalTime;

  int _intensityColorMapType;
  QColor _userDefinedLowIntensityColor;
  QColor _userDefinedHighIntensityColor;

  bool _useCenterFrequencyFlag;
  double _centerFrequency;

  timespec _dataTimestamp;
  double _timePerFFT;
  bool _initialized;

  bool _createCoordinateSystemFlag;

private:

};

#endif /* WATERFALL_3D_DISPLAY_PLOT_HPP */