diff --git a/Core/Instrument/IntensityDataFunctions.cpp b/Core/Instrument/IntensityDataFunctions.cpp index aec60baa20d137b6d8e4867a5b68ea96555ef8ae..9dd8d2904bf5a1fd57391c5f4d902b027ab546e2 100644 --- a/Core/Instrument/IntensityDataFunctions.cpp +++ b/Core/Instrument/IntensityDataFunctions.cpp @@ -17,6 +17,7 @@ #include "ConvolutionDetectorResolution.h" #include "IHistogram.h" #include "Numeric.h" +#include "BornAgainNamespace.h" #include <memory> //! Returns relative difference between two data sets sum(dat[i] - ref[i])/ref[i]). @@ -108,3 +109,50 @@ OutputData<double>* IntensityDataFunctions::applyDetectorResolution( P_resolution->applyDetectorResolution(result); return result; } + +// For axis FixedBinAxis("axis", 8, -5.0, 3.0) the coordinate x=-4.5 (center of bin #0) will +// be converted into 0.5 (which is a bin center expressed in bin fraction coordinates). +// The coordinate -5.0 (outside of axis definition) will be converted to -0.5 +// (center of non-existing bin #-1). +// Used for Mask convertion. + +double IntensityDataFunctions::coordinateToBinf(double coordinate, const IAxis *axis) +{ + int index = axis->findClosestIndex(coordinate); + Bin1D bin = axis->getBin(index); + double f = (coordinate - bin.m_lower)/bin.getBinSize(); + return static_cast<double>(index) + f; +} + +double IntensityDataFunctions::coordinateFromBinf(double value, const IAxis *axis) +{ + int index = static_cast<int>(value); + + double result(0); + if(index < 0) { + Bin1D bin = axis->getBin(0); + result = bin.m_lower + value*bin.getBinSize(); + } else if(index >= (int)axis->getSize()) { + Bin1D bin = axis->getBin(axis->getSize()-1); + result = bin.m_upper + (value-axis->getSize())*bin.getBinSize(); + } else { + Bin1D bin = axis->getBin(index); + result = bin.m_lower + (value - static_cast<double>(index))*bin.getBinSize(); + } + + return result; +} + +void IntensityDataFunctions::coordinateToBinf(double &x, double &y, const OutputData<double> *data) +{ + x = coordinateToBinf(x, data->getAxis(BornAgain::X_AXIS_INDEX)); + y = coordinateToBinf(y, data->getAxis(BornAgain::Y_AXIS_INDEX)); +} + +void IntensityDataFunctions::coordinateFromBinf(double &x, double &y, + const OutputData<double> *data) +{ + x = coordinateFromBinf(x, data->getAxis(BornAgain::X_AXIS_INDEX)); + y = coordinateFromBinf(y, data->getAxis(BornAgain::Y_AXIS_INDEX)); +} + diff --git a/Core/Instrument/IntensityDataFunctions.h b/Core/Instrument/IntensityDataFunctions.h index 1310be1f46bf0eaac73df4acf8d2df4609f7848c..64875905fe0d73b2a6ad4a5e7713892e4b12b5d5 100644 --- a/Core/Instrument/IntensityDataFunctions.h +++ b/Core/Instrument/IntensityDataFunctions.h @@ -43,6 +43,18 @@ public: //! Applies detector resolution function and returns new IntensityData object static OutputData<double>* applyDetectorResolution( const OutputData<double>& origin, const IResolutionFunction2D& resolution_function); + + //! Transforms coordinate on axis into the bin-fraction-coordinate. + static double coordinateToBinf(double coordinate, const IAxis *axis); + + //! Transforms bin-fraction-coordinate into axis coordinate. + static double coordinateFromBinf(double value, const IAxis *axis); + + //! Transform x,y coordinate from OutputData axes coordinates to bin-fraction-coordinates + static void coordinateToBinf(double &x, double &y, const OutputData<double> *data); + + //! Transform x,y coordinate from bin-fraction-coordinates to OutputData's axes coordinates + static void coordinateFromBinf(double &x, double &y, const OutputData<double> *data); }; #endif // INTENSITYDATAFUNCTIONS_H diff --git a/GUI/coregui/Models/IntensityDataItem.cpp b/GUI/coregui/Models/IntensityDataItem.cpp index 9ccc09c1f749567453a172ced591af878b2f28dc..20ea96caee3badc87f1f7780a2661dd857137683 100644 --- a/GUI/coregui/Models/IntensityDataItem.cpp +++ b/GUI/coregui/Models/IntensityDataItem.cpp @@ -19,6 +19,7 @@ #include "BornAgainNamespace.h" #include "ComboProperty.h" #include "GUIHelpers.h" +#include "MaskItems.h" const QString IntensityDataItem::P_AXES_UNITS = "Axes Units"; const QString IntensityDataItem::P_TITLE = "Title"; @@ -371,3 +372,8 @@ void IntensityDataItem::resetView() if(!isZAxisLocked()) computeDataRange(); } + +MaskContainerItem *IntensityDataItem::maskContainerItem() +{ + return dynamic_cast<MaskContainerItem *>(getItem(IntensityDataItem::T_MASKS)); +} diff --git a/GUI/coregui/Models/IntensityDataItem.h b/GUI/coregui/Models/IntensityDataItem.h index bd81f7322708da20e6f6002c82bb27c7a6fa807d..0028f69adc0f7523e5cfad128410a574abb1253f 100644 --- a/GUI/coregui/Models/IntensityDataItem.h +++ b/GUI/coregui/Models/IntensityDataItem.h @@ -21,7 +21,7 @@ #include "IDetector2D.h" class BasicAxisItem; - +class MaskContainerItem; class BA_CORE_API_ IntensityDataItem : public SessionItem { @@ -94,6 +94,8 @@ public: void resetView(); + MaskContainerItem *maskContainerItem(); + public slots: void setLowerX(double xmin); void setUpperX(double xmax); diff --git a/GUI/coregui/Models/RealDataItem.cpp b/GUI/coregui/Models/RealDataItem.cpp index a972c6262604c6d0d25c11485d748b2e865b9932..c9655b75b2cefcc1d879b7879bbdf7f0277914b7 100644 --- a/GUI/coregui/Models/RealDataItem.cpp +++ b/GUI/coregui/Models/RealDataItem.cpp @@ -22,6 +22,7 @@ #include "ComboProperty.h" #include "JobItemHelper.h" #include "ImportDataAssistant.h" +#include "MaskUnitsConverter.h" const QString RealDataItem::P_INSTRUMENT_ID = "Instrument Id"; const QString RealDataItem::P_INSTRUMENT_NAME = "Instrument"; @@ -65,7 +66,14 @@ RealDataItem::RealDataItem() return; mapper()->setActive(false); Q_ASSERT(m_linkedInstrument); + + MaskUnitsConverter converter; + converter.convertToNbins(intensityDataItem()); + JobItemHelper::updateDataAxes(intensityDataItem(), m_linkedInstrument); + + converter.convertFromNbins(intensityDataItem()); + mapper()->setActive(true); } }); diff --git a/GUI/coregui/Views/ImportDataView.cpp b/GUI/coregui/Views/ImportDataView.cpp index 3f0455bf7ac1aeda7db2b7c8265e82444fed7438..2519b6fcc3f6f476a2db3a9aa82c4d6f984d96d6 100644 --- a/GUI/coregui/Views/ImportDataView.cpp +++ b/GUI/coregui/Views/ImportDataView.cpp @@ -29,8 +29,8 @@ ImportDataView::ImportDataView(MainWindow *mainWindow) , m_toolBar(new ImportDataToolBar) , m_splitter(new Manhattan::MiniSplitter) , m_selectorWidget(new RealDataSelectorWidget) - , m_stackedWidget(new ItemStackPresenter<RealDataEditorWidget>) -// , m_stackedWidget(new ItemStackPresenter<RealDataMaskWidget>) +// , m_stackedWidget(new ItemStackPresenter<RealDataEditorWidget>) + , m_stackedWidget(new ItemStackPresenter<RealDataMaskWidget>) , m_realDataModel(mainWindow->realDataModel()) { QVBoxLayout *mainLayout = new QVBoxLayout; @@ -71,8 +71,8 @@ void ImportDataView::onSelectionChanged(SessionItem *item) bool isNew(false); m_stackedWidget->setItem(item, isNew); if(isNew) { - RealDataEditorWidget *widget = m_stackedWidget->currentWidget(); -// RealDataMaskWidget *widget = m_stackedWidget->currentWidget(); +// RealDataEditorWidget *widget = m_stackedWidget->currentWidget(); + RealDataMaskWidget *widget = m_stackedWidget->currentWidget(); Q_ASSERT(widget); widget->setItem(item); } diff --git a/GUI/coregui/Views/ImportDataView.h b/GUI/coregui/Views/ImportDataView.h index dfa0c9b181a0991e5d0aab42afa3913f367aa82c..fdb0aeefdc7e68baed87df54a11d6f831dc40c94 100644 --- a/GUI/coregui/Views/ImportDataView.h +++ b/GUI/coregui/Views/ImportDataView.h @@ -24,10 +24,7 @@ class ImportDataToolBar; class RealDataModel; class RealDataSelectorWidget; - -namespace Manhattan { - class MiniSplitter; -} +namespace Manhattan { class MiniSplitter; } //! The ImportDataView class is a main view for importing experimental data. @@ -47,8 +44,8 @@ private: ImportDataToolBar *m_toolBar; Manhattan::MiniSplitter *m_splitter; RealDataSelectorWidget *m_selectorWidget; -// ItemStackPresenter<RealDataMaskWidget> *m_stackedWidget; - ItemStackPresenter<RealDataEditorWidget> *m_stackedWidget; + ItemStackPresenter<RealDataMaskWidget> *m_stackedWidget; +// ItemStackPresenter<RealDataEditorWidget> *m_stackedWidget; RealDataModel *m_realDataModel; }; diff --git a/GUI/coregui/Views/ImportDataWidgets/RealDataMaskWidget.cpp b/GUI/coregui/Views/ImportDataWidgets/RealDataMaskWidget.cpp index 9ce26872f1ae6e2e1f690446a78f9951655787ac..593f8ee6b7217897dbfe713d62cdac93070f0115 100644 --- a/GUI/coregui/Views/ImportDataWidgets/RealDataMaskWidget.cpp +++ b/GUI/coregui/Views/ImportDataWidgets/RealDataMaskWidget.cpp @@ -49,7 +49,6 @@ RealDataMaskWidget::RealDataMaskWidget(QWidget *parent) mainLayout->addLayout(hlayout); setLayout(mainLayout); - } void RealDataMaskWidget::setItem(SessionItem *item) @@ -67,8 +66,7 @@ void RealDataMaskWidget::setItem(SessionItem *item) QList<QAction *> RealDataMaskWidget::actionList() { -// return m_intensityWidget->actionList() + m_propertyWidget->actionList(); - return QList<QAction*>(); + return m_maskEditor->topToolBarActions(); } MaskContainerItem *RealDataMaskWidget::createMaskContainer(IntensityDataItem *intensityData) diff --git a/GUI/coregui/Views/IntensityDataWidgets/IntensityDataPropertyWidget.h b/GUI/coregui/Views/IntensityDataWidgets/IntensityDataPropertyWidget.h index ba4685433c47d106a79a905e3037d9852abed94b..9690c8e7ef90c98287806165bebb80cab0ef6312 100644 --- a/GUI/coregui/Views/IntensityDataWidgets/IntensityDataPropertyWidget.h +++ b/GUI/coregui/Views/IntensityDataWidgets/IntensityDataPropertyWidget.h @@ -22,6 +22,7 @@ class JobModel; class IntensityDataItem; class ComponentEditor; +class SessionItem; //! The IntensityDataPropertyWidget shows ComponentEditor for given IntensityDataItem. diff --git a/GUI/coregui/Views/MaskWidgets/MaskDrawingContext.cpp b/GUI/coregui/Views/MaskWidgets/MaskDrawingContext.cpp index 134662a1cef568dd0fc5aedb547eb9f8fcd91fe5..3f9e15b9c55c055786ae60f0b4659b3de1594cf0 100644 --- a/GUI/coregui/Views/MaskWidgets/MaskDrawingContext.cpp +++ b/GUI/coregui/Views/MaskWidgets/MaskDrawingContext.cpp @@ -19,7 +19,7 @@ #include <QDebug> MaskDrawingContext::MaskDrawingContext() - : m_current_activity(MaskEditorFlags::SELECTION_MODE) + : m_current_activity(MaskEditorFlags::PAN_ZOOM_MODE) , m_mask_value(MaskEditorFlags::MASK_ON) , m_drawing_in_progress(false) { diff --git a/GUI/coregui/Views/MaskWidgets/MaskEditor.cpp b/GUI/coregui/Views/MaskWidgets/MaskEditor.cpp index d8f30d84dbc1ccc583cd4cfbae30baa370a55c25..90db0678bc3fc5c4d06ffc89dc8073faac1982da 100644 --- a/GUI/coregui/Views/MaskWidgets/MaskEditor.cpp +++ b/GUI/coregui/Views/MaskWidgets/MaskEditor.cpp @@ -29,27 +29,28 @@ #include "SampleBuilderFactory.h" #include "SessionModel.h" #include "SimulationFactory.h" +#include "minisplitter.h" #include <QBoxLayout> #include <QContextMenuEvent> #include <QDebug> #include <QMenu> -#include <QSplitter> MaskEditor::MaskEditor(QWidget* parent) : QMainWindow(parent) - , m_itemActions(new MaskEditorActions(this)) - , m_toolBar(new MaskEditorToolBar(m_itemActions)) + , m_editorActions(new MaskEditorActions(this)) + , m_toolBar(new MaskEditorToolBar(m_editorActions)) , m_editorPropertyPanel(new MaskEditorPropertyPanel) , m_editorCanvas(new MaskEditorCanvas) - , m_splitter(new QSplitter(this)) + , m_splitter(new Manhattan::MiniSplitter) { setObjectName(QStringLiteral("MaskEditor")); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); m_splitter->addWidget(m_editorCanvas); m_splitter->addWidget(m_editorPropertyPanel); + m_splitter->setCollapsible(1, true); - addToolBar(m_toolBar); + addToolBar(Qt::RightToolBarArea, m_toolBar); setCentralWidget(m_splitter); @@ -70,8 +71,8 @@ void MaskEditor::setMaskContext(SessionModel* model, const QModelIndex &maskCont m_editorCanvas->setMaskContext(model, maskContainerIndex, intensityItem); m_editorCanvas->setSelectionModel(m_editorPropertyPanel->selectionModel()); - m_itemActions->setModel(model, maskContainerIndex); - m_itemActions->setSelectionModel(m_editorPropertyPanel->selectionModel()); + m_editorActions->setModel(model, maskContainerIndex); + m_editorActions->setSelectionModel(m_editorPropertyPanel->selectionModel()); } //! shows/hides right panel with properties @@ -161,8 +162,36 @@ void MaskEditor::init_test_model() setMaskContext(maskModel, maskModel->indexOfItem(container), intensityItem); } +//! Returns list of actions intended for styled toolbar (on the top). + +QList<QAction *> MaskEditor::topToolBarActions() +{ + return m_editorActions->topToolBarActions(); +} + void MaskEditor::setup_connections() { + // reset view request is propagated from editorActions to graphics view + connect(m_editorActions, + SIGNAL(resetViewRequest()), + m_editorCanvas, + SLOT(onResetViewRequest()) + ); + + // tool panel request is propagated from editorActions to this MaskEditor + connect(m_editorActions, + SIGNAL(propertyPanelRequest()), + this, + SLOT(onPropertyPanelRequest()) + ); + + // save plot request is propagated from editorActions to graphics scene + connect(m_editorActions, + SIGNAL(savePlotRequest()), + m_editorCanvas, + SLOT(onSavePlotRequest()) + ); + // selection/drawing activity is propagated from ToolBar to graphics scene connect(m_toolBar, SIGNAL(activityModeChanged(MaskEditorFlags::Activity)), @@ -177,13 +206,6 @@ void MaskEditor::setup_connections() SLOT(onMaskValueChanged(MaskEditorFlags::MaskValue)) ); - // tool panel request is propagated from ToolBar to this MaskEditor - connect(m_toolBar, - SIGNAL(propertyPanelRequest()), - this, - SLOT(onPropertyPanelRequest()) - ); - // show results request is propagated from ToolBar to Canvas connect(m_toolBar, SIGNAL(presentationTypeRequest(MaskEditorFlags::PresentationType)), @@ -191,15 +213,8 @@ void MaskEditor::setup_connections() SLOT(onPresentationTypeRequest(MaskEditorFlags::PresentationType)) ); - // reset view request is propagated from ToolBar to graphics view - connect(m_toolBar, - SIGNAL(resetViewRequest()), - m_editorCanvas->getView(), - SLOT(onResetViewRequest()) - ); - // space bar push (request for zoom mode) is propagated from graphics view to ToolBar - connect(m_editorCanvas->getView(), + connect(m_editorCanvas, SIGNAL(changeActivityRequest(MaskEditorFlags::Activity)), m_toolBar, SLOT(onChangeActivityRequest(MaskEditorFlags::Activity)) @@ -208,15 +223,14 @@ void MaskEditor::setup_connections() // context menu request is propagated from graphics scene to MaskEditorActions connect(m_editorCanvas->getScene(), SIGNAL(itemContextMenuRequest(QPoint)), - m_itemActions, + m_editorActions, SLOT(onItemContextMenuRequest(QPoint)) ); // context menu request is propagated from PropertyPanel to MaskEditorActions connect(m_editorPropertyPanel, SIGNAL(itemContextMenuRequest(QPoint)), - m_itemActions, + m_editorActions, SLOT(onItemContextMenuRequest(QPoint)) ); - } diff --git a/GUI/coregui/Views/MaskWidgets/MaskEditor.h b/GUI/coregui/Views/MaskWidgets/MaskEditor.h index edbbcf3bc7b859a8335469abf7508a21a7bca22b..8bbe09859cc1f229f9ca29fecb1e2c69ca23b0d0 100644 --- a/GUI/coregui/Views/MaskWidgets/MaskEditor.h +++ b/GUI/coregui/Views/MaskWidgets/MaskEditor.h @@ -26,9 +26,9 @@ class MaskEditorPropertyPanel; class MaskEditorActions; class MaskEditorToolBar; class MaskEditorCanvas; -class QSplitter; class SessionModel; class IntensityDataItem; +namespace Manhattan { class MiniSplitter; } //! Main class to draw masks on top of intensity data map @@ -49,17 +49,19 @@ public slots: void onPropertyPanelRequest(); void init_test_model(); + QList<QAction *> topToolBarActions(); + protected: void contextMenuEvent(QContextMenuEvent *event); private: void setup_connections(); - MaskEditorActions *m_itemActions; + MaskEditorActions *m_editorActions; MaskEditorToolBar *m_toolBar; MaskEditorPropertyPanel *m_editorPropertyPanel; MaskEditorCanvas *m_editorCanvas; - QSplitter *m_splitter; + Manhattan::MiniSplitter *m_splitter; }; diff --git a/GUI/coregui/Views/MaskWidgets/MaskEditorActions.cpp b/GUI/coregui/Views/MaskWidgets/MaskEditorActions.cpp index 9945794e17cf907cd0b6e449e364bf01f0c69a71..27427def2ec3758f3800ffc89e1a5a64a53744e4 100644 --- a/GUI/coregui/Views/MaskWidgets/MaskEditorActions.cpp +++ b/GUI/coregui/Views/MaskWidgets/MaskEditorActions.cpp @@ -48,6 +48,24 @@ MaskEditorActions::MaskEditorActions(QWidget *parent) parent->addAction(m_deleteMaskAction); connect(m_deleteMaskAction, SIGNAL(triggered()), this, SLOT(onDeleteMaskAction())); + // Actions for top toolbar + m_resetViewAction = new QAction(this); + m_resetViewAction->setText("Reset"); + m_resetViewAction->setIcon(QIcon(":/images/toolbar16light_refresh.svg")); + m_resetViewAction->setToolTip("Reset View"); + connect(m_resetViewAction, SIGNAL(triggered()), this, SIGNAL(resetViewRequest())); + + m_savePlotAction = new QAction(this); + m_savePlotAction->setText("Save"); + m_savePlotAction->setIcon(QIcon(":/images/toolbar16light_save.svg")); + m_savePlotAction->setToolTip("Save Plot"); + connect(m_savePlotAction, SIGNAL(triggered()), this, SIGNAL(savePlotRequest())); + + m_togglePanelAction = new QAction(this); + m_togglePanelAction->setText("Properties"); + m_togglePanelAction->setIcon(QIcon(":/images/toolbar16light_propertypanel.svg")); + m_togglePanelAction->setToolTip("Toggle Property Panel"); + connect(m_togglePanelAction, SIGNAL(triggered()), this, SIGNAL(propertyPanelRequest())); } void MaskEditorActions::setModel(SessionModel *maskModel, const QModelIndex &rootIndex) @@ -61,16 +79,21 @@ void MaskEditorActions::setSelectionModel(QItemSelectionModel *selectionModel) m_selectionModel = selectionModel; } -QAction *MaskEditorActions::getSendToBackAction() +QAction *MaskEditorActions::sendToBackAction() { return m_sendToBackAction; } -QAction *MaskEditorActions::getBringToFrontAction() +QAction *MaskEditorActions::bringToFrontAction() { return m_bringToFrontAction; } +QList<QAction *> MaskEditorActions::topToolBarActions() +{ + return QList<QAction*>() << m_resetViewAction << m_savePlotAction << m_togglePanelAction; +} + //! Constructs MaskItem context menu following the request from MaskGraphicsScene //! or MaskEditorInfoPanel void MaskEditorActions::onItemContextMenuRequest(const QPoint &point) diff --git a/GUI/coregui/Views/MaskWidgets/MaskEditorActions.h b/GUI/coregui/Views/MaskWidgets/MaskEditorActions.h index 1f6532c36eec0c5130e65d996b1efdcc4c68e733..0004f76fc51cb6a3a15333cd984127f54ff5911e 100644 --- a/GUI/coregui/Views/MaskWidgets/MaskEditorActions.h +++ b/GUI/coregui/Views/MaskWidgets/MaskEditorActions.h @@ -21,6 +21,7 @@ #include "WinDllMacros.h" #include <QModelIndex> #include <QObject> +#include <QList> class QAction; class SessionModel; @@ -41,8 +42,15 @@ public: void setModel(SessionModel *maskModel, const QModelIndex &rootIndex); void setSelectionModel(QItemSelectionModel *selectionModel); - QAction *getSendToBackAction(); - QAction *getBringToFrontAction(); + QAction *sendToBackAction(); + QAction *bringToFrontAction(); + + QList<QAction *> topToolBarActions(); + +signals: + void resetViewRequest(); + void propertyPanelRequest(); + void savePlotRequest(); public slots: void onItemContextMenuRequest(const QPoint &point); @@ -65,6 +73,10 @@ private: QAction *m_sendToBackAction; QAction *m_deleteMaskAction; + QAction *m_resetViewAction; + QAction *m_savePlotAction; + QAction *m_togglePanelAction; + SessionModel *m_maskModel; QModelIndex m_rootIndex; //! Index in the model corresponding to IntensityDataItem QItemSelectionModel *m_selectionModel; diff --git a/GUI/coregui/Views/MaskWidgets/MaskEditorCanvas.cpp b/GUI/coregui/Views/MaskWidgets/MaskEditorCanvas.cpp index e689a5eb45c6ead5b41c08bbeda4ced2eda2ac43..a2c90a92342e231ab4af0aac7e11935dc5be0f4c 100644 --- a/GUI/coregui/Views/MaskWidgets/MaskEditorCanvas.cpp +++ b/GUI/coregui/Views/MaskWidgets/MaskEditorCanvas.cpp @@ -20,7 +20,13 @@ #include "MaskGraphicsView.h" #include "MaskResultsPresenter.h" #include "SessionModel.h" -#include <QDebug> +#include "ColorMapLabel.h" +#include "SavePlotAssistant.h" +#include "AppSvc.h" +#include "projectmanager.h" +#include "ColorMap.h" +#include "IntensityDataItem.h" +#include "MaskItems.h" #include <QDebug> #include <QGraphicsRectItem> #include <QModelIndex> @@ -31,6 +37,8 @@ MaskEditorCanvas::MaskEditorCanvas(QWidget *parent) : QWidget(parent) , m_scene(new MaskGraphicsScene(this)) , m_view(new MaskGraphicsView(m_scene)) + , m_intensityDataItem(0) + , m_statusLabel(new ColorMapLabel(0, this)) , m_resultsPresenter(new MaskResultsPresenter(this)) { setObjectName(QStringLiteral("MaskEditorCanvas")); @@ -38,18 +46,25 @@ MaskEditorCanvas::MaskEditorCanvas(QWidget *parent) QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addWidget(m_view); + mainLayout->addWidget(m_statusLabel); mainLayout->setMargin(0); mainLayout->setSpacing(0); setLayout(mainLayout); + connect(m_view, SIGNAL(changeActivityRequest(MaskEditorFlags::Activity)), + this, SIGNAL(changeActivityRequest(MaskEditorFlags::Activity))); + } void MaskEditorCanvas::setMaskContext(SessionModel *model, const QModelIndex &maskContainerIndex, IntensityDataItem *intensityItem) { + m_intensityDataItem = intensityItem; + m_scene->setMaskContext(model, maskContainerIndex, intensityItem); m_resultsPresenter->setMaskContext(model, maskContainerIndex, intensityItem); - getView()->updateSize(getView()->size()); + m_view->updateSize(m_view->size()); + m_statusLabel->addColorMap(m_scene->colorMap()); } void MaskEditorCanvas::setSelectionModel(QItemSelectionModel *model) @@ -62,13 +77,54 @@ MaskGraphicsScene *MaskEditorCanvas::getScene() return m_scene; } -MaskGraphicsView *MaskEditorCanvas::getView() -{ - return m_view; -} - void MaskEditorCanvas::onPresentationTypeRequest(MaskEditorFlags::PresentationType presentationType) { m_resultsPresenter->updatePresenter(presentationType); m_scene->onPresentationTypeRequest(presentationType); } + +//! Saves plot into project directory. + +void MaskEditorCanvas::onSavePlotRequest() +{ + QString dirname = AppSvc::projectManager()->userExportDir(); + + SavePlotAssistant saveAssistant; + saveAssistant.savePlot(dirname, m_scene->colorMap()->customPlot(), m_intensityDataItem); +} + +void MaskEditorCanvas::onResetViewRequest() +{ + m_view->onResetViewRequest(); + + if(isAxisRangeMatchData()) { + setZoomToROI(); + } else { + m_intensityDataItem->resetView(); + } +} + +//! Returns true if IntensityData is currently at 100% zoom level + +bool MaskEditorCanvas::isAxisRangeMatchData() const +{ + Q_ASSERT(m_intensityDataItem); + + if(m_intensityDataItem->getLowerX() != m_intensityDataItem->getXmin()) return false; + if(m_intensityDataItem->getUpperX() != m_intensityDataItem->getXmax()) return false; + if(m_intensityDataItem->getLowerY() != m_intensityDataItem->getYmin()) return false; + if(m_intensityDataItem->getUpperY() != m_intensityDataItem->getYmax()) return false; + return true; +} + +void MaskEditorCanvas::setZoomToROI() +{ + if(MaskContainerItem *maskContainer = m_intensityDataItem->maskContainerItem()) { + if(SessionItem *roiItem = maskContainer->getChildOfType(Constants::RegionOfInterestType)) { + m_intensityDataItem->setLowerX(roiItem->getItemValue(RectangleItem::P_XLOW).toDouble()); + m_intensityDataItem->setUpperX(roiItem->getItemValue(RectangleItem::P_XUP).toDouble()); + m_intensityDataItem->setLowerY(roiItem->getItemValue(RectangleItem::P_YLOW).toDouble()); + m_intensityDataItem->setUpperY(roiItem->getItemValue(RectangleItem::P_YUP).toDouble()); + } + } +} diff --git a/GUI/coregui/Views/MaskWidgets/MaskEditorCanvas.h b/GUI/coregui/Views/MaskWidgets/MaskEditorCanvas.h index 647ee3096bbf681018eb4900036ca87cb5cbf46f..b667632453a00dfed33efabe55170323ad74428d 100644 --- a/GUI/coregui/Views/MaskWidgets/MaskEditorCanvas.h +++ b/GUI/coregui/Views/MaskWidgets/MaskEditorCanvas.h @@ -27,6 +27,8 @@ class QItemSelectionModel; class QModelIndex; class MaskResultsPresenter; class IntensityDataItem; +class ColorMapLabel; +class IntensityDataItem; //! Painting widget for MaskEditor, contains graphics scene and graphics view @@ -40,14 +42,23 @@ public: void setSelectionModel(QItemSelectionModel *model); MaskGraphicsScene *getScene(); - MaskGraphicsView *getView(); + +signals: + void changeActivityRequest(MaskEditorFlags::Activity); public slots: void onPresentationTypeRequest(MaskEditorFlags::PresentationType presentationType); + void onSavePlotRequest(); + void onResetViewRequest(); private: + bool isAxisRangeMatchData() const; + void setZoomToROI(); + MaskGraphicsScene *m_scene; MaskGraphicsView *m_view; + IntensityDataItem *m_intensityDataItem; + ColorMapLabel *m_statusLabel; MaskResultsPresenter *m_resultsPresenter; }; diff --git a/GUI/coregui/Views/MaskWidgets/MaskEditorPropertyPanel.cpp b/GUI/coregui/Views/MaskWidgets/MaskEditorPropertyPanel.cpp index 4b6b54a8b5848c1b3ca68a5b808bb030c2ab234e..11e9ab2c517b48e4226182e05ae23d36441dc09e 100644 --- a/GUI/coregui/Views/MaskWidgets/MaskEditorPropertyPanel.cpp +++ b/GUI/coregui/Views/MaskWidgets/MaskEditorPropertyPanel.cpp @@ -37,6 +37,7 @@ MaskEditorPropertyPanel::MaskEditorPropertyPanel(QWidget *parent) , m_listView(new QListView) , m_maskPropertyEditor(new ComponentEditor) , m_plotPropertyEditor(new ComponentEditor) + , m_accordion(new AccordionWidget) , m_maskModel(0) , m_intensityDataItem(0) { @@ -49,15 +50,14 @@ MaskEditorPropertyPanel::MaskEditorPropertyPanel(QWidget *parent) QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->setContentsMargins(0,0,0,0); - - AccordionWidget *accordion = new AccordionWidget(); - mainLayout->addWidget(accordion); mainLayout->setSpacing(0); - setup_MaskStack(accordion); - setup_MaskProperties(accordion); - setup_PlotProperties(accordion); -// mainLayout->addWidget(m_plotPropertyEditor); + setup_PlotProperties(m_accordion); + setup_MaskStack(m_accordion); + setup_MaskProperties(m_accordion); + //m_accordion->getContentPane(0)->headerClicked(); + + mainLayout->addWidget(m_accordion); setLayout(mainLayout); } @@ -115,6 +115,8 @@ void MaskEditorPropertyPanel::onSelectionChanged(const QItemSelection &selected, } else { m_maskPropertyEditor->setItem(0); } + + } void MaskEditorPropertyPanel::onCustomContextMenuRequested(const QPoint &point) @@ -122,49 +124,48 @@ void MaskEditorPropertyPanel::onCustomContextMenuRequested(const QPoint &point) emit itemContextMenuRequest(m_listView->mapToGlobal(point)); } -void MaskEditorPropertyPanel::setup_MaskStack(AccordionWidget *accordion) +void MaskEditorPropertyPanel::setup_PlotProperties(AccordionWidget *accordion) { - ContentPane *cp = accordion->getContentPane(accordion->addContentPane("Mask stack")); - cp->setMaximumHeight(400); - cp->headerClicked(); - cp->setHeaderTooltip("List of created masks representing mask stacking order."); + ContentPane *cp = accordion->getContentPane(accordion->addContentPane("Plot properties")); + cp->setMaximumHeight(600); + cp->setHeaderTooltip("Plot properties editor"); cp->setContainerFrameStyle(QFrame::Plain); QFrame *contentFrame = cp->getContentFrame(); + //contentFrame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + QVBoxLayout *layout = new QVBoxLayout(); layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(m_listView); + m_plotPropertyEditor->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + layout->addWidget(m_plotPropertyEditor); contentFrame->setLayout(layout); } -void MaskEditorPropertyPanel::setup_MaskProperties(AccordionWidget *accordion) + +void MaskEditorPropertyPanel::setup_MaskStack(AccordionWidget *accordion) { - ContentPane *cp = accordion->getContentPane(accordion->addContentPane("Mask properties")); - cp->setMaximumHeight(400); - cp->setHeaderTooltip("Property editor for currently selected mask."); + ContentPane *cp = accordion->getContentPane(accordion->addContentPane("Mask stack")); + cp->setMaximumHeight(600); + cp->setHeaderTooltip("List of created masks representing mask stacking order."); cp->setContainerFrameStyle(QFrame::Plain); QFrame *contentFrame = cp->getContentFrame(); QVBoxLayout *layout = new QVBoxLayout(); layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(m_maskPropertyEditor); + layout->addWidget(m_listView); contentFrame->setLayout(layout); } -void MaskEditorPropertyPanel::setup_PlotProperties(AccordionWidget *accordion) +void MaskEditorPropertyPanel::setup_MaskProperties(AccordionWidget *accordion) { - ContentPane *cp = accordion->getContentPane(accordion->addContentPane("Plot properties")); - cp->setMaximumHeight(400); - cp->setHeaderTooltip("Plot properties editor"); + ContentPane *cp = accordion->getContentPane(accordion->addContentPane("Mask properties")); + cp->setMaximumHeight(600); + cp->setHeaderTooltip("Property editor for currently selected mask."); cp->setContainerFrameStyle(QFrame::Plain); QFrame *contentFrame = cp->getContentFrame(); - //contentFrame->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - QVBoxLayout *layout = new QVBoxLayout(); layout->setContentsMargins(0, 0, 0, 0); - m_plotPropertyEditor->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - layout->addWidget(m_plotPropertyEditor); + layout->addWidget(m_maskPropertyEditor); contentFrame->setLayout(layout); } - diff --git a/GUI/coregui/Views/MaskWidgets/MaskEditorPropertyPanel.h b/GUI/coregui/Views/MaskWidgets/MaskEditorPropertyPanel.h index 536d2f0cb4cde056f1c09789767477230ed7a3ba..66ace3f748cc625c3f88f0263d2ce16bf2648013 100644 --- a/GUI/coregui/Views/MaskWidgets/MaskEditorPropertyPanel.h +++ b/GUI/coregui/Views/MaskWidgets/MaskEditorPropertyPanel.h @@ -64,6 +64,7 @@ private: QListView *m_listView; ComponentEditor *m_maskPropertyEditor; ComponentEditor *m_plotPropertyEditor; + AccordionWidget *m_accordion; SessionModel *m_maskModel; QModelIndex m_rootIndex; IntensityDataItem *m_intensityDataItem; diff --git a/GUI/coregui/Views/MaskWidgets/MaskEditorToolBar.cpp b/GUI/coregui/Views/MaskWidgets/MaskEditorToolBar.cpp index 3fa49a7fcf02f631d796c9f99f74d9ec3e7604eb..9c531ac88a93ce67b06678198499f48c5fdceb36 100644 --- a/GUI/coregui/Views/MaskWidgets/MaskEditorToolBar.cpp +++ b/GUI/coregui/Views/MaskWidgets/MaskEditorToolBar.cpp @@ -38,13 +38,9 @@ MaskEditorToolBar::MaskEditorToolBar(MaskEditorActions *editorActions, QWidget * setProperty("_q_custom_style_disabled", QVariant(true)); setup_selection_group(); - add_separator(); - setup_maskvalue_group(); - add_separator(); +// setup_maskvalue_group(); setup_shapes_group(); - add_separator(); setup_maskmodify_group(); - add_separator(); setup_extratools_group(); connect(m_activityButtonGroup, SIGNAL(buttonClicked(int)), @@ -92,28 +88,29 @@ void MaskEditorToolBar::onPresentationTypeReleased() void MaskEditorToolBar::setup_selection_group() { - QToolButton *selectionButton = new QToolButton(this); - selectionButton->setIcon(QIcon(":/MaskWidgets/images/maskeditor_arrow.svg")); - selectionButton->setToolTip("Select/modify mode"); - selectionButton->setCheckable(true); - selectionButton->setChecked(true); - addWidget(selectionButton); - QToolButton *panButton = new QToolButton(this); panButton->setIcon(QIcon(":/MaskWidgets/images/maskeditor_hand.svg")); panButton->setToolTip("Pan/zoom mode (space)"); panButton->setCheckable(true); + panButton->setChecked(true); addWidget(panButton); QToolButton *resetViewButton = new QToolButton(this); resetViewButton->setIcon(QIcon(":/MaskWidgets/images/maskeditor_refresh.svg")); resetViewButton->setToolTip("Reset pan/zoom to initial state"); addWidget(resetViewButton); + connect(resetViewButton, SIGNAL(clicked()), m_editorActions, SIGNAL(resetViewRequest())); - m_activityButtonGroup->addButton(selectionButton, MaskEditorFlags::SELECTION_MODE); - m_activityButtonGroup->addButton(panButton, MaskEditorFlags::PAN_ZOOM_MODE); + add_separator(); + + QToolButton *selectionButton = new QToolButton(this); + selectionButton->setIcon(QIcon(":/MaskWidgets/images/maskeditor_arrow.svg")); + selectionButton->setToolTip("Select/modify mask"); + selectionButton->setCheckable(true); + addWidget(selectionButton); - connect(resetViewButton, SIGNAL(clicked()), this, SIGNAL(resetViewRequest())); + m_activityButtonGroup->addButton(panButton, MaskEditorFlags::PAN_ZOOM_MODE); + m_activityButtonGroup->addButton(selectionButton, MaskEditorFlags::SELECTION_MODE); } void MaskEditorToolBar::setup_maskvalue_group() @@ -142,7 +139,7 @@ void MaskEditorToolBar::setup_maskvalue_group() void MaskEditorToolBar::setup_shapes_group() { QToolButton *roiButton = new QToolButton(this); - roiButton->setIcon(QIcon(":/MaskWidgets/images/maskeditor_rectangle.svg")); + roiButton->setIcon(QIcon(":/MaskWidgets/images/maskeditor_roi.svg")); roiButton->setToolTip("Create region of interest"); roiButton->setCheckable(true); addWidget(roiButton); @@ -177,12 +174,12 @@ void MaskEditorToolBar::setup_shapes_group() ellipseButton->setCheckable(true); addWidget(ellipseButton); - QToolButton *maskAllButton = new QToolButton(this); - maskAllButton->setIcon(QIcon(":/MaskWidgets/images/maskeditor_maskall.svg")); - maskAllButton->setToolTip("Create masked area covering whole detector plane\n" - "Will be placed beneath all masks. Only one instance is allowed."); - maskAllButton->setCheckable(true); - addWidget(maskAllButton); +// QToolButton *maskAllButton = new QToolButton(this); +// maskAllButton->setIcon(QIcon(":/MaskWidgets/images/maskeditor_maskall.svg")); +// maskAllButton->setToolTip("Create masked area covering whole detector plane\n" +// "Will be placed beneath all masks. Only one instance is allowed."); +// maskAllButton->setCheckable(true); +// addWidget(maskAllButton); m_activityButtonGroup->addButton(roiButton, MaskEditorFlags::ROI_MODE); m_activityButtonGroup->addButton(rectangleButton, MaskEditorFlags::RECTANGLE_MODE); @@ -190,14 +187,16 @@ void MaskEditorToolBar::setup_shapes_group() m_activityButtonGroup->addButton(verticalLineButton, MaskEditorFlags::VERTICAL_LINE_MODE); m_activityButtonGroup->addButton(horizontalLineButton, MaskEditorFlags::HORIZONTAL_LINE_MODE); m_activityButtonGroup->addButton(ellipseButton, MaskEditorFlags::ELLIPSE_MODE); - m_activityButtonGroup->addButton(maskAllButton, MaskEditorFlags::MASKALL_MODE); +// m_activityButtonGroup->addButton(maskAllButton, MaskEditorFlags::MASKALL_MODE); + add_separator(); } void MaskEditorToolBar::setup_maskmodify_group() { Q_ASSERT(m_editorActions); - addAction(m_editorActions->getBringToFrontAction()); - addAction(m_editorActions->getSendToBackAction()); + addAction(m_editorActions->bringToFrontAction()); + addAction(m_editorActions->sendToBackAction()); + add_separator(); } void MaskEditorToolBar::setup_extratools_group() @@ -207,10 +206,8 @@ void MaskEditorToolBar::setup_extratools_group() presentationButton->setToolTip("Press and hold to see mask results."); addWidget(presentationButton); - connect(presentationButton, SIGNAL(pressed()), - this, SLOT(onPresentationTypePressed())); - connect(presentationButton, SIGNAL(released()), - this, SLOT(onPresentationTypeReleased())); + connect(presentationButton, SIGNAL(pressed()), this, SLOT(onPresentationTypePressed())); + connect(presentationButton, SIGNAL(released()), this, SLOT(onPresentationTypeReleased())); QToolButton *propertyPanelButton = new QToolButton(this); propertyPanelButton->setIcon(QIcon(":/MaskWidgets/images/maskeditor_toolpanel.svg")); @@ -218,7 +215,8 @@ void MaskEditorToolBar::setup_extratools_group() addWidget(propertyPanelButton); connect(propertyPanelButton, SIGNAL(clicked()), - this, SIGNAL(propertyPanelRequest())); + m_editorActions, SIGNAL(propertyPanelRequest())); + add_separator(); } void MaskEditorToolBar::add_separator() diff --git a/GUI/coregui/Views/MaskWidgets/MaskEditorToolBar.h b/GUI/coregui/Views/MaskWidgets/MaskEditorToolBar.h index 462e425e91238b3df006a70d4bf4f176609ffb55..ff2d69377d9fd192c6f5e3a291cf2d2fc23c8052 100644 --- a/GUI/coregui/Views/MaskWidgets/MaskEditorToolBar.h +++ b/GUI/coregui/Views/MaskWidgets/MaskEditorToolBar.h @@ -34,10 +34,8 @@ public: signals: void activityModeChanged(MaskEditorFlags::Activity); - void propertyPanelRequest(); void presentationTypeRequest(MaskEditorFlags::PresentationType); void maskValueChanged(MaskEditorFlags::MaskValue); - void resetViewRequest(); public slots: void onChangeActivityRequest(MaskEditorFlags::Activity value); diff --git a/GUI/coregui/Views/MaskWidgets/MaskGraphicsProxy.cpp b/GUI/coregui/Views/MaskWidgets/MaskGraphicsProxy.cpp index 63d16171243c7b3c69bebcd2370eb0ac666bfbd5..2661079f537a0aa222a6185f1096c01b36ff0838 100644 --- a/GUI/coregui/Views/MaskWidgets/MaskGraphicsProxy.cpp +++ b/GUI/coregui/Views/MaskWidgets/MaskGraphicsProxy.cpp @@ -18,8 +18,8 @@ #include "ColorMapSceneAdaptor.h" #include "ColorMap.h" #include "IntensityDataItem.h" -#include <QDebug> #include <QGraphicsSceneMouseEvent> +#include <QDebug> MaskGraphicsProxy::MaskGraphicsProxy() : m_colorMap(new ColorMap) @@ -27,7 +27,7 @@ MaskGraphicsProxy::MaskGraphicsProxy() , m_send_signals_to_colormap(false) { resize(1200, 1000); - setAcceptedMouseButtons(Qt::NoButton); + setInZoomMode(true); } MaskGraphicsProxy::~MaskGraphicsProxy() @@ -63,10 +63,9 @@ void MaskGraphicsProxy::setInZoomMode(bool value) } } -void MaskGraphicsProxy::resetView() +ColorMap *MaskGraphicsProxy::colorMap() { - Q_ASSERT(m_colorMap); - m_colorMap->resetView(); + return m_colorMap; } void MaskGraphicsProxy::mousePressEvent(QGraphicsSceneMouseEvent *event) diff --git a/GUI/coregui/Views/MaskWidgets/MaskGraphicsProxy.h b/GUI/coregui/Views/MaskWidgets/MaskGraphicsProxy.h index ba1b008808365f5c1e33cd50e088b31f81d9ba48..e30bac1fd3d7ba517fbdd63303b45639d27adeed 100644 --- a/GUI/coregui/Views/MaskWidgets/MaskGraphicsProxy.h +++ b/GUI/coregui/Views/MaskWidgets/MaskGraphicsProxy.h @@ -42,7 +42,7 @@ public: void setSceneAdaptor(ISceneAdaptor *sceneAdaptor); void setInZoomMode(bool value); - void resetView(); + ColorMap *colorMap(); protected: void mousePressEvent(QGraphicsSceneMouseEvent *event); diff --git a/GUI/coregui/Views/MaskWidgets/MaskGraphicsScene.cpp b/GUI/coregui/Views/MaskWidgets/MaskGraphicsScene.cpp index f538facd4d4b47130b55197aa55965c209bbd818..be7bd9b59756a3c96458fb76a33f2fe1c38cebff 100644 --- a/GUI/coregui/Views/MaskWidgets/MaskGraphicsScene.cpp +++ b/GUI/coregui/Views/MaskWidgets/MaskGraphicsScene.cpp @@ -116,6 +116,12 @@ void MaskGraphicsScene::setSelectionModel(QItemSelectionModel *model) } } +ColorMap *MaskGraphicsScene::colorMap() +{ + Q_ASSERT(m_proxy); + return m_proxy->colorMap(); +} + void MaskGraphicsScene::onActivityModeChanged(MaskEditorFlags::Activity value) { if(!m_proxy) @@ -134,14 +140,6 @@ void MaskGraphicsScene::onMaskValueChanged(MaskEditorFlags::MaskValue value) m_context.setMaskValue(value); } -//! Returns ColorMap view to original state (axes, zoom). - -void MaskGraphicsScene::onResetViewRequest() -{ - if(!m_proxy) return; - m_proxy->resetView(); -} - void MaskGraphicsScene::onRowsInserted(const QModelIndex &, int, int) { updateScene(); diff --git a/GUI/coregui/Views/MaskWidgets/MaskGraphicsScene.h b/GUI/coregui/Views/MaskWidgets/MaskGraphicsScene.h index 9101dfc2b3c1b1df91892095c96dfa9149ae17a5..30facc00445a6b5927b32759118a3c3c197dc366 100644 --- a/GUI/coregui/Views/MaskWidgets/MaskGraphicsScene.h +++ b/GUI/coregui/Views/MaskWidgets/MaskGraphicsScene.h @@ -36,6 +36,7 @@ class MaskEditorAction; class IntensityDataItem; class QGraphicsSceneMouseEvent; class QPainter; +class ColorMap; //! Graphics scene for MaskEditorCanvas to draw masks on top of intensity data widgets. @@ -50,13 +51,13 @@ public: void setSelectionModel(QItemSelectionModel *model); + ColorMap *colorMap(); signals: void itemContextMenuRequest(const QPoint &point); public slots: void onActivityModeChanged(MaskEditorFlags::Activity value); void onMaskValueChanged(MaskEditorFlags::MaskValue value); - void onResetViewRequest(); void onRowsInserted(const QModelIndex &, int, int); void onRowsAboutToBeRemoved(const QModelIndex &parent, int first, int last); void onRowsRemoved(const QModelIndex &, int, int); diff --git a/GUI/coregui/Views/MaskWidgets/MaskGraphicsView.cpp b/GUI/coregui/Views/MaskWidgets/MaskGraphicsView.cpp index 07bb926149ec5af48818f3353590aceb5b7a0dee..03f7e744e0e08989f93093ac92a3d34f71ed6b42 100644 --- a/GUI/coregui/Views/MaskWidgets/MaskGraphicsView.cpp +++ b/GUI/coregui/Views/MaskWidgets/MaskGraphicsView.cpp @@ -36,16 +36,14 @@ MaskGraphicsView::MaskGraphicsView(QGraphicsScene *scene, QWidget *parent) setObjectName(QStringLiteral("MaskGraphicsView")); setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setRenderHints(QPainter::HighQualityAntialiasing|QPainter::TextAntialiasing); + setStyleSheet( "QGraphicsView { border-style: none; }" ); setMouseTracking(true); } //! Reset given view to original zoom state. Also asks graphics scene to do the same with color map. void MaskGraphicsView::onResetViewRequest() { - qDebug() << "MaskGraphicsView::onResetViewRequest()"; setZoomValue(1.0); - MaskGraphicsScene *maskScene = dynamic_cast<MaskGraphicsScene *>(scene()); - maskScene->onResetViewRequest(); } void MaskGraphicsView::wheelEvent(QWheelEvent *event) diff --git a/GUI/coregui/Views/MaskWidgets/MaskUnitsConverter.cpp b/GUI/coregui/Views/MaskWidgets/MaskUnitsConverter.cpp new file mode 100644 index 0000000000000000000000000000000000000000..270a3df799a1e9dd09592879798e5199cb3f7747 --- /dev/null +++ b/GUI/coregui/Views/MaskWidgets/MaskUnitsConverter.cpp @@ -0,0 +1,145 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file GUI/coregui/Views/MaskWidgets/MaskUnitsConverter.cpp +//! @brief Implements class MaskUnitsConverter +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2016 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors Céline Durniak, Marina Ganeva, David Li, Gennady Pospelov +//! @authors Walter Van Herck, Joachim Wuttke +// +// ************************************************************************** // + +#include "MaskUnitsConverter.h" +#include "IntensityDataItem.h" +#include "MaskItems.h" +#include "BornAgainNamespace.h" +#include "IntensityDataFunctions.h" +#include "GUIHelpers.h" +#include <QDebug> + +MaskUnitsConverter::MaskUnitsConverter() + : m_data(0) + , m_direction(UNDEFINED) +{ + +} + +//! Converts all masks on board of IntensityDataItem into bin-fraction coordinates. + +void MaskUnitsConverter::convertToNbins(IntensityDataItem *intensityData) +{ + m_direction = TO_NBINS; + convertIntensityDataItem(intensityData); +} + +//! Converts all masks on board of IntensityDataItem from bin-fraction coordinates to coordinates +//! of axes currently defined in OutputData. + +void MaskUnitsConverter::convertFromNbins(IntensityDataItem *intensityData) +{ + m_direction = FROM_NBINS; + convertIntensityDataItem(intensityData); +} + +//! Converts all masks on board of IntensityDataItem from/to bin-fraction coordinates + +void MaskUnitsConverter::convertIntensityDataItem(IntensityDataItem *intensityData) +{ + if(!intensityData || !intensityData->getOutputData() || !intensityData->maskContainerItem()) + return; + + m_data = intensityData->getOutputData(); + + foreach(SessionItem *maskItem, intensityData->maskContainerItem()->getItems()) + convertMask(maskItem); +} + +//! Converts single mask from/to bin-fraction coordinates + +void MaskUnitsConverter::convertMask(SessionItem *maskItem) +{ + if(maskItem->modelType() == Constants::RectangleMaskType || + maskItem->modelType() == Constants::RegionOfInterestType) { + convertCoordinate(maskItem, RectangleItem::P_XLOW, RectangleItem::P_YLOW); + convertCoordinate(maskItem, RectangleItem::P_XUP, RectangleItem::P_YUP); + } + + else if(maskItem->modelType() == Constants::PolygonMaskType) { + foreach (SessionItem *pointItem, maskItem->getChildrenOfType(Constants::PolygonPointType)) + convertCoordinate(pointItem, PolygonPointItem::P_POSX, PolygonPointItem::P_POSY); + } + + else if(maskItem->modelType() == Constants::VerticalLineMaskType) { + convertCoordinate(maskItem, VerticalLineItem::P_POSX, QString()); + } + + else if(maskItem->modelType() == Constants::HorizontalLineMaskType) { + convertCoordinate(maskItem, QString(), HorizontalLineItem::P_POSY); + } + + else if(maskItem->modelType() == Constants::EllipseMaskType) { + double xc = maskItem->getItemValue(EllipseItem::P_XCENTER).toDouble(); + double yc = maskItem->getItemValue(EllipseItem::P_YCENTER).toDouble(); + double xR = maskItem->getItemValue(EllipseItem::P_XRADIUS).toDouble(); + double yR = maskItem->getItemValue(EllipseItem::P_YRADIUS).toDouble(); + + double x2 = xc + xR; + double y2 = yc + yR; + + if(m_direction == TO_NBINS) { + IntensityDataFunctions::coordinateToBinf(xc, yc, m_data); + IntensityDataFunctions::coordinateToBinf(x2, y2, m_data); + } else { + IntensityDataFunctions::coordinateFromBinf(xc, yc, m_data); + IntensityDataFunctions::coordinateFromBinf(x2, y2, m_data); + } + + maskItem->setItemValue(EllipseItem::P_XCENTER, xc); + maskItem->setItemValue(EllipseItem::P_YCENTER, yc); + maskItem->setItemValue(EllipseItem::P_XRADIUS, x2 - xc); + maskItem->setItemValue(EllipseItem::P_YRADIUS, y2 - yc); + + } + +} + +//! Convert (x,y) coordinates registered as property (i.e. under P_XPOS, P_YPOS) from/to +//! bin-fraction coordinates. Result of operation are new values for registered properties. + +void MaskUnitsConverter::convertCoordinate(SessionItem *maskItem, const QString &xname, + const QString &yname) +{ + if(maskItem->isTag(xname)) { + double x = convert(maskItem->getItemValue(xname).toDouble(), BornAgain::X_AXIS_INDEX); + maskItem->setItemValue(xname, x); + } + + if(maskItem->isTag(yname)) { + double y = convert(maskItem->getItemValue(yname).toDouble(), BornAgain::Y_AXIS_INDEX); + maskItem->setItemValue(yname, y); + } + +} + +//! Convert value of axis from/to bin-fraction coordinates. + +double MaskUnitsConverter::convert(double value, int axis_index) +{ + Q_ASSERT(m_data); + Q_ASSERT(axis_index == BornAgain::X_AXIS_INDEX || axis_index == BornAgain::Y_AXIS_INDEX); + + if(m_direction == TO_NBINS) { + return IntensityDataFunctions::coordinateToBinf(value, m_data->getAxis(axis_index)); + + } else if (m_direction == FROM_NBINS){ + return IntensityDataFunctions::coordinateFromBinf(value, m_data->getAxis(axis_index)); + } + + throw GUIHelpers::Error("MaskUnitsConverter::convertX() -> Error. Unknown convertion"); +} + diff --git a/GUI/coregui/Views/MaskWidgets/MaskUnitsConverter.h b/GUI/coregui/Views/MaskWidgets/MaskUnitsConverter.h new file mode 100644 index 0000000000000000000000000000000000000000..36c1eee8102d500300982118538ba64c88480f65 --- /dev/null +++ b/GUI/coregui/Views/MaskWidgets/MaskUnitsConverter.h @@ -0,0 +1,57 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file GUI/coregui/Views/MaskWidgets/MaskUnitsConverter.h +//! @brief Defines class MaskUnitsConverter +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2016 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors Céline Durniak, Marina Ganeva, David Li, Gennady Pospelov +//! @authors Walter Van Herck, Joachim Wuttke +// +// ************************************************************************** // + +#ifndef MASKUNITSCONVERTER_H +#define MASKUNITSCONVERTER_H + +#include "WinDllMacros.h" + +class IntensityDataItem; +class SessionItem; +class IAxis; +template<class T> class OutputData; +class QString; + +//! The MaskUnitsConverter converts coordinates of all masks from one units to anoter. +//! I.e. masks in 'mm' into masks in 'deg'. This is done in two steps. +//! On first step masks are converted from native coordinates (as given by axes of OutputData) +//! into bin-fraction coordinates. +//! On second step masks are converted from bin-fraction coordinates into current axes of OutputData. + +class BA_CORE_API_ MaskUnitsConverter +{ +public: + enum EConvertionDirection {TO_NBINS, FROM_NBINS, UNDEFINED}; + + MaskUnitsConverter(); + + void convertToNbins(IntensityDataItem *intensityData); + void convertFromNbins(IntensityDataItem *intensityData); + +private: + void convertIntensityDataItem(IntensityDataItem *intensityData); + void convertMask(SessionItem *maskItem); + + void convertCoordinate(SessionItem *maskItem, const QString &xname, + const QString &yname); + + double convert(double value, int axis_index); + + const OutputData<double> *m_data; + EConvertionDirection m_direction; +}; + +#endif diff --git a/GUI/coregui/Views/MaskWidgets/MaskWidgets.qrc b/GUI/coregui/Views/MaskWidgets/MaskWidgets.qrc index a6669a35175a444a88a34de04690b431ee5d982a..415b72940a37769fbcee7d1bb9fc6eeb2a454415 100644 --- a/GUI/coregui/Views/MaskWidgets/MaskWidgets.qrc +++ b/GUI/coregui/Views/MaskWidgets/MaskWidgets.qrc @@ -15,5 +15,6 @@ <file>images/maskeditor_masktrue.svg</file> <file>images/maskeditor_maskfalse.svg</file> <file>images/maskeditor_lightbulb.svg</file> + <file>images/maskeditor_roi.svg</file> </qresource> </RCC> diff --git a/GUI/coregui/Views/MaskWidgets/images/maskeditor_roi.svg b/GUI/coregui/Views/MaskWidgets/images/maskeditor_roi.svg new file mode 100644 index 0000000000000000000000000000000000000000..e57b57d618f0b546a6d217bdfdbb9b0fa5bb843c --- /dev/null +++ b/GUI/coregui/Views/MaskWidgets/images/maskeditor_roi.svg @@ -0,0 +1,554 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="32" + height="32" + id="svg2985" + version="1.1" + inkscape:version="0.91 r13725" + sodipodi:docname="maskeditor_roi.svg"> + <defs + id="defs2987"> + <linearGradient + id="linearGradient4619"> + <stop + style="stop-color:#f0f0f0;stop-opacity:1;" + offset="0" + id="stop4621" /> + <stop + style="stop-color:#bebebe;stop-opacity:1;" + offset="1" + id="stop4623" /> + </linearGradient> + <linearGradient + id="linearGradient4592"> + <stop + style="stop-color:#5a5a5a;stop-opacity:1;" + offset="0" + id="stop4594" /> + <stop + style="stop-color:#969696;stop-opacity:0.98039216;" + offset="1" + id="stop4596" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4592" + id="linearGradient4598" + x1="45" + y1="48" + x2="2" + y2="-3" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(10.909648,55.154329)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient4625" + x1="29" + y1="43" + x2="29" + y2="35" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.9869024,0,0,0.88776083,14.858206,-1.0006961)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient4656" + x1="22" + y1="38" + x2="22" + y2="26" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.62685746,0,0,0.94809312,-12.449527,-7.6976699)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient4668" + gradientUnits="userSpaceOnUse" + x1="22" + y1="38" + x2="22" + y2="26" + gradientTransform="matrix(1,0,0,1.4537913,18.3876,-22.652505)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient4672" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1,0,0,0.79979796,22.377703,2.0874223)" + x1="22" + y1="38" + x2="22" + y2="26" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient4676" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0164907,0,0,0.3860471,26.03748,17.720659)" + x1="22" + y1="38" + x2="22" + y2="26" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient4680" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1,0,0,1.1601616,30.256893,-11.572613)" + x1="22" + y1="38" + x2="22" + y2="26" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient4700" + gradientUnits="userSpaceOnUse" + x1="11" + y1="12" + x2="11" + y2="6" + gradientTransform="translate(15.508666,0.29673785)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient4704" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(15.508666,4.2449983)" + x1="11" + y1="12" + x2="11" + y2="6" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient4708" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(-0.90913729,12.020815)" + x1="11" + y1="12" + x2="11" + y2="6" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient4712" + gradientUnits="userSpaceOnUse" + x1="11" + y1="12" + x2="11" + y2="6" + gradientTransform="matrix(4.6365492,0,0,0.66328254,-16.517836,-0.93725566)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient4716" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(4.6702208,0,0,0.66328257,-16.95234,3.0023381)" + x1="11" + y1="12" + x2="11" + y2="6" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient4720" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(4.6702208,0,0,0.71090166,-16.851325,6.6321668)" + x1="11" + y1="12" + x2="11" + y2="6" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient4724" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(4.3671751,0,0,0.36023659,-29.207084,18.152322)" + x1="11" + y1="12" + x2="11" + y2="6" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient4726" + gradientUnits="userSpaceOnUse" + x1="11" + y1="12" + x2="11" + y2="6" + gradientTransform="translate(15.508666,-3.5505077)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient4759" + x1="-12" + y1="130" + x2="-53" + y2="80" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.99471384,0,0,1,69.141448,-85.657091)" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient4765" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(15.437237,8.3570368)" + x1="11" + y1="12" + x2="11" + y2="6" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient4767" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(4.6365491,0,0,0.7347112,-16.517838,10.410751)" + x1="11" + y1="12" + x2="11" + y2="6" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient3052" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.65017886,0,0,1.1934711,-7.0238202,-19.963314)" + x1="22" + y1="38" + x2="22" + y2="26" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient3063" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.66208822,0,0,1.1934971,-10.226661,-19.964316)" + x1="22" + y1="38" + x2="22" + y2="26" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient3067" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0,0.62685746,-0.61777663,0,23.807484,13.761641)" + x1="21.943026" + y1="41.468658" + x2="21.886053" + y2="19.814222" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient3071" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.62685746,0,0,0.4762124,-9.4495267,12.189559)" + x1="21.886053" + y1="34.025185" + x2="22" + y2="26" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient3121" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.69005948,-0.67245431,1.4201209,1.4075539,-53.070729,-8.4925184)" + x1="21.556009" + y1="32.141224" + x2="21.209343" + y2="43.517174" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient3123" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.95335715,0,0,1.1887523,-17.132487,-19.248728)" + x1="21.625385" + y1="32.712341" + x2="21.73777" + y2="45.918842" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient3125" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0,0.95335715,-1.1887523,0,46.986745,-2.2784594)" + x1="22.112387" + y1="35.53643" + x2="22.22477" + y2="20.952692" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient3071-8" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.94569472,0,0,0.68138399,33.945275,8.7477615)" + x1="21.886053" + y1="34.025185" + x2="22" + y2="26" /> + <linearGradient + id="linearGradient4619-3"> + <stop + style="stop-color:#c3c3c3;stop-opacity:1;" + offset="0" + id="stop4621-2" /> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="1" + id="stop4623-9" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient3067-0" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0,0.96209819,-3.2915854,0,153.92022,-13.373467)" + x1="21.943026" + y1="41.468658" + x2="21.886053" + y2="19.814222" /> + <linearGradient + id="linearGradient3054"> + <stop + style="stop-color:#c3c3c3;stop-opacity:1;" + offset="0" + id="stop3056" /> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="1" + id="stop3058" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient3060-8" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.98087805,0,0,2.904224,45.21041,-75.483853)" + x1="22" + y1="38" + x2="22" + y2="26" /> + <linearGradient + id="linearGradient3061"> + <stop + style="stop-color:#c3c3c3;stop-opacity:1;" + offset="0" + id="stop3063" /> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="1" + id="stop3065" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient3056-0" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.99846971,0,0,1.8468808,40.832148,-43.406433)" + x1="22" + y1="38" + x2="22" + y2="26" /> + <linearGradient + id="linearGradient3068"> + <stop + style="stop-color:#c3c3c3;stop-opacity:1;" + offset="0" + id="stop3070" /> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="1" + id="stop3072" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient3052-8" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(1.0041995,0,0,1.8544742,36.566184,-43.708232)" + x1="22" + y1="38" + x2="22" + y2="26" /> + <linearGradient + id="linearGradient3075"> + <stop + style="stop-color:#c3c3c3;stop-opacity:1;" + offset="0" + id="stop3077" /> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="1" + id="stop3079" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619" + id="linearGradient3063-8" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.99884484,0,0,1.8639461,32.701441,-44.067296)" + x1="22" + y1="38" + x2="22" + y2="26" /> + <linearGradient + id="linearGradient3082"> + <stop + style="stop-color:#c3c3c3;stop-opacity:1;" + offset="0" + id="stop3084" /> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="1" + id="stop3086" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619-3" + id="linearGradient4656-0" + x1="22" + y1="38" + x2="22" + y2="26" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(0.62685746,0,0,0.94809312,-11.485241,9.0523301)" /> + <linearGradient + id="linearGradient3089"> + <stop + style="stop-color:#c3c3c3;stop-opacity:1;" + offset="0" + id="stop3091" /> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="1" + id="stop3093" /> + </linearGradient> + <linearGradient + y2="26" + x2="22" + y1="38" + x1="22" + gradientTransform="matrix(0.99233754,0,0,1.4501735,27.913663,-23.398288)" + gradientUnits="userSpaceOnUse" + id="linearGradient3102" + xlink:href="#linearGradient4619" + inkscape:collect="always" /> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient4619-6" + id="linearGradient3829" + x1="8.0355835" + y1="34.827862" + x2="8.0653534" + y2="52.404518" + gradientUnits="userSpaceOnUse" /> + <linearGradient + id="linearGradient4619-6"> + <stop + style="stop-color:#c3c3c3;stop-opacity:1;" + offset="0" + id="stop4621-1" /> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="1" + id="stop4623-6" /> + </linearGradient> + <linearGradient + gradientTransform="matrix(1.8315569,0,0,1.4306141,39.435999,-29.762744)" + y2="52.404518" + x2="8.0653534" + y1="34.827862" + x1="8.0355835" + gradientUnits="userSpaceOnUse" + id="linearGradient3061-8" + xlink:href="#linearGradient4619-6" + inkscape:collect="always" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="22.444444" + inkscape:cx="33.766855" + inkscape:cy="7.2547506" + inkscape:current-layer="layer1" + showgrid="true" + inkscape:grid-bbox="true" + inkscape:document-units="px" + inkscape:window-width="2466" + inkscape:window-height="1365" + inkscape:window-x="0" + inkscape:window-y="0" + inkscape:window-maximized="1" + inkscape:snap-global="false"> + <inkscape:grid + type="xygrid" + id="grid3012" + empspacing="5" + visible="true" + enabled="true" + snapvisiblegridlinesonly="true" /> + </sodipodi:namedview> + <metadata + id="metadata2990"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + id="layer1" + inkscape:label="Layer 1" + inkscape:groupmode="layer" + transform="translate(0,-16)"> + <path + style="fill:none;fill-opacity:1;stroke:#646464;stroke-width:0.99999982;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="m 5.4772603,29.108439 0,-4.457077 c 0,-0.615821 0.4957689,-1.11159 1.1115893,-1.11159 l 0,0 4.4157064,1e-6" + id="path4254" + inkscape:connector-curvature="0" /> + <path + style="fill:none;fill-opacity:1;stroke:#646464;stroke-width:0.99999982;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="m 20.89141,23.47645 4.457077,0 c 0.615821,0 1.11159,0.495769 1.11159,1.11159 l 0,0 -10e-7,4.415706" + id="path4254-09" + inkscape:connector-curvature="0" /> + <path + style="fill:none;fill-opacity:1;stroke:#646464;stroke-width:0.99999982;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="m 26.5285,34.940914 0,4.457077 c 0,0.615821 -0.495769,1.11159 -1.111589,1.11159 l 0,0 -4.415707,-10e-7" + id="path4254-6" + inkscape:connector-curvature="0" /> + <path + style="fill:none;fill-opacity:1;stroke:#646464;stroke-width:0.99999982;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + d="m 11.09869,40.533449 -4.457077,0 c -0.615821,0 -1.11159,-0.495769 -1.11159,-1.11159 l 0,0 1e-6,-4.415706" + id="path4254-09-3" + inkscape:connector-curvature="0" /> + <ellipse + style="fill:#6e6e6e;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + id="path4381" + cx="15.933643" + cy="32.000004" + rx="2.8787129" + ry="2.9455445" /> + </g> +</svg> diff --git a/Tests/UnitTests/Core/6/IntensityDataFunctionsTest.h b/Tests/UnitTests/Core/6/IntensityDataFunctionsTest.h index 1f5c9b557d4f8181774250e162f23a77fa17d28b..5234c0dac042b9c8aa4d22bf91e5080befb1cdcc 100644 --- a/Tests/UnitTests/Core/6/IntensityDataFunctionsTest.h +++ b/Tests/UnitTests/Core/6/IntensityDataFunctionsTest.h @@ -145,4 +145,51 @@ TEST_F(IntensityDataFunctionsTest, ClipDataSetVariable) //} +TEST_F(IntensityDataFunctionsTest, coordinateToFromBinf) +{ + FixedBinAxis axis("axis", 8, -5.0, 3.0); + EXPECT_EQ(0.5, IntensityDataFunctions::coordinateToBinf(-4.5, &axis)); + EXPECT_EQ(-4.5, IntensityDataFunctions::coordinateFromBinf(0.5, &axis)); + + EXPECT_EQ(1.0, IntensityDataFunctions::coordinateToBinf(-4.0, &axis)); + EXPECT_EQ(-4.0, IntensityDataFunctions::coordinateFromBinf(1.0, &axis)); + + EXPECT_EQ(-0.5, IntensityDataFunctions::coordinateToBinf(-5.5, &axis)); + EXPECT_EQ(-5.5, IntensityDataFunctions::coordinateFromBinf(-0.5, &axis)); + + EXPECT_EQ(8.0, IntensityDataFunctions::coordinateToBinf(3.0, &axis)); + EXPECT_EQ(3.0, IntensityDataFunctions::coordinateFromBinf(8.0, &axis)); + + EXPECT_EQ(8.5, IntensityDataFunctions::coordinateToBinf(3.5, &axis)); + EXPECT_EQ(3.5, IntensityDataFunctions::coordinateFromBinf(8.5, &axis)); +} + + +//! Transformation of coordinates from one OutputData to another using convertion from axes +//! coordinates to bin-fraction-coordinates and then to another axes coordinates. + +TEST_F(IntensityDataFunctionsTest, outputDataCoordinatesToFromBinf) +{ + OutputData<double> data1; + data1.addAxis("axis0", 8, -5.0, 3.0); + data1.addAxis("axis1", 3, 2.0, 5.0); + + OutputData<double> data2; + data2.addAxis("axis0", 8, -10.0, 70.0); + data2.addAxis("axis1", 3, -10.0, 20.0); + + double x(-4.5), y(2.5); + IntensityDataFunctions::coordinateToBinf(x, y, &data1); + IntensityDataFunctions::coordinateFromBinf(x, y, &data2); + EXPECT_FLOAT_EQ(x, -5.0); + EXPECT_FLOAT_EQ(y, -5.0); + + x = 3.1; y = 5.1; + IntensityDataFunctions::coordinateToBinf(x, y, &data1); + IntensityDataFunctions::coordinateFromBinf(x, y, &data2); + EXPECT_FLOAT_EQ(x, 71.0); + EXPECT_FLOAT_EQ(y, 21.0); + +} + #endif // INTENSITYDATAFUNCTIONSTEST_H