13 #include <QVBoxLayout> 14 #include <QHBoxLayout> 16 #include <QTableWidget> 17 #include <QHeaderView> 18 #include <QApplication> 19 #include <QDesktopWidget> 23 #include <QStackedWidget> 24 #include <vtkImageData.h> 45 int w = t->verticalHeader()->width() + 4;
46 for (
int i = 0; i < t->columnCount(); i++)
47 w += t->columnWidth(i);
48 int h = t->horizontalHeader()->height() + 4;
49 for (
int i = 0; i < t->rowCount(); i++)
55 BaseWidget(parent,
"ImportDataTypeWidget",
"Import"),
56 mImportWidget(parent),
60 mParentCandidates(parentCandidates),
61 mSelectedIndexInTable(0),
62 mImageTypeCombo(NULL),
66 mAnatomicalCoordinateSystems =
new QComboBox();
67 mAnatomicalCoordinateSystems->addItem(
"LPS");
68 mAnatomicalCoordinateSystems->addItem(
"RAS");
70 if(isInputFileInNiftiFormat())
71 mAnatomicalCoordinateSystems->setCurrentText(
"RAS");
73 mShouldImportParentTransform =
new QComboBox();
74 mShouldImportParentTransform->addItem(
"No");
75 mShouldImportParentTransform->addItem(
"Yes");
77 mParentCandidatesCB =
new QComboBox();
79 mShouldConvertDataToUnsigned =
new QCheckBox();
80 mShouldConvertDataToUnsigned->setCheckState(Qt::Unchecked);
82 mStackedWidgetImageParameters =
new QStackedWidget;
83 mTableWidget =
new QTableWidget();
84 mTableWidget->setRowCount(0);
85 mTableWidget->setColumnCount(7);
86 mTableHeader<<
""<<
"Series num"<<
"#"<<
"Name"<<
"Type"<<
"Slice spacing"<<
"Space";
87 mTableWidget->setHorizontalHeaderLabels(mTableHeader);
88 mTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
89 mTableWidget->verticalHeader()->setVisible(
false);
90 mTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
91 mTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
92 mTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
93 mTableWidget->setShowGrid(
false);
94 mTableWidget->setStyleSheet(
"QTableView {selection-background-color: #ACCEF7;}");
95 mTableWidget->setGeometry(QApplication::desktop()->screenGeometry());
96 connect(mTableWidget, &QTableWidget::currentCellChanged,
this, &ImportDataTypeWidget::tableItemSelected);
99 for(
unsigned i=0; i<mData.size(); ++i)
103 CX_LOG_WARNING() <<
"ImportDataTypeWidget::ImportDataTypeWidget: No data";
106 type = mData[i]->getType();
107 name = mData[i]->getName();
108 QString space = mData[i]->getSpace();
112 space = boost::dynamic_pointer_cast<
PointMetric>(mData[i])->getSpace().toString();
113 (mPointMetricGroups[space]).push_back(mData[i]);
119 QIcon trashcan(
":/icons/open_icon_library/edit-delete-2.png");
120 QPushButton *removeButton =
new QPushButton(trashcan,
"");
121 connect(removeButton, &QPushButton::clicked,
this, &ImportDataTypeWidget::removeRowFromTableAndDataFromImportList);
123 int newRowIndex = mTableWidget->rowCount();
124 mTableWidget->setRowCount(newRowIndex+1);
125 mTableWidget->setCellWidget(newRowIndex, 0, removeButton);
126 mTableWidget->setItem(newRowIndex, mNumSlicesColoumn,
new QTableWidgetItem(
"1"));
127 mTableWidget->setItem(newRowIndex, mFilenameColoumn,
new QTableWidgetItem(name));
128 mTableWidget->setItem(newRowIndex, mTypeColoumn,
new QTableWidgetItem(type));
130 this->createDataSpecificGui(i);
132 this->addPointMetricGroupsToTable();
137 QVBoxLayout *topLayout =
new QVBoxLayout(
this);
138 this->setLayout(topLayout);
140 QFileInfo fileInfo(filename);
141 QString title = fileInfo.fileName();
143 QGroupBox *groupBox =
new QGroupBox(title);
145 QGridLayout *gridLayout =
new QGridLayout();
146 gridLayout->addWidget(
new QLabel(
"For all data in the file: "), 0, 0, 1, 2);
147 gridLayout->addWidget(
new QLabel(
"Specify anatomical coordinate system"), 1, 0);
148 gridLayout->addWidget(mAnatomicalCoordinateSystems, 1, 1);
149 gridLayout->addWidget(
new QLabel(
"Import parents transform?"), 2, 0);
150 gridLayout->addWidget(mShouldImportParentTransform, 2, 1);
151 gridLayout->addWidget(
new QLabel(
"Set parent"), 3, 0);
152 gridLayout->addWidget(mParentCandidatesCB, 3, 1);
153 gridLayout->addWidget(
new QLabel(
"Convert data to unsigned?"), 4, 0);
154 gridLayout->addWidget(mShouldConvertDataToUnsigned, 4,1);
155 gridLayout->addWidget(mTableWidget, 5, 0, 1, 2);
156 gridLayout->addWidget(mStackedWidgetImageParameters);
157 gridLayout->setSpacing(1);
159 groupBox->setLayout(gridLayout);
160 topLayout->addWidget(groupBox, 1);
161 topLayout->addStretch();
176 for(
int i=0; i<tableWidget->rowCount(); ++i)
178 int buttonColoumn = 0;
179 QWidget *cellWidget = tableWidget->cellWidget(i,buttonColoumn);
180 if(button == cellWidget)
186 void ImportDataTypeWidget::createDataSpecificGui(
int index)
188 QWidget* paramWidget =
new QWidget(
this);
190 ImagePtr image = boost::dynamic_pointer_cast<
Image>(mData[index]);
193 mTableWidget->setItem(mTableWidget->rowCount()-1, mSeriesNumColumn,
new QTableWidgetItem(image->getDicomSeriesNumber()));
194 this->updateTableWithNumberOfSlices(image);
195 this->updateTableWithSliceSpacing(image);
199 mModalityAdapter->setData(image);
203 mImageTypeAdapter->setData(image);
205 if(isInputFileInNiftiFormat())
210 QHBoxLayout* layout =
new QHBoxLayout();
211 layout->addWidget(mModalityCombo);
212 layout->addWidget(mImageTypeCombo);
213 paramWidget->setLayout(layout);
216 mStackedWidgetImageParameters->insertWidget(index, paramWidget);
219 void ImportDataTypeWidget::updateTableWithNumberOfSlices(
ImagePtr image)
222 image->getBaseVtkImageData()->GetDimensions(dims);
223 QString numSlices = QString::number(dims[2]);
224 QTableWidgetItem *tableItem = mTableWidget->item(mTableWidget->rowCount()-1, mNumSlicesColoumn);
225 tableItem->setText(numSlices);
229 void ImportDataTypeWidget::updateTableWithSliceSpacing(
ImagePtr image)
231 double spacing = image->getSpacing()[2];
233 spacingText.setNum(spacing,
'g', 2);
234 mTableWidget->setItem(mTableWidget->rowCount()-1, mSliceSpacingColoumn,
new QTableWidgetItem(spacingText+
" mm"));
237 void ImportDataTypeWidget::tableItemSelected(
int currentRow,
int currentColumn,
int previousRow,
int previousColumn)
239 mStackedWidgetImageParameters->setCurrentIndex(currentRow);
242 void ImportDataTypeWidget::removeRowFromTableAndDataFromImportList()
244 QPushButton *button = qobject_cast<QPushButton*>(QObject::sender());
246 QString fullfilename = mTableWidget->item(rowindex, mFilenameColoumn)->text();
248 mTableWidget->removeRow(rowindex);
250 for (std::vector<DataPtr>::iterator it = mData.begin(); it != mData.end();)
252 if((*it)->getName() == fullfilename)
258 QWidget *widgetToRemove = mStackedWidgetImageParameters->widget(rowindex);
259 mStackedWidgetImageParameters->removeWidget(widgetToRemove);
262 void ImportDataTypeWidget::updateImageType()
266 mImageTypeAdapter->setValue(
enum2string(imageSubType));
269 std::map<QString, QString> ImportDataTypeWidget::getParentCandidateList()
271 std::map<QString, QString> parentCandidates;
272 for(
unsigned i=0; i<mParentCandidates.size(); ++i)
274 parentCandidates[mParentCandidates[i]->getName()] = mParentCandidates[i]->getUid();
277 return parentCandidates;
280 void ImportDataTypeWidget::updateSpaceComboBox(QComboBox *box, QString pointMetricGroupId)
283 std::map<QString, QString> parentCandidates = this->getParentCandidateList();
284 std::map<QString, QString>::iterator it;
285 for(it= parentCandidates.begin(); it != parentCandidates.end(); ++it)
287 QVariant id(it->second);
288 box->addItem(it->first,
id);
290 std::vector<DataPtr> pointMetricGroup = mPointMetricGroups[pointMetricGroupId];
291 QString currentSpace = pointMetricGroup[0]->getSpace();
292 box->setCurrentText(currentSpace);
295 void ImportDataTypeWidget::updateParentCandidatesComboBox()
298 QString selectedParentId = (mParentCandidatesCB->itemData(mParentCandidatesCB->currentIndex()).toString());
300 mParentCandidatesCB->clear();
301 std::map<QString, QString> parentCandidates = this->getParentCandidateList();
302 std::map<QString, QString>::iterator it;
303 QVariant emptyId(
"");
304 mParentCandidatesCB->addItem(
"", emptyId);
305 int selectedIndex = 0;
306 for(it= parentCandidates.begin(); it != parentCandidates.end(); ++it)
308 QString idString = it->second;
309 QVariant id(idString);
310 mParentCandidatesCB->addItem(it->first,
id);
311 if(selectedParentId.compare(idString, Qt::CaseInsensitive) == 0)
312 selectedIndex = mParentCandidatesCB->count()-1;
315 if(selectedIndex != 0)
316 mParentCandidatesCB->setCurrentIndex(selectedIndex);
320 QString parentGuess = this->getInitialGuessForParentFrame();
322 mParentCandidatesCB->setCurrentText(parentGuess);
328 void ImportDataTypeWidget::importAllData()
330 for(
unsigned i=0; i<mData.size(); ++i)
334 QString parentId = (mParentCandidatesCB->itemData(mParentCandidatesCB->currentIndex()).toString());
335 mData[i]->get_rMd_History()->setParentSpace(parentId);
337 mServices->patient()->insertData(mData[i]);
338 mServices->view()->autoShowData(mData[i]);
343 void ImportDataTypeWidget::applyParentTransformImport()
347 QString parentId = (mParentCandidatesCB->itemData(mParentCandidatesCB->currentIndex()).toString());
348 DataPtr parent = mServices->patient()->getData(parentId);
352 CX_LOG_ERROR() <<
"Could not find parent data with uid: " << parentId;
356 std::vector<DataPtr>::iterator it = mData.begin();
357 for(;it!=mData.end(); ++it)
360 data->get_rMd_History()->setRegistration(parent->get_rMd());
361 report(
"Assigned rMd from data [" + parent->getName() +
"] to data [" + data->getName() +
"]");
377 void ImportDataTypeWidget::applyConversionLPS()
381 std::vector<DataPtr>::iterator it = mData.begin();
382 for(;it!=mData.end(); ++it)
388 data->get_rMd_History()->setRegistration(rMd);
389 report(
"Nifti import: Converted data " + data->getName() +
" from LPS to RAS coordinates.");
407 void ImportDataTypeWidget::applyConversionToUnsigned()
411 std::vector<DataPtr>::iterator it = mData.begin();
412 for(;it!=mData.end(); ++it)
422 image->setVtkImageData(converted->getBaseVtkImageData());
424 ImageTF3DPtr TF3D = converted->getTransferFunctions3D()->createCopy();
425 ImageLUT2DPtr LUT2D = converted->getLookupTable2D()->createCopy();
426 image->setLookupTable2D(LUT2D);
427 image->setTransferFunctions3D(TF3D);
430 DataPtr convertedData = boost::dynamic_pointer_cast<
Data>(image);
431 (*it) = convertedData;
456 this->updateParentCandidatesComboBox();
458 std::map<QString, QComboBox *>::iterator it;
459 for(it=mSpaceCBs.begin(); it != mSpaceCBs.end(); ++it)
461 QString
id = it->first;
462 QComboBox *box = it->second;
463 this->updateSpaceComboBox(box,
id);
469 if(mShouldConvertDataToUnsigned->isChecked())
470 this->applyConversionToUnsigned();
472 this->importAllData();
474 if(mShouldImportParentTransform->currentText() ==
"Yes")
475 this->applyParentTransformImport();
476 if(mAnatomicalCoordinateSystems->currentText() !=
"LPS")
477 this->applyConversionLPS();
480 void ImportDataTypeWidget::showEvent(QShowEvent *event)
486 void ImportDataTypeWidget::pointMetricGroupSpaceChanged(
int index)
488 QComboBox *box = qobject_cast<QComboBox*>(QObject::sender());
489 QString newSpace = box->currentData().toString();
491 QString pointMetricsGroupId;
492 std::map<QString, QComboBox *>::iterator it;
493 for(it = mSpaceCBs.begin(); it != mSpaceCBs.end(); ++it)
495 if(it->second == box)
496 pointMetricsGroupId = it->first;
498 std::vector<DataPtr> pointMetricGroup = mPointMetricGroups[pointMetricsGroupId];
499 for(
unsigned i=0; i<pointMetricGroup.size(); ++i)
502 boost::dynamic_pointer_cast<
PointMetric>(pointMetricGroup[i])->setSpace(cs);
506 QString ImportDataTypeWidget::getInitialGuessForParentFrame()
508 int candidateScore = 0;
509 QString bestCandidate;
511 for(
unsigned i=0; i < mData.size(); ++i)
514 std::map<QString, QString> parentCandidates = this->getParentCandidateList();
516 std::map<QString, QString>::iterator iter;
517 for(iter= parentCandidates.begin(); iter != parentCandidates.end(); ++iter)
519 int similarity = similatiryMeasure(data->getUid(), iter->second);
520 if(similarity > candidateScore && !isSegmentation(iter->second))
522 candidateScore = similarity;
523 bestCandidate = iter->first;
528 return bestCandidate;
531 int ImportDataTypeWidget::similatiryMeasure(QString current, QString candidate)
533 QStringList currentList = splitStringIntoSeparateParts(current);
534 QStringList candidateList = splitStringIntoSeparateParts(candidate);
535 return countEqualListElements(currentList, candidateList);
538 QStringList ImportDataTypeWidget::splitStringIntoSeparateParts(QString current)
540 current = removeParenthesis(current);
542 QStringList list = current.split(
".", QString::SkipEmptyParts);
544 for (
int i = 0; i < list.size(); ++i)
546 list2 << list[i].split(
"_", QString::SkipEmptyParts);
548 QStringList currentParts;
549 for (
int i = 0; i < list2.size(); ++i)
551 currentParts << list2[i].split(
"-", QString::SkipEmptyParts);
556 QString ImportDataTypeWidget::removeParenthesis(QString current)
558 int startParenthesis;
561 startParenthesis = current.indexOf(
"{");
562 int endParenthesis = current.indexOf(
"}");
563 current.replace(startParenthesis, endParenthesis-startParenthesis+1,
"");
564 }
while (startParenthesis != -1);
568 int ImportDataTypeWidget::countEqualListElements(QStringList first, QStringList second)
571 int numComparedElements = 0;
572 for (
int i = 0; i < first.size(); ++i)
574 if(excludeElement(first[i]))
576 ++numComparedElements;
577 for (
int j = 0; j < second.size(); ++j)
579 if(first[i].compare(second[j]) == 0)
587 if (retval == numComparedElements)
592 bool ImportDataTypeWidget::excludeElement(QString element)
594 if (isSegmentation(element))
599 void ImportDataTypeWidget::addPointMetricGroupsToTable()
603 std::map<QString, std::vector<DataPtr> >::iterator it = mPointMetricGroups.begin();
604 for(; it != mPointMetricGroups.end(); ++it)
608 QString space = it->first;
609 std::vector<DataPtr> datas = it->second;
611 if(datas.empty() || !data)
616 QComboBox *spaceCB =
new QComboBox();
617 mSpaceCBs[space] = spaceCB;
618 connect(spaceCB, SIGNAL(currentIndexChanged(
int)),
this, SLOT(pointMetricGroupSpaceChanged(
int)));
619 this->updateSpaceComboBox(spaceCB, space);
621 type = data->getType();
622 name =
"Point metric group "+QString::number(groupnr);
624 int newRowIndex = mTableWidget->rowCount();
625 mTableWidget->setRowCount(newRowIndex+1);
626 mTableWidget->setItem(newRowIndex, mNumSlicesColoumn,
new QTableWidgetItem(QString::number(datas.size())));
627 mTableWidget->setItem(newRowIndex, mFilenameColoumn,
new QTableWidgetItem(name));
628 mTableWidget->setItem(newRowIndex, mTypeColoumn,
new QTableWidgetItem(type));
629 mTableWidget->setCellWidget(newRowIndex, mSpaceColoumn, spaceCB);
633 bool ImportDataTypeWidget::isInputFileInNiftiFormat()
635 if(mFilename.endsWith(
".nii", Qt::CaseInsensitive))
640 bool ImportDataTypeWidget::isSegmentation(QString filename)
642 if(filename.contains(
"label", Qt::CaseInsensitive))
644 if(filename.contains(
"seg", Qt::CaseInsensitive))
651 QTableWidget* simpleTableWidget =
new QTableWidget();
652 simpleTableWidget->setRowCount(0);
653 simpleTableWidget->setColumnCount(4);
654 QStringList tableHeader;
655 tableHeader<<
"Series num"<<
"Name"<<
"Num slices"<<
"Slice spacing";
656 simpleTableWidget->setHorizontalHeaderLabels(tableHeader);
657 simpleTableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
658 simpleTableWidget->verticalHeader()->setVisible(
false);
659 simpleTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
660 simpleTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
661 simpleTableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
662 simpleTableWidget->setShowGrid(
true);
663 simpleTableWidget->setStyleSheet(
"QTableView {selection-background-color: #ACCEF7;}");
664 simpleTableWidget->setGeometry(QApplication::desktop()->screenGeometry());
667 simpleTableWidget->setRowCount(mTableWidget->rowCount());
668 for(
int i = 0; i < mTableWidget->rowCount(); ++i)
670 simpleTableWidget->setItem(i, 0,
new QTableWidgetItem(mTableWidget->item(i, mSeriesNumColumn)->text()));
671 simpleTableWidget->setItem(i, 1,
new QTableWidgetItem(mTableWidget->item(i, mFilenameColoumn)->text()));
672 simpleTableWidget->setItem(i, 2,
new QTableWidgetItem(mTableWidget->item(i, mNumSlicesColoumn)->text()));
673 simpleTableWidget->setItem(i, 3,
new QTableWidgetItem(mTableWidget->item(i, mSliceSpacingColoumn)->text()));
677 return simpleTableWidget;
pcsRAS
Right-Anterior-Superior, used by Slicer3D, ITK-Snap, nifti, MINC.
boost::shared_ptr< class VisServices > VisServicesPtr
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
cxResource_EXPORT Transform3D createTransformFromReferenceToExternal(PATIENT_COORDINATE_SYSTEM external)
static StringPropertyDataModalityPtr New(PatientModelServicePtr patientModelService)
boost::shared_ptr< class Image > ImagePtr
ImagePtr convertImageToUnsigned(PatientModelServicePtr dataManager, ImagePtr image, vtkImageDataPtr suggestedConvertedVolume, bool verbose)
boost::shared_ptr< class Data > DataPtr
static StringPropertyImageTypePtr New(PatientModelServicePtr patientModelService)
boost::shared_ptr< class ImageLUT2D > ImageLUT2DPtr
IMAGE_SUBTYPE convertToImageSubType(QString imageTypeSubString)
Identification of a Coordinate system.
Data class that represents a single point.
Superclass for all data objects.
static QString getTypeName()
QString enum2string(const ENUM &val)
boost::shared_ptr< class ImageTF3D > ImageTF3DPtr
Namespace for all CustusX production code.