00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "QmitkDiffusionQuantificationView.h"
00020 #include "mitkDiffusionImagingConfigure.h"
00021
00022 #include "itkTimeProbe.h"
00023 #include "itkImage.h"
00024
00025 #include "mitkNodePredicateDataType.h"
00026 #include "mitkDataNodeObject.h"
00027 #include "mitkQBallImage.h"
00028 #include "mitkImageCast.h"
00029 #include "mitkStatusBar.h"
00030 #include "itkDiffusionQballGeneralizedFaImageFilter.h"
00031 #include "itkShiftScaleImageFilter.h"
00032 #include "itkTensorFractionalAnisotropyImageFilter.h"
00033 #include "itkTensorRelativeAnisotropyImageFilter.h"
00034 #include "itkTensorDerivedMeasurementsFilter.h"
00035
00036 #include "QmitkDataStorageComboBox.h"
00037 #include "QmitkStdMultiWidget.h"
00038
00039 #include <QMessageBox>
00040
00041 #include "berryIWorkbenchWindow.h"
00042 #include "berryISelectionService.h"
00043
00044
00045 const std::string QmitkDiffusionQuantificationView::VIEW_ID = "org.mitk.views.diffusionquantification";
00046
00047 using namespace berry;
00048
00049 const float QmitkDiffusionQuantificationView::m_ScaleDAIValues = 100.0;
00050
00051 struct DqSelListener : ISelectionListener
00052 {
00053
00054 berryObjectMacro(DqSelListener);
00055
00056 DqSelListener(QmitkDiffusionQuantificationView* view)
00057 {
00058 m_View = view;
00059 }
00060
00061 void DoSelectionChanged(ISelection::ConstPointer selection)
00062 {
00063
00064 m_View->m_CurrentSelection = selection.Cast<const IStructuredSelection>();
00065
00066
00067 if(m_View->m_CurrentSelection)
00068 {
00069 bool foundQBIVolume = false;
00070 bool foundTensorVolume = false;
00071
00072
00073 for (IStructuredSelection::iterator i = m_View->m_CurrentSelection->Begin();
00074 i != m_View->m_CurrentSelection->End(); ++i)
00075 {
00076
00077
00078 if (mitk::DataNodeObject::Pointer nodeObj = i->Cast<mitk::DataNodeObject>())
00079 {
00080 mitk::DataNode::Pointer node = nodeObj->GetDataNode();
00081
00082
00083 if(QString("QBallImage").compare(node->GetData()->GetNameOfClass())==0)
00084 {
00085 foundQBIVolume = true;
00086 }
00087
00088 if(QString("TensorImage").compare(node->GetData()->GetNameOfClass())==0)
00089 {
00090 foundTensorVolume = true;
00091 }
00092 }
00093 }
00094
00095 m_View->m_Controls->m_GFAButton->setEnabled(foundQBIVolume);
00096 m_View->m_Controls->m_CurvatureButton->setEnabled(foundQBIVolume);
00097
00098 m_View->m_Controls->m_FAButton->setEnabled(foundTensorVolume);
00099 m_View->m_Controls->m_RAButton->setEnabled(foundTensorVolume);
00100 m_View->m_Controls->m_ADButton->setEnabled(foundTensorVolume);
00101 m_View->m_Controls->m_RDButton->setEnabled(foundTensorVolume);
00102 m_View->m_Controls->m_ClusteringAnisotropy->setEnabled(foundTensorVolume);
00103 }
00104 }
00105
00106 void SelectionChanged(IWorkbenchPart::Pointer part, ISelection::ConstPointer selection)
00107 {
00108
00109 if (part)
00110 {
00111 QString partname(part->GetPartName().c_str());
00112 if(partname.compare("Datamanager")==0)
00113 {
00114
00115
00116 DoSelectionChanged(selection);
00117
00118 }
00119 }
00120 }
00121
00122 QmitkDiffusionQuantificationView* m_View;
00123 };
00124
00125 QmitkDiffusionQuantificationView::QmitkDiffusionQuantificationView()
00126 : QmitkFunctionality(),
00127 m_Controls(NULL),
00128 m_MultiWidget(NULL)
00129 {
00130 }
00131
00132 QmitkDiffusionQuantificationView::~QmitkDiffusionQuantificationView()
00133 {
00134 this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->RemovePostSelectionListener( m_SelListener);
00135 }
00136
00137 void QmitkDiffusionQuantificationView::CreateQtPartControl(QWidget *parent)
00138 {
00139 if (!m_Controls)
00140 {
00141
00142 m_Controls = new Ui::QmitkDiffusionQuantificationViewControls;
00143 m_Controls->setupUi(parent);
00144 this->CreateConnections();
00145 GFACheckboxClicked();
00146
00147 #ifndef DIFFUSION_IMAGING_EXTENDED
00148 m_Controls->m_StandardGFACheckbox->setVisible(false);
00149 m_Controls->frame_3->setVisible(false);
00150 m_Controls->m_CurvatureButton->setVisible(false);
00151 #endif
00152 }
00153
00154 m_SelListener = berry::ISelectionListener::Pointer(new DqSelListener(this));
00155 this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->AddPostSelectionListener( m_SelListener);
00156 berry::ISelection::ConstPointer sel(
00157 this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager"));
00158 m_CurrentSelection = sel.Cast<const IStructuredSelection>();
00159 m_SelListener.Cast<DqSelListener>()->DoSelectionChanged(sel);
00160 }
00161
00162 void QmitkDiffusionQuantificationView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget)
00163 {
00164 m_MultiWidget = &stdMultiWidget;
00165 }
00166
00167 void QmitkDiffusionQuantificationView::StdMultiWidgetNotAvailable()
00168 {
00169 m_MultiWidget = NULL;
00170 }
00171
00172 void QmitkDiffusionQuantificationView::CreateConnections()
00173 {
00174 if ( m_Controls )
00175 {
00176 connect( (QObject*)(m_Controls->m_StandardGFACheckbox), SIGNAL(clicked()), this, SLOT(GFACheckboxClicked()) );
00177 connect( (QObject*)(m_Controls->m_GFAButton), SIGNAL(clicked()), this, SLOT(GFA()) );
00178 connect( (QObject*)(m_Controls->m_CurvatureButton), SIGNAL(clicked()), this, SLOT(Curvature()) );
00179 connect( (QObject*)(m_Controls->m_FAButton), SIGNAL(clicked()), this, SLOT(FA()) );
00180 connect( (QObject*)(m_Controls->m_RAButton), SIGNAL(clicked()), this, SLOT(RA()) );
00181 connect( (QObject*)(m_Controls->m_ADButton), SIGNAL(clicked()), this, SLOT(AD()) );
00182 connect( (QObject*)(m_Controls->m_RDButton), SIGNAL(clicked()), this, SLOT(RD()) );
00183 connect( (QObject*)(m_Controls->m_ClusteringAnisotropy), SIGNAL(clicked()), this, SLOT(ClusterAnisotropy()) );
00184 }
00185 }
00186
00187 void QmitkDiffusionQuantificationView::Activated()
00188 {
00189 berry::ISelection::ConstPointer sel(
00190 this->GetSite()->GetWorkbenchWindow()->GetSelectionService()->GetSelection("org.mitk.views.datamanager"));
00191 m_CurrentSelection = sel.Cast<const IStructuredSelection>();
00192 m_SelListener.Cast<DqSelListener>()->DoSelectionChanged(sel);
00193 QmitkFunctionality::Activated();
00194 }
00195
00196 void QmitkDiffusionQuantificationView::Deactivated()
00197 {
00198 QmitkFunctionality::Deactivated();
00199 }
00200
00201 void QmitkDiffusionQuantificationView::GFACheckboxClicked()
00202 {
00203 m_Controls->frame_2->setVisible(m_Controls->
00204 m_StandardGFACheckbox->isChecked());
00205 }
00206
00207 void QmitkDiffusionQuantificationView::GFA()
00208 {
00209 if(m_Controls->m_StandardGFACheckbox->isChecked())
00210 {
00211 QBIQuantify(13);
00212 }
00213 else
00214 {
00215 QBIQuantify(0);
00216 }
00217 }
00218
00219 void QmitkDiffusionQuantificationView::Curvature()
00220 {
00221 QBIQuantify(12);
00222 }
00223
00224 void QmitkDiffusionQuantificationView::FA()
00225 {
00226 TensorQuantify(0);
00227 }
00228
00229 void QmitkDiffusionQuantificationView::RA()
00230 {
00231 TensorQuantify(1);
00232 }
00233
00234 void QmitkDiffusionQuantificationView::AD()
00235 {
00236 TensorQuantify(2);
00237 }
00238
00239 void QmitkDiffusionQuantificationView::RD()
00240 {
00241 TensorQuantify(3);
00242 }
00243
00244 void QmitkDiffusionQuantificationView::ClusterAnisotropy()
00245 {
00246 TensorQuantify(4);
00247 }
00248
00249 void QmitkDiffusionQuantificationView::QBIQuantify(int method)
00250 {
00251 if (m_CurrentSelection)
00252 {
00253 mitk::DataStorage::SetOfObjects::Pointer set =
00254 mitk::DataStorage::SetOfObjects::New();
00255
00256 int at = 0;
00257 for (IStructuredSelection::iterator i = m_CurrentSelection->Begin();
00258 i != m_CurrentSelection->End();
00259 ++i)
00260 {
00261
00262 if (mitk::DataNodeObject::Pointer nodeObj = i->Cast<mitk::DataNodeObject>())
00263 {
00264 mitk::DataNode::Pointer node = nodeObj->GetDataNode();
00265 if(QString("QBallImage").compare(node->GetData()->GetNameOfClass())==0)
00266 {
00267 set->InsertElement(at++, node);
00268 }
00269 }
00270 }
00271
00272 QBIQuantification(set, method);
00273
00274 }
00275 }
00276
00277 void QmitkDiffusionQuantificationView::TensorQuantify(int method)
00278 {
00279 if (m_CurrentSelection)
00280 {
00281 mitk::DataStorage::SetOfObjects::Pointer set =
00282 mitk::DataStorage::SetOfObjects::New();
00283
00284 int at = 0;
00285 for (IStructuredSelection::iterator i = m_CurrentSelection->Begin();
00286 i != m_CurrentSelection->End();
00287 ++i)
00288 {
00289
00290 if (mitk::DataNodeObject::Pointer nodeObj = i->Cast<mitk::DataNodeObject>())
00291 {
00292 mitk::DataNode::Pointer node = nodeObj->GetDataNode();
00293 if(QString("TensorImage").compare(node->GetData()->GetNameOfClass())==0)
00294 {
00295 set->InsertElement(at++, node);
00296 }
00297 }
00298 }
00299
00300 TensorQuantification(set, method);
00301
00302 }
00303 }
00304
00305 void QmitkDiffusionQuantificationView::QBIQuantification(
00306 mitk::DataStorage::SetOfObjects::Pointer inImages, int method)
00307 {
00308 itk::TimeProbe clock;
00309 QString status;
00310
00311 int nrFiles = inImages->size();
00312 if (!nrFiles) return;
00313
00314 mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() );
00315 mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() );
00316
00317 std::vector<mitk::DataNode::Pointer> nodes;
00318 while ( itemiter != itemiterend )
00319 {
00320
00321 typedef float TOdfPixelType;
00322 const int odfsize = QBALL_ODFSIZE;
00323 typedef itk::Vector<TOdfPixelType,odfsize> OdfVectorType;
00324 typedef itk::Image<OdfVectorType,3> OdfVectorImgType;
00325 mitk::Image* vol =
00326 static_cast<mitk::Image*>((*itemiter)->GetData());
00327 OdfVectorImgType::Pointer itkvol = OdfVectorImgType::New();
00328 mitk::CastToItkImage<OdfVectorImgType>(vol, itkvol);
00329
00330 std::string nodename;
00331 (*itemiter)->GetStringProperty("name", nodename);
00332 ++itemiter;
00333
00334 float p1 = m_Controls->m_ParamKEdit->text().toFloat();
00335 float p2 = m_Controls->m_ParamPEdit->text().toFloat();
00336
00337
00338 clock.Start();
00339 MBI_INFO << "Computing GFA ";
00340 mitk::StatusBar::GetInstance()->DisplayText(status.sprintf(
00341 "Computing GFA for %s", nodename.c_str()).toAscii());
00342 typedef OdfVectorType::ValueType RealValueType;
00343 typedef itk::Image< RealValueType, 3 > RAImageType;
00344 typedef itk::DiffusionQballGeneralizedFaImageFilter<TOdfPixelType,TOdfPixelType,odfsize>
00345 GfaFilterType;
00346 GfaFilterType::Pointer gfaFilter = GfaFilterType::New();
00347 gfaFilter->SetInput(itkvol);
00348 gfaFilter->SetNumberOfThreads(8);
00349
00350 double scale = 1;
00351 std::string newname;
00352 newname.append(nodename);
00353 switch(method)
00354 {
00355 case 0:
00356 {
00357 gfaFilter->SetComputationMethod(GfaFilterType::GFA_STANDARD);
00358 newname.append("GFA");
00359 scale = m_ScaleDAIValues;
00360 break;
00361 }
00362 case 1:
00363 {
00364 gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILES_HIGH_LOW);
00365 newname.append("01");
00366 scale = m_ScaleDAIValues;
00367 break;
00368 }
00369 case 2:
00370 {
00371 gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILE_HIGH);
00372 newname.append("02");
00373 scale = m_ScaleDAIValues;
00374 break;
00375 }
00376 case 3:
00377 {
00378 gfaFilter->SetComputationMethod(GfaFilterType::GFA_MAX_ODF_VALUE);
00379 newname.append("03");
00380 scale = m_ScaleDAIValues;
00381 break;
00382 }
00383 case 4:
00384 {
00385 gfaFilter->SetComputationMethod(GfaFilterType::GFA_DECONVOLUTION_COEFFS);
00386 newname.append("04");
00387 scale = m_ScaleDAIValues;
00388 break;
00389 }
00390 case 5:
00391 {
00392 gfaFilter->SetComputationMethod(GfaFilterType::GFA_MIN_MAX_NORMALIZED_STANDARD);
00393 newname.append("05");
00394 scale = m_ScaleDAIValues;
00395 break;
00396 }
00397 case 6:
00398 {
00399 gfaFilter->SetComputationMethod(GfaFilterType::GFA_NORMALIZED_ENTROPY);
00400 newname.append("06");
00401 break;
00402 }
00403 case 7:
00404 {
00405 gfaFilter->SetComputationMethod(GfaFilterType::GFA_NEMATIC_ORDER_PARAMETER);
00406 newname.append("07");
00407 scale = m_ScaleDAIValues;
00408 break;
00409 }
00410 case 8:
00411 {
00412 gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILES_LOW_HIGH);
00413 newname.append("08");
00414 scale = m_ScaleDAIValues;
00415 break;
00416 }
00417 case 9:
00418 {
00419 gfaFilter->SetComputationMethod(GfaFilterType::GFA_QUANTILE_LOW);
00420 newname.append("09");
00421 scale = m_ScaleDAIValues;
00422 break;
00423 }
00424 case 10:
00425 {
00426 gfaFilter->SetComputationMethod(GfaFilterType::GFA_MIN_ODF_VALUE);
00427 newname.append("10");
00428 scale = m_ScaleDAIValues;
00429 break;
00430 }
00431 case 11:
00432 {
00433 gfaFilter->SetComputationMethod(GfaFilterType::GFA_STD_BY_MAX);
00434 newname.append("11");
00435 scale = m_ScaleDAIValues;
00436 break;
00437 }
00438 case 12:
00439 {
00440 p1 = m_Controls->MinAngle->text().toFloat();
00441 p2 = m_Controls->MaxAngle->text().toFloat();
00442 gfaFilter->SetComputationMethod(GfaFilterType::GFA_PRINCIPLE_CURVATURE);
00443 QString paramString;
00444 paramString = paramString.append("PC%1-%2").arg(p1).arg(p2);
00445 newname.append(paramString.toAscii());
00446 gfaFilter->SetParam1(p1);
00447 gfaFilter->SetParam2(p2);
00448 scale = m_ScaleDAIValues;
00449 break;
00450 }
00451 case 13:
00452 {
00453 gfaFilter->SetComputationMethod(GfaFilterType::GFA_GENERALIZED_GFA);
00454 QString paramString;
00455 paramString = paramString.append("GFAK%1P%2").arg(p1).arg(p2);
00456 newname.append(paramString.toAscii());
00457 gfaFilter->SetParam1(p1);
00458 gfaFilter->SetParam2(p2);
00459 scale = m_ScaleDAIValues;
00460 break;
00461 }
00462 default:
00463 {
00464 newname.append("0");
00465 gfaFilter->SetComputationMethod(GfaFilterType::GFA_STANDARD);
00466 scale = m_ScaleDAIValues;
00467 }
00468 }
00469 gfaFilter->Update();
00470 clock.Stop();
00471 MBI_DEBUG << "took " << clock.GetMeanTime() << "s.";
00472
00473 typedef itk::Image<TOdfPixelType, 3> ImgType;
00474 ImgType::Pointer img = ImgType::New();
00475 img->SetSpacing( gfaFilter->GetOutput()->GetSpacing() );
00476 img->SetOrigin( gfaFilter->GetOutput()->GetOrigin() );
00477 img->SetDirection( gfaFilter->GetOutput()->GetDirection() );
00478 img->SetLargestPossibleRegion( gfaFilter->GetOutput()->GetLargestPossibleRegion());
00479 img->SetBufferedRegion( gfaFilter->GetOutput()->GetLargestPossibleRegion() );
00480 img->Allocate();
00481 itk::ImageRegionIterator<ImgType> ot (img, img->GetLargestPossibleRegion() );
00482 ot = ot.Begin();
00483 itk::ImageRegionConstIterator<GfaFilterType::OutputImageType> it
00484 (gfaFilter->GetOutput(), gfaFilter->GetOutput()->GetLargestPossibleRegion() );
00485 it = it.Begin();
00486
00487 for (it = it.Begin(); !it.IsAtEnd(); ++it)
00488 {
00489 GfaFilterType::OutputImageType::PixelType val = it.Get();
00490 ot.Set(val * scale);
00491 ++ot;
00492 }
00493
00494
00495
00496 mitk::Image::Pointer image = mitk::Image::New();
00497 image->InitializeByItk( img.GetPointer() );
00498 image->SetVolume( img->GetBufferPointer() );
00499 mitk::DataNode::Pointer node=mitk::DataNode::New();
00500 node->SetData( image );
00501 node->SetProperty( "name", mitk::StringProperty::New(newname) );
00502 nodes.push_back(node);
00503
00504 mitk::StatusBar::GetInstance()->DisplayText("Computation complete.");
00505
00506 }
00507
00508 std::vector<mitk::DataNode::Pointer>::iterator nodeIt;
00509 for(nodeIt = nodes.begin(); nodeIt != nodes.end(); ++nodeIt)
00510 GetDefaultDataStorage()->Add(*nodeIt);
00511
00512 m_MultiWidget->RequestUpdate();
00513
00514 }
00515
00516 void QmitkDiffusionQuantificationView::TensorQuantification(
00517 mitk::DataStorage::SetOfObjects::Pointer inImages, int method)
00518 {
00519 itk::TimeProbe clock;
00520 QString status;
00521
00522 int nrFiles = inImages->size();
00523 if (!nrFiles) return;
00524
00525 mitk::DataStorage::SetOfObjects::const_iterator itemiter( inImages->begin() );
00526 mitk::DataStorage::SetOfObjects::const_iterator itemiterend( inImages->end() );
00527
00528 std::vector<mitk::DataNode::Pointer> nodes;
00529 while ( itemiter != itemiterend )
00530 {
00531
00532 typedef float TTensorPixelType;
00533 typedef itk::DiffusionTensor3D< TTensorPixelType > TensorPixelType;
00534 typedef itk::Image< TensorPixelType, 3 > TensorImageType;
00535
00536 mitk::Image* vol =
00537 static_cast<mitk::Image*>((*itemiter)->GetData());
00538 TensorImageType::Pointer itkvol = TensorImageType::New();
00539 mitk::CastToItkImage<TensorImageType>(vol, itkvol);
00540
00541 std::string nodename;
00542 (*itemiter)->GetStringProperty("name", nodename);
00543 ++itemiter;
00544
00545
00546 clock.Start();
00547 MBI_INFO << "Computing FA ";
00548 mitk::StatusBar::GetInstance()->DisplayText(status.sprintf(
00549 "Computing FA for %s", nodename.c_str()).toAscii());
00550 typedef itk::Image< TTensorPixelType, 3 > FAImageType;
00551
00552 typedef itk::ShiftScaleImageFilter<FAImageType, FAImageType>
00553 ShiftScaleFilterType;
00554 ShiftScaleFilterType::Pointer multi =
00555 ShiftScaleFilterType::New();
00556 multi->SetShift(0.0);
00557 multi->SetScale(m_ScaleDAIValues);
00558
00559 typedef itk::TensorDerivedMeasurementsFilter<TTensorPixelType> MeasurementsType;
00560
00561 if(method == 0)
00562 {
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572 MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
00573 measurementsCalculator->SetInput(itkvol.GetPointer() );
00574 measurementsCalculator->SetMeasure(MeasurementsType::FA);
00575 measurementsCalculator->Update();
00576 multi->SetInput(measurementsCalculator->GetOutput());
00577 nodename = QString(nodename.c_str()).append("_FA").toStdString();
00578
00579 }
00580 else if(method == 1)
00581 {
00582
00583
00584
00585
00586
00587
00588
00589
00590 MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
00591 measurementsCalculator->SetInput(itkvol.GetPointer() );
00592 measurementsCalculator->SetMeasure(MeasurementsType::RA);
00593 measurementsCalculator->Update();
00594 multi->SetInput(measurementsCalculator->GetOutput());
00595 nodename = QString(nodename.c_str()).append("_RA").toStdString();
00596
00597 }
00598 else if(method == 2)
00599 {
00600 MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
00601 measurementsCalculator->SetInput(itkvol.GetPointer() );
00602 measurementsCalculator->SetMeasure(MeasurementsType::AD);
00603 measurementsCalculator->Update();
00604 multi->SetInput(measurementsCalculator->GetOutput());
00605 nodename = QString(nodename.c_str()).append("_AD").toStdString();
00606 }
00607 else if(method == 3)
00608 {
00609 MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
00610 measurementsCalculator->SetInput(itkvol.GetPointer() );
00611 measurementsCalculator->SetMeasure(MeasurementsType::RD);
00612 measurementsCalculator->Update();
00613 multi->SetInput(measurementsCalculator->GetOutput());
00614 nodename = QString(nodename.c_str()).append("_RD").toStdString();
00615 }
00616 else if(method == 4)
00617 {
00618 MeasurementsType::Pointer measurementsCalculator = MeasurementsType::New();
00619 measurementsCalculator->SetInput(itkvol.GetPointer() );
00620 measurementsCalculator->SetMeasure(MeasurementsType::CA);
00621 measurementsCalculator->Update();
00622 multi->SetInput(measurementsCalculator->GetOutput());
00623 nodename = QString(nodename.c_str()).append("_CA").toStdString();
00624 }
00625
00626 multi->Update();
00627 clock.Stop();
00628 MBI_DEBUG << "took " << clock.GetMeanTime() << "s.";
00629
00630
00631 mitk::Image::Pointer image = mitk::Image::New();
00632 image->InitializeByItk( multi->GetOutput() );
00633 image->SetVolume( multi->GetOutput()->GetBufferPointer() );
00634 mitk::DataNode::Pointer node=mitk::DataNode::New();
00635 node->SetData( image );
00636 node->SetProperty( "name", mitk::StringProperty::New(nodename) );
00637 nodes.push_back(node);
00638
00639 mitk::StatusBar::GetInstance()->DisplayText("Computation complete.");
00640
00641 }
00642
00643 std::vector<mitk::DataNode::Pointer>::iterator nodeIt;
00644 for(nodeIt = nodes.begin(); nodeIt != nodes.end(); ++nodeIt)
00645 GetDefaultDataStorage()->Add(*nodeIt);
00646
00647 m_MultiWidget->RequestUpdate();
00648
00649 }