00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef OPENMS_VISUAL_SPECTRUMCANVAS_H
00037 #define OPENMS_VISUAL_SPECTRUMCANVAS_H
00038
00039
00040 #include <OpenMS/CONCEPT/Types.h>
00041 #include <OpenMS/CONCEPT/VersionInfo.h>
00042 #include <OpenMS/DATASTRUCTURES/DRange.h>
00043 #include <OpenMS/VISUAL/LayerData.h>
00044 #include <OpenMS/DATASTRUCTURES/DefaultParamHandler.h>
00045
00046
00047 #include <QtGui/QWidget>
00048 #include <QtGui/QRubberBand>
00049 class QWheelEvent;
00050 class QKeyEvent;
00051 class QMouseEvent;
00052 class QFocusEvent;
00053 class QMenu;
00054
00055
00056 #include <stack>
00057 #include <vector>
00058
00059 namespace OpenMS
00060 {
00061 class SpectrumWidget;
00062
00094 class OPENMS_GUI_DLLAPI SpectrumCanvas :
00095 public QWidget,
00096 public DefaultParamHandler
00097 {
00098 Q_OBJECT
00099
00100 public:
00103
00105 typedef LayerData::ExperimentType ExperimentType;
00107 typedef LayerData::ExperimentSharedPtrType ExperimentSharedPtrType;
00109 typedef LayerData::FeatureMapType FeatureMapType;
00111 typedef LayerData::FeatureMapSharedPtrType FeatureMapSharedPtrType;
00113 typedef LayerData::ConsensusMapType ConsensusMapType;
00115 typedef LayerData::ConsensusMapSharedPtrType ConsensusMapSharedPtrType;
00116
00118 typedef ExperimentType::SpectrumType SpectrumType;
00120 typedef SpectrumType::ConstIterator SpectrumConstIteratorType;
00122 typedef SpectrumType::PeakType PeakType;
00124 typedef FeatureMapType::FeatureType FeatureType;
00125
00127 typedef DPosition<2> PointType;
00129 typedef DRange<2> AreaType;
00130
00131
00133 enum ActionModes
00134 {
00135 AM_TRANSLATE,
00136 AM_ZOOM,
00137 AM_MEASURE
00138 };
00139
00141 enum IntensityModes
00142 {
00143 IM_NONE,
00144 IM_PERCENTAGE,
00145 IM_SNAP,
00146 IM_LOG
00147 };
00148
00150
00152 SpectrumCanvas(const Param & preferences, QWidget * parent = 0);
00153
00155 virtual ~SpectrumCanvas();
00156
00164 inline void setSpectrumWidget(SpectrumWidget * widget)
00165 {
00166 spectrum_widget_ = widget;
00167 }
00168
00175 inline SpectrumWidget * getSpectrumWidget() const
00176 {
00177 return spectrum_widget_;
00178 }
00179
00186 inline Int getActionMode() const
00187 {
00188 return action_mode_;
00189 }
00190
00198 inline Int getIntensityMode() const
00199 {
00200 return intensity_mode_;
00201 }
00202
00212 inline void setIntensityMode(IntensityModes mod)
00213 {
00214 intensity_mode_ = mod;
00215 intensityModeChange_();
00216 }
00217
00223 inline bool gridLinesShown() const
00224 {
00225 return show_grid_;
00226 }
00227
00229 inline const LayerData & getLayer(Size index) const
00230 {
00231 OPENMS_PRECONDITION(index < layers_.size(), "SpectrumCanvas::getLayer(index) index overflow");
00232 return layers_[index];
00233 }
00234
00236 inline const LayerData & getCurrentLayer() const
00237 {
00238 OPENMS_PRECONDITION(current_layer_ < layers_.size(), "SpectrumCanvas::getCurrentLayer() index overflow");
00239 return layers_[current_layer_];
00240 }
00241
00243 inline LayerData & getCurrentLayer()
00244 {
00245 OPENMS_PRECONDITION(current_layer_ < layers_.size(), "SpectrumCanvas::getCurrentLayer() index overflow");
00246 return layers_[current_layer_];
00247 }
00248
00250 bool getLayerFlag(LayerData::Flags f) const
00251 {
00252 return getLayerFlag(current_layer_, f);
00253 }
00254
00256 void setLayerFlag(LayerData::Flags f, bool value)
00257 {
00258 setLayerFlag(current_layer_, f, value);
00259 }
00260
00262 bool getLayerFlag(Size layer, LayerData::Flags f) const
00263 {
00264 OPENMS_PRECONDITION(layer < layers_.size(), "SpectrumCanvas::getLayerFlag() index overflow");
00265 return layers_[layer].flags.test(f);
00266 }
00267
00269 void setLayerFlag(Size layer, LayerData::Flags f, bool value)
00270 {
00271
00272 if (layers_.empty()) return;
00273
00274 OPENMS_PRECONDITION(layer < layers_.size(), "SpectrumCanvas::setLayerFlag() index overflow");
00275
00276 layers_[layer].flags.set(f, value);
00277 update_buffer_ = true;
00278 update();
00279 }
00280
00281 inline void setLabel(LayerData::LabelType label)
00282 {
00283
00284 if (layers_.empty()) return;
00285
00286 OPENMS_PRECONDITION(current_layer_ < layers_.size(), "SpectrumCanvas::setLabel() index overflow");
00287 layers_[current_layer_].label = label;
00288
00289 update_buffer_ = true;
00290 update();
00291 }
00292
00298 inline const AreaType & getVisibleArea() const
00299 {
00300 return visible_area_;
00301 }
00302
00306 virtual void setFilters(const DataFilters & filters);
00307
00309 inline bool isMzToXAxis()
00310 {
00311 return mz_to_x_axis_;
00312 }
00313
00315 void mzToXAxis(bool mz_to_x_axis);
00316
00323
00324 inline Size getLayerCount() const
00325 {
00326 return layers_.size();
00327 }
00328
00330 Size activeLayerIndex() const;
00332 virtual void activateLayer(Size layer_index) = 0;
00334 virtual void removeLayer(Size layer_index) = 0;
00345 bool addLayer(ExperimentSharedPtrType map, const String & filename = "");
00346
00355 bool addLayer(FeatureMapSharedPtrType map, const String & filename = "");
00356
00365 bool addLayer(ConsensusMapSharedPtrType map, const String & filename = "");
00367
00376 bool addLayer(std::vector<PeptideIdentification> & peptides,
00377 const String & filename = "");
00378
00380 inline Real getCurrentMinIntensity() const
00381 {
00382 if (getCurrentLayer().type == LayerData::DT_PEAK || getCurrentLayer().type == LayerData::DT_CHROMATOGRAM)
00383 {
00384 return getCurrentLayer().getPeakData()->getMinInt();
00385 }
00386 else if (getCurrentLayer().type == LayerData::DT_FEATURE)
00387 {
00388 return getCurrentLayer().getFeatureMap()->getMinInt();
00389 }
00390 else
00391 {
00392 return getCurrentLayer().getConsensusMap()->getMinInt();
00393 }
00394 }
00395
00397 inline Real getCurrentMaxIntensity() const
00398 {
00399 if (getCurrentLayer().type == LayerData::DT_PEAK || getCurrentLayer().type == LayerData::DT_CHROMATOGRAM)
00400 {
00401 return getCurrentLayer().getPeakData()->getMaxInt();
00402 }
00403 else if (getCurrentLayer().type == LayerData::DT_FEATURE)
00404 {
00405 return getCurrentLayer().getFeatureMap()->getMaxInt();
00406 }
00407 else
00408 {
00409 return getCurrentLayer().getConsensusMap()->getMaxInt();
00410 }
00411 }
00412
00414 inline Real getMinIntensity(Size index) const
00415 {
00416 if (getLayer(index).type == LayerData::DT_PEAK || getCurrentLayer().type == LayerData::DT_CHROMATOGRAM)
00417 {
00418 return getLayer(index).getPeakData()->getMinInt();
00419 }
00420 else if (getLayer(index).type == LayerData::DT_FEATURE)
00421 {
00422 return getLayer(index).getFeatureMap()->getMinInt();
00423 }
00424 else
00425 {
00426 return getLayer(index).getConsensusMap()->getMinInt();
00427 }
00428 }
00429
00431 inline Real getMaxIntensity(Size index) const
00432 {
00433 if (getLayer(index).type == LayerData::DT_PEAK || getCurrentLayer().type == LayerData::DT_CHROMATOGRAM)
00434 {
00435 return getLayer(index).getPeakData()->getMaxInt();
00436 }
00437 else if (getLayer(index).type == LayerData::DT_FEATURE)
00438 {
00439 return getLayer(index).getFeatureMap()->getMaxInt();
00440 }
00441 else
00442 {
00443 return getLayer(index).getConsensusMap()->getMaxInt();
00444 }
00445 }
00446
00448 void setLayerName(Size i, const String & name);
00449
00451 String getLayerName(Size i);
00452
00454 inline void setCurrentLayerParameters(const Param & param)
00455 {
00456 getCurrentLayer_().param = param;
00457 emit preferencesChange();
00458 }
00459
00465 const DRange<3> & getDataRange();
00466
00472 DoubleReal getSnapFactor();
00473
00475 DoubleReal getPercentageFactor();
00476
00478 virtual void showCurrentLayerPreferences() = 0;
00479
00486 virtual void showMetaData(bool modifiable = false, Int index = -1);
00487
00493 virtual void saveCurrentLayer(bool visible) = 0;
00494
00495 public slots:
00496
00503 void changeVisibility(Size i, bool b);
00504
00511 void changeLayerFilterState(Size i, bool b);
00512
00519 void showGridLines(bool show);
00520
00528 void resetZoom(bool repaint = true);
00529
00536 void setVisibleArea(AreaType area);
00537
00543 virtual void horizontalScrollBarChange(int value);
00544
00550 virtual void verticalScrollBarChange(int value);
00551
00553 void setAdditionalContextMenu(QMenu * menu);
00554
00562 void getVisiblePeakData(ExperimentType & map) const;
00563
00564
00572 void getVisibleFeatureData(FeatureMapType & map) const;
00573
00581 void getVisibleConsensusData(ConsensusMapType & map) const;
00582
00590 void getVisibleIdentifications(std::vector<PeptideIdentification> & peptides) const;
00591
00593 virtual void updateLayer(Size i) = 0;
00594
00595 signals:
00596
00598 void layerModficationChange(Size layer, bool modified);
00599
00601 void layerActivated(QWidget * w);
00602
00604 void layerZoomChanged(QWidget * w);
00605
00612 void visibleAreaChanged(DRange<2> area);
00613
00615 void sendCursorStatus(double mz = -1.0, double rt = -1.0);
00616
00618 void sendStatusMessage(std::string message, OpenMS::UInt time);
00619
00621 void recalculateAxes();
00622
00624 void updateVScrollbar(float, float, float, float);
00625
00627 void updateHScrollbar(float, float, float, float);
00628
00630 void changeLegendVisibility();
00631
00633 void actionModeChange();
00634
00636 void preferencesChange();
00637
00638 protected slots:
00639
00641 void updateCursor_();
00642
00643 protected:
00644
00646 void drawText_(QPainter & painter, QStringList text);
00647
00649 DoubleReal getIdentificationMZ_(const Size layer_index,
00650 const PeptideIdentification & peptide) const;
00651
00653 virtual bool finishAdding_() = 0;
00654
00656 inline LayerData & getLayer_(Size index)
00657 {
00658 OPENMS_PRECONDITION(index < layers_.size(), "SpectrumCanvas::getLayer_(index) index overflow");
00659 return layers_[index];
00660 }
00661
00663 inline LayerData & getCurrentLayer_()
00664 {
00665 return getLayer_(current_layer_);
00666 }
00667
00669 inline ExperimentSharedPtrType currentPeakData_()
00670 {
00671 return getCurrentLayer_().getPeakData();
00672 }
00673
00675
00676 void resizeEvent(QResizeEvent * e);
00677 void wheelEvent(QWheelEvent * e);
00678 void keyPressEvent(QKeyEvent * e);
00679 void keyReleaseEvent(QKeyEvent * e);
00680 void focusOutEvent(QFocusEvent * e);
00681 void leaveEvent(QEvent * e);
00682 void enterEvent(QEvent * e);
00684
00686 virtual void intensityModeChange_();
00687
00698 virtual void changeVisibleArea_(const AreaType & new_area, bool repaint = true, bool add_to_stack = false);
00699
00705 virtual void recalculateSnapFactor_();
00706
00708
00709
00710 void zoom(int x, int y, bool zoom_in);
00712 void zoomBack_();
00714 virtual void zoomForward_();
00716 void zoomAdd_(const AreaType & area);
00718 void zoomClear_();
00720
00722
00723
00724 virtual void translateLeft_();
00726 virtual void translateRight_();
00728 virtual void translateForward_();
00730 virtual void translateBackward_();
00732
00738 virtual void updateScrollbars_();
00739
00740
00749 inline PointType widgetToData_(DoubleReal x, DoubleReal y)
00750 {
00751 if (!isMzToXAxis())
00752 {
00753 return PointType(
00754 visible_area_.minX() + (height() - y) / height() * visible_area_.width(),
00755 visible_area_.minY() + x / width() * visible_area_.height()
00756 );
00757 }
00758 else
00759 {
00760 return PointType(
00761 visible_area_.minX() + x / width() * visible_area_.width(),
00762 visible_area_.minY() + (height() - y) / height() * visible_area_.height()
00763 );
00764 }
00765 }
00766
00768 inline PointType widgetToData_(const QPoint & pos)
00769 {
00770 return widgetToData_(pos.x(), pos.y());
00771 }
00772
00781 inline void dataToWidget_(DoubleReal x, DoubleReal y, QPoint & point)
00782 {
00783 if (!isMzToXAxis())
00784 {
00785
00786
00787 if (intensity_mode_ != SpectrumCanvas::IM_LOG)
00788 {
00789 point.setX(int((y - visible_area_.minY()) / visible_area_.height() * width()));
00790 }
00791 else
00792 {
00793 point.setX(int(
00794 std::log10((y - visible_area_.minY()) + 1) / std::log10(visible_area_.height() + 1) * width())
00795 );
00796 }
00797
00798 point.setY(height() - int((x - visible_area_.minX()) / visible_area_.width() * height()));
00799 }
00800 else
00801 {
00802 point.setX(int((x - visible_area_.minX()) / visible_area_.width() * width()));
00803
00804 if (intensity_mode_ != SpectrumCanvas::IM_LOG)
00805 {
00806 point.setY(height() - int((y - visible_area_.minY()) / visible_area_.height() * height()));
00807 }
00808 else
00809 {
00810 point.setY(height() - int(
00811 std::log10((y - visible_area_.minY()) + 1) / std::log10(visible_area_.height() + 1) * height()
00812 ));
00813 }
00814 }
00815 }
00816
00818 virtual void paintGridLines_(QPainter & painter);
00819
00821 QImage buffer_;
00822
00824 ActionModes action_mode_;
00825
00827 IntensityModes intensity_mode_;
00828
00830 std::vector<LayerData> layers_;
00831
00833 bool mz_to_x_axis_;
00834
00841 AreaType visible_area_;
00842
00852 void recalculateRanges_(UInt mz_dim, UInt rt_dim, UInt it_dim);
00853
00861 DRange<3> overall_data_range_;
00862
00864 bool show_grid_;
00865
00867 std::vector<AreaType> zoom_stack_;
00869 std::vector<AreaType>::iterator zoom_pos_;
00870
00880 virtual void update_(const char * caller_name);
00881
00883 void modificationStatus_(Size layer_index, bool modified);
00884
00886 bool update_buffer_;
00887
00889 Size current_layer_;
00890
00892 void adjustBuffer_();
00893
00895 SpectrumWidget * spectrum_widget_;
00896
00898 QPoint last_mouse_pos_;
00899
00905 double percentage_factor_;
00906
00912 std::vector<DoubleReal> snap_factors_;
00913
00915 QRubberBand rubber_band_;
00916
00918 QMenu * context_add_;
00919
00921 bool show_timing_;
00922
00924 PeakIndex selected_peak_;
00926 PeakIndex measurement_start_;
00927
00929 template <typename PeakType>
00930 void addDataProcessing_(MSExperiment<PeakType> & map, DataProcessing::ProcessingAction action) const
00931 {
00932 std::set<DataProcessing::ProcessingAction> actions;
00933 actions.insert(action);
00934
00935 DataProcessing p;
00936
00937 p.setProcessingActions(actions);
00938
00939 p.getSoftware().setName("SpectrumCanvas");
00940
00941 p.getSoftware().setVersion(VersionInfo::getVersion());
00942
00943 p.setCompletionTime(DateTime::now());
00944
00945 for (Size i = 0; i < map.size(); ++i)
00946 {
00947 map[i].getDataProcessing().push_back(p);
00948 }
00949 }
00950
00951 };
00952 }
00953
00954 #endif