CustusX  15.3.4-beta
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxReconstructionWidget.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 #include "cxReconstructionWidget.h"
33 
35 #include "cxLogger.h"
36 #include "cxHelperWidgets.h"
37 #include "cxTypeConversions.h"
39 #include "cxSettings.h"
40 #include "cxTimedAlgorithm.h"
41 #include "cxStringProperty.h"
42 #include "cxDoubleProperty.h"
43 #include "cxBoolProperty.h"
45 
46 namespace cx
47 {
48 
50  BaseWidget(parent, "USReconstruction", "US Reconstruction"),
51  mReconstructer(reconstructer),
52  mFileSelectWidget( new FileSelectWidget(this))
53 {
54  connect(mReconstructer.get(), &UsReconstructionService::reconstructAboutToStart, this, &ReconstructionWidget::reconstructAboutToStartSlot);
55  connect(mReconstructer.get(), &UsReconstructionService::reconstructStarted, this, &ReconstructionWidget::reconstructStartedSlot);
56  connect(mReconstructer.get(), &UsReconstructionService::reconstructFinished, this, &ReconstructionWidget::reconstructFinishedSlot);
57 
59  connect(mReconstructer.get(), &UsReconstructionService::inputDataSelected, this, &ReconstructionWidget::inputDataSelected);
60  connect(mReconstructer.get(), &UsReconstructionService::algorithmChanged, this, &ReconstructionWidget::repopulateAlgorithmGroup);
61 
62 
63  QVBoxLayout* topLayout = new QVBoxLayout(this);
64 
65  connect(mFileSelectWidget, &FileSelectWidget::fileSelected, this, &ReconstructionWidget::selectData);
66  mFileSelectWidget->setNameFilter(QStringList() << "*.fts");
67  connect(mReconstructer.get(), &UsReconstructionService::newInputDataAvailable, mFileSelectWidget, &FileSelectWidget::refresh);
68  connect(mReconstructer.get(), &UsReconstructionService::newInputDataPath, this, &ReconstructionWidget::updateFileSelectorPath);
69 
70  QHBoxLayout* extentLayout = new QHBoxLayout;
71  mExtentLineEdit = new QLineEdit(this);
72  mExtentLineEdit->setReadOnly(true);
73  extentLayout->addWidget(new QLabel("Extent", this));
74  extentLayout->addWidget(mExtentLineEdit);
75 
76  mInputSpacingLineEdit = new QLineEdit(this);
77  mInputSpacingLineEdit->setReadOnly(true);
78  QLabel* inputSpacingLabel = new QLabel("Spacing In", this);
79 
80  mReconstructButton = new QPushButton("Reconstruct", this);
81  connect(mReconstructButton, &QPushButton::clicked, this, &ReconstructionWidget::reconstruct);
82 
83  mTimedAlgorithmProgressBar = new cx::TimedAlgorithmProgressBar;
84 
85  QGridLayout* sizesLayout = new QGridLayout;
86  QWidget* maxVolSizeWidget = sscCreateDataWidget(this, mReconstructer->getParam("Volume Size"));
87  sizesLayout->addWidget(inputSpacingLabel, 0, 0);
88  sizesLayout->addWidget(mInputSpacingLineEdit, 0, 1);
89  sizesLayout->addLayout(extentLayout, 0, 2);
90  mSpacingWidget = new SpinBoxGroupWidget(this, DoublePropertyBasePtr(new DoublePropertySpacing(mReconstructer)), sizesLayout, 1);
91  sizesLayout->addWidget(maxVolSizeWidget, 1, 2);
92 
93  QHBoxLayout* runLayout = new QHBoxLayout;
94  topLayout->addLayout(runLayout);
95  runLayout->addWidget(mReconstructButton);
96  this->createAction(this,
97  QIcon(":/icons/open_icon_library/system-run-5.png"),
98  "Details", "Show Advanced Settings",
99  SLOT(toggleDetailsSlot()),
100  runLayout);
101 
102  topLayout->addWidget(mFileSelectWidget);
103  topLayout->addLayout(sizesLayout);
104 
105  QWidget* presetTFWidget = sscCreateDataWidget(this, mReconstructer->getParam("Preset"));
106  topLayout->addWidget(presetTFWidget);
107 
108  mOptionsWidget = this->createOptionsWidget();
109  mOptionsWidget->setVisible(settings()->value("reconstruction/guiShowDetails").toBool());
110  topLayout->addWidget(mOptionsWidget);
111 
112  topLayout->addStretch();
113  topLayout->addWidget(mTimedAlgorithmProgressBar);
114 }
115 
116 void ReconstructionWidget::updateFileSelectorPath(QString path)
117 {
118  mFileSelectWidget->setPath(path);
119  mFileSelectWidget->refresh();
120 }
121 
122 QString ReconstructionWidget::defaultWhatsThis() const
123 {
124  return "<html>"
125  "<h3>US 3D Reconstruction.</h3>"
126  "<p><i>Reconstruct 3D US data from acquired a 2D sequence.</i></br>"
127  "</html>";
128 }
129 
130 void ReconstructionWidget::toggleDetailsSlot()
131 {
132  mOptionsWidget->setVisible(!mOptionsWidget->isVisible());
133  settings()->setValue("reconstruction/guiShowDetails", mOptionsWidget->isVisible());
134 }
135 
136 QWidget* ReconstructionWidget::createOptionsWidget()
137 {
138  QWidget* retval = new QWidget(this);
139  QGridLayout* layout = new QGridLayout(retval);
140  layout->setMargin(0);
141 
142  int line = 0;
143 
144  layout->addWidget(this->createHorizontalLine(), line, 0, 1, 2);
145  ++line;
146 
147  mAlgorithmGroup = new QFrame(this);
148  mAlgorithmGroup->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
149  mAlgorithmGroup->setSizePolicy(mAlgorithmGroup->sizePolicy().horizontalPolicy(),QSizePolicy::Fixed);
150 
151  QVBoxLayout* algoOuterLayout = new QVBoxLayout(mAlgorithmGroup);
152  //algoOuterLayout->setMargin(0);
153  QWidget* algorithmWidget = sscCreateDataWidget(this, mReconstructer->getParam("Algorithm"));
154  algoOuterLayout->addWidget(algorithmWidget);
155  mAlgoLayout = new QStackedLayout;
156  this->repopulateAlgorithmGroup();
157  mAlgoLayout->setMargin(0);
158  algoOuterLayout->addLayout(mAlgoLayout);
159  //algoOuterLayout->addStretch();
160  layout->addWidget(mAlgorithmGroup, line, 0, 1, 2);
161  ++line;
162 
163  sscCreateDataWidget(this, mReconstructer->getParam("Angio data"), layout, line++);
164  sscCreateDataWidget(this, mReconstructer->getParam("Dual Angio"), layout, line++);
165  sscCreateDataWidget(this, mReconstructer->getParam("Orientation"), layout, line++);
166  layout->addWidget(this->createHorizontalLine(), line++, 0, 1, 2);
167 
168  mDimXWidget = new SpinBoxGroupWidget(this, DoublePropertyBasePtr(new DoublePropertyXDim(mReconstructer)));
169  mDimYWidget = new SpinBoxGroupWidget(this, DoublePropertyBasePtr(new DoublePropertyYDim(mReconstructer)));
170  mDimZWidget = new SpinBoxGroupWidget(this, DoublePropertyBasePtr(new DoublePropertyZDim(mReconstructer)));
171  QHBoxLayout* outputVolDimLayout = new QHBoxLayout;
172  outputVolDimLayout->addWidget(mDimXWidget);
173  outputVolDimLayout->addWidget(mDimYWidget);
174  outputVolDimLayout->addWidget(mDimZWidget);
175  layout->addLayout(outputVolDimLayout, line++, 0, 1, 2);
176 
177  sscCreateDataWidget(this, mReconstructer->getParam("Align timestamps"), layout, line++);
178  sscCreateDataWidget(this, mReconstructer->getParam("Extra Temporal Calib"), layout, line++);
179  sscCreateDataWidget(this, mReconstructer->getParam("Reduce mask (% in 1D)"), layout, line++);
180 
181  return retval;
182 }
183 
184 void ReconstructionWidget::repopulateAlgorithmGroup()
185 {
186  QString algoName = mReconstructer->getParam("Algorithm")->getValueAsVariant().toString();
187 
188  if (mAlgoLayout->currentWidget() && (algoName == mAlgoLayout->currentWidget()->objectName()))
189  return;
190 
191  for (int i=0; i<mAlgoLayout->count(); ++i)
192  {
193  if (algoName==mAlgoLayout->widget(i)->objectName())
194  {
195  mAlgoLayout->setCurrentIndex(i);
196  return;
197  }
198  }
199 
200  // Remove previous widget: this ensures that the widget wraps tightly around the current
201  // widget instead of wrapping all algorithms.
202  QLayoutItem *child;
203  while ((child = mAlgoLayout->takeAt(0)) != 0)
204  {
205  // delete both the layoutitem AND the widget. Not auto done because layoutitem is no QObject.
206  QWidget* widget = child->widget();
207  delete child;
208  delete widget;
209  }
210 
211  this->createNewStackedWidget(algoName);
212 }
213 
214 void ReconstructionWidget::createNewStackedWidget(QString algoName)
215 {
216  QWidget* oneAlgoWidget = new QWidget(this);
217  oneAlgoWidget->setObjectName(algoName);
218  mAlgoLayout->addWidget(oneAlgoWidget);
219  QGridLayout* oneAlgoLayout = new QGridLayout(oneAlgoWidget);
220  oneAlgoLayout->setMargin(0);
221 
222  std::vector<PropertyPtr> algoOption = mReconstructer->getAlgoOptions();
223  unsigned row = 0;
224  for (;row < algoOption.size(); ++row)
225  {
226  sscCreateDataWidget(oneAlgoWidget, algoOption[row], oneAlgoLayout, row);
227  }
228  oneAlgoLayout->setRowStretch(row, 1); // Set stretch on last row
229 
230  mAlgoLayout->setCurrentWidget(oneAlgoWidget);
231 }
232 
233 QString ReconstructionWidget::getCurrentPath()
234 {
235  return QFileInfo(mReconstructer->getSelectedFilename()).dir().absolutePath();
236 }
237 
239 {
240  mReconstructer->startReconstruction();
241 }
242 
243 
245 {
246  this->selectData(mReconstructer->getSelectedFilename());
247 }
248 
252 void ReconstructionWidget::inputDataSelected(QString mhdFileName)
253 {
254  if (mReconstructer->getSelectedFilename().isEmpty())
255  {
256  return;
257  }
258 
259  mFileSelectWidget->setFilename(mhdFileName);
260 }
261 
262 void ReconstructionWidget::selectData(QString filename)
263 {
264  if (filename.isEmpty())
265  {
266  reportWarning("no file selected");
267  return;
268  }
269 
270  mReconstructer->selectData(filename);
271 }
272 
277 {
278  Vector3D range = mReconstructer->getOutputVolumeParams().getExtent().range();
279 
280  QString extText =
281  QString("%1, %2, %3").arg(range[0], 0, 'f', 1).arg(range[1], 0, 'f', 1).arg(range[2], 0, 'f', 1);
282  mExtentLineEdit->setText(extText);
283 
284  mInputSpacingLineEdit->setText(QString("%1").arg(mReconstructer->getOutputVolumeParams().getInputSpacing(), 0, 'f', 4));
285 }
286 
287 void ReconstructionWidget::reconstructAboutToStartSlot()
288 {
289  std::set<cx::TimedAlgorithmPtr> threads = mReconstructer->getThreadedReconstruction();
290  mTimedAlgorithmProgressBar->attach(threads);
291 }
292 
293 void ReconstructionWidget::reconstructStartedSlot()
294 {
295  mReconstructButton->setEnabled(false);
296 }
297 
298 void ReconstructionWidget::reconstructFinishedSlot()
299 {
300  std::set<cx::TimedAlgorithmPtr> threads = mReconstructer->getThreadedReconstruction();
301  mTimedAlgorithmProgressBar->detach(threads);
302  mReconstructButton->setEnabled(true);
303 }
304 
305 
306 }//namespace
void newInputDataAvailable(QString mhdFileName)
void fileSelected(QString name)
boost::shared_ptr< class UsReconstructionService > UsReconstructionServicePtr
void inputDataSelected(QString mhdFileName)
void setNameFilter(QStringList filter)
ReconstructionWidget(QWidget *parent, UsReconstructionServicePtr reconstructer)
Show progress for a TimedBaseAlgorithm.
QAction * createAction(QObject *parent, QIcon iconName, QString text, QString tip, T slot, QLayout *layout=NULL, QToolButton *button=new QToolButton())
Definition: cxBaseWidget.h:130
void detach(TimedAlgorithmPtr algorithm)
void setValue(const QString &key, const QVariant &value)
Definition: cxSettings.cpp:91
static QFrame * createHorizontalLine()
Creates a horizontal line which can be inserted into widgets.
void reportWarning(QString msg)
Definition: cxLogger.cpp:91
void setFilename(QString name)
void setPath(QString path)
boost::shared_ptr< class DoublePropertyBase > DoublePropertyBasePtr
Settings * settings()
Shortcut for accessing the settings instance.
Definition: cxSettings.cpp:42
void attach(TimedAlgorithmPtr algorithm)
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:63
Interface for QWidget which handles widgets uniformly for the system.
Definition: cxBaseWidget.h:108
Composite widget for scalar data manipulation.
void newInputDataPath(QString path)
QWidget * sscCreateDataWidget(QWidget *parent, PropertyPtr data, QGridLayout *gridLayout, int row)
Create a widget capable of displaying the input data.
void selectData(QString inputfile)
Widget for displaying and selecting a single file.