CFEL - ASG Software Suite  2.5.0
CASS
two_d_viewer.cpp
Go to the documentation of this file.
1 // Copyright (C) 2013 Lutz Foucar
2 
3 /**
4  * @file two_d_viewer.cpp contains viewer for 2d data
5  *
6  * @author Lutz Foucar
7  */
8 
9 #include <QtCore/QDebug>
10 #include <QtCore/QSettings>
11 #include <QtCore/QFileInfo>
12 
13 #if QT_VERSION >= 0x050000
14 #include <QtWidgets/QVBoxLayout>
15 #include <QtWidgets/QToolBar>
16 #include <QtWidgets/QSpinBox>
17 #include <QtWidgets/QLabel>
18 #include <QtWidgets/QFileDialog>
19 #include <QtWidgets/QInputDialog>
20 #include <QtWidgets/QAction>
21 #else
22 #include <QtGui/QVBoxLayout>
23 #include <QtGui/QToolBar>
24 #include <QtGui/QSpinBox>
25 #include <QtGui/QLabel>
26 #include <QtGui/QFileDialog>
27 #include <QtGui/QInputDialog>
28 #include <QtGui/QAction>
29 #endif
30 
31 #include <qwt_plot.h>
32 #include <qwt_scale_widget.h>
33 #include <qwt_plot_layout.h>
34 #include <qwt_plot_spectrogram.h>
35 #include <qwt_color_map.h>
36 #include <qwt_scale_engine.h>
37 
38 #include "two_d_viewer.h"
39 
40 #include "two_d_viewer_data.h"
41 #include "minmax_control.h"
42 #include "track_zoomer_2d.h"
43 #include "logcolor_map.h"
44 #include "data.h"
45 #include "file_handler.h"
46 
47 using namespace jocassview;
48 using namespace cass;
49 
51  : DataViewer(title,parent)
52 {
53  // settings to read from the ini file
54  QSettings settings;
55  settings.beginGroup(windowTitle());
56  _geomFile = settings.value("GeomFile","").toString();
57 
58  // create the plot where the 2d data will be displayed in as central widget
59  _plot = new QwtPlot(this);
60  QwtScaleWidget *rightAxis(_plot->axisWidget(QwtPlot::yRight));
61  rightAxis->setColorBarEnabled(true);
62  _plot->enableAxis(QwtPlot::yRight);
63  _plot->plotLayout()->setAlignCanvasToScales(true);
64  _plot->setAutoReplot(false);
65  // create spectrogram data
67  // create the spectrom that is displayed in the plot
68  _spectrogram = new QwtPlotSpectrogram();
69  _spectrogram->setData(data);
70  _spectrogram->attach(_plot);
71  // create a zoomer for the 2d data
72  _zoomer = new TrackZoomer2D(_plot->canvas());
73 // _zoomer->setSelectionFlags( QwtPicker::RectSelection | QwtPicker::DragSelection );
74  _zoomer->setMousePattern(QwtEventPattern::MouseSelect2,
75  Qt::RightButton, Qt::ControlModifier);
76  _zoomer->setMousePattern(QwtEventPattern::MouseSelect3,
77  Qt::RightButton);
78  _zoomer->setData(data);
79  _zoomer->setWavelength_A(settings.value("Wavelength_A",0).toDouble());
80  _zoomer->setCameraDistance_cm(settings.value("CameraDistance_cm",0).toDouble());
81  _zoomer->setPixelSize_um(settings.value("PixelSize_um",0).toDouble());
82  //_zoomer->setStatusBar(statusBar());
83 
85 
86  // create the toolbar
87  QToolBar * toolbar(new QToolBar("Plot Control",this));
88  addToolBar(Qt::BottomToolBarArea,toolbar);
89 
90  // Add title display to the toolbar
91  _axisTitleControl = new QAction(QIcon(":images/axistitle.png"),
92  tr("Toggle Axis Titles"),toolbar);
93  _axisTitleControl->setCheckable(true);
94  _axisTitleControl->setChecked(settings.value("DisplayTitles",true).toBool());
95  connect(_axisTitleControl,SIGNAL(triggered()),this,SLOT(replot()));
96  toolbar->addAction(_axisTitleControl);
97 
98  // Add a button that allows to add a reference curve
99  toolbar->addAction(QIcon(":images/graph_add.png"),
100  tr("Load geom file"),
101  this,SLOT(on_load_geomfile_triggered()));
102 
103  // add the min/max control to the toolbar
104  _zControl = new MinMaxControl(QString(windowTitle() + "/z-scale"),toolbar);
105  connect(_zControl,SIGNAL(controls_changed()),this,SLOT(replot()));
106  toolbar->addWidget(_zControl);
107 
108  // Add separator
109  toolbar->addSeparator();
110 
111  // Add the colorbar control
112  _colorId = new QSpinBox();
113  _colorId->setRange(-4,11);
114  _colorId->setValue(settings.value("ColorTableID",-1).toInt());
115  _colorId->setWrapping(true);
116  _colorId->setToolTip(tr("Select the used Colorbar"));
117  connect(_colorId,SIGNAL(valueChanged(int)),this,SLOT(replot()));
118  toolbar->addWidget(_colorId);
119 
120  // Set the size and position of the window
121  resize(settings.value("WindowSize",size()).toSize());
122  move(settings.value("WindowPosition",pos()).toPoint());
123 
124  // set the original flag
125  _isOriginalData = true;
126 
127  // set the lookuptable flag
128  _lutPresent = false;
129 
130  settings.endGroup();
131 }
132 
134 {
135 
136 }
137 
139 {
140  QList<Data*> list;
141  list.append(dynamic_cast<TwoDViewerData*>(_spectrogram->data()));
142  return list;
143 }
144 
146 {
147  return QString("2DViewer");
148 }
149 
150 void TwoDViewer::saveData(const QString &filename)
151 {
152  if (data().isEmpty())
153  return;
154  /** print a png of the whole widget if requested and the file doesn't exist */
155  QFileInfo fileInfo(filename);
156  if (fileInfo.suffix().toUpper() == QString("png").toUpper())
157  {
158  if (!fileInfo.exists())
159  {
160  QPixmap pix(this->grab());
161  if (fileInfo.suffix().toUpper() == QString("png").toUpper())
162  {
163  pix.save(filename, "PNG");
164  }
165  }
166  }
167  else
168  {
169  /** let the file handler handle the other formats */
170  FileHandler::saveData(filename,data().front()->result());
171  }
172 }
173 
175 {
176  /** check if the data has really been updated, when it should original data */
177  if (_isOriginalData && !(data().front()->wasUpdated()))
178  return;
179 
180  /** if the data is original, save the original histogram */
181  if (_isOriginalData)
182  _origHist = data().front()->result()->clone();
183 
184  /** reset flag */
185  _isOriginalData = true;
186 
187  /** check if the user wants to convert cheetah layout to lab frame */
188  if (!_geomFile.isEmpty())
189  {
190  /** create lookup table from the geom file if its not created yet */
191  if (!_lutPresent)
192  {
194  _origHist->size(),
195  _origHist->shape().first,
196  false);
197  _lutPresent = true;
198  }
199 
201  ( new cass::Result<float>
204  labHist->name(_origHist->name());
205 
208 
209  std::vector<size_t>::const_iterator idx(_lut.lut.begin());
210 
211  for (; srcpixel != srcImageEnd; ++srcpixel, ++idx)
212  (*labHist)[*idx] = *srcpixel;
213 
214  data().front()->setResult(labHist);
215  }
216  else
217  {
218  data().front()->setResult(_origHist->clone());
219  }
220 
221  /** check if the data is different (the bounding box changed) in which case we
222  * reinitialize the zoomer
223  * @note the below will be done when zooming into the initial bounding rect
224 @code
225  _plot->setAxisScale(QwtPlot::yLeft,_data->boundingRect().top(),_data->boundingRect().bottom());
226  _plot->setAxisScale(QwtPlot::xBottom,_data->boundingRect().left(),_data->boundingRect().right());
227 @endcode
228  */
229  if (_zoomer->zoomBase() != _spectrogram->boundingRect())
230  {
231  _zoomer->setZoomBase(_spectrogram->boundingRect());
232  _zoomer->zoom(_spectrogram->boundingRect());
233  _zoomer->setZoomBase(true);
234  }
235  replot();
236 }
237 
239 {
240  QStringList list;
241  list << "h5"<<"hst"<<"csv"<<"png"<<"cbf";
242  return list;
243 }
244 
246 {
247  /** @note we need to new the color bar for both the axis widget and the spectrogram
248  * as they take over possesion of the colorbar and delete them when they
249  * think appropriate.
250  */
251 
252  /** get the data from the spectrogram and get the min and max z-values to be displayed */
253  TwoDViewerData *data(dynamic_cast<TwoDViewerData*>(_spectrogram->data()));
254  const double min(!_zControl->autoscale() ? _zControl->min() : data->origZInterval(_zControl->log()).minValue());
255  const double max(!_zControl->autoscale() ? _zControl->max() : data->origZInterval(_zControl->log()).maxValue());
256 
257  /** get the colormap to be used */
258  int colorid = _colorId->value();
259 
260  /** set the colormap and min / max z-value */
261  data->setInterval(Qt::ZAxis,QwtInterval(min,max));
262  _spectrogram->setColorMap(cmap(colorid,_zControl->log()));
263  _plot->axisWidget(QwtPlot::yRight)->setColorMap(_spectrogram->data()->interval(Qt::ZAxis),cmap(colorid,_zControl->log()));
264  _plot->setAxisScale(QwtPlot::yRight,min,max);
265 
266  if (_zControl->log())
267  _plot->setAxisScaleEngine(QwtPlot::yRight, new QwtLogScaleEngine);
268  else
269  _plot->setAxisScaleEngine(QwtPlot::yRight, new QwtLinearScaleEngine);
270 
271  /** display the axis titles if requested */
272  if (_axisTitleControl->isChecked())
273  {
275  if (result)
276  {
277  QString xtitle(QString::fromStdString(result->axis(cass::Result<float>::xAxis).title));
278  _plot->axisWidget(QwtPlot::xBottom)->setTitle(xtitle);
279  QString ytitle(QString::fromStdString(result->axis(cass::Result<float>::yAxis).title));
280  _plot->axisWidget(QwtPlot::yLeft)->setTitle(ytitle);
281  }
282  }
283  else
284  {
285  _plot->axisWidget(QwtPlot::yLeft)->setTitle("");
286  _plot->axisWidget(QwtPlot::xBottom)->setTitle("");
287  }
288 
289  /** replot the plot */
290  _plot->replot();
291 
292  /** save the current settings */
293  QSettings settings;
294  settings.beginGroup(windowTitle());
295  settings.setValue("ColorTableID",colorid);
296  settings.setValue("DisplayTitles",_axisTitleControl->isChecked());
297  settings.endGroup();
298 }
299 
301 {
302  QSettings settings;
303  settings.beginGroup(windowTitle());
304 
305  /** reset the parameters */
306  _geomFile.clear();
307  double wavelength_A = 0;
308  double cameraDistance_cm = 0;
309  double pixelsize_um = 0;
310 
311  _zoomer->setWavelength_A(wavelength_A);
312  _zoomer->setCameraDistance_cm(cameraDistance_cm);
313  _zoomer->setPixelSize_um(pixelsize_um);
314 
315 
316  /** open dialogs and retrieve the requested info */
317  QString filter("Geom Files (*.geom)");
318  QString filename = QFileDialog::getOpenFileName(this, tr("Load Geom File"),
319  QDir::currentPath(), filter);
320  if (!filename.isEmpty() && QFileInfo(filename).exists())
321  {
322  _geomFile = filename;
323  _lutPresent = false;
324  }
325 
326  bool ok(false);
327  wavelength_A =
328  QInputDialog::getDouble(this, tr("Set Wavelength [Angstroem]"),
329  tr("Wavelength [Angstroem]:"),
330  settings.value("Wavelength_A",5).toDouble(),
331  0, 20, 5, &ok);
332  if (ok)
333  _zoomer->setWavelength_A(wavelength_A);
334 
335  cameraDistance_cm =
336  QInputDialog::getDouble(this, tr("Set Camera Distance [cm]"),
337  tr("Camera Distance [cm]:"),
338  settings.value("CameraDistance_cm",7).toDouble(),
339  0, 200, 5, &ok);
340  if (ok)
341  _zoomer->setCameraDistance_cm(cameraDistance_cm);
342 
343  pixelsize_um =
344  QInputDialog::getDouble(this, tr("Set PixelSize [um]"),
345  tr("Pixel Size [um]:"),
346  settings.value("PixelSize_um",110).toDouble(),
347  0, 1000, 5, &ok);
348  if (ok)
349  _zoomer->setPixelSize_um(pixelsize_um);
350 
351  settings.setValue("GeomFile",_geomFile);
352  settings.setValue("Wavelength_A",wavelength_A);
353  settings.setValue("CameraDistance_cm",cameraDistance_cm);
354  settings.setValue("PixelSize_um",pixelsize_um);
355  settings.endGroup();
356 
357  _isOriginalData = false;
358  dataChanged();
359 }
360 
361 QwtLinearColorMap* TwoDViewer::cmap(const int colorid,bool log) const
362 {
363  if (colorid == -4)
364  {
365  QwtLinearColorMap *map(log ? new LogColorMap(Qt::black, Qt::red) :
366  new QwtLinearColorMap(Qt::black, Qt::red));
367  map->addColorStop(0.999, QColor(Qt::white));
368  map->addColorStop(0.001, QColor(Qt::white));
369  return map;
370  }
371  if (colorid == -3)
372  {
373  QwtLinearColorMap *map(log ? new LogColorMap(Qt::black, Qt::black) :
374  new QwtLinearColorMap(Qt::black, Qt::black));
375  map->addColorStop(0.999, QColor(Qt::white));
376  return map;
377  }
378  if (colorid == -2)
379  {
380  QwtLinearColorMap *map(log ? new LogColorMap(Qt::white, Qt::black) :
381  new QwtLinearColorMap(Qt::white, Qt::black));
382  return map;
383  }
384  if (colorid == -1)
385  {
386  QwtLinearColorMap *map(log ? new LogColorMap(Qt::black, Qt::white) :
387  new QwtLinearColorMap(Qt::black, Qt::white));
388  return map;
389  }
390  else if(colorid == 0)
391  {
392  QwtLinearColorMap *map(log ? new LogColorMap(Qt::darkCyan, Qt::red) :
393  new QwtLinearColorMap(Qt::darkCyan, Qt::red));
394  map->addColorStop(0.10, QColor(Qt::darkCyan));
395  map->addColorStop(0.60, QColor(Qt::green));
396  map->addColorStop(0.90, QColor(Qt::yellow));
397  return map;
398  }
399  else if(colorid == 1)
400  {
401  QwtLinearColorMap *map(log ? new LogColorMap(Qt::black, QColor(255,0,0)) :
402  new QwtLinearColorMap(Qt::black, QColor(255,0,0)));
403  map->addColorStop(0.10, QColor(50,0,0));
404  map->addColorStop(0.35, QColor(115,0,0));
405  map->addColorStop(0.80, QColor(180,0,0));
406  return map;
407  }
408  else if(colorid == 2)
409  {
410  QwtLinearColorMap *map(log ? new LogColorMap(Qt::black, QColor(0,255,0)) :
411  new QwtLinearColorMap(Qt::black, QColor(0,255,0)));
412  return map;
413  }
414  else if(colorid == 3)
415  {
416  QwtLinearColorMap *map(log ? new LogColorMap(Qt::black, QColor(0,0,255)) :
417  new QwtLinearColorMap(Qt::black, QColor(0,0,255)));
418  return map;
419  }
420  else if(colorid == 4)
421  {
422  QwtLinearColorMap *map(log ? new LogColorMap(Qt::black, QColor(255,0,255)) :
423  new QwtLinearColorMap(Qt::black, QColor(255,0,255)));
424  return map;
425  }
426  else if(colorid == 5)
427  {
428  QwtLinearColorMap *map(log ? new LogColorMap(Qt::black, QColor(0,255,255)) :
429  new QwtLinearColorMap(Qt::black, QColor(0,255,255)));
430  return map;
431  }
432  else if(colorid == 7)
433  {
434  QwtLinearColorMap *map(log ? new LogColorMap(Qt::black, QColor(255,255,0)) :
435  new QwtLinearColorMap(Qt::black, QColor(255,255,0)));
436  return map;
437  }
438  else if(colorid == 6)
439  {
440  QwtLinearColorMap *map(log ? new LogColorMap(Qt::black, Qt::red) :
441  new QwtLinearColorMap(Qt::black, Qt::red));
442  map->addColorStop(0.10, Qt::blue);
443  map->addColorStop(0.30, Qt::darkCyan);
444  map->addColorStop(0.40, Qt::cyan);
445  map->addColorStop(0.60, Qt::darkGreen);
446  map->addColorStop(0.70, Qt::green);
447  map->addColorStop(0.95, Qt::yellow);
448  return map;
449  }
450  else if(colorid == 8)
451  {
452  QwtLinearColorMap *map(log ? new LogColorMap(Qt::darkBlue, Qt::white) :
453  new QwtLinearColorMap(Qt::darkBlue, Qt::white));
454  map->addColorStop(0.15, Qt::blue);
455  map->addColorStop(0.30, QColor(255,90,255));
456  map->addColorStop(0.40, Qt::yellow);
457  map->addColorStop(0.60, Qt::darkYellow);
458  map->addColorStop(0.70, Qt::red);
459  map->addColorStop(0.80, Qt::darkRed);
460  map->addColorStop(0.95, QColor(149,24,0));
461  return map;
462  }
463  else if(colorid == 9)
464  {
465  QwtLinearColorMap *map(log ? new LogColorMap(QColor(65,105,241), QColor(255,51,204)) :
466  new QwtLinearColorMap(QColor(65,105,241), QColor(255,51,204)));
467  map->addColorStop(0.10, QColor(0,127,255));
468  map->addColorStop(0.60, QColor(221,0,225));
469  map->addColorStop(0.95, QColor(255,51,204));
470  return map;
471  }
472  else if(colorid ==10)
473  {
474  QwtLinearColorMap *map(log ? new LogColorMap(QColor(72,6,7), Qt::white) :
475  new QwtLinearColorMap(QColor(72,6,7), Qt::white));
476  map->addColorStop(0.10, QColor(72,6,7));
477  map->addColorStop(0.20, Qt::darkRed);
478  map->addColorStop(0.35, Qt::red);
479  map->addColorStop(0.65, QColor(255,195,59));
480  map->addColorStop(0.85, Qt::yellow);
481  map->addColorStop(0.98, Qt::white);
482  return map;
483  }
484  else if(colorid ==11)
485  {
486  QwtLinearColorMap *map(log ? new LogColorMap(QColor(16,16,255), QColor(0,255,129)) :
487  new QwtLinearColorMap(QColor(16,16,255), QColor(0,255,129)));
488  map->addColorStop(0.10, QColor(16,16,255));
489  map->addColorStop(0.50, Qt::cyan);
490  map->addColorStop(0.90, QColor(0,255,155));
491  return map;
492  }
493  else if(colorid ==12)
494  {
495  QwtLinearColorMap *map(log ? new LogColorMap(QColor(10,10,10), QColor(184,115,51)) :
496  new QwtLinearColorMap(QColor(10,10,10), QColor(184,115,51)));
497  map->addColorStop(0.10, QColor(10,10,10));
498  map->addColorStop(0.20, QColor(149,34,0));
499  map->addColorStop(0.90, QColor(184,115,51));
500  return map;
501  }
502  else
503  {
504  return cmap(-1,log);
505  }
506 }
507 
509 {
510  QStringList list;
511  return list;
512 }
QwtInterval origZInterval(bool log) const
return the min max values of the values in the data
TrackZoomer2D * _zoomer
a zoomer for the 2d view
Definition: two_d_viewer.h:121
storage_t::const_iterator const_iterator
a const iterator on the storage
Definition: result.hpp:338
addToolBar(Qt::ToolBarArea area, QToolBar *toolbar)
contains zoomer for a 2d plot with tracking information
QwtPlotSpectrogram * _spectrogram
the spectrogram that is used to display the 2d data
Definition: two_d_viewer.h:109
base class for viewers
Definition: data_viewer.h:37
const_iterator end() const
retrieve iterator to the end of storage
Definition: result.hpp:632
virtual void dataChanged()
update the plot
create the noise and bad pixel map[Processor]
std::tr1::shared_ptr< self_type > shared_pointer
a shared pointer of this class
Definition: result.hpp:323
contains the wrappe of the data for the 2d viewer
QString _geomFile
the geom file to convert data to lab frame
Definition: two_d_viewer.h:124
bool log() const
return wether log is enabled
static void saveData(const QString &filename, result_t::shared_pointer data)
save data to a given file
virtual QString type() const
retrieve the type of the data viewer
contains the base class for add viewer data
a logarithmic color map
Definition: logcolor_map.h:22
virtual QList< Data * > data()
set the data to display
addWidget(QWidget *widget)
void setWavelength_A(double wavelength_A)
set the wavelength that is needed of the optional resolution calculation
QwtPlot * _plot
the plot inside which the data will be displayed
Definition: data_viewer.h:115
size_type size() const
return the raw size of the storage
Definition: result.hpp:881
std::string name() const
retrieve the name of the result
Definition: result.hpp:916
void replot()
replot the data
an axis of a more than 0 dimensional container
Definition: result.hpp:29
void setCameraDistance_cm(double cameradistance_cm)
set the camera distance that is needed of the optional resolution calculation
things written only at end of run H5Dump ProcessorSummary size
currentPath()
setRange(int minimum, int maximum)
widget to control the min and max values
virtual void saveData(const QString &filename)
save the data to file
MinMaxControl * _zControl
the z-scale control
Definition: two_d_viewer.h:112
setValue(const QString &key, const QVariant &value)
virtual ~TwoDViewer()
destructor
const_iterator begin() const
retrieve a iterator for read access to beginning
Definition: result.hpp:608
void on_load_geomfile_triggered()
load the geom file
fromStdString(const std::string &str)
void setPixelSize_um(double pixelsize_um)
set the size of a pixel in micro meters
append(const T &value)
save(const QString &fileName, const char *format=0, int quality=-1)
cass::GeometryInfo::lookupTable_t _lut
the geom file to convert data to lab frame
Definition: two_d_viewer.h:130
shared_pointer clone() const
create a copy of the result
Definition: result.hpp:890
bool autoscale() const
return whether the plot should be autoscaled
contains a logarithmic color map.
QwtLinearColorMap * cmap(const int mapId, bool log) const
retrieve a color id
contains a file handler
TwoDViewer(QString title, QWidget *parent=0)
constructor
the 2d data wrapper
setCentralWidget(QWidget *widget)
getDouble(QWidget *parent, const QString &title, const QString &label, double value=0, double min=-2147483647, double max=2147483647, int decimals=1, bool *ok=0, Qt::WindowFlags flags=0)
fluorescence front
cass::Result< float >::shared_pointer _origHist
the original histogram
Definition: two_d_viewer.h:133
value(const QString &key, const QVariant &defaultValue=QVariant()
bool _isOriginalData
flag to tell whether the data is the original data
Definition: two_d_viewer.h:136
result_t::shared_pointer result()
retrieve the pointer to the data
QSpinBox * _colorId
the colorbar control
Definition: two_d_viewer.h:115
QAction * _axisTitleControl
an action to control the legend of curves
Definition: two_d_viewer.h:118
QStringList cmaps() const
return the list of possible colormaps
double max() const
retieve the maximum value
contains a control over min and max values
class that allows to zoom in a 2d view with tracking information
getOpenFileName(QWidget *parent=0, const QString &caption=QString()
void setData(TwoDViewerData *data)
set the data to retrieve the values from
shape_t shape() const
return the shape of the result
Definition: result.hpp:811
double min() const
retrieve the minimum value
addAction(QAction *action)
bool _lutPresent
the geom file to convert data to lab frame
Definition: two_d_viewer.h:127
virtual QStringList dataFileSuffixes() const
suffixes for the data of this viewer
beginGroup(const QString &prefix)
std::vector< size_t > lut
Definition: geom_parser.h:34
contains the viewer for 2d data
lookupTable_t generateLookupTable(const std::string &filename, const size_t sizeOfSrc, const size_t nSrcCols, const bool convertFromCheetahToCASS)
generate a lookup table for a new image