Fraxinus  16.5.0-fx-rc9
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxTubeSegmentationFilterService.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 
34 
35 #include "tube-segmentation.hpp"
36 #include "tsf-config.h"
37 #include "Exceptions.hpp"
38 
39 #include <QTimer>
40 
41 #include <vtkImageImport.h>
42 #include <vtkImageData.h>
43 #include <vtkImageShiftScale.h>
44 #include <ctkPluginContext.h>
45 
46 #include "cxTime.h"
47 #include "cxTypeConversions.h"
48 #include "cxLogger.h"
49 #include "cxDataReaderWriter.h"
51 #include "cxDoubleProperty.h"
52 #include "cxContourFilter.h"
53 #include "cxDataLocations.h"
55 #include "cxTSFPresets.h"
56 #include "vtkForwardDeclarations.h"
58 #include "cxVisServices.h"
59 
60 namespace cx {
61 
62 TubeSegmentationFilter::TubeSegmentationFilter(ctkPluginContext *pluginContext) :
63  FilterImpl(VisServices::create(pluginContext)), mOutput(NULL)
64 {
65  connect(patientService().get(), SIGNAL(patientChanged()), this, SLOT(patientChangedSlot()));
66  mPresets = this->populatePresets();
67 }
68 
70 {
71  return "Tube-Segmentation Filter";
72 }
73 
75 {
76  return "TubeSegmentationFilter";
77 }
78 
80 {
81  return "<html>"
82  "<h3>Tube-Segmentation.</h3>"
83  "<p><i>Extracts the centerline and creates a segmentation. </br>GPU-based algorithm written by Erik Smistad (NTNU).</i></p>"
84  "</html>";
85 }
86 
88 {
89  return true;
90 }
91 
93 {
94  return mPresets;
95 }
96 
98 {
99  std::vector<PropertyPtr> newPresetOptions = this->getNotDefaultOptions();
100 
101  std::map<QString, QString> newPresetMap;
102  std::vector<PropertyPtr>::iterator it;
103  for(it = newPresetOptions.begin(); it != newPresetOptions.end(); ++it){
104  PropertyPtr option = *it;
105  QString valuename = option->getDisplayName();
106  QString value;
107  StringPropertyPtr stringOption = boost::dynamic_pointer_cast<StringProperty>(option);
108  BoolPropertyPtr boolOption = boost::dynamic_pointer_cast<BoolProperty>(option);
109  DoublePropertyPtr doubleOption = boost::dynamic_pointer_cast<DoubleProperty>(option);
110  if(stringOption)
111  value = stringOption->getValue();
112  else if(boolOption)
113  value = boolOption->getValue() ? "true" : "false";
114  else if(doubleOption)
115  value = QString::number(doubleOption->getValue());
116  else
117  reportError("Could not determine what kind of option to get the value for.");
118  newPresetMap[valuename] = value;
119  }
120  StringPropertyBasePtr centerlineMethod = this->getStringOption("centerline-method");
121  newPresetMap[centerlineMethod->getDisplayName()] = centerlineMethod->getValue();
122 
123  //create xml
124  QDomElement retval = TSFPresets::createPresetElement(name, newPresetMap);
125 
126  return retval;
127 }
128 
130 {
131  QString centerLineMethod = "gpu";
132  if((name == "<Default preset>") || (name == "none") || (name == "default") || (name == "Default"))
133  mParameterFile = "none";
134  else
135  {
136  mParameterFile = name;
137  }
138  this->loadNewParametersSlot();
139 
140  StringPropertyPtr centerlineMethodOption = this->getStringOption("centerline-method");
141  centerlineMethodOption->setValue(centerLineMethod);
142 }
143 
145 {
146  ImagePtr input = this->getCopiedInputImage();
147  if (!input)
148  return false;
149 
150  mParameters = this->getParametersFromOptions();
151  std::string filename = (patientService()->getActivePatientFolder()+"/"+input->getFilename()).toStdString();
152 
153  try {
154  std::cout << "=================TSF START====================" << std::endl;
155  std::cout << "Input: " << input->getName().toStdString() << std::endl;
156  std::cout << "Preset: " << getParamStr(mParameters, "parameters") << std::endl;
157  std::cout << "Centerline-method: " << getParamStr(mParameters, "centerline-method") << std::endl;
158  QString kernelDir = cx::DataLocations::findConfigFolder("/tsf", KERNELS_DIR);
159  QString oulDir = cx::DataLocations::findConfigFolder("/tsf", OUL_DIR);
160  std::cout << "Kernel paths: " << kernelDir.toStdString();
161  std::cout << " and " << oulDir.toStdString() << std::endl;
162  std::cout << "--------------" << std::endl;
163  mOutput = run(filename, mParameters, kernelDir.toStdString(), oulDir.toStdString());
164  std::cout << "=================TSF END====================" << std::endl;
165  } catch(SIPL::SIPLException& e) {
166  std::string error = e.what();
167  reportError("SIPL::SIPLException: "+qstring_cast(error));
168 
169  if(mOutput != NULL){
170  delete mOutput;
171  mOutput = NULL;
172  }
173  return false;
174  } catch(cl::Error& e) {
175  reportError("cl::Error:"+qstring_cast(e.what()));
176 
177  if(mOutput != NULL){
178  delete mOutput;
179  mOutput = NULL;
180  }
181  return false;
182  } catch (std::exception& e){
183  reportError("std::exception:"+qstring_cast(e.what()));
184 
185  if(mOutput != NULL){
186  delete mOutput;
187  mOutput = NULL;
188  }
189  return false;
190  } catch (...){
191  reportError("Tube segmentation algorithm threw a unknown exception.");
192 
193  if(mOutput != NULL){
194  delete mOutput;
195  mOutput = NULL;
196  }
197  return false;
198  }
199  return true;
200 }
201 
203 {
204  if(!mOutput)
205  {
206  reportWarning("No output generated from the tube segmentation filter.");
207  return false;
208  }
209 
210  ImagePtr inputImage = this->getCopiedInputImage();
211  if (!inputImage)
212  return false;
213 
214  double inputImageSpacing_x, inputImageSpacing_y, inputImageSpacing_z;
215  inputImage->getBaseVtkImageData()->GetSpacing(inputImageSpacing_x, inputImageSpacing_y, inputImageSpacing_z);
216 
217  //compensate for cropping
218  SIPL::int3 voxelsCropped = mOutput->getShiftVector();
219  Vector3D croppingVectorInInpuImageSpace((inputImageSpacing_x*voxelsCropped.x), (inputImageSpacing_y*voxelsCropped.y), (inputImageSpacing_z*voxelsCropped.z));
220  Transform3D d_iMd_c = createTransformTranslate(croppingVectorInInpuImageSpace); //dc = data cropped, di = data input
221  Transform3D rMd_i = inputImage->get_rMd(); //transform from the volumes coordinate system to our reference coordinate system
222  Transform3D rMd_c = rMd_i * d_iMd_c; //translation due to cropping accounted for
223 
224  // Centerline (volume)
225  //======================================================
226  if(mOutput->hasCenterlineVoxels())
227  {
228  QString uidCenterline = inputImage->getUid() + "_tsf_cl_vol%1";
229  QString nameCenterline = inputImage->getName()+"_tsf_cl_vol%1";
230  SIPL::int3* size = mOutput->getSize();
231  vtkImageDataPtr rawCenterlineResult = this->convertToVtkImageData(mOutput->getCenterlineVoxels(), size->x, size->y, size->z, inputImage);
232  if(!rawCenterlineResult)
233  return false;
234 
235 // ImagePtr outputCenterline = patientService()->createDerivedImage(rawCenterlineResult ,uidCenterline, nameCenterline, inputImage);
236  ImagePtr outputCenterline = patientService()->createSpecificData<Image>(uidCenterline, nameCenterline);
237  outputCenterline->intitializeFromParentImage(inputImage);
238  outputCenterline->setVtkImageData(rawCenterlineResult);
239 
240  if (!outputCenterline)
241  return false;
242 
243  outputCenterline->get_rMd_History()->setRegistration(rMd_c);
244 
245  patientService()->insertData(outputCenterline);
246 // dataManager()->loadData(outputCenterline);
247 // dataManager()->saveImage(outputCenterline, patientService()->getPatientData()->getActivePatientFolder());
248 
249  mOutputTypes[0]->setValue(outputCenterline->getUid());
250  }
251 
252  // Centerline (vtk)
253  //======================================================
254  boost::unordered_map<std::string, StringParameter>::iterator it = mParameters.strings.find("centerline-vtk-file");
255  if(it != mParameters.strings.end() && (it->second.get() != "off"))
256  {
257  QString tsfVtkFilename = qstring_cast(it->second.get());
258  QString uidVtkCenterline = inputImage->getUid() + "_tsf_cl%1";
259  QString nameVtkCenterline = inputImage->getName()+"_tsf_cl%1";
260 
261  //load vtk file created by tsf into CustusX
262  MeshPtr tsfMesh = this->loadVtkFile(tsfVtkFilename, uidVtkCenterline);
263 
264  Vector3D inpuImageSpacing(inputImageSpacing_x, inputImageSpacing_y, inputImageSpacing_z);
265  Transform3D dMv = createTransformScale(inpuImageSpacing); // transformation from voxelspace to imagespace
266 
267  Transform3D rMv = rMd_c*dMv;
268 
269  vtkPolyDataPtr poly = tsfMesh->getTransformedPolyData(rMv);
270 
271  //create, load and save mesh
272  MeshPtr cxMesh = patientService()->createSpecificData<Mesh>(uidVtkCenterline, nameVtkCenterline);
273  cxMesh->setVtkPolyData(poly);
274  cxMesh->get_rMd_History()->setParentSpace(inputImage->getUid());
275  patientService()->insertData(cxMesh);
276 // dataManager()->loadData(cxMesh);
277 // dataManager()->saveMesh(cxMesh, patientService()->getPatientData()->getActivePatientFolder());
278  QString uid = cxMesh->getUid();
279 
280  mOutputTypes[1]->setValue(uid);
281  }
282 
283  // Segmentation
284  //======================================================
285  if(mOutput->hasSegmentation())
286  {
287  //get segmented volume
288  SIPL::int3* size = mOutput->getSize();
289  vtkImageDataPtr rawSegmentation = this->convertToVtkImageData(mOutput->getSegmentation(), size->x, size->y, size->z, inputImage);
290 
291  //make contour of segmented volume
292  double threshold = 1;
293  vtkPolyDataPtr rawContour = ContourFilter::execute(rawSegmentation, threshold);
294 
295  //add segmentation internally to cx
296  QString uidSegmentation = inputImage->getUid() + "_tsf_seg%1";
297  QString nameSegmentation = inputImage->getName()+"_tsf_seg%1";
298 
299  ImagePtr outputSegmentation = patientService()->createSpecificData<Image>(uidSegmentation, nameSegmentation);
300  outputSegmentation->intitializeFromParentImage(inputImage);
301  outputSegmentation->setVtkImageData(rawSegmentation);
302 // ImagePtr outputSegmentation = dataManager()->createDerivedImage(rawSegmentation,uidSegmentation, nameSegmentation, inputImage);
303  if (!outputSegmentation)
304  return false;
305 
306  outputSegmentation->get_rMd_History()->setRegistration(rMd_c);
307  patientService()->insertData(outputSegmentation);
308 // dataManager()->loadData(outputSegmentation);
309 // dataManager()->saveImage(outputSegmentation, patientService()->getPatientData()->getActivePatientFolder());
310 
311  //add contour internally to cx
312  MeshPtr contour = ContourFilter::postProcess(patientService(), rawContour, inputImage, QColor("blue"));
313  contour->get_rMd_History()->setRegistration(rMd_c);
314 
315  //set output
316  mOutputTypes[2]->setValue(outputSegmentation->getUid());
317  mOutputTypes[3]->setValue(contour->getUid());
318  }
319 
320  // TDF
321  //======================================================
322  if(mOutput->hasTDF())
323  {
324  QString uidTDF = inputImage->getUid() + "_tsf_tdf%1";
325  QString nameTDF = inputImage->getName()+"_tsf_tdf%1";
326  SIPL::int3* size = mOutput->getSize();
327 
328  // convert volume
329  vtkImageDataPtr convertedImageData = this->convertToVtkImageData(mOutput->getTDF(), size->x, size->y, size->z, inputImage);
330 
331  //scale volume
332  if (!convertedImageData)
333  return false;
334 
335  vtkImageShiftScalePtr cast = vtkImageShiftScalePtr::New();
336  cast->SetInputData(convertedImageData);
337  cast->ClampOverflowOn();
338 
339  //tdfs voxels contains values [0.0,1.0]
340  //scaling these to be able to visualize them in CustusX
341  int scale = 255; //unsigned char ranges from 0 to 255
342  cast->SetScale(scale);
343  cast->SetOutputScalarType(VTK_UNSIGNED_CHAR);
344  cast->Update();
345  convertedImageData = cast->GetOutput();
346 
347 // ImagePtr outputTDF = dataManager()->createDerivedImage(convertedImageData,uidTDF, nameTDF, inputImage);
348  ImagePtr outputTDF = patientService()->createSpecificData<Image>(uidTDF, nameTDF);
349  outputTDF->intitializeFromParentImage(inputImage);
350  outputTDF->setVtkImageData(convertedImageData);
351 
352 
353  if (!outputTDF)
354  return false;
355 
356  rMd_i = rMd_i * d_iMd_c; //translation due to cropping accounted for
357  outputTDF->get_rMd_History()->setRegistration(rMd_i);
358  patientService()->insertData(outputTDF);
359 // dataManager()->loadData(outputTDF);
360 // dataManager()->saveImage(outputTDF, patientService()->getPatientData()->getActivePatientFolder());
361 
362  mOutputTypes[4]->setValue(outputTDF->getUid());
363  }
364 
365  //clean up
366  if(mOutput != NULL){
367  delete mOutput;
368  mOutput = NULL;
369  }
370 
371  return true;
372 }
373 
375 {
376  this->createDefaultOptions(mOptions);
377 
378  std::vector<StringPropertyPtr>::iterator stringIt;
379  for(stringIt = mStringOptions.begin(); stringIt != mStringOptions.end(); ++stringIt)
380  mOptionsAdapters.push_back(*stringIt);
381 
382  std::vector<BoolPropertyPtr>::iterator boolIt;
383  for(boolIt = mBoolOptions.begin(); boolIt != mBoolOptions.end(); ++boolIt)
384  mOptionsAdapters.push_back(*boolIt);
385 
386  std::vector<DoublePropertyPtr>::iterator doubleIt;
387  for(doubleIt = mDoubleOptions.begin(); doubleIt != mDoubleOptions.end(); ++doubleIt)
388  mOptionsAdapters.push_back(*doubleIt);
389 }
390 
392 {
394 
396  temp->setValueName("Input");
397  temp->setHelp("Select input to run Tube segmentation on.");
398  mInputTypes.push_back(temp);
399 
400  connect(temp.get(), SIGNAL(changed()), this, SLOT(inputChangedSlot()));
401 }
402 
404 {
405  SelectDataStringPropertyBasePtr tempDataStringAdapter;
406  StringPropertySelectMeshPtr tempMeshStringAdapter;
407 
408  //0
409  tempDataStringAdapter = StringPropertySelectData::New(patientService());
410  tempDataStringAdapter->setValueName("Centerline volume");
411  tempDataStringAdapter->setHelp("Generated centerline volume.");
412  mOutputTypes.push_back(tempDataStringAdapter);
413 
414  //1
415  tempMeshStringAdapter = StringPropertySelectMesh::New(patientService());
416  tempMeshStringAdapter->setValueName("Centerline mesh");
417  tempMeshStringAdapter->setHelp("Generated centerline mesh (vtk-format).");
418  mOutputTypes.push_back(tempMeshStringAdapter);
419 
420  //2
421  tempDataStringAdapter = StringPropertySelectData::New(patientService());
422  tempDataStringAdapter->setValueName("Segmented centerline");
423  tempDataStringAdapter->setHelp("Grown segmentation from the centerline.");
424  mOutputTypes.push_back(tempDataStringAdapter);
425 
426  //3
427  tempMeshStringAdapter = StringPropertySelectMesh::New(patientService());
428  tempMeshStringAdapter->setValueName("Segmented centerlines surface");
429  tempMeshStringAdapter->setHelp("Generated surface of the segmented volume.");
430  mOutputTypes.push_back(tempMeshStringAdapter);
431 
432  //4
433  tempDataStringAdapter = StringPropertySelectData::New(patientService());
434  tempDataStringAdapter->setValueName("TDF volume");
435  tempDataStringAdapter->setHelp("Volume showing the probability of a voxel being part of a tubular structure.");
436  mOutputTypes.push_back(tempDataStringAdapter);
437 }
438 
439 void TubeSegmentationFilter::patientChangedSlot()
440 {
441  QString activePatientFolder = patientService()->getActivePatientFolder()+"/Images/";
442 
443  StringPropertyPtr option = this->getStringOption("storage-dir");
444  if(option)
445  option->setValue(activePatientFolder);
446 }
447 
448 void TubeSegmentationFilter::inputChangedSlot()
449 {
450  QString activePatientFolder = patientService()->getActivePatientFolder()+"/Images/";
451  QString inputsValue = mInputTypes.front()->getValue();
452 
453  StringPropertyPtr option = this->getStringOption("centerline-vtk-file");
454  if(option)
455  option->setValue(activePatientFolder+inputsValue+QDateTime::currentDateTime().toString(timestampSecondsFormat())+"_tsf_vtk.vtk");
456 }
457 
458 void TubeSegmentationFilter::loadNewParametersSlot()
459 {
460  paramList list = this->getDefaultParameters();
461 
462  if(mParameterFile != "none")
463  {
464  try
465  {
466  setParameter(list, "parameters", mParameterFile.toStdString());
467  loadParameterPreset(list, cx::DataLocations::findConfigFolder("/tsf", QString(KERNELS_DIR)).toStdString()+"/parameters");
468  } catch (SIPL::SIPLException& e)
469  {
470  reportWarning("Error when loading a parameter file. Preset is corrupt. "+QString(e.what()));
471  return;
472  }
473  }
474 
475  blockSignals(true);
476  this->setOptionsSlot(list);
477  this->resetOptionsAdvancedSlot();
478  //set parameters found in the parameter file as not advanced
479  std::vector<std::string> notDefaultOptions = this->getNotDefault(list);
480  std::vector<std::string>::iterator it;
481  for(it = notDefaultOptions.begin() ;it != notDefaultOptions.end(); ++it)
482  {
483  this->getOption(qstring_cast(*it))->setAdvanced(false);
484  }
485  blockSignals(false);
486 
487  emit changed();
488 }
489 
490 void TubeSegmentationFilter::resetOptionsAdvancedSlot()
491 {
492  std::vector<StringPropertyPtr>::iterator stringIt;
493  for(stringIt = mStringOptions.begin(); stringIt != mStringOptions.end(); ++stringIt)
494  {
495  StringPropertyPtr adapter = *stringIt;
496  if(adapter->getDisplayName() == "parameters")
497  {
498  adapter->setAdvanced(false);
499  }
500  else
501  adapter->setAdvanced(true);
502  }
503 
504  std::vector<BoolPropertyPtr>::iterator boolIt;
505  for(boolIt = mBoolOptions.begin(); boolIt != mBoolOptions.end(); ++boolIt)
506  {
507  BoolPropertyPtr adapter = *boolIt;
508  adapter->setAdvanced(true);
509  }
510 
511  std::vector<DoublePropertyPtr>::iterator doubleIt;
512  for(doubleIt = mDoubleOptions.begin(); doubleIt != mDoubleOptions.end(); ++doubleIt)
513  {
514  DoublePropertyPtr adapter = *doubleIt;
515  adapter->setAdvanced(true);
516  }
517 }
518 
519 void TubeSegmentationFilter::resetOptionsSlot()
520 {
521  paramList defaultParameters = this->getDefaultParameters();
522  this->resetOptionsAdvancedSlot();
523  this->setOptionsSlot(defaultParameters);
524 }
525 
526 void TubeSegmentationFilter::setOptionsSlot(paramList& list)
527 {
528  this->setParamtersToOptions(list);
529  this->patientChangedSlot();
530  this->inputChangedSlot();
531  emit changed();
532 }
533 
534 vtkImageDataPtr TubeSegmentationFilter::convertToVtkImageData(char * data, int size_x, int size_y, int size_z, ImagePtr input)
535 {
536  if (!input)
537  return vtkImageDataPtr::New();
538 
539  vtkImageDataPtr retval = this->importRawImageData((void*) data, size_x, size_y, size_z, input, VTK_UNSIGNED_CHAR);
540  return retval;
541 }
542 
543 vtkImageDataPtr TubeSegmentationFilter::convertToVtkImageData(float * data, int size_x, int size_y, int size_z, ImagePtr input)
544 {
545  if (!input)
546  return vtkImageDataPtr::New();
547 
548  vtkImageDataPtr retval = this->importRawImageData((void*) data, size_x, size_y, size_z, input, VTK_FLOAT);
549  return retval;
550 }
551 
552 //From vtkType.h (on Ubuntu 12.04)
553 //#define VTK_VOID 0
554 //#define VTK_BIT 1
555 //#define VTK_CHAR 2
556 //#define VTK_SIGNED_CHAR 15
557 //#define VTK_UNSIGNED_CHAR 3
558 //#define VTK_SHORT 4
559 //#define VTK_UNSIGNED_SHORT 5
560 //#define VTK_INT 6
561 //#define VTK_UNSIGNED_INT 7
562 //#define VTK_LONG 8
563 //#define VTK_UNSIGNED_LONG 9
564 //#define VTK_FLOAT 10
565 //#define VTK_DOUBLE 11
566 //#define VTK_ID_TYPE 12
567 vtkImageDataPtr TubeSegmentationFilter::importRawImageData(void * data, int size_x, int size_y, int size_z, ImagePtr input, int type)
568 {
569  vtkImageImportPtr imageImport = vtkImageImportPtr::New();
570 
571  imageImport->SetWholeExtent(0, size_x - 1, 0, size_y - 1, 0, size_z - 1);
572  imageImport->SetDataExtentToWholeExtent();
573  imageImport->SetDataScalarType(type);
574  imageImport->SetNumberOfScalarComponents(1);
575  imageImport->SetDataSpacing(input->getBaseVtkImageData()->GetSpacing());
576  imageImport->SetImportVoidPointer(data);
577 // imageImport->GetOutput()->Update();
578  imageImport->Update();
579  imageImport->Modified();
580 
581  vtkImageDataPtr retval = vtkImageDataPtr::New();
582  retval->DeepCopy(imageImport->GetOutput());
583 
584  return retval;
585 }
586 
587 MeshPtr TubeSegmentationFilter::loadVtkFile(QString pathToFile, QString newDatasUid){
588  PolyDataMeshReader reader;
589  DataPtr data;
590  if(reader.canLoad("vtk", pathToFile))
591  data = reader.load(newDatasUid, pathToFile);
592 
593  MeshPtr retval = boost::dynamic_pointer_cast<Mesh>(data);
594 
595  if(!data || !retval)
596  reportError("Could not load "+pathToFile);
597 
598  return retval;
599 }
600 
601 void TubeSegmentationFilter::createDefaultOptions(QDomElement root)
602 {
603  //get list with default options
604  paramList defaultOptions = this->getDefaultParameters();
605 
606  //generate string adapters
607  boost::unordered_map<std::string, StringParameter>::iterator stringIt;
608  for(stringIt = defaultOptions.strings.begin(); stringIt != defaultOptions.strings.end(); ++stringIt )
609  {
610  StringPropertyPtr option = this->makeStringOption(root, stringIt->first, stringIt->second);
611  option->setAdvanced(true);
612  option->setGroup(qstring_cast(stringIt->second.getGroup()));
613  mStringOptions.push_back(option);
614  if(stringIt->first == "parameters")
615  option->setEnabled(false);
616  option->setAdvanced(true);
617  }
618 
619  //generate bool adapters
620  boost::unordered_map<std::string, BoolParameter>::iterator boolIt;
621  for(boolIt = defaultOptions.bools.begin(); boolIt != defaultOptions.bools.end(); ++boolIt )
622  {
623  BoolPropertyPtr option = this->makeBoolOption(root, boolIt->first, boolIt->second);
624  option->setAdvanced(true);
625  option->setGroup(qstring_cast(boolIt->second.getGroup()));
626  mBoolOptions.push_back(option);
627  }
628 
629  //generate double adapters
630  boost::unordered_map<std::string, NumericParameter>::iterator numericIt;
631  for(numericIt = defaultOptions.numerics.begin(); numericIt != defaultOptions.numerics.end(); ++numericIt )
632  {
633  DoublePropertyPtr option = this->makeDoubleOption(root, numericIt->first, numericIt->second);
634  option->setAdvanced(true);
635  option->setGroup(qstring_cast(numericIt->second.getGroup()));
636  mDoubleOptions.push_back(option);
637  }
638 }
639 
640 paramList TubeSegmentationFilter::getParametersFromOptions()
641 {
642  paramList retval = this->getDefaultParameters();
643 
644  std::vector<StringPropertyPtr>::iterator stringIt;
645  for(stringIt = mStringOptions.begin(); stringIt != mStringOptions.end(); ++stringIt)
646  {
647  try{
648  setParameter(retval, stringIt->get()->getDisplayName().toStdString(), stringIt->get()->getValue().toStdString());
649  }catch(SIPL::SIPLException& e){
650  std::string message = "Could not process a string parameter: \""+std::string(e.what())+"\"";
651  reportError(qstring_cast(message));
652  continue;
653  }
654  }
655 
656  std::vector<BoolPropertyPtr>::iterator boolIt;
657  for(boolIt = mBoolOptions.begin(); boolIt != mBoolOptions.end(); ++boolIt)
658  {
659  try{
660  std::string value = boolIt->get()->getValue() ? "true" : "false";
661  setParameter(retval, boolIt->get()->getDisplayName().toStdString(), value);
662  }catch(SIPL::SIPLException& e){
663  std::string message = "Could not process a bool parameter: \""+std::string(e.what())+"\"";
664  reportError(qstring_cast(message));
665  continue;
666  }
667  }
668 
669  std::vector<DoublePropertyPtr>::iterator doubleIt;
670  for(doubleIt = mDoubleOptions.begin(); doubleIt != mDoubleOptions.end(); ++doubleIt)
671  {
672  try{
673  double dbl = doubleIt->get()->getValue();
674  std::string value = boost::lexical_cast<std::string>(dbl);
675  setParameter(retval, doubleIt->get()->getDisplayName().toStdString(), value);
676  }catch(SIPL::SIPLException& e){
677  std::string message = "Could not process a double parameter: \""+std::string(e.what())+"\"";
678  reportError(qstring_cast(message));
679  continue;
680  }
681  }
682  return retval;
683 }
684 void TubeSegmentationFilter::setParamtersToOptions(paramList& parameters)
685 {
686  //set string adapters
687  boost::unordered_map<std::string, StringParameter>::iterator stringIt;
688  for(stringIt = parameters.strings.begin(); stringIt != parameters.strings.end(); ++stringIt )
689  this->setOptionValue(qstring_cast(stringIt->first),qstring_cast(stringIt->second.get()));
690 
691  //set bool adapters
692  boost::unordered_map<std::string, BoolParameter>::iterator boolIt;
693  for(boolIt = parameters.bools.begin(); boolIt != parameters.bools.end(); ++boolIt )
694  this->setOptionValue(qstring_cast(boolIt->first),qstring_cast(boolIt->second.get()));
695 
696  //set double adapters
697  boost::unordered_map<std::string, NumericParameter>::iterator numericIt;
698  for(numericIt = parameters.numerics.begin(); numericIt != parameters.numerics.end(); ++numericIt )
699  this->setOptionValue(qstring_cast(numericIt->first),qstring_cast(numericIt->second.get()));
700 }
701 
702 StringPropertyPtr TubeSegmentationFilter::getStringOption(QString valueName)
703 {
704  StringPropertyPtr retval;
705  std::vector<StringPropertyPtr>::iterator stringIt;
706  for(stringIt = mStringOptions.begin(); stringIt != mStringOptions.end(); ++stringIt)
707  {
708  if(stringIt->get()->getDisplayName().compare(valueName) == 0)
709  {
710  retval = *stringIt;
711  return retval;
712  }
713  }
714  return retval;
715 }
716 
717 BoolPropertyPtr TubeSegmentationFilter::getBoolOption(QString valueName)
718 {
719  BoolPropertyPtr retval;
720  std::vector<BoolPropertyPtr>::iterator boolIt;
721  for(boolIt = mBoolOptions.begin(); boolIt != mBoolOptions.end(); ++boolIt)
722  {
723  if(boolIt->get()->getDisplayName().compare(valueName) == 0)
724  {
725  retval = *boolIt;
726  return retval;
727  }
728  }
729  return retval;
730 }
731 
732 DoublePropertyPtr TubeSegmentationFilter::getDoubleOption(QString valueName)
733 {
734  DoublePropertyPtr retval;
735  std::vector<DoublePropertyPtr>::iterator doubleIt;
736  for(doubleIt = mDoubleOptions.begin(); doubleIt != mDoubleOptions.end(); ++doubleIt)
737  {
738  if(doubleIt->get()->getDisplayName().compare(valueName) == 0)
739  {
740  retval = *doubleIt;
741  return retval;
742  }
743  }
744  return retval;
745 }
746 
747 PropertyPtr TubeSegmentationFilter::getOption(QString valueName)
748 {
749  PropertyPtr retval;
750 
751  retval = getStringOption(valueName);
752  if(retval)
753  return retval;
754  retval = getBoolOption(valueName);
755  if(retval)
756  return retval;
757  retval = getDoubleOption(valueName);
758  if(retval)
759  return retval;
760 
761  return retval;
762 }
763 
764 void TubeSegmentationFilter::setOptionAdvanced(QString valueName, bool advanced)
765 {
766  PropertyPtr option = this->getOption(valueName);
767  option->setAdvanced(advanced);
768 }
769 
770 void TubeSegmentationFilter::setOptionValue(QString valueName, QString value)
771 {
772  PropertyPtr option = this->getOption(valueName);
773  if(!option)
774  return;
775 
776  StringPropertyPtr stringOption = boost::dynamic_pointer_cast<StringProperty>(option);
777  BoolPropertyPtr boolOption = boost::dynamic_pointer_cast<BoolProperty>(option);
778  DoublePropertyPtr doubleOption = boost::dynamic_pointer_cast<DoubleProperty>(option);
779  if(stringOption)
780  {
781  stringOption->setValue(value);
782  }
783  else if(boolOption)
784  {
785  bool boolValue = (value.compare("1") == 0) ? true : false;
786  boolOption->setValue(boolValue);
787  }
788  else if(doubleOption)
789  {
790  doubleOption->setValue(value.toDouble());
791  }
792  else
793  {
794  reportError("Could not determine what kind of option to set the value for.");
795  return;
796  }
797 }
798 
799 std::vector<std::string> TubeSegmentationFilter::getNotDefault(paramList list)
800 {
801  return this->getDifference(this->getDefaultParameters(), list);
802 }
803 
804 std::vector<std::string> TubeSegmentationFilter::getDifference(paramList list1, paramList list2)
805 {
806  std::vector<std::string> retval;
807  try{
808  boost::unordered_map<std::string, StringParameter>::iterator stringIt;
809  for(stringIt = list1.strings.begin(); stringIt != list1.strings.end(); ++stringIt )
810  {
811  std::string name = stringIt->first;
812  if(getParamStr(list1, name) != getParamStr(list2, name))
813  retval.push_back(name);
814  }
815  boost::unordered_map<std::string, BoolParameter>::iterator boolIt;
816  for(boolIt = list1.bools.begin(); boolIt != list1.bools.end(); ++boolIt )
817  {
818  std::string name = boolIt->first;
819  if(getParamBool(list1, name) != getParamBool(list2, name))
820  retval.push_back(name);
821  }
822  boost::unordered_map<std::string, NumericParameter>::iterator numericIt;
823  for(numericIt = list1.numerics.begin(); numericIt != list1.numerics.end(); ++numericIt )
824  {
825  std::string name = numericIt->first;
826  if(getParam(list1, name) != getParam(list2, name))
827  retval.push_back(name);
828  }
829 
830  }catch (SIPL::SIPLException& e){
831  reportError(QString(e.what()));
832  }
833  return retval;
834 
835 }
836 
837 std::vector<PropertyPtr> TubeSegmentationFilter::getNotDefaultOptions()
838 {
839  std::vector<PropertyPtr> retval;
840 
841  //get list with default options
842  paramList defaultOptions = this->getDefaultParameters();
843 
844  std::vector<StringPropertyPtr>::iterator stringDAIt;
845  for(stringDAIt = mStringOptions.begin(); stringDAIt != mStringOptions.end(); ++stringDAIt)
846  {
847  boost::unordered_map<std::string, StringParameter>::iterator stringIt;
848  for(stringIt = defaultOptions.strings.begin(); stringIt != defaultOptions.strings.end(); ++stringIt )
849  {
850  if(stringDAIt->get()->getDisplayName().toStdString() == stringIt->first)
851  {
852  if(stringDAIt->get()->getValue().toStdString() != stringIt->second.get())
853  retval.push_back(*stringDAIt);
854  }
855  }
856  }
857 
858  std::vector<BoolPropertyPtr>::iterator boolDAIt;
859  for(boolDAIt = mBoolOptions.begin(); boolDAIt != mBoolOptions.end(); ++boolDAIt)
860  {
861  boost::unordered_map<std::string, BoolParameter>::iterator boolIt;
862  for(boolIt = defaultOptions.bools.begin(); boolIt != defaultOptions.bools.end(); ++boolIt )
863  {
864  if(boolDAIt->get()->getDisplayName().toStdString() == boolIt->first)
865  {
866  if(boolDAIt->get()->getValue() != boolIt->second.get())
867  retval.push_back(*boolDAIt);
868  }
869  }
870  }
871 
872  std::vector<DoublePropertyPtr>::iterator doubleDAIt;
873  for(doubleDAIt = mDoubleOptions.begin(); doubleDAIt != mDoubleOptions.end(); ++doubleDAIt)
874  {
875  boost::unordered_map<std::string, NumericParameter>::iterator numericIt;
876  for(numericIt = defaultOptions.numerics.begin(); numericIt != defaultOptions.numerics.end(); ++numericIt )
877  {
878  if(doubleDAIt->get()->getDisplayName().toStdString() == numericIt->first)
879  {
880  if(!similar(doubleDAIt->get()->getValue(), numericIt->second.get()))
881  retval.push_back(*doubleDAIt);
882  }
883  }
884  }
885 
886  return retval;
887 }
888 
889 paramList TubeSegmentationFilter::getDefaultParameters()
890 {
891  //get list with default options
892  paramList defaultOptions;
893  try{
894  defaultOptions = initParameters(cx::DataLocations::findConfigFolder("/tsf", QString(KERNELS_DIR)).toStdString() + "/parameters");
895  } catch (SIPL::SIPLException& e){
896  std::string message = "When creating default options, could not init parameters. \""+std::string(e.what())+"\"";
897  reportError(qstring_cast(message));
898  }
899  return defaultOptions;
900 }
901 
902 void TubeSegmentationFilter::printParameters(paramList parameters)
903 {
904  std::cout << "\n" << std::endl;
905  std::cout << "The following parameters are set: " << std::endl;
906 
907  boost::unordered_map<std::string,StringParameter>::iterator itString;
908  for(itString = parameters.strings.begin(); itString != parameters.strings.end(); ++itString) {
909  std::cout << itString->first << " " << itString->second.get() << std::endl;
910  }
911 
912  boost::unordered_map<std::string,BoolParameter>::iterator itBool;
913  for(itBool = parameters.bools.begin(); itBool != parameters.bools.end(); ++itBool) {
914  std::string value = itBool->second.get() ? "true" : "false";
915  std::cout << itBool->first << " " << value << std::endl;
916  }
917 
918  boost::unordered_map<std::string,NumericParameter>::iterator itNumeric;
919  for(itNumeric = parameters.numerics.begin(); itNumeric != parameters.numerics.end(); ++itNumeric) {
920  std::cout << itNumeric->first << " " << itNumeric->second.get() << std::endl;
921  }
922 
923  std::cout << "\n" << std::endl;
924 }
925 
926 StringPropertyPtr TubeSegmentationFilter::makeStringOption(QDomElement root, std::string name, StringParameter parameter)
927 {
928  QString helptext = qstring_cast(parameter.getDescription());
929  std::vector<std::string> possibilities = parameter.getPossibilities();
930 
931  QString value = qstring_cast(parameter.get());
932 
933  QStringList list;
934  std::vector<std::string>::iterator it;
935  for(it = possibilities.begin(); it != possibilities.end(); ++it)
936  {
937  QString item = qstring_cast(*it);
938  if(!item.isEmpty())
939  list << item;
940  }
941 
942  if(!possibilities.empty())
943  return StringProperty::initialize(qstring_cast("tsf_"+name), qstring_cast(name), helptext, value, list, root);
944  else
945  {
946  //NB. hvis en string type ikke har noen possibilities betyr det at det er fritekst
947  return StringProperty::initialize(qstring_cast("tsf_"+name), qstring_cast(name), helptext, value, root);
948  }
949 }
950 
951 BoolPropertyPtr TubeSegmentationFilter::makeBoolOption(QDomElement root, std::string name, BoolParameter parameter)
952 {
953  QString helptext = qstring_cast(parameter.getDescription());
954  bool value = parameter.get();
955  return BoolProperty::initialize(qstring_cast("tsf_"+name), qstring_cast(name), helptext, value, root);
956 }
957 
958 DoublePropertyPtr TubeSegmentationFilter::makeDoubleOption(QDomElement root, std::string name, NumericParameter parameter)
959 {
960  QString helptext = qstring_cast(parameter.getDescription());
961  double value = parameter.get();
962  double min = parameter.getMin();
963  double max = parameter.getMax();
964  double step = parameter.getStep();
965 
966  DoubleRange range(min, max, step);
967  int decimals = 2;
968 
969  DoublePropertyPtr retval = DoubleProperty::initialize(qstring_cast("tsf_"+name), qstring_cast(name), helptext, value, range, decimals, root);
970  retval->setGuiRepresentation(DoublePropertyBase::grSLIDER);
971  return retval;
972 }
973 
974 TSFPresetsPtr TubeSegmentationFilter::populatePresets()
975 {
976  TSFPresetsPtr retval(new TSFPresets());
977  return retval;
978 }
979 
981  // Cleanup the output from TSF
982  if(mOutput != NULL)
983  delete mOutput;
984 }
985 
986 } /* namespace cx */
987 
QString qstring_cast(const T &val)
virtual QDomElement generatePresetFromCurrentlySetOptions(QString name)
get a xml element containing the currently set parameters
static BoolPropertyPtr initialize(const QString &uid, QString name, QString help, bool value, QDomNode root=QDomNode())
std::vector< SelectDataStringPropertyBasePtr > mInputTypes
Definition: cxFilterImpl.h:94
void reportError(QString msg)
Definition: cxLogger.cpp:92
A mesh data set.
Definition: cxMesh.h:61
vtkSmartPointer< class vtkImageShiftScale > vtkImageShiftScalePtr
Transform3D createTransformScale(const Vector3D &scale_)
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
static StringPropertySelectDataPtr New(PatientModelServicePtr patientModelService, QString typeRegexp=".*")
boost::shared_ptr< class Image > ImagePtr
Definition: cxDicomWidget.h:48
QString timestampSecondsFormat()
Definition: cxTime.cpp:39
virtual void intitializeFromParentImage(ImagePtr parentImage)
Definition: cxImage.cpp:172
bool similar(const DoubleBoundingBox3D &a, const DoubleBoundingBox3D &b, double tol)
std::vector< PropertyPtr > mOptionsAdapters
Definition: cxFilterImpl.h:96
boost::shared_ptr< class Data > DataPtr
static QString findConfigFolder(QString pathRelativeToConfigRoot, QString alternativeAbsolutePath="")
boost::shared_ptr< class StringProperty > StringPropertyPtr
boost::shared_ptr< class TSFPresets > TSFPresetsPtr
Definition: cxTSFPresets.h:79
vtkSmartPointer< class vtkPolyData > vtkPolyDataPtr
boost::shared_ptr< class SelectDataStringPropertyBase > SelectDataStringPropertyBasePtr
boost::shared_ptr< class StringPropertyBase > StringPropertyBasePtr
boost::shared_ptr< class Property > PropertyPtr
PatientModelServicePtr patientService()
virtual bool execute()
void reportWarning(QString msg)
Definition: cxLogger.cpp:91
void setVtkPolyData(const vtkPolyDataPtr &polyData)
Definition: cxMesh.cpp:100
A volumetric data set.
Definition: cxImage.h:66
static QDomElement createPresetElement(QString name, std::map< QString, QString > &parameters)
ImagePtr getCopiedInputImage(int index=0)
Transform3D createTransformTranslate(const Vector3D &translation)
QDomElement mOptions
Definition: cxFilterImpl.h:97
Represents one option of the string type. The data are stored within a xml document.
boost::shared_ptr< class Presets > PresetsPtr
static StringPropertyPtr initialize(const QString &uid, QString name, QString help, QString value, QStringList range, QDomNode root=QDomNode())
boost::shared_ptr< class DoubleProperty > DoublePropertyPtr
Eigen::Vector3d Vector3D
Vector3D is a representation of a point or vector in 3D.
Definition: cxVector3D.h:63
virtual double getValue() const
get the data value.
vtkSmartPointer< class vtkImageImport > vtkImageImportPtr
TubeSegmentationFilter(ctkPluginContext *pluginContext)
std::vector< SelectDataStringPropertyBasePtr > mOutputTypes
Definition: cxFilterImpl.h:95
static DoublePropertyPtr initialize(const QString &uid, QString name, QString help, double value, DoubleRange range, int decimals, QDomNode root=QDomNode())
virtual void requestSetPresetSlot(QString name)
try to set a specific preset
static StringPropertySelectMeshPtr New(PatientModelServicePtr patientModelService)
virtual bool postProcess()
static StringPropertySelectImagePtr New(PatientModelServicePtr patientModelService)
boost::shared_ptr< class BoolProperty > BoolPropertyPtr
boost::shared_ptr< class Mesh > MeshPtr
vtkSmartPointer< class vtkImageData > vtkImageDataPtr
boost::shared_ptr< class StringPropertySelectMesh > StringPropertySelectMeshPtr
void changed()