CustusX  2023.01.05-dev+develop.0da12
An IGT application
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) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 #include "cxReconstructionWidget.h"
12 
14 #include "cxLogger.h"
15 #include "cxHelperWidgets.h"
16 #include "cxTypeConversions.h"
18 #include "cxSettings.h"
19 #include "cxTimedAlgorithm.h"
20 #include "cxStringProperty.h"
21 #include "cxDoubleProperty.h"
22 #include "cxBoolProperty.h"
24 
25 namespace cx
26 {
27 
29  BaseWidget(parent, "us_reconstruction", "US Reconstruction"),
30  mReconstructer(reconstructer),
31  mFileSelectWidget( new FileSelectWidget(this))
32 {
33  this->setToolTip("Reconstruct 3D US data from an acquired 2D sequence");
34  connect(mReconstructer.get(), &UsReconstructionService::reconstructAboutToStart, this, &ReconstructionWidget::reconstructAboutToStartSlot);
35  connect(mReconstructer.get(), &UsReconstructionService::reconstructStarted, this, &ReconstructionWidget::reconstructStartedSlot);
36  connect(mReconstructer.get(), &UsReconstructionService::reconstructFinished, this, &ReconstructionWidget::reconstructFinishedSlot);
37 
39  connect(mReconstructer.get(), &UsReconstructionService::inputDataSelected, this, &ReconstructionWidget::inputDataSelected);
40  connect(mReconstructer.get(), &UsReconstructionService::algorithmChanged, this, &ReconstructionWidget::repopulateAlgorithmGroup);
41 
42 
43  QVBoxLayout* topLayout = new QVBoxLayout(this);
44 
45  connect(mFileSelectWidget, &FileSelectWidget::fileSelected, this, &ReconstructionWidget::selectData);
46  mFileSelectWidget->setNameFilter(QStringList() << "*.fts");
47  connect(mReconstructer.get(), &UsReconstructionService::newInputDataAvailable, mFileSelectWidget, &FileSelectWidget::refresh);
48  connect(mReconstructer.get(), &UsReconstructionService::newInputDataPath, this, &ReconstructionWidget::updateFileSelectorPath);
49 
50  QHBoxLayout* extentLayout = new QHBoxLayout;
51  mExtentLineEdit = new QLineEdit(this);
52  mExtentLineEdit->setReadOnly(true);
53  extentLayout->addWidget(new QLabel("Extent", this));
54  extentLayout->addWidget(mExtentLineEdit);
55 
56  mInputSpacingLineEdit = new QLineEdit(this);
57  mInputSpacingLineEdit->setReadOnly(true);
58  QLabel* inputSpacingLabel = new QLabel("Spacing In", this);
59 
60  mReconstructButton = new QPushButton("Reconstruct", this);
61  connect(mReconstructButton, &QPushButton::clicked, this, &ReconstructionWidget::reconstruct);
62 
63  mTimedAlgorithmProgressBar = new cx::TimedAlgorithmProgressBar;
64 
65  QGridLayout* sizesLayout = new QGridLayout;
66  QWidget* maxVolSizeWidget = sscCreateDataWidget(this, mReconstructer->getParam("Volume Size"));
67  sizesLayout->addWidget(inputSpacingLabel, 0, 0);
68  sizesLayout->addWidget(mInputSpacingLineEdit, 0, 1);
69  sizesLayout->addLayout(extentLayout, 0, 2);
70  mSpacingWidget = new SpinBoxGroupWidget(this, DoublePropertyBasePtr(new DoublePropertySpacing(mReconstructer)), sizesLayout, 1);
71  sizesLayout->addWidget(maxVolSizeWidget, 1, 2);
72 
73  QHBoxLayout* runLayout = new QHBoxLayout;
74  topLayout->addLayout(runLayout);
75  runLayout->addWidget(mReconstructButton);
76  this->createAction(this,
77  QIcon(":/icons/open_icon_library/system-run-5.png"),
78  "Details", "Show Advanced Settings",
79  SLOT(toggleDetailsSlot()),
80  runLayout);
81 
82  topLayout->addWidget(mFileSelectWidget);
83  topLayout->addLayout(sizesLayout);
84 
85  QWidget* presetTFWidget = sscCreateDataWidget(this, mReconstructer->getParam("Preset"));
86  topLayout->addWidget(presetTFWidget);
87 
88  mOptionsWidget = this->createOptionsWidget();
89  mOptionsWidget->setVisible(settings()->value("reconstruction/guiShowDetails").toBool());
90  topLayout->addWidget(mOptionsWidget);
91 
92  topLayout->addStretch();
93  topLayout->addWidget(mTimedAlgorithmProgressBar);
94 }
95 
96 void ReconstructionWidget::updateFileSelectorPath(QString path)
97 {
98  mFileSelectWidget->setPath(path);
99  mFileSelectWidget->refresh();
100 }
101 
102 void ReconstructionWidget::toggleDetailsSlot()
103 {
104  mOptionsWidget->setVisible(!mOptionsWidget->isVisible());
105  settings()->setValue("reconstruction/guiShowDetails", mOptionsWidget->isVisible());
106 }
107 
108 QWidget* ReconstructionWidget::createOptionsWidget()
109 {
110  QWidget* retval = new QWidget(this);
111  QGridLayout* layout = new QGridLayout(retval);
112  layout->setMargin(0);
113 
114  int line = 0;
115 
116  layout->addWidget(this->createHorizontalLine(), line, 0, 1, 2);
117  ++line;
118 
119  mAlgorithmGroup = new QFrame(this);
120  mAlgorithmGroup->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
121  mAlgorithmGroup->setFocusPolicy(Qt::StrongFocus); // needed for help system: focus is used to display help text
122  mAlgorithmGroup->setSizePolicy(mAlgorithmGroup->sizePolicy().horizontalPolicy(),QSizePolicy::Fixed);
123 
124  QVBoxLayout* algoOuterLayout = new QVBoxLayout(mAlgorithmGroup);
125  //algoOuterLayout->setMargin(0);
126  QWidget* algorithmWidget = sscCreateDataWidget(this, mReconstructer->getParam("Algorithm"));
127  algoOuterLayout->addWidget(algorithmWidget);
128  mAlgoLayout = new QStackedLayout;
129  this->repopulateAlgorithmGroup();
130  mAlgoLayout->setMargin(0);
131  algoOuterLayout->addLayout(mAlgoLayout);
132  //algoOuterLayout->addStretch();
133  layout->addWidget(mAlgorithmGroup, line, 0, 1, 2);
134  ++line;
135 
136  sscCreateDataWidget(this, mReconstructer->getParam("Angio data"), layout, line++);
137  sscCreateDataWidget(this, mReconstructer->getParam("Dual Angio"), layout, line++);
138  sscCreateDataWidget(this, mReconstructer->getParam("Orientation"), layout, line++);
139  layout->addWidget(this->createHorizontalLine(), line++, 0, 1, 2);
140 
141  mDimXWidget = new SpinBoxGroupWidget(this, DoublePropertyBasePtr(new DoublePropertyXDim(mReconstructer)));
142  mDimYWidget = new SpinBoxGroupWidget(this, DoublePropertyBasePtr(new DoublePropertyYDim(mReconstructer)));
143  mDimZWidget = new SpinBoxGroupWidget(this, DoublePropertyBasePtr(new DoublePropertyZDim(mReconstructer)));
144  QHBoxLayout* outputVolDimLayout = new QHBoxLayout;
145  outputVolDimLayout->addWidget(mDimXWidget);
146  outputVolDimLayout->addWidget(mDimYWidget);
147  outputVolDimLayout->addWidget(mDimZWidget);
148  layout->addLayout(outputVolDimLayout, line++, 0, 1, 2);
149 
150  sscCreateDataWidget(this, mReconstructer->getParam("Align timestamps"), layout, line++);
151  sscCreateDataWidget(this, mReconstructer->getParam("Extra Temporal Calib"), layout, line++);
152 // sscCreateDataWidget(this, mReconstructer->getParam("Position Thinning"), layout, line++);
153  sscCreateDataWidget(this, mReconstructer->getParam("Position Filter Strength"), layout, line++);
154  sscCreateDataWidget(this, mReconstructer->getParam("Reduce mask (% in 1D)"), layout, line++);
155 
156  return retval;
157 }
158 
159 void ReconstructionWidget::repopulateAlgorithmGroup()
160 {
161  QString algoName = mReconstructer->getParam("Algorithm")->getValueAsVariant().toString();
162 
163  if (mAlgoLayout->currentWidget() && (algoName == mAlgoLayout->currentWidget()->objectName()))
164  return;
165 
166  for (int i=0; i<mAlgoLayout->count(); ++i)
167  {
168  if (algoName==mAlgoLayout->widget(i)->objectName())
169  {
170  mAlgoLayout->setCurrentIndex(i);
171  return;
172  }
173  }
174 
175  // Remove previous widget: this ensures that the widget wraps tightly around the current
176  // widget instead of wrapping all algorithms.
177  QLayoutItem *child;
178  while ((child = mAlgoLayout->takeAt(0)) != 0)
179  {
180  // delete both the layoutitem AND the widget. Not auto done because layoutitem is no QObject.
181  QWidget* widget = child->widget();
182  delete child;
183  delete widget;
184  }
185 
186  this->createNewStackedWidget(algoName);
187 }
188 
189 void ReconstructionWidget::createNewStackedWidget(QString algoName)
190 {
191  QWidget* oneAlgoWidget = new QWidget(this);
192  oneAlgoWidget->setObjectName(algoName);
193  mAlgorithmGroup->setObjectName(algoName);
194  mAlgoLayout->addWidget(oneAlgoWidget);
195  QGridLayout* oneAlgoLayout = new QGridLayout(oneAlgoWidget);
196  oneAlgoLayout->setMargin(0);
197 
198  std::vector<PropertyPtr> algoOption = mReconstructer->getAlgoOptions();
199  unsigned row = 0;
200  for (;row < algoOption.size(); ++row)
201  {
202  sscCreateDataWidget(oneAlgoWidget, algoOption[row], oneAlgoLayout, row);
203  }
204  oneAlgoLayout->setRowStretch(row, 1); // Set stretch on last row
205 
206  mAlgoLayout->setCurrentWidget(oneAlgoWidget);
207 }
208 
209 QString ReconstructionWidget::getCurrentPath()
210 {
211  return QFileInfo(mReconstructer->getSelectedFilename()).dir().absolutePath();
212 }
213 
215 {
216  mReconstructer->startReconstruction();
217 }
218 
219 
221 {
222  this->selectData(mReconstructer->getSelectedFilename());
223 }
224 
228 void ReconstructionWidget::inputDataSelected(QString mhdFileName)
229 {
230  if (mReconstructer->getSelectedFilename().isEmpty())
231  {
232  return;
233  }
234 
235  mFileSelectWidget->setFilename(mhdFileName);
236 }
237 
238 void ReconstructionWidget::selectData(QString filename)
239 {
240  if (filename.isEmpty())
241  {
242  reportWarning("no file selected");
243  return;
244  }
245 
246  mReconstructer->selectData(filename);
247 }
248 
253 {
254  Vector3D range = mReconstructer->getOutputVolumeParams().getExtent().range();
255 
256  QString extText =
257  QString("%1, %2, %3").arg(range[0], 0, 'f', 1).arg(range[1], 0, 'f', 1).arg(range[2], 0, 'f', 1);
258  mExtentLineEdit->setText(extText);
259 
260  mInputSpacingLineEdit->setText(QString("%1").arg(mReconstructer->getOutputVolumeParams().getInputSpacing(), 0, 'f', 4));
261 }
262 
263 void ReconstructionWidget::reconstructAboutToStartSlot()
264 {
265  std::set<cx::TimedAlgorithmPtr> threads = mReconstructer->getThreadedReconstruction();
266  mTimedAlgorithmProgressBar->attach(threads);
267 }
268 
269 void ReconstructionWidget::reconstructStartedSlot()
270 {
271  mReconstructButton->setEnabled(false);
272 }
273 
274 void ReconstructionWidget::reconstructFinishedSlot()
275 {
276  std::set<cx::TimedAlgorithmPtr> threads = mReconstructer->getThreadedReconstruction();
277  mTimedAlgorithmProgressBar->detach(threads);
278  mReconstructButton->setEnabled(true);
279 }
280 
281 
282 }//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:129
void detach(TimedAlgorithmPtr algorithm)
void setValue(const QString &key, const QVariant &value)
Definition: cxSettings.cpp:58
static QFrame * createHorizontalLine()
Creates a horizontal line which can be inserted into widgets.
void reportWarning(QString msg)
Definition: cxLogger.cpp:70
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:21
void attach(TimedAlgorithmPtr algorithm)
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:42
Interface for QWidget which handles widgets uniformly for the system.
Definition: cxBaseWidget.h:88
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.
Namespace for all CustusX production code.