diff --git a/Examples/Annotation/AnnotationExample.cpp b/Examples/Annotation/AnnotationExample.cpp index 7cc527f043..af11390779 100644 --- a/Examples/Annotation/AnnotationExample.cpp +++ b/Examples/Annotation/AnnotationExample.cpp @@ -1,143 +1,140 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkRegisterClasses.h" #include "QmitkRenderWindow.h" #include #include #include #include #include #include #include #include #include //##Documentation //## @brief Load image (nrrd format) and display it in a 2D view int main(int argc, char *argv[]) { QApplication qtapplication(argc, argv); if (argc < 2) { fprintf(stderr, "Usage: %s [filename] \n\n", itksys::SystemTools::GetFilenameName(argv[0]).c_str()); return 1; } // Register Qmitk-dependent global instances QmitkRegisterClasses(); mitk::StandaloneDataStorage::Pointer ds = mitk::StandaloneDataStorage::New(); // Load datanode (eg. many image formats, surface formats, etc.) mitk::IOUtil::Load(argv[1], *ds); // Create a RenderWindow QmitkRenderWindow renderWindow; // Tell the RenderWindow which (part of) the datastorage to render renderWindow.GetRenderer()->SetDataStorage(ds); // Initialize the RenderWindow auto geo = ds->ComputeBoundingGeometry3D(ds->GetAll()); mitk::RenderingManager::GetInstance()->InitializeViews(geo); // mitk::RenderingManager::GetInstance()->InitializeViews(); // Add Overlays //![TextAnnotation2D] // Create a textAnnotation2D mitk::TextAnnotation2D::Pointer textAnnotation = mitk::TextAnnotation2D::New(); textAnnotation->SetText("Test!"); // set UTF-8 encoded text to render textAnnotation->SetFontSize(40); textAnnotation->SetColor(1, 0, 0); // Set text color to red textAnnotation->SetOpacity(1); // The position of the Annotation can be set to a fixed coordinate on the display. mitk::Point2D pos; pos[0] = 10; pos[1] = 20; textAnnotation->SetPosition2D(pos); std::string rendererID = renderWindow.GetRenderer()->GetName(); // The LayoutAnnotationRenderer can place the TextAnnotation2D at some defined corner positions mitk::LayoutAnnotationRenderer::AddAnnotation( textAnnotation, rendererID, mitk::LayoutAnnotationRenderer::TopLeft, 5, 5, 1); //![TextAnnotation2D] //![TextAnnotation3D] mitk::PointSet::Pointer pointset = mitk::PointSet::New(); // This vector is used to define an offset for the annotations, in order to show them with a margin to the actual // coordinate. mitk::Point3D offset; offset[0] = .5; offset[1] = .5; offset[2] = .5; // save references to Annotations so that they do not get deregistered std::vector annotationReferences; // Just a loop to create some points for (unsigned long i = 0; i < 10; i++) { // To each point, a TextAnnotation3D is created mitk::TextAnnotation3D::Pointer textAnnotation3D = mitk::TextAnnotation3D::New(); mitk::Point3D point; point[0] = i * 20; point[1] = i * 30; point[2] = i * -50; pointset->InsertPoint(i, point); textAnnotation3D->SetText("A Point"); // The Position is set to the point coordinate to create an annotation to the point in the PointSet. textAnnotation3D->SetPosition3D(point); // move the annotation away from the actual point textAnnotation3D->SetOffsetVector(offset); annotationReferences.push_back(textAnnotation3D); mitk::ManualPlacementAnnotationRenderer::AddAnnotation(textAnnotation3D, rendererID); } // Get the MicroserviceID of the registered textAnnotation std::string serviceID = textAnnotation->GetMicroserviceID(); // The AnnotationUtils can retrieve any registered annotations by their microservice ID mitk::Annotation *annotation = mitk::AnnotationUtils::GetAnnotation(serviceID); // This way, it is possible to change the properties of Annotations without knowing their implementation annotation->SetText("changed text!"); // also show the created pointset mitk::DataNode::Pointer datanode = mitk::DataNode::New(); datanode->SetData(pointset); datanode->SetName("pointSet"); ds->Add(datanode); //! [TextAnnotation3D] renderWindow.show(); renderWindow.resize(256, 256); renderWindow.show(); renderWindow.resize(256, 256); // cleanup: Remove References to DataStorage. This will delete the object ds = nullptr; } -/** -\example Step1.cpp -*/ diff --git a/Examples/Plugins/org.mitk.example.gui.customviewer/documentation/doxygen/code_snippets/MinimalApplicationSnippet.cpp b/Examples/Plugins/org.mitk.example.gui.customviewer/documentation/doxygen/code_snippets/MinimalApplicationSnippet.cpp index 6b052c48a4..db9873a898 100644 --- a/Examples/Plugins/org.mitk.example.gui.customviewer/documentation/doxygen/code_snippets/MinimalApplicationSnippet.cpp +++ b/Examples/Plugins/org.mitk.example.gui.customviewer/documentation/doxygen/code_snippets/MinimalApplicationSnippet.cpp @@ -1,39 +1,21 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ -#include "CustomViewer.h" -#include "CustomViewerWorkbenchAdvisor.h" - -#include - -CustomViewer::CustomViewer() -{ -} - -CustomViewer::~CustomViewer() -{ -} //! [MinimalApplicationClass_StartMethod] -int CustomViewer::Start() -{ - berry::Display *display = berry::PlatformUI::CreateDisplay(); +berry::Display *display = berry::PlatformUI::CreateDisplay(); - wbAdvisor.reset(new berry::WorkbenchAdvisor); - int code = berry::PlatformUI::CreateAndRunWorkbench(display, wbAdvisor.data()); +wbAdvisor.reset(new berry::WorkbenchAdvisor); +int code = berry::PlatformUI::CreateAndRunWorkbench(display, wbAdvisor.data()); - // exit the application with an appropriate return code - return code == berry::PlatformUI::RETURN_RESTART ? EXIT_RESTART : EXIT_OK; -} +// exit the application with an appropriate return code +return code == berry::PlatformUI::RETURN_RESTART ? EXIT_RESTART : EXIT_OK; //! [MinimalApplicationClass_StartMethod] -void CustomViewer::Stop() -{ -} diff --git a/Modules/AlgorithmsExt/include/mitkGeometryClipImageFilter.h b/Modules/AlgorithmsExt/include/mitkGeometryClipImageFilter.h index 077ba6ba26..0ad82e2d51 100644 --- a/Modules/AlgorithmsExt/include/mitkGeometryClipImageFilter.h +++ b/Modules/AlgorithmsExt/include/mitkGeometryClipImageFilter.h @@ -1,182 +1,182 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef MITKGEOMETRYCLIPIMAGEFILTER_H_HEADER_INCLUDED_C1F48A22 #define MITKGEOMETRYCLIPIMAGEFILTER_H_HEADER_INCLUDED_C1F48A22 #include "MitkAlgorithmsExtExports.h" #include "mitkCommon.h" #include "mitkGeometryData.h" #include "mitkImageTimeSelector.h" #include "mitkImageToImageFilter.h" namespace itk { template class ITK_EXPORT Image; } namespace mitk { //##Documentation //## @brief Filter for clipping an image with a PlaneGeometry //## //## The given geometry for clipping can be either a PlaneGeometry //## or a TimeGeometry containing multiple instances //## of PlaneGeometry //## //## \todo add AutoOrientLabels, which makes the "left" side (minimum X value) side of the image get one defined //label. //## left-most because vtkPolyDataNormals uses the same definition and this filter is used for visualization of //## front/back side of curved planes //## //## @ingroup Process class MITKALGORITHMSEXT_EXPORT GeometryClipImageFilter : public ImageToImageFilter { public: mitkClassMacro(GeometryClipImageFilter, ImageToImageFilter); itkFactorylessNewMacro(Self); itkCloneMacro(Self); /** * Set the geometry to be used for clipping * * The given geometry for clipping must be a PlaneGeometry. */ void SetClippingGeometry(const mitk::BaseGeometry *aClippingGeometry); /** * Set the geometry to be used for clipping * * The given geometry for clipping must a * TimeGeometry containing multiple instances * of PlaneGeometry */ void SetClippingGeometry(const mitk::TimeGeometry *aClippingGeometry); const mitk::BaseGeometry *GetClippingGeometry() const; const mitk::TimeGeometry *GetClippingTimeGeometry() const; //##Description //## @brief Get whether the part above or below the geometry //## shall be clipped (default: @a true) itkGetConstMacro(ClipPartAboveGeometry, bool); //## @brief Set whether the part above or below the geometry //## shall be clipped (default: @a true) itkSetMacro(ClipPartAboveGeometry, bool); //## @brief Set whether the part above or below the geometry //## shall be clipped (default: @a true) itkBooleanMacro(ClipPartAboveGeometry); //##Description //## @brief Set value for outside pixels (default: 0), //## used when m_AutoOutsideValue is \a false itkSetMacro(OutsideValue, ScalarType); itkGetConstMacro(OutsideValue, ScalarType); //##Description //## @brief If set to \a true the minimum of the ouput pixel type is //## used as outside value (default: \a false) itkSetMacro(AutoOutsideValue, bool); itkGetConstMacro(AutoOutsideValue, bool); itkBooleanMacro(AutoOutsideValue); itkSetMacro(AutoOrientLabels, bool); itkGetConstMacro(AutoOrientLabels, bool); //##Description //## @brief If set to \a true both sides of the clipping //## geometry will be labeld using m_AboveGeometryLabel and //## m_BelowGeometryLabel itkSetMacro(LabelBothSides, bool); itkGetConstMacro(LabelBothSides, bool); itkBooleanMacro(LabelBothSides); //##Description //## @brief Set for voxels above the clipping geometry. //## This value is only used, if m_LabelBothSides is set to true. itkSetMacro(AboveGeometryLabel, ScalarType); itkGetConstMacro(AboveGeometryLabel, ScalarType); //##Description //## @brief Set for voxels below the clipping geometry. //## This value is only used, if m_LabelBothSides is set to true. itkSetMacro(BelowGeometryLabel, ScalarType); itkGetConstMacro(BelowGeometryLabel, ScalarType); protected: GeometryClipImageFilter(); ~GeometryClipImageFilter() override; void GenerateInputRequestedRegion() override; void GenerateOutputInformation() override; void GenerateData() override; template - friend void _InternalComputeClippedImage(itk::Image *itkImage, - mitk::GeometryClipImageFilter *geometryClipper, - const mitk::PlaneGeometry *clippingPlaneGeometry); + void _InternalComputeClippedImage(itk::Image *itkImage, + mitk::GeometryClipImageFilter *geometryClipper, + const mitk::PlaneGeometry *clippingPlaneGeometry); mitk::BaseGeometry::ConstPointer m_ClippingGeometry; mitk::GeometryData::Pointer m_ClippingGeometryData; mitk::TimeGeometry::ConstPointer m_TimeClippingGeometry; mitk::ImageTimeSelector::Pointer m_InputTimeSelector; mitk::ImageTimeSelector::Pointer m_OutputTimeSelector; //##Description //## @brief Defines whether the part above or below the geometry //## shall be clipped (default: @a true) bool m_ClipPartAboveGeometry; //##Description //## @brief Value for outside pixels (default: 0) //## //## Used only if m_AutoOutsideValue is \a false. ScalarType m_OutsideValue; //##Description //## @brief If \a true the minimum of the ouput pixel type is //## used as outside value (default: \a false) bool m_AutoOutsideValue; //##Description //## @brief If \a true all pixels above and below the geometry //## are labeled with m_AboveGeometryLabel and m_BelowGeometryLabel bool m_LabelBothSides; /** * \brief Orient above like vtkPolyDataNormals does with AutoOrientNormals */ bool m_AutoOrientLabels; //##Description //## @brief Is used for labeling all pixels above the geometry //## when m_LabelBothSides is on ScalarType m_AboveGeometryLabel; //##Description //## @brief Is used for labeling all pixels below the geometry //## when m_LabelBothSides is on ScalarType m_BelowGeometryLabel; //##Description //## @brief Time when Header was last initialized itk::TimeStamp m_TimeOfHeaderInitialization; }; } // namespace mitk #endif /* MITKGEOMETRYCLIPIMAGEFILTER_H_HEADER_INCLUDED_C1F48A22 */ diff --git a/Modules/AlgorithmsExt/src/mitkGeometryClipImageFilter.cpp b/Modules/AlgorithmsExt/src/mitkGeometryClipImageFilter.cpp index 8e33510007..e70277292b 100644 --- a/Modules/AlgorithmsExt/src/mitkGeometryClipImageFilter.cpp +++ b/Modules/AlgorithmsExt/src/mitkGeometryClipImageFilter.cpp @@ -1,261 +1,261 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkGeometryClipImageFilter.h" #include "mitkImageTimeSelector.h" #include "mitkProperties.h" #include "mitkTimeHelper.h" #include "mitkImageToItk.h" #include "itkImageRegionConstIterator.h" #include "itkImageRegionIteratorWithIndex.h" #include mitk::GeometryClipImageFilter::GeometryClipImageFilter() : m_ClippingGeometry(nullptr), m_ClipPartAboveGeometry(true), m_OutsideValue(0), m_AutoOutsideValue(false), m_LabelBothSides(false), m_AutoOrientLabels(false), m_AboveGeometryLabel(1), m_BelowGeometryLabel(2) { this->SetNumberOfIndexedInputs(2); this->SetNumberOfRequiredInputs(2); m_InputTimeSelector = mitk::ImageTimeSelector::New(); m_OutputTimeSelector = mitk::ImageTimeSelector::New(); m_ClippingGeometryData = mitk::GeometryData::New(); } mitk::GeometryClipImageFilter::~GeometryClipImageFilter() { } void mitk::GeometryClipImageFilter::SetClippingGeometry(const mitk::TimeGeometry *timeClippingGeometry) { m_TimeClippingGeometry = timeClippingGeometry; SetClippingGeometry(timeClippingGeometry->GetGeometryForTimeStep(0)); } void mitk::GeometryClipImageFilter::SetClippingGeometry(const mitk::BaseGeometry *aClippingGeometry) { if (aClippingGeometry != m_ClippingGeometry.GetPointer()) { m_ClippingGeometry = aClippingGeometry; m_ClippingGeometryData->SetGeometry(const_cast(aClippingGeometry)); SetNthInput(1, m_ClippingGeometryData); Modified(); } } const mitk::BaseGeometry *mitk::GeometryClipImageFilter::GetClippingGeometry() const { return m_ClippingGeometry; } const mitk::TimeGeometry *mitk::GeometryClipImageFilter::GetClippingTimeGeometry() const { return m_TimeClippingGeometry; } void mitk::GeometryClipImageFilter::GenerateInputRequestedRegion() { Superclass::GenerateInputRequestedRegion(); mitk::Image *output = this->GetOutput(); mitk::Image *input = this->GetInput(); if ((output->IsInitialized() == false) || (m_ClippingGeometry.IsNull())) return; input->SetRequestedRegionToLargestPossibleRegion(); GenerateTimeInInputRegion(output, input); } void mitk::GeometryClipImageFilter::GenerateOutputInformation() { mitk::Image::ConstPointer input = this->GetInput(); mitk::Image::Pointer output = this->GetOutput(); if ((output->IsInitialized()) && (this->GetMTime() <= m_TimeOfHeaderInitialization.GetMTime())) return; itkDebugMacro(<< "GenerateOutputInformation()"); unsigned int i; auto tmpDimensions = new unsigned int[input->GetDimension()]; for (i = 0; i < input->GetDimension(); ++i) tmpDimensions[i] = input->GetDimension(i); output->Initialize(input->GetPixelType(), input->GetDimension(), tmpDimensions, input->GetNumberOfChannels()); delete[] tmpDimensions; output->SetGeometry(static_cast(input->GetGeometry()->Clone().GetPointer())); output->SetPropertyList(input->GetPropertyList()->Clone()); m_TimeOfHeaderInitialization.Modified(); } template -void mitk::_InternalComputeClippedImage(itk::Image *inputItkImage, - mitk::GeometryClipImageFilter *geometryClipper, - const mitk::PlaneGeometry *clippingPlaneGeometry) +void mitk::GeometryClipImageFilter::_InternalComputeClippedImage(itk::Image *inputItkImage, + mitk::GeometryClipImageFilter *geometryClipper, + const mitk::PlaneGeometry *clippingPlaneGeometry) { typedef itk::Image ItkInputImageType; typedef itk::Image ItkOutputImageType; typedef itk::ImageRegionConstIteratorWithIndex ItkInputImageIteratorType; typedef itk::ImageRegionIteratorWithIndex ItkOutputImageIteratorType; typename mitk::ImageToItk::Pointer outputimagetoitk = mitk::ImageToItk::New(); outputimagetoitk->SetInput(geometryClipper->m_OutputTimeSelector->GetOutput()); outputimagetoitk->Update(); typename ItkOutputImageType::Pointer outputItkImage = outputimagetoitk->GetOutput(); // create the iterators typename ItkInputImageType::RegionType inputRegionOfInterest = inputItkImage->GetLargestPossibleRegion(); ItkInputImageIteratorType inputIt(inputItkImage, inputRegionOfInterest); ItkOutputImageIteratorType outputIt(outputItkImage, inputRegionOfInterest); typename ItkOutputImageType::PixelType outsideValue; if (geometryClipper->m_AutoOutsideValue) outsideValue = itk::NumericTraits::min(); else outsideValue = (typename ItkOutputImageType::PixelType)geometryClipper->m_OutsideValue; mitk::BaseGeometry *inputGeometry = geometryClipper->m_InputTimeSelector->GetOutput()->GetGeometry(); typedef itk::Index IndexType; Point3D indexPt; indexPt.Fill(0); int i, dim = IndexType::GetIndexDimension(); Point3D pointInMM; bool above = geometryClipper->m_ClipPartAboveGeometry; bool labelBothSides = geometryClipper->GetLabelBothSides(); if (geometryClipper->GetAutoOrientLabels()) { Point3D leftMostPoint; leftMostPoint.Fill(std::numeric_limits::min() / 2.0); if (clippingPlaneGeometry->IsAbove(pointInMM) != above) { // invert meaning of above --> left is always the "above" side above = !above; MITK_INFO << leftMostPoint << " is BELOW geometry. Inverting meaning of above" << std::endl; } else MITK_INFO << leftMostPoint << " is above geometry" << std::endl; } auto aboveLabel = (typename ItkOutputImageType::PixelType)geometryClipper->GetAboveGeometryLabel(); auto belowLabel = (typename ItkOutputImageType::PixelType)geometryClipper->GetBelowGeometryLabel(); for (inputIt.GoToBegin(), outputIt.GoToBegin(); !inputIt.IsAtEnd(); ++inputIt, ++outputIt) { if ((typename ItkOutputImageType::PixelType)inputIt.Get() == outsideValue) { outputIt.Set(outsideValue); } else { for (i = 0; i < dim; ++i) indexPt[i] = (mitk::ScalarType)inputIt.GetIndex()[i]; inputGeometry->IndexToWorld(indexPt, pointInMM); if (clippingPlaneGeometry->IsAbove(pointInMM) == above) { if (labelBothSides) outputIt.Set(aboveLabel); else outputIt.Set(outsideValue); } else { if (labelBothSides) outputIt.Set(belowLabel); else outputIt.Set(inputIt.Get()); } } } } #include "mitkImageAccessByItk.h" void mitk::GeometryClipImageFilter::GenerateData() { Image::ConstPointer input = this->GetInput(); Image::Pointer output = this->GetOutput(); if ((output->IsInitialized() == false) || (m_ClippingGeometry.IsNull())) return; const PlaneGeometry *clippingGeometryOfCurrentTimeStep = nullptr; if (m_TimeClippingGeometry.IsNull()) { clippingGeometryOfCurrentTimeStep = dynamic_cast(m_ClippingGeometry.GetPointer()); } else { clippingGeometryOfCurrentTimeStep = dynamic_cast(m_TimeClippingGeometry->GetGeometryForTimeStep(0).GetPointer()); } if (clippingGeometryOfCurrentTimeStep == nullptr) return; m_InputTimeSelector->SetInput(input); m_OutputTimeSelector->SetInput(this->GetOutput()); mitk::Image::RegionType outputRegion = output->GetRequestedRegion(); const mitk::TimeGeometry *outputTimeGeometry = output->GetTimeGeometry(); const mitk::TimeGeometry *inputTimeGeometry = input->GetTimeGeometry(); ScalarType timeInMS; int timestep = 0; int tstart = outputRegion.GetIndex(3); int tmax = tstart + outputRegion.GetSize(3); int t; for (t = tstart; t < tmax; ++t) { timeInMS = outputTimeGeometry->TimeStepToTimePoint(t); timestep = inputTimeGeometry->TimePointToTimeStep(timeInMS); m_InputTimeSelector->SetTimeNr(timestep); m_InputTimeSelector->UpdateLargestPossibleRegion(); m_OutputTimeSelector->SetTimeNr(t); m_OutputTimeSelector->UpdateLargestPossibleRegion(); if (m_TimeClippingGeometry.IsNotNull()) { timestep = m_TimeClippingGeometry->TimePointToTimeStep(timeInMS); if (m_TimeClippingGeometry->IsValidTimeStep(timestep) == false) continue; clippingGeometryOfCurrentTimeStep = dynamic_cast(m_TimeClippingGeometry->GetGeometryForTimeStep(timestep).GetPointer()); } AccessByItk_2( m_InputTimeSelector->GetOutput(), _InternalComputeClippedImage, this, clippingGeometryOfCurrentTimeStep); } m_TimeOfHeaderInitialization.Modified(); } diff --git a/Modules/AlgorithmsExt/src/mitkPointLocator.cpp b/Modules/AlgorithmsExt/src/mitkPointLocator.cpp index 9e9963d233..354ba1566e 100644 --- a/Modules/AlgorithmsExt/src/mitkPointLocator.cpp +++ b/Modules/AlgorithmsExt/src/mitkPointLocator.cpp @@ -1,241 +1,241 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkPointLocator.h" #include #include mitk::PointLocator::PointLocator() : m_SearchTreeInitialized(false), m_VtkPoints(nullptr), m_MitkPoints(nullptr), m_ItkPoints(nullptr), m_ANNK(1), m_ANNDimension(3), m_ANNEpsilon(0), m_ANNDataPoints(nullptr), m_ANNQueryPoint(nullptr), m_ANNPointIndexes(nullptr), m_ANNDistances(nullptr), m_ANNTree(nullptr) { } mitk::PointLocator::~PointLocator() { if (m_SearchTreeInitialized) DestroyANN(); } void mitk::PointLocator::SetPoints(vtkPointSet *pointSet) { if (pointSet == nullptr) { itkWarningMacro("Points are nullptr!"); return; } vtkPoints *points = pointSet->GetPoints(); if (m_VtkPoints) { if ((m_VtkPoints == points) && (m_VtkPoints->GetMTime() == points->GetMTime())) { return; // no need to recalculate search tree } } m_VtkPoints = points; size_t size = points->GetNumberOfPoints(); if (m_ANNDataPoints != nullptr) delete[] m_ANNDataPoints; m_ANNDataPoints = annAllocPts(size, m_ANNDimension); m_IndexToPointIdContainer.clear(); m_IndexToPointIdContainer.resize(size); for (vtkIdType i = 0; (unsigned)i < size; ++i) { double *currentPoint = points->GetPoint(i); (m_ANNDataPoints[i])[0] = currentPoint[0]; (m_ANNDataPoints[i])[1] = currentPoint[1]; (m_ANNDataPoints[i])[2] = currentPoint[2]; m_IndexToPointIdContainer[i] = i; } InitANN(); } void mitk::PointLocator::SetPoints(mitk::PointSet *points) { if (points == nullptr) { itkWarningMacro("Points are nullptr!"); return; } if (m_MitkPoints) { if ((m_MitkPoints == points) && (m_MitkPoints->GetMTime() == points->GetMTime())) { return; // no need to recalculate search tree } } m_MitkPoints = points; size_t size = points->GetSize(); if (m_ANNDataPoints != nullptr) delete[] m_ANNDataPoints; m_ANNDataPoints = annAllocPts(size, m_ANNDimension); m_IndexToPointIdContainer.clear(); m_IndexToPointIdContainer.resize(size); size_t counter = 0; mitk::PointSet::PointsContainer *pointsContainer = points->GetPointSet()->GetPoints(); mitk::PointSet::PointsContainer::Iterator it; mitk::PointSet::PointType currentPoint; mitk::PointSet::PointsContainer::ElementIdentifier currentId; for (it = pointsContainer->Begin(); it != pointsContainer->End(); ++it, ++counter) { currentPoint = it->Value(); currentId = it->Index(); (m_ANNDataPoints[counter])[0] = currentPoint[0]; (m_ANNDataPoints[counter])[1] = currentPoint[1]; (m_ANNDataPoints[counter])[2] = currentPoint[2]; m_IndexToPointIdContainer[counter] = currentId; } InitANN(); } void mitk::PointLocator::SetPoints(ITKPointSet *pointSet) { if (pointSet == nullptr) { itkWarningMacro("Points are nullptr!"); return; } if (m_ItkPoints) { if ((m_ItkPoints == pointSet) && (m_ItkPoints->GetMTime() == pointSet->GetMTime())) { return; // no need to recalculate search tree } } m_ItkPoints = pointSet; size_t size = pointSet->GetNumberOfPoints(); if (m_ANNDataPoints != nullptr) delete[] m_ANNDataPoints; m_ANNDataPoints = annAllocPts(size, m_ANNDimension); m_IndexToPointIdContainer.clear(); m_IndexToPointIdContainer.resize(size); size_t counter = 0; ITKPointSet::PointsContainerConstPointer pointsContainer = pointSet->GetPoints(); ITKPointSet::PointsContainer::ConstIterator it; ITKPointSet::PointType currentPoint; ITKPointSet::PointsContainer::ElementIdentifier currentId; for (it = pointsContainer->Begin(); it != pointsContainer->End(); ++it, ++counter) { currentPoint = it->Value(); currentId = it->Index(); (m_ANNDataPoints[counter])[0] = currentPoint[0]; (m_ANNDataPoints[counter])[1] = currentPoint[1]; (m_ANNDataPoints[counter])[2] = currentPoint[2]; m_IndexToPointIdContainer[counter] = currentId; } InitANN(); } mitk::PointLocator::IdType mitk::PointLocator::FindClosestPoint(const double point[3]) { m_ANNQueryPoint[0] = point[0]; m_ANNQueryPoint[1] = point[1]; m_ANNQueryPoint[2] = point[2]; return FindClosestANNPoint(m_ANNQueryPoint); } mitk::PointLocator::IdType mitk::PointLocator::FindClosestPoint(double x, double y, double z) { m_ANNQueryPoint[0] = x; m_ANNQueryPoint[1] = y; m_ANNQueryPoint[2] = z; return FindClosestANNPoint(m_ANNQueryPoint); } mitk::PointLocator::IdType mitk::PointLocator::FindClosestPoint(mitk::PointSet::PointType point) { m_ANNQueryPoint[0] = point[0]; m_ANNQueryPoint[1] = point[1]; m_ANNQueryPoint[2] = point[2]; return FindClosestANNPoint(m_ANNQueryPoint); } mitk::PointLocator::IdType mitk::PointLocator::FindClosestANNPoint(const ANNpoint &point) { if (!m_SearchTreeInitialized) return -1; m_ANNTree->annkSearch(point, m_ANNK, m_ANNPointIndexes, m_ANNDistances); return m_IndexToPointIdContainer[m_ANNPointIndexes[0]]; } mitk::PointLocator::DistanceType mitk::PointLocator::GetMinimalDistance(mitk::PointSet::PointType point) { m_ANNQueryPoint[0] = point[0]; m_ANNQueryPoint[1] = point[1]; m_ANNQueryPoint[2] = point[2]; return GetMinimalDistance(m_ANNQueryPoint); } -mitk::PointLocator::DistanceType mitk::PointLocator::GetMinimalDistance(const ANNpoint &point) +mitk::PointLocator::DistanceType mitk::PointLocator::GetMinimalDistance(const MyANNpoint &point) { if (!m_SearchTreeInitialized) return -1; m_ANNTree->annkSearch(point, m_ANNK, m_ANNPointIndexes, m_ANNDistances); return m_ANNDistances[0]; } void mitk::PointLocator::InitANN() { if (m_SearchTreeInitialized) DestroyANN(); m_ANNQueryPoint = annAllocPt(m_ANNDimension); m_ANNPointIndexes = new ANNidx[m_ANNK]; m_ANNDistances = new ANNdist[m_ANNK]; m_ANNTree = new ANNkd_tree(m_ANNDataPoints, m_IndexToPointIdContainer.size(), m_ANNDimension); m_SearchTreeInitialized = true; } void mitk::PointLocator::DestroyANN() { m_SearchTreeInitialized = false; if (m_ANNQueryPoint != nullptr) annDeallocPt(m_ANNQueryPoint); if (m_ANNDataPoints != nullptr) annDeallocPts(m_ANNDataPoints); if (m_ANNPointIndexes != nullptr) delete[] m_ANNPointIndexes; if (m_ANNDistances != nullptr) delete[] m_ANNDistances; if (m_ANNTree != nullptr) delete m_ANNTree; } bool mitk::PointLocator::FindClosestPointAndDistance(mitk::PointSet::PointType point, IdType *id, DistanceType *dist) { m_ANNQueryPoint[0] = point[0]; m_ANNQueryPoint[1] = point[1]; m_ANNQueryPoint[2] = point[2]; m_ANNTree->annkSearch(m_ANNQueryPoint, m_ANNK, m_ANNPointIndexes, m_ANNDistances); *id = m_IndexToPointIdContainer[m_ANNPointIndexes[0]]; *dist = m_ANNDistances[0]; return true; } diff --git a/Modules/Classification/CLUtilities/include/mitkGIFIntensityVolumeHistogramFeatures.h b/Modules/Classification/CLUtilities/include/mitkGIFIntensityVolumeHistogramFeatures.h index aab89fedd2..a28c48a689 100644 --- a/Modules/Classification/CLUtilities/include/mitkGIFIntensityVolumeHistogramFeatures.h +++ b/Modules/Classification/CLUtilities/include/mitkGIFIntensityVolumeHistogramFeatures.h @@ -1,84 +1,82 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkGIFIntensityVolumeHistogramFeatures_h #define mitkGIFIntensityVolumeHistogramFeatures_h #include #include #include namespace mitk { /** * \brief Calculates the Intensity Volume Histogram features * * This class can be used to calculate the volume histogram and features that are calculated from * it. It is based on the intensity-volume histogram (IVH) which describes the relation between the - * grey level index i (and the corresponding intensity \f§x_i\f$) and the volume fraction \f$f\f$ that + * grey level index i (and the corresponding intensity \f$x_i\f$) and the volume fraction \f$f\f$ that * with an intensity that is equal or greater than \f$x_i\f$. This feature is original proposed in * El Naqa et al. Exploring feature-based approaches in PET images for prediciting cancer treatment outcomes. * Pattern recognition 2009. * * This feature calculator is activated by the option "-intensity-volume-histogram" or "-ivoh". * Beside the configuration of the histogram, which follows the describtion given in AbstractGlobalImageFeature * there are no additional parameters to configure this feature. Remark that, different from other features, * the number of bins is 1000 by default and not 256. * * The features are calculated based on a mask. It is assumed that the mask is * of the type of an unsigned short image and all voxels with an value of greater than zero * are treated as masked. * * The resulting features are: * - Intensity Volume Histogram::Volume fration at 0.10 intensity: The volume fraction with an intensity * of greater or equal to 10% of the maximum intensity. * - Intensity Volume Histogram::Volume fration at 0.90 intensity: The volume fraction with an intensity * of greater or equal to 90% of the maximum intensity. * - Intensity Volume Histogram::Intensity at 0.10 volume: The highest intensity so that at least * 10% of the masked image area has the same or higher intensity. * - Intensity Volume Histogram::Intensity at 0.90 volume: The highest intensity so that at least * 10% of the masked image area has the same or higher intensity. * - Intensity Volume Histogram::Difference volume fration at 0.10 and 0.90 intensity: The difference * between the volume fraction at 10% intensity and 90% intensity. * - Intensity Volume Histogram::Difference intensity at 0.10 and 0.90 volume: The intensity difference * between the intenstiy of 90% of the volume and 10% volume. * - Intensity Volume Histogram::Area under IVH curve: If the IVH is interpreted as curve, this value represents * the area under the curve. It is calculated using the bin indexes rather than the intensity values. */ class MITKCLUTILITIES_EXPORT GIFIntensityVolumeHistogramFeatures : public AbstractGlobalImageFeature { public: mitkClassMacro(GIFIntensityVolumeHistogramFeatures, AbstractGlobalImageFeature); - itkFactorylessNewMacro(Self); - itkCloneMacro(Self); + itkFactorylessNewMacro(Self); + itkCloneMacro(Self); - GIFIntensityVolumeHistogramFeatures(); + GIFIntensityVolumeHistogramFeatures(); /** * \brief Calculates the Cooccurence-Matrix based features for this class. */ - FeatureListType CalculateFeatures(const Image::Pointer & image, const Image::Pointer &feature) override; + FeatureListType CalculateFeatures(const Image::Pointer & image, const Image::Pointer &mask) override; /** * \brief Returns a list of the names of all features that are calculated from this class */ FeatureNameListType GetFeatureNames() override; void AddArguments(mitkCommandLineParser &parser) override; void CalculateFeaturesUsingParameters(const Image::Pointer & feature, const Image::Pointer &mask, const Image::Pointer &maskNoNAN, FeatureListType &featureList) override; std::string GetCurrentFeatureEncoding() override; - - private: }; } #endif //mitkGIFIntensityVolumeHistogramFeatures_h diff --git a/Modules/Classification/CLUtilities/include/mitkGIFNeighbouringGreyLevelDependenceFeatures.h b/Modules/Classification/CLUtilities/include/mitkGIFNeighbouringGreyLevelDependenceFeatures.h index 7731056524..fb4b464b40 100644 --- a/Modules/Classification/CLUtilities/include/mitkGIFNeighbouringGreyLevelDependenceFeatures.h +++ b/Modules/Classification/CLUtilities/include/mitkGIFNeighbouringGreyLevelDependenceFeatures.h @@ -1,164 +1,164 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef mitkGIFNeighbouringGreyLevelDependenceFeatures_h #define mitkGIFNeighbouringGreyLevelDependenceFeatures_h #include #include #include #include namespace mitk { /** * \brief Calculates the Neighbouring Grey Level Dependence Features * * The Neighbouring Grey Level Dependence Features were proposed by Sun and Wee (1983) and * capture the coarsness of the image texture. They are rotational invariant. * * The features are calculated on a matrix \f$ m \f$. To obtain the matrix, a neighbourhood * around each feature is calculated and the number of voxels within the neighbourhood that * are greater than the center voxel plus \f$ \alpha \f$ is counted. This is called the * number of dependence voxels. The matrix gives the - * number of voxels with an intesity \f$ x \f$ and $\f d \f$ dependence neighbourhood voxels. + * number of voxels with an intesity \f$ x \f$ and \f$ d \f$ dependence neighbourhood voxels. * * The image is quantified prior to the calculation of the features. This reduces the number of * available intensity values. Instead of using the pure intensity value, the features are * calculated using the number of the bins as intensity value \f$ x_i \f$. The parameter of the * quantification of the image can be controlled using the general binning parameters as defined * in AbstractGlobalImageFeature. * * By default, the calculation is based on a 26 neighourhood for 3D and a 8 neighbourhood in 2D. It is further * possible to exclude directions from the calculation, e.g. calculating the feature in 2D, even if a * 3D image is passed. This is controlled by determine the * dimensionality of the neighbourhood using direction-related commands as described in AbstractGlobalImageFeature. * * In addition to this, the size of the neighbourhood can be controlled by setting the parameter * ngld::range. By default it is one. To pass more than one range, separate the ranges with * a semicolon. E.g. 1;2;3 would calculate the features for the ranges 1, 2, and 3. * * This feature calculator is activated by the option -neighbouring-grey-level-dependence * or -ngld. * * The features are calculated based on a mask. It is assumed that the mask is * a unsigned short image. All voxels with a value greater 0 are treated as masked. * * Several values are definied for the definition of the features. \f$ N_v \f$ is the number of masked voxels, * \f$N_s \f$ is the number of neighbourhoods, \f$ m_{x,\cdot} = \sum_d m{x,d} \f$ is the number of neighbourhoods * with a given intensity value, and likewise \f$ m_{\cdot, d} = \sum_x m{x,d} \f$ is the number of neighbourhoods * with a given number of dependence features: * - Neighbouring Grey Level Dependence::Low Dependence Emphasis: * \f[ \textup{Low dependence emphasis}= \frac{1}{N_s} \sum_d { \frac{m_{\cdot, d}}{d^2} } \f] * - Neighbouring Grey Level Dependence::High Dependence Emphasis: * \f[ \textup{High dependence emphasis}= \frac{1}{N_s} \sum_d { m_{\cdot, d} d^2} \f] * - Neighbouring Grey Level Dependence::Low Grey Level Count Emphasis: * \f[ \textup{Low grey level count emphasis}= \frac{1}{N_s} \sum_x { \frac{m_{x,\cdot}}{x^2} } \f] * - Neighbouring Grey Level Dependence::High Grey Level Count Emphasis: * \f[ \textup{High grey level count emphasis}= \frac{1}{N_s} \sum_x { m_{x,\cdot} x^2} \f] * - Neighbouring Grey Level Dependence::Low Dependence Low Grey Level Emphasis: * \f[ \textup{Low Dependence Low Grey Level Emphasis}= \frac{1}{N_s} \sum_x \sum_d { \frac{m_{x,d}}{x^2 d^2} } \f] * - Neighbouring Grey Level Dependence::Low Dependence High Grey Level Emphasis: * \f[ \textup{Low dependence high grey level emphasis}= \frac{1}{N_s} \sum_x \sum_d { \frac{x^2 m_{x,d}}{d^2} } \f] * - Neighbouring Grey Level Dependence::High Dependence Low Grey Level Emphasis: * \f[ \textup{High Dependence Low Grey Level Emphasis}= \frac{1}{N_s} \sum_x \sum_d { \frac{d^2 m_{x,d}}{x^2} } \f] * - Neighbouring Grey Level Dependence::High Dependence High Grey Level Emphasis: * \f[ \textup{High dependence high grey level emphasis}= \frac{1}{N_s} \sum_x \sum_d { x^2 d^2 m_{x,d} } \f] * - Neighbouring Grey Level Dependence::Grey level nonuniformity: * \f[ \textup{Grey level nonuniformity}= \frac{1}{N_s} \sum_x m_{x,\cdot}^2 \f] * - Neighbouring Grey Level Dependence::Grey level nonuniformity normalized: * \f[ \textup{Grey level nonuniformity normalized}= \frac{1}{N_s^2} \sum_x m_{x,\cdot}^2 \f] * - Neighbouring Grey Level Dependence::Dependence Count Nonuniformity: * \f[ \textup{Dependence count nonuniformity}= \frac{1}{N_s} \sum_d m_{\cdot, d}^2 \f] * - Neighbouring Grey Level Dependence::Dependence Count Nonuniformity Normalized: * \f[ \textup{Dependence count nonuniformity normalized}= \frac{1}{N_s^2} \sum_d m_{\cdot, d}^2 \f] * - Neighbouring Grey Level Dependence::DEpendence Count Percentage THe number of realized * neighbourhoods relativ to the theoretical maximum of realized neighbourhoods. This feature is always * one for this implementation as partial neighbourhoods are still considered. * - Neighbouring Grey Level Dependence::Grey Level Mean: The mean value of all grey level. * \f[ \textup{Grey Level Mean} = \mu_x = \frac{1}{N_s} \sum_x x m_{x,\cdot} \f] * - Neighbouring Grey Level Dependence::Grey Level Variance: * \f[ \textup{Grey level variance} = \frac{1}{N_s} \sum_x (x -mu_x)^2 m_{x, \cdot} \f] * - Neighbouring Grey Level Dependence::Dependence Count Mean: The mean value of all dependence counts. * \f[ \textup{Dependence count mean} = \mu_d = \frac{1}{N_s} \sum_d d m_{\cdot,d} \f] * - Neighbouring Grey Level Dependence::Dependence Count Variance: * \f[ \textup{Dependence count variance} = \frac{1}{N_s} \sum_d (d -mu_d)^2 m_{\cdot, d} \f] * - Neighbouring Grey Level Dependence::Dependence Count Entropy: This feature would be equivalent with * the Grey Level Entropy, which is therefore not included. It is based on the likelihood * for a given intensity- size combination \f$ p_{x,d} = \frac{m_{x,d}}{N_s} \f$. : * \f[ \textup{Dependence count entropy} = \sum_x \sum_d p_{x,d} \textup{log}_2 \left( p_{x,d} \right) \f] * - Neighbouring Grey Level Dependence::Dependence Count Energy: This feature would be equivalent with * the Grey Level Energy, which is therefore not included. It is based on the likelihood * for a given intensity- size combination \f$ p_{x,d} = \frac{m_{x,d}}{N_s} \f$. : * \f[ \textup{Dependence count energy} = \sum_x \sum_d p_{x,d}^2 \f] * - Neighbouring Grey Level Dependence::Expected Neighbourhood Size: The expected size of a * full neighbourhood. It depends on the dimension of the area that is looked at. * - Neighbouring Grey Level Dependence::Average Neighbourhood Size: The feature calculation * allows to consider partially masked neighbourhoods. Due to that, some neighbourhoods might be smaller. * This feature gives not the theoretical neighbourhood size but the average realized neighbourhood sizes. * - Neighbouring Grey Level Dependence::Average Incomplete Neighbourhood Size: Gives the average * size of all neighbourhoods that are not complete. * - Neighbouring Grey Level Dependence::Percentage of complete Neighbourhoods: Gives the percentage * of all complete neighbourhoods from all realized neighbourhoods. * - Neighbouring Grey Level Dependence::Percentage of Dependence Neighbour Voxels: Gives the * percentage of voxels in all neighbourhoods compared to the expected number of voxels. */ class MITKCLUTILITIES_EXPORT GIFNeighbouringGreyLevelDependenceFeature : public AbstractGlobalImageFeature { public: mitkClassMacro(GIFNeighbouringGreyLevelDependenceFeature, AbstractGlobalImageFeature); itkFactorylessNewMacro(Self); itkCloneMacro(Self); GIFNeighbouringGreyLevelDependenceFeature(); /** * \brief Calculates the Cooccurence-Matrix based features for this class. */ FeatureListType CalculateFeatures(const Image::Pointer & image, const Image::Pointer &feature) override; /** * \brief Returns a list of the names of all features that are calculated from this class */ FeatureNameListType GetFeatureNames() override; std::string GetCurrentFeatureEncoding() override; itkGetConstMacro(Range,double); itkSetMacro(Range, double); itkGetConstMacro(Alpha, int); itkSetMacro(Alpha, int); void CalculateFeaturesUsingParameters(const Image::Pointer & feature, const Image::Pointer &mask, const Image::Pointer &maskNoNAN, FeatureListType &featureList) override; void AddArguments(mitkCommandLineParser &parser) override; struct GIFNeighbouringGreyLevelDependenceFeatureConfiguration { double range; unsigned int direction; int alpha; double MinimumIntensity; double MaximumIntensity; int Bins; std::string FeatureEncoding; }; private: double m_Range; int m_Alpha; }; } #endif //mitkGIFNeighbouringGreyLevelDependenceFeature_h diff --git a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFIntensityVolumeHistogramFeatures.cpp b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFIntensityVolumeHistogramFeatures.cpp index d2ecb1f42d..c520c1d3d7 100644 --- a/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFIntensityVolumeHistogramFeatures.cpp +++ b/Modules/Classification/CLUtilities/src/GlobalImageFeatures/mitkGIFIntensityVolumeHistogramFeatures.cpp @@ -1,169 +1,169 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include // MITK #include #include #include #include // ITK #include #include // STL #include -struct GIFIntensityVolumeHistogramFeaturesParameters +namespace { - mitk::IntensityQuantifier::Pointer quantifier; - std::string prefix; -}; - + struct GIFIntensityVolumeHistogramFeaturesParameters + { + mitk::IntensityQuantifier::Pointer quantifier; + std::string prefix; + }; -template -static void -CalculateIntensityPeak(itk::Image* itkImage, mitk::Image::Pointer mask, GIFIntensityVolumeHistogramFeaturesParameters params, mitk::GIFIntensityVolumeHistogramFeatures::FeatureListType & featureList) -{ - typedef itk::Image ImageType; - typedef itk::Image MaskType; + template + void CalculateIntensityPeak(itk::Image* itkImage, mitk::Image::Pointer mask, GIFIntensityVolumeHistogramFeaturesParameters params, mitk::GIFIntensityVolumeHistogramFeatures::FeatureListType& featureList) + { + typedef itk::Image ImageType; + typedef itk::Image MaskType; - typename MaskType::Pointer itkMask = MaskType::New(); - mitk::CastToItkImage(mask, itkMask); + typename MaskType::Pointer itkMask = MaskType::New(); + mitk::CastToItkImage(mask, itkMask); - mitk::IntensityQuantifier::Pointer quantifier = params.quantifier; - std::string prefix = params.prefix; + mitk::IntensityQuantifier::Pointer quantifier = params.quantifier; + std::string prefix = params.prefix; - itk::ImageRegionConstIterator iter(itkImage, itkImage->GetLargestPossibleRegion()); - itk::ImageRegionConstIterator iterMask(itkMask, itkMask->GetLargestPossibleRegion()); + itk::ImageRegionConstIterator iter(itkImage, itkImage->GetLargestPossibleRegion()); + itk::ImageRegionConstIterator iterMask(itkMask, itkMask->GetLargestPossibleRegion()); - MITK_INFO << "Quantification: " << quantifier->GetMinimum() << " to " << quantifier->GetMaximum() << " with " << quantifier->GetBins()<< " bins"; + MITK_INFO << "Quantification: " << quantifier->GetMinimum() << " to " << quantifier->GetMaximum() << " with " << quantifier->GetBins() << " bins"; - iter.GoToBegin(); - iterMask.GoToBegin(); - std::vector hist; - hist.resize(quantifier->GetBins() , 0); + iter.GoToBegin(); + iterMask.GoToBegin(); + std::vector hist; + hist.resize(quantifier->GetBins(), 0); - int count = 0; - while (!iter.IsAtEnd()) - { - if (iterMask.Get() > 0) + int count = 0; + while (!iter.IsAtEnd()) { - double value = iter.Get(); - //std::size_t index = std::floor((value - minimum) / (maximum - minimum) * (bins-1)); - std::size_t index = quantifier->IntensityToIndex(value); - ++count; - hist[index] += 1.0;// / count; + if (iterMask.Get() > 0) + { + double value = iter.Get(); + //std::size_t index = std::floor((value - minimum) / (maximum - minimum) * (bins-1)); + std::size_t index = quantifier->IntensityToIndex(value); + ++count; + hist[index] += 1.0;// / count; + } + ++iterMask; + ++iter; } - ++iterMask; - ++iter; - } - bool notFoundIntenstiy010 = true; - bool notFoundIntenstiy090 = true; + bool notFoundIntenstiy010 = true; + bool notFoundIntenstiy090 = true; - double intensity010 = -1; - double intensity090 = -1; - double fraction = 0; - double auc = 0; - bool firstRound = true; - for (int i = quantifier->GetBins()-1; i >= 0; --i) - { - hist[i] /= count; - hist[i] += fraction; - fraction = hist[i]; - if (!firstRound) + double intensity010 = -1; + double intensity090 = -1; + double fraction = 0; + double auc = 0; + bool firstRound = true; + for (int i = quantifier->GetBins() - 1; i >= 0; --i) { - auc += 0.5 * (hist[i] + hist[i+1]) / (quantifier->GetBins()-1); + hist[i] /= count; + hist[i] += fraction; + fraction = hist[i]; + if (!firstRound) + { + auc += 0.5 * (hist[i] + hist[i + 1]) / (quantifier->GetBins() - 1); + } + firstRound = false; + + if (notFoundIntenstiy010 && fraction > 0.1) + { + intensity010 = quantifier->IndexToMeanIntensity(i + 1); + notFoundIntenstiy010 = false; + } + if (notFoundIntenstiy090 && fraction > 0.9) + { + intensity090 = quantifier->IndexToMeanIntensity(i + 1); + notFoundIntenstiy090 = false; + } } - firstRound = false; - if (notFoundIntenstiy010 && fraction > 0.1) - { - intensity010 = quantifier->IndexToMeanIntensity(i + 1); - notFoundIntenstiy010 = false; - } - if (notFoundIntenstiy090 && fraction > 0.9) - { - intensity090 = quantifier->IndexToMeanIntensity(i + 1); - notFoundIntenstiy090 = false; - } + unsigned int index010 = std::ceil(quantifier->GetBins() * 0.1); + unsigned int index090 = std::floor(quantifier->GetBins() * 0.9); + + featureList.push_back(std::make_pair(prefix + "Volume fraction at 0.10 intensity", hist[index010])); + featureList.push_back(std::make_pair(prefix + "Volume fraction at 0.90 intensity", hist[index090])); + featureList.push_back(std::make_pair(prefix + "Intensity at 0.10 volume", intensity010)); + featureList.push_back(std::make_pair(prefix + "Intensity at 0.90 volume", intensity090)); + featureList.push_back(std::make_pair(prefix + "Difference volume fraction at 0.10 and 0.90 intensity", std::abs(hist[index010] - hist[index090]))); + featureList.push_back(std::make_pair(prefix + "Difference intensity at 0.10 and 0.90 volume", std::abs(intensity090 - intensity010))); + featureList.push_back(std::make_pair(prefix + "Area under IVH curve", auc)); + //featureList.push_back(std::make_pair("Local Intensity Global Intensity Peak", globalPeakValue)); } - - unsigned int index010 = std::ceil(quantifier->GetBins() * 0.1); - unsigned int index090 = std::floor(quantifier->GetBins() * 0.9); - - featureList.push_back(std::make_pair(prefix + "Volume fraction at 0.10 intensity", hist[index010])); - featureList.push_back(std::make_pair(prefix + "Volume fraction at 0.90 intensity", hist[index090])); - featureList.push_back(std::make_pair(prefix + "Intensity at 0.10 volume", intensity010)); - featureList.push_back(std::make_pair(prefix + "Intensity at 0.90 volume", intensity090)); - featureList.push_back(std::make_pair(prefix + "Difference volume fraction at 0.10 and 0.90 intensity", std::abs(hist[index010] - hist[index090]))); - featureList.push_back(std::make_pair(prefix + "Difference intensity at 0.10 and 0.90 volume", std::abs(intensity090 - intensity010))); - featureList.push_back(std::make_pair(prefix + "Area under IVH curve", auc)); - //featureList.push_back(std::make_pair("Local Intensity Global Intensity Peak", globalPeakValue)); } - mitk::GIFIntensityVolumeHistogramFeatures::GIFIntensityVolumeHistogramFeatures() { SetLongName("intensity-volume-histogram"); SetShortName("ivoh"); SetFeatureClassName("Intensity Volume Histogram"); } mitk::GIFIntensityVolumeHistogramFeatures::FeatureListType mitk::GIFIntensityVolumeHistogramFeatures::CalculateFeatures(const Image::Pointer & image, const Image::Pointer &mask) { InitializeQuantifier(image, mask, 1000); FeatureListType featureList; GIFIntensityVolumeHistogramFeaturesParameters params; params.quantifier = GetQuantifier(); params.prefix = FeatureDescriptionPrefix(); AccessByItk_3(image, CalculateIntensityPeak, mask, params, featureList); return featureList; } mitk::GIFIntensityVolumeHistogramFeatures::FeatureNameListType mitk::GIFIntensityVolumeHistogramFeatures::GetFeatureNames() { FeatureNameListType featureList; return featureList; } void mitk::GIFIntensityVolumeHistogramFeatures::AddArguments(mitkCommandLineParser &parser) { std::string name = GetOptionPrefix(); parser.addArgument(GetLongName(), name, mitkCommandLineParser::Bool, "Use Local Intensity", "calculates local intensity based features", us::Any()); AddQuantifierArguments(parser); } void mitk::GIFIntensityVolumeHistogramFeatures::CalculateFeaturesUsingParameters(const Image::Pointer & feature, const Image::Pointer &mask, const Image::Pointer &, FeatureListType &featureList) { InitializeQuantifierFromParameters(feature, mask, 1000); auto parsedArgs = GetParameter(); if (parsedArgs.count(GetLongName())) { MITK_INFO << "Start calculating local intensity features ...."; auto localResults = this->CalculateFeatures(feature, mask); featureList.insert(featureList.end(), localResults.begin(), localResults.end()); MITK_INFO << "Finished calculating local intensity features...."; } } std::string mitk::GIFIntensityVolumeHistogramFeatures::GetCurrentFeatureEncoding() { return QuantifierParameterString(); } diff --git a/Modules/Core/include/mitkDataNode.h b/Modules/Core/include/mitkDataNode.h index fd6e62ef21..7199095d72 100644 --- a/Modules/Core/include/mitkDataNode.h +++ b/Modules/Core/include/mitkDataNode.h @@ -1,614 +1,598 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef DATATREENODE_H_HEADER_INCLUDED_C1E14338 #define DATATREENODE_H_HEADER_INCLUDED_C1E14338 #include "mitkBaseData.h" //#include "mitkMapper.h" #include "mitkDataInteractor.h" #include "mitkIdentifiable.h" #include "mitkIPropertyOwner.h" -#ifdef MBI_NO_STD_NAMESPACE -#define MBI_STD -#include -#include -#else -#define MBI_STD std #include #include -#endif #include "mitkColorProperty.h" #include "mitkPropertyList.h" #include "mitkStringProperty.h" //#include "mitkMapper.h" #include "mitkGeometry3D.h" #include "mitkLevelWindow.h" #include #include class vtkLinearTransform; namespace mitk { class BaseRenderer; class Mapper; /** * \brief Class for nodes of the DataTree * * Contains the data (instance of BaseData), a list of mappers, which can * draw the data, a transform (vtkTransform) and a list of properties * (PropertyList). * \ingroup DataManagement * * \todo clean up all the GetProperty methods. There are too many different flavours... Can most probably be reduced * to * bool GetProperty(type&) * * \warning Change in semantics of SetProperty() since Aug 25th 2006. Check your usage of this method if you do * more with properties than just call SetProperty( "key", new SomeProperty("value") ). */ class MITKCORE_EXPORT DataNode : public itk::DataObject, public IPropertyOwner { public: typedef mitk::Geometry3D::Pointer Geometry3DPointer; typedef std::vector> MapperVector; typedef std::map MapOfPropertyLists; typedef std::vector PropertyListKeyNames; typedef std::set GroupTagList; /** * \brief Definition of an itk::Event that is invoked when * a DataInteractor is set on this DataNode. */ itkEventMacro(InteractorChangedEvent, itk::AnyEvent) mitkClassMacroItkParent(DataNode, itk::DataObject); itkFactorylessNewMacro(Self); itkCloneMacro(Self); // IPropertyProvider BaseProperty::ConstPointer GetConstProperty(const std::string &propertyKey, const std::string &contextName = "", bool fallBackOnDefaultContext = true) const override; std::vector GetPropertyKeys(const std::string &contextName = "", bool includeDefaultContext = false) const override; std::vector GetPropertyContextNames() const override; // IPropertyOwner BaseProperty * GetNonConstProperty(const std::string &propertyKey, const std::string &contextName = "", bool fallBackOnDefaultContext = true) override; void SetProperty(const std::string &propertyKey, BaseProperty *property, const std::string &contextName = "", bool fallBackOnDefaultContext = false) override; void RemoveProperty(const std::string &propertyKey, const std::string &contextName = "", bool fallBackOnDefaultContext = false) override; mitk::Mapper *GetMapper(MapperSlotId id) const; /** * \brief Get the data object (instance of BaseData, e.g., an Image) * managed by this DataNode */ BaseData *GetData() const; /** * \brief Get the transformation applied prior to displaying the data as * a vtkTransform * \deprecated use GetData()->GetGeometry()->GetVtkTransform() instead */ vtkLinearTransform *GetVtkTransform(int t = 0) const; /** * \brief Set the data object (instance of BaseData, e.g., an Image) * managed by this DataNode * * Prior set properties are kept if previous data of the node already exists and has the same * type as the new data to be set. Otherwise, the default properties are used. * In case that previous data already exists, the property list of the data node is cleared * before setting new default properties. * * \warning the actor-mode of the vtkInteractor does not work any more, if the transform of the * data-tree-node is connected to the transform of the basedata via vtkTransform->SetInput. */ virtual void SetData(mitk::BaseData *baseData); /** * \brief Set the Interactor. */ virtual void SetDataInteractor(const DataInteractor::Pointer interactor); virtual DataInteractor::Pointer GetDataInteractor() const; mitk::DataNode &operator=(const DataNode &right); mitk::DataNode &operator=(BaseData *right); virtual void SetMapper(MapperSlotId id, mitk::Mapper *mapper); void UpdateOutputInformation() override; void SetRequestedRegionToLargestPossibleRegion() override; bool RequestedRegionIsOutsideOfTheBufferedRegion() override; bool VerifyRequestedRegion() override; void SetRequestedRegion(const itk::DataObject *data) override; void CopyInformation(const itk::DataObject *data) override; /** * \brief The "names" used for (renderer-specific) PropertyLists in GetPropertyList(string). * * All possible values for the "renderer" parameters of * the diverse GetProperty/List() methods. */ PropertyListKeyNames GetPropertyListNames() const; /** * \brief Set the property (instance of BaseProperty) with key \a propertyKey in the PropertyList * of the \a renderer (if nullptr, use BaseRenderer-independent PropertyList). This is set-by-value. * * \warning Change in semantics since Aug 25th 2006. Check your usage of this method if you do * more with properties than just call SetProperty( "key", new SomeProperty("value") ). * * \sa GetProperty * \sa m_PropertyList * \sa m_MapOfPropertyLists */ void SetProperty(const char *propertyKey, BaseProperty *property, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Replace the property (instance of BaseProperty) with key \a propertyKey in the PropertyList * of the \a renderer (if nullptr, use BaseRenderer-independent PropertyList). This is set-by-reference. * * If \a renderer is \a nullptr the property is set in the BaseRenderer-independent * PropertyList of this DataNode. * \sa GetProperty * \sa m_PropertyList * \sa m_MapOfPropertyLists */ void ReplaceProperty(const char *propertyKey, BaseProperty *property, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Add the property (instance of BaseProperty) if it does * not exist (or always if\a overwrite is\a true) * with key \a propertyKey in the PropertyList * of the \a renderer (if nullptr, use BaseRenderer-independent * PropertyList). This is set-by-value. * * For\a overwrite ==\a false the property is\em not changed * if it already exists. For\a overwrite ==\a true the method * is identical to SetProperty. * * \sa SetProperty * \sa GetProperty * \sa m_PropertyList * \sa m_MapOfPropertyLists */ void AddProperty(const char *propertyKey, BaseProperty *property, const mitk::BaseRenderer *renderer = nullptr, bool overwrite = false); /** * \brief Get the PropertyList of the \a renderer. If \a renderer is \a * nullptr, the BaseRenderer-independent PropertyList of this DataNode * is returned. * \sa GetProperty * \sa m_PropertyList * \sa m_MapOfPropertyLists */ mitk::PropertyList *GetPropertyList(const mitk::BaseRenderer *renderer = nullptr) const; mitk::PropertyList *GetPropertyList(const std::string &rendererName) const; /** * \brief Add values from another PropertyList. * * Overwrites values in m_PropertyList only when possible (i.e. when types are compatible). * If you want to allow for object type changes (replacing a "visible":BoolProperty with "visible":IntProperty, * set the \param replace. * * \param replace true: if \param pList contains a property "visible" of type ColorProperty and our m_PropertyList * also has a "visible" property of a different type (e.g. BoolProperty), change the type, i.e. replace the objects * behind the pointer. * * \sa SetProperty * \sa ReplaceProperty * \sa m_PropertyList */ void ConcatenatePropertyList(PropertyList *pList, bool replace = false); /** * \brief Get the property (instance of BaseProperty) with key \a propertyKey from the PropertyList * of the \a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList. * * If \a renderer is \a nullptr or the \a propertyKey cannot be found * in the PropertyList specific to \a renderer or is disabled there, the BaseRenderer-independent * PropertyList of this DataNode is queried. * * If \a fallBackOnDataProperties is true, the data property list is queried as a last resort. * * \sa GetPropertyList * \sa m_PropertyList * \sa m_MapOfPropertyLists */ mitk::BaseProperty *GetProperty(const char *propertyKey, const mitk::BaseRenderer *renderer = nullptr, bool fallBackOnDataProperties = true) const; /** * \brief Get the property of type T with key \a propertyKey from the PropertyList * of the \a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList. * * If \a renderer is \a nullptr or the \a propertyKey cannot be found * in the PropertyList specific to \a renderer or is disabled there, the BaseRenderer-independent * PropertyList of this DataNode is queried. * \sa GetPropertyList * \sa m_PropertyList * \sa m_MapOfPropertyLists */ template bool GetProperty(itk::SmartPointer &property, const char *propertyKey, const mitk::BaseRenderer *renderer = nullptr) const { property = dynamic_cast(GetProperty(propertyKey, renderer)); return property.IsNotNull(); } /** * \brief Get the property of type T with key \a propertyKey from the PropertyList * of the \a renderer, if available there, otherwise use the BaseRenderer-independent PropertyList. * * If \a renderer is \a nullptr or the \a propertyKey cannot be found * in the PropertyList specific to \a renderer or is disabled there, the BaseRenderer-independent * PropertyList of this DataNode is queried. * \sa GetPropertyList * \sa m_PropertyList * \sa m_MapOfPropertyLists */ template bool GetProperty(T *&property, const char *propertyKey, const mitk::BaseRenderer *renderer = nullptr) const { property = dynamic_cast(GetProperty(propertyKey, renderer)); return property != nullptr; } /** * \brief Convenience access method for GenericProperty properties * (T being the type of the second parameter) * \return \a true property was found */ template bool GetPropertyValue(const char *propertyKey, T &value, const mitk::BaseRenderer *renderer = nullptr) const { GenericProperty *gp = dynamic_cast *>(GetProperty(propertyKey, renderer)); if (gp != nullptr) { value = gp->GetValue(); return true; } return false; } /// \brief Get a set of all group tags from this node's property list GroupTagList GetGroupTags() const; /** * \brief Convenience access method for bool properties (instances of * BoolProperty) * \return \a true property was found */ bool GetBoolProperty(const char *propertyKey, bool &boolValue, const mitk::BaseRenderer *renderer = nullptr) const; /** * \brief Convenience access method for int properties (instances of * IntProperty) * \return \a true property was found */ bool GetIntProperty(const char *propertyKey, int &intValue, const mitk::BaseRenderer *renderer = nullptr) const; /** * \brief Convenience access method for float properties (instances of * FloatProperty) * \return \a true property was found */ bool GetFloatProperty(const char *propertyKey, float &floatValue, const mitk::BaseRenderer *renderer = nullptr) const; /** * \brief Convenience access method for double properties (instances of * DoubleProperty) * * If there is no DoubleProperty for the given\c propertyKey argument, the method * looks for a corresponding FloatProperty instance. * * \return \a true property was found */ bool GetDoubleProperty(const char *propertyKey, double &doubleValue, const mitk::BaseRenderer *renderer = nullptr) const; /** * \brief Convenience access method for string properties (instances of * StringProperty) * \return \a true property was found */ bool GetStringProperty(const char *propertyKey, std::string &string, const mitk::BaseRenderer *renderer = nullptr) const; /** * \brief Convenience access method for color properties (instances of * ColorProperty) * \return \a true property was found */ bool GetColor(float rgb[3], const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "color") const; /** * \brief Convenience access method for level-window properties (instances of * LevelWindowProperty) * \return \a true property was found */ bool GetLevelWindow(mitk::LevelWindow &levelWindow, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "levelwindow") const; /** * \brief set the node as selected */ void SetSelected(bool selected, const mitk::BaseRenderer *renderer = nullptr); /** * \brief set the node as selected * \return \a true node is selected */ bool IsSelected(const mitk::BaseRenderer *renderer = nullptr); /** * \brief Convenience access method for accessing the name of an object (instance of * StringProperty with property-key "name") * \return \a true property was found */ bool GetName(std::string &nodeName, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "name") const { return GetStringProperty(propertyKey, nodeName, renderer); } /** * \brief Extra convenience access method for accessing the name of an object (instance of * StringProperty with property-key "name"). * * This method does not take the renderer specific * propertylists into account, because the name of an object should never be renderer specific. * \returns a std::string with the name of the object (content of "name" Property). * If there is no "name" Property, an empty string will be returned. */ virtual std::string GetName() const { mitk::StringProperty *sp = dynamic_cast(this->GetProperty("name")); if (sp == nullptr) return ""; return sp->GetValue(); } /** Value constant that is used indicate that node names are not set so far.*/ static std::string NO_NAME_VALUE() { return "No Name!"; } /** * \brief Extra convenience access method to set the name of an object. * * The name will be stored in the non-renderer-specific PropertyList in a StringProperty named "name". */ virtual void SetName(const char *name) { if (name == nullptr) return; this->SetProperty("name", StringProperty::New(name)); } /** * \brief Extra convenience access method to set the name of an object. * * The name will be stored in the non-renderer-specific PropertyList in a StringProperty named "name". */ virtual void SetName(const std::string name) { this->SetName(name.c_str()); } /** * \brief Convenience access method for visibility properties (instances * of BoolProperty with property-key "visible") * \return \a true property was found * \sa IsVisible */ bool GetVisibility(bool &visible, const mitk::BaseRenderer *renderer, const char *propertyKey = "visible") const { return GetBoolProperty(propertyKey, visible, renderer); } /** * \brief Convenience access method for opacity properties (instances of * FloatProperty) * \return \a true property was found */ bool GetOpacity(float &opacity, const mitk::BaseRenderer *renderer, const char *propertyKey = "opacity") const; /** * \brief Convenience access method for boolean properties (instances * of BoolProperty). Return value is the value of the property. If the property is * not found, the value of \a defaultIsOn is returned. * * Thus, the return value has a different meaning than in the * GetBoolProperty method! * \sa GetBoolProperty */ bool IsOn(const char *propertyKey, const mitk::BaseRenderer *renderer, bool defaultIsOn = true) const { if (propertyKey == nullptr) return defaultIsOn; GetBoolProperty(propertyKey, defaultIsOn, renderer); return defaultIsOn; } /** * \brief Convenience access method for visibility properties (instances * of BoolProperty). Return value is the visibility. Default is * visible==true, i.e., true is returned even if the property (\a * propertyKey) is not found. * * Thus, the return value has a different meaning than in the * GetVisibility method! * \sa GetVisibility * \sa IsOn */ bool IsVisible(const mitk::BaseRenderer *renderer, const char *propertyKey = "visible", bool defaultIsOn = true) const { return IsOn(propertyKey, renderer, defaultIsOn); } /** * \brief Convenience method for setting color properties (instances of * ColorProperty) */ void SetColor(const mitk::Color &color, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "color"); /** * \brief Convenience method for setting color properties (instances of * ColorProperty) */ void SetColor(float red, float green, float blue, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "color"); /** * \brief Convenience method for setting color properties (instances of * ColorProperty) */ void SetColor(const float rgb[3], const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "color"); /** * \brief Convenience method for setting visibility properties (instances * of BoolProperty) * \param visible If set to true, the data will be rendered. If false, the render will skip this data. * \param renderer Specify a renderer if the visibility shall be specific to a renderer * \param propertykey Can be used to specify a user defined name of the visibility propery. */ void SetVisibility(bool visible, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "visible"); /** * \brief Convenience method for setting opacity properties (instances of * FloatProperty) */ void SetOpacity(float opacity, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "opacity"); /** * \brief Convenience method for setting level-window properties * (instances of LevelWindowProperty) */ void SetLevelWindow(mitk::LevelWindow levelWindow, const mitk::BaseRenderer *renderer = nullptr, const char *propertyKey = "levelwindow"); /** * \brief Convenience method for setting int properties (instances of * IntProperty) */ void SetIntProperty(const char *propertyKey, int intValue, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Convenience method for setting boolean properties (instances of * BoolProperty) */ void SetBoolProperty(const char *propertyKey, bool boolValue, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Convenience method for setting float properties (instances of * FloatProperty) */ void SetFloatProperty(const char *propertyKey, float floatValue, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Convenience method for setting double properties (instances of * DoubleProperty) */ void SetDoubleProperty(const char *propertyKey, double doubleValue, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Convenience method for setting string properties (instances of * StringProperty) */ void SetStringProperty(const char *propertyKey, const char *string, const mitk::BaseRenderer *renderer = nullptr); /** * \brief Get the timestamp of the last change of the contents of this node or * the referenced BaseData. */ unsigned long GetMTime() const override; /** * \brief Get the timestamp of the last change of the reference to the * BaseData. */ unsigned long GetDataReferenceChangedTime() const { return m_DataReferenceChangedTime.GetMTime(); } protected: DataNode(); ~DataNode() override; /// Invoked when the property list was modified. Calls Modified() of the DataNode virtual void PropertyListModified(const itk::Object *caller, const itk::EventObject &event); /// \brief Mapper-slots mutable MapperVector m_Mappers; /** * \brief The data object (instance of BaseData, e.g., an Image) managed * by this DataNode */ BaseData::Pointer m_Data; /** * \brief BaseRenderer-independent PropertyList * * Properties herein can be overwritten specifically for each BaseRenderer * by the BaseRenderer-specific properties defined in m_MapOfPropertyLists. */ PropertyList::Pointer m_PropertyList; /// \brief Map associating each BaseRenderer with its own PropertyList mutable MapOfPropertyLists m_MapOfPropertyLists; DataInteractor::Pointer m_DataInteractor; /// \brief Timestamp of the last change of m_Data itk::TimeStamp m_DataReferenceChangedTime; unsigned long m_PropertyListModifiedObserverTag; }; -#if (_MSC_VER > 1200) || !defined(_MSC_VER) - MITKCORE_EXPORT MBI_STD::istream &operator>>(MBI_STD::istream &i, DataNode::Pointer &dtn); - - MITKCORE_EXPORT MBI_STD::ostream &operator<<(MBI_STD::ostream &o, DataNode::Pointer &dtn); -#endif + MITKCORE_EXPORT std::istream &operator>>(std::istream &i, DataNode::Pointer &dtn); + MITKCORE_EXPORT std::ostream &operator<<(std::ostream &o, DataNode::Pointer &dtn); } // namespace mitk -#if ((defined(_MSC_VER)) && (_MSC_VER <= 1200)) -MITKCORE_EXPORT MBI_STD::istream &operator>>(MBI_STD::istream &i, mitk::DataNode::Pointer &dtn); - -MITKCORE_EXPORT MBI_STD::ostream &operator<<(MBI_STD::ostream &o, mitk::DataNode::Pointer &dtn); -#endif - #endif /* DATATREENODE_H_HEADER_INCLUDED_C1E14338 */ diff --git a/Modules/Core/include/mitkPixelTypeTraits.h b/Modules/Core/include/mitkPixelTypeTraits.h index ee5eddd913..16772df28d 100644 --- a/Modules/Core/include/mitkPixelTypeTraits.h +++ b/Modules/Core/include/mitkPixelTypeTraits.h @@ -1,272 +1,271 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef PIXELTYPETRAITS_H #define PIXELTYPETRAITS_H #include #include #include #include #include #include /** \file mitkPixelTypeTraits.h * * The pixel type traits are in general used for compile time resolution of the component type and * the number of components for compound types like the ones in ItkImageType. * The default values are used to define the corresponding variable also for scalar types */ namespace itk { /** Forward declaration of the Variable Length Vector class from ITK */ template class VariableLengthVector; } #define MITK_PIXEL_COMPONENT_TYPE(type, ctype, name) \ template <> \ struct mitk::MapPixelComponentType \ { \ static const int value = ctype; \ } template <> \ std::string mitk::PixelComponentTypeToString() \ { \ return name; \ } namespace mitk { static const int PixelUserType = itk::ImageIOBase::MATRIX + 1; static const int PixelComponentUserType = itk::ImageIOBase::DOUBLE + 1; /** * Maps pixel component types (primitive types like int, short, double, etc. and custom * types) to and integer constant. Specialize this template for custom types by using the * #MITK_PIXEL_COMPONENT_TYPE macro. */ template struct MapPixelComponentType { static const int value = itk::ImageIOBase::MapPixelType::CType; }; /** \brief This is an implementation of a type trait to provide a compile-time check for PixelType used in the instantiation of an itk::Image */ template struct isPrimitiveType { static const bool value = false; }; -/** \def DEFINE_TYPE_PRIMITIVE macro which provides a partial specialization for the \sa isPrimitiveType - object */ +/** \brief Provides a partial specialization for the \sa isPrimitiveType object */ #define DEFINE_TYPE_PRIMITIVE(_TYPEIN) \ template <> \ struct isPrimitiveType<_TYPEIN> \ { \ static const bool value = true; \ } /** \brief Partial specialization (unsigned char) for the isPrimitiveType object */ DEFINE_TYPE_PRIMITIVE(unsigned char); /** \brief Partial specialization (char) for the isPrimitiveType object */ DEFINE_TYPE_PRIMITIVE(char); /** \brief Partial specialization (signed char) for the isPrimitiveType object */ DEFINE_TYPE_PRIMITIVE(signed char); /** \brief Partial specialization (unsigned short) for the isPrimitiveType object */ DEFINE_TYPE_PRIMITIVE(unsigned short); /** \brief Partial specialization (short) for the isPrimitiveType object */ DEFINE_TYPE_PRIMITIVE(short); /** \brief Partial specialization (unsigned int) for the isPrimitiveType object */ DEFINE_TYPE_PRIMITIVE(unsigned int); /** \brief Partial specialization (int) for the isPrimitiveType object */ DEFINE_TYPE_PRIMITIVE(int); /** \brief Partial specialization (long int) for the isPrimitiveType object */ DEFINE_TYPE_PRIMITIVE(long int); /** \brief Partial specialization (long unsigned int) for the isPrimitiveType object */ DEFINE_TYPE_PRIMITIVE(long unsigned int); /** \brief Partial specialization (float) for the isPrimitiveType object */ DEFINE_TYPE_PRIMITIVE(float); /** \brief Partial specialization (double) for the isPrimitiveType object */ DEFINE_TYPE_PRIMITIVE(double); template struct ImageTypeTrait { typedef itk::Image ImageType; static const bool IsVectorImage = false; }; template struct ImageTypeTrait, VDimension> { typedef itk::VectorImage ImageType; static const bool IsVectorImage = true; }; template struct ImageTypeTrait { typedef T ImageType; static const bool IsVectorImage = false; }; template struct ImageTypeTrait, 0> { typedef itk::VectorImage ImageType; static const bool IsVectorImage = true; }; /** \brief Compile-time trait for resolving the ValueType from an ItkImageType */ template struct PixelTypeTrait { typedef T ValueType; }; /** \brief Partial specialization for the PixelTypeTrait * * Specialization for the false value. Used to define the value type for non-primitive pixel types */ template struct PixelTypeTrait { typedef typename T::ValueType ValueType; }; /** \brief Compile time resolving of the type of a component */ template struct GetComponentType { typedef typename PixelTypeTrait::value, T>::ValueType ComponentType; }; /** \brief Object for compile-time resolving of the number of components for given type. * * Default value for the component number is 1 */ template struct ComponentsTrait { static const size_t Size = 1; }; /** \brief Partial specialization for the ComponentsTraits in case of compound types */ template struct ComponentsTrait { static const size_t Size = T::ValueType::Length; }; typedef itk::ImageIOBase::IOPixelType itkIOPixelType; /** \brief Object for compile-time translation of a composite pixel type into an itk::ImageIOBase::IOPixelType * information * * The default value of the IOCompositeType is the UNKNOWNPIXELTYPE, the default value will be used for all but the * types below with own partial specialization. The values of the IOCompositeType member in the specializations * correspond * to the values of the itk::ImageIOBase::IOPixelType enum values. */ template struct MapCompositePixelType { static const itkIOPixelType IOCompositeType = itk::ImageIOBase::UNKNOWNPIXELTYPE; }; //------------------------ // Partial template specialization for fixed-length types //------------------------ template struct MapCompositePixelType> { static const itkIOPixelType IOCompositeType = itk::ImageIOBase::RGB; }; template struct MapCompositePixelType> { static const itkIOPixelType IOCompositeType = itk::ImageIOBase::RGBA; }; template struct MapCompositePixelType> { static const itkIOPixelType IOCompositeType = itk::ImageIOBase::DIFFUSIONTENSOR3D; }; template struct MapCompositePixelType> { static const itkIOPixelType IOCompositeType = itk::ImageIOBase::VECTOR; }; //------------------------ // Partial template specialization for variable-length types //------------------------ template struct MapCompositePixelType> { static const itkIOPixelType IOCompositeType = itk::ImageIOBase::VECTOR; }; template struct MapCompositePixelType> { static const itkIOPixelType IOCompositeType = itk::ImageIOBase::COVARIANTVECTOR; }; template struct MapCompositePixelType> { static const itkIOPixelType IOCompositeType = itk::ImageIOBase::COVARIANTVECTOR; }; template struct MapCompositePixelType> { static const itkIOPixelType IOCompositeType = itk::ImageIOBase::MATRIX; }; /** \brief Object for compile-time translation of a pixel type into an itk::ImageIOBase::IOPixelType information * * The first template parameter is the pixel type to be translated, the second parameter determines the processing * way. For non-primitive types the first template parameter is passed to the MapCompositePixelType object to be * resolved there * for primitive types the value is set to SCALAR. * * To initalize the flag correctly in compile-time use the \sa isPrimitiveType trait. */ template struct MapPixelType { static const itkIOPixelType IOPixelType = MapCompositePixelType::IOCompositeType; static const int IOComponentType = MapPixelComponentType::ComponentType>::value; }; /** \brief Partial specialization for setting the IOPixelType for primitive types to SCALAR */ template struct MapPixelType { static const itkIOPixelType IOPixelType = itk::ImageIOBase::SCALAR; static const int IOComponentType = MapPixelComponentType::value; }; } // end namespace mitk #endif // PIXELTYPETRAITS_H diff --git a/Modules/Core/src/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp b/Modules/Core/src/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp index 1519b90c5d..b0656e48f5 100644 --- a/Modules/Core/src/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp +++ b/Modules/Core/src/Algorithms/mitkClippedSurfaceBoundsCalculator.cpp @@ -1,292 +1,292 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkClippedSurfaceBoundsCalculator.h" #include "mitkLine.h" #define ROUND_P(x) ((x) >= 0 ? (int)((x) + 0.5) : (int)((x)-0.5)) mitk::ClippedSurfaceBoundsCalculator::ClippedSurfaceBoundsCalculator(const mitk::PlaneGeometry *geometry, mitk::Image::Pointer image) : m_PlaneGeometry(nullptr), m_Geometry3D(nullptr), m_Image(nullptr) { this->InitializeOutput(); this->SetInput(geometry, image); } mitk::ClippedSurfaceBoundsCalculator::ClippedSurfaceBoundsCalculator(const mitk::BaseGeometry *geometry, mitk::Image::Pointer image) : m_PlaneGeometry(nullptr), m_Geometry3D(nullptr), m_Image(nullptr) { this->InitializeOutput(); this->SetInput(geometry, image); } mitk::ClippedSurfaceBoundsCalculator::ClippedSurfaceBoundsCalculator(const PointListType pointlist, mitk::Image::Pointer image) : m_PlaneGeometry(nullptr), m_Geometry3D(nullptr), m_Image(image) { this->InitializeOutput(); m_ObjectPointsInWorldCoordinates = pointlist; } void mitk::ClippedSurfaceBoundsCalculator::InitializeOutput() { // initialize with meaningless slice indices m_MinMaxOutput.clear(); m_MinMaxOutput.reserve(3); for (int i = 0; i < 3; i++) { m_MinMaxOutput.push_back(OutputType(std::numeric_limits::max(), std::numeric_limits::min())); } } mitk::ClippedSurfaceBoundsCalculator::~ClippedSurfaceBoundsCalculator() { } void mitk::ClippedSurfaceBoundsCalculator::SetInput(const mitk::PlaneGeometry *geometry, mitk::Image *image) { if (geometry && image) { this->m_PlaneGeometry = geometry; this->m_Image = image; this->m_Geometry3D = nullptr; // Not possible to set both m_ObjectPointsInWorldCoordinates.clear(); } } void mitk::ClippedSurfaceBoundsCalculator::SetInput(const mitk::BaseGeometry *geometry, mitk::Image *image) { if (geometry && image) { this->m_Geometry3D = geometry; this->m_Image = image; this->m_PlaneGeometry = nullptr; // Not possible to set both m_ObjectPointsInWorldCoordinates.clear(); } } -void mitk::ClippedSurfaceBoundsCalculator::SetInput(const std::vector pointlist, mitk::Image *image) +void mitk::ClippedSurfaceBoundsCalculator::SetInput(const PointListType pointlist, mitk::Image *image) { if (!pointlist.empty() && image) { m_Geometry3D = nullptr; m_PlaneGeometry = nullptr; m_Image = image; m_ObjectPointsInWorldCoordinates = pointlist; } } mitk::ClippedSurfaceBoundsCalculator::OutputType mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionX() { return this->m_MinMaxOutput[0]; } mitk::ClippedSurfaceBoundsCalculator::OutputType mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionY() { return this->m_MinMaxOutput[1]; } mitk::ClippedSurfaceBoundsCalculator::OutputType mitk::ClippedSurfaceBoundsCalculator::GetMinMaxSpatialDirectionZ() { return this->m_MinMaxOutput[2]; } void mitk::ClippedSurfaceBoundsCalculator::Update() { this->m_MinMaxOutput.clear(); m_MinMaxOutput.reserve(3); for (int i = 0; i < 3; i++) { this->m_MinMaxOutput.push_back(OutputType(std::numeric_limits::max(), std::numeric_limits::min())); } if (m_PlaneGeometry.IsNotNull()) { this->CalculateIntersectionPoints(m_PlaneGeometry); } else if (m_Geometry3D.IsNotNull()) { // go through all slices of the image, ... const auto *slicedGeometry3D = dynamic_cast(m_Geometry3D.GetPointer()); int allSlices = slicedGeometry3D->GetSlices(); this->CalculateIntersectionPoints(dynamic_cast(slicedGeometry3D->GetPlaneGeometry(0))); this->CalculateIntersectionPoints( dynamic_cast(slicedGeometry3D->GetPlaneGeometry(allSlices - 1))); } else if (!m_ObjectPointsInWorldCoordinates.empty()) { this->CalculateIntersectionPoints(m_ObjectPointsInWorldCoordinates); this->EnforceImageBounds(); } } void mitk::ClippedSurfaceBoundsCalculator::CalculateIntersectionPoints(const mitk::PlaneGeometry *geometry) { // SEE HEADER DOCUMENTATION for explanation const mitk::BaseGeometry::Pointer imageGeometry = m_Image->GetGeometry()->Clone(); // the cornerpoint(0) is the corner based Origin, which is original center based Point3D origin = imageGeometry->GetCornerPoint(0); // Left, bottom, front // Get axis vector for the spatial directions const Vector3D xDirection = imageGeometry->GetAxisVector(0); const Vector3D yDirection = imageGeometry->GetAxisVector(1); const Vector3D zDirection = imageGeometry->GetAxisVector(2); const Point3D leftBottomFront = origin; const Point3D leftTopFront = origin + yDirection; const Point3D leftBottomBack = origin + zDirection; const Point3D leftTopBack = origin + yDirection + zDirection; const Point3D rightBottomFront = origin + xDirection; const Point3D rightTopFront = origin + xDirection + yDirection; const Point3D rightBottomBack = origin + xDirection + zDirection; const Point3D rightTopBack = origin + xDirection + yDirection + zDirection; typedef std::vector> EdgesVector; EdgesVector edgesOf3DBox; edgesOf3DBox.reserve(12); edgesOf3DBox.push_back(std::make_pair(leftBottomFront, // x = left=xfront, y=bottom=yfront, z=front=zfront leftTopFront)); // left, top, front edgesOf3DBox.push_back(std::make_pair(leftBottomFront, // left, bottom, front leftBottomBack)); // left, bottom, back edgesOf3DBox.push_back(std::make_pair(leftBottomFront, // left, bottom, front rightBottomFront)); // right, bottom, front edgesOf3DBox.push_back(std::make_pair(leftTopFront, // left, top, front rightTopFront)); // right, top, front edgesOf3DBox.push_back(std::make_pair(leftTopFront, // left, top, front leftTopBack)); // left, top, back edgesOf3DBox.push_back(std::make_pair(rightTopFront, // right, top, front rightTopBack)); // right, top, back edgesOf3DBox.push_back(std::make_pair(rightTopFront, // right, top, front rightBottomFront)); // right, bottom, front edgesOf3DBox.push_back(std::make_pair(rightBottomFront, // right, bottom, front rightBottomBack)); // right, bottom, back edgesOf3DBox.push_back(std::make_pair(rightBottomBack, // right, bottom, back leftBottomBack)); // left, bottom, back edgesOf3DBox.push_back(std::make_pair(rightBottomBack, // right, bottom, back rightTopBack)); // right, top, back edgesOf3DBox.push_back(std::make_pair(rightTopBack, // right, top, back leftTopBack)); // left, top, back edgesOf3DBox.push_back(std::make_pair(leftTopBack, // left, top, back leftBottomBack)); // left, bottom, back for (auto iterator = edgesOf3DBox.cbegin(); iterator != edgesOf3DBox.cend(); ++iterator) { const Point3D startPoint = (*iterator).first; // start point of the line const Point3D endPoint = (*iterator).second; // end point of the line const Vector3D lineDirection = endPoint - startPoint; const mitk::Line3D line(startPoint, lineDirection); // Get intersection point of line and plane geometry Point3D intersectionWorldPoint(std::numeric_limits::min()); double t = -1.0; bool doesLineIntersectWithPlane(false); const double norm = line.GetDirection().GetNorm(); const double dist = geometry->Distance(line.GetPoint1()); if (norm < mitk::eps && dist < mitk::sqrteps) { t = 1.0; doesLineIntersectWithPlane = true; intersectionWorldPoint = line.GetPoint1(); } else { geometry->IntersectionPoint(line, intersectionWorldPoint); doesLineIntersectWithPlane = geometry->IntersectionPointParam(line, t); } // Get index point mitk::Point3D intersectionIndexPoint; imageGeometry->WorldToIndex(intersectionWorldPoint, intersectionIndexPoint); const bool lowerBoundGood = (0 - mitk::sqrteps) <= t; const bool upperBoundGood = t <= 1.0 + mitk::sqrteps; if (doesLineIntersectWithPlane && lowerBoundGood && upperBoundGood) { for (int dim = 0; dim < 3; ++dim) { m_MinMaxOutput[dim].first = std::min(m_MinMaxOutput[dim].first, ROUND_P(intersectionIndexPoint[dim])); m_MinMaxOutput[dim].second = std::max(m_MinMaxOutput[dim].second, ROUND_P(intersectionIndexPoint[dim])); } this->EnforceImageBounds(); } } } void mitk::ClippedSurfaceBoundsCalculator::CalculateIntersectionPoints(PointListType pointList) { PointListType::const_iterator pointIterator; const mitk::SlicedGeometry3D::Pointer imageGeometry = m_Image->GetSlicedGeometry(); for (pointIterator = pointList.cbegin(); pointIterator != pointList.cend(); ++pointIterator) { mitk::Point3D pntInIndexCoordinates; imageGeometry->WorldToIndex((*pointIterator), pntInIndexCoordinates); m_MinMaxOutput[0].first = pntInIndexCoordinates[0] < m_MinMaxOutput[0].first ? ROUND_P(pntInIndexCoordinates[0]) : m_MinMaxOutput[0].first; m_MinMaxOutput[0].second = pntInIndexCoordinates[0] > m_MinMaxOutput[0].second ? ROUND_P(pntInIndexCoordinates[0]) : m_MinMaxOutput[0].second; m_MinMaxOutput[1].first = pntInIndexCoordinates[1] < m_MinMaxOutput[1].first ? ROUND_P(pntInIndexCoordinates[1]) : m_MinMaxOutput[1].first; m_MinMaxOutput[1].second = pntInIndexCoordinates[1] > m_MinMaxOutput[1].second ? ROUND_P(pntInIndexCoordinates[1]) : m_MinMaxOutput[1].second; m_MinMaxOutput[2].first = pntInIndexCoordinates[2] < m_MinMaxOutput[2].first ? ROUND_P(pntInIndexCoordinates[2]) : m_MinMaxOutput[2].first; m_MinMaxOutput[2].second = pntInIndexCoordinates[2] > m_MinMaxOutput[2].second ? ROUND_P(pntInIndexCoordinates[2]) : m_MinMaxOutput[2].second; } // this->EnforceImageBounds(); } void mitk::ClippedSurfaceBoundsCalculator::EnforceImageBounds() { m_MinMaxOutput[0].first = std::max(m_MinMaxOutput[0].first, 0); m_MinMaxOutput[1].first = std::max(m_MinMaxOutput[1].first, 0); m_MinMaxOutput[2].first = std::max(m_MinMaxOutput[2].first, 0); m_MinMaxOutput[0].first = std::min(m_MinMaxOutput[0].first, (int)m_Image->GetDimension(0) - 1); m_MinMaxOutput[1].first = std::min(m_MinMaxOutput[1].first, (int)m_Image->GetDimension(1) - 1); m_MinMaxOutput[2].first = std::min(m_MinMaxOutput[2].first, (int)m_Image->GetDimension(2) - 1); m_MinMaxOutput[0].second = std::min(m_MinMaxOutput[0].second, (int)m_Image->GetDimension(0) - 1); m_MinMaxOutput[1].second = std::min(m_MinMaxOutput[1].second, (int)m_Image->GetDimension(1) - 1); m_MinMaxOutput[2].second = std::min(m_MinMaxOutput[2].second, (int)m_Image->GetDimension(2) - 1); m_MinMaxOutput[0].second = std::max(m_MinMaxOutput[0].second, 0); m_MinMaxOutput[1].second = std::max(m_MinMaxOutput[1].second, 0); m_MinMaxOutput[2].second = std::max(m_MinMaxOutput[2].second, 0); } diff --git a/Modules/Core/src/DataManagement/mitkDataNode.cpp b/Modules/Core/src/DataManagement/mitkDataNode.cpp index f9f548d0b4..3097aa7f3c 100644 --- a/Modules/Core/src/DataManagement/mitkDataNode.cpp +++ b/Modules/Core/src/DataManagement/mitkDataNode.cpp @@ -1,732 +1,732 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkDataNode.h" #include "mitkCoreObjectFactory.h" #include #include "mitkGroupTagProperty.h" #include "mitkProperties.h" #include "mitkSmartPointerProperty.h" #include "mitkStringProperty.h" //#include "mitkMaterialProperty.h" #include "mitkColorProperty.h" #include "mitkCoreObjectFactory.h" #include "mitkGenericProperty.h" #include "mitkGeometry3D.h" #include "mitkImageSource.h" #include "mitkLevelWindowProperty.h" #include "mitkRenderingManager.h" mitk::Mapper *mitk::DataNode::GetMapper(MapperSlotId id) const { if ((id >= m_Mappers.size()) || (m_Mappers[id].IsNull())) { if (id >= m_Mappers.capacity()) { // int i, size=id-m_Mappers.capacity()+10; m_Mappers.resize(id + 10); } m_Mappers[id] = CoreObjectFactory::GetInstance()->CreateMapper(const_cast(this), id); } return m_Mappers[id]; } mitk::BaseData *mitk::DataNode::GetData() const { return m_Data; } void mitk::DataNode::SetData(mitk::BaseData *baseData) { if (m_Data != baseData) { m_Mappers.clear(); m_Mappers.resize(10); if (m_Data.IsNotNull() && baseData != nullptr) { // Do previous and new data have same type? Keep existing properties. if (0 == strcmp(m_Data->GetNameOfClass(), baseData->GetNameOfClass())) { m_Data = baseData; } else { m_Data = baseData; this->GetPropertyList()->Clear(); mitk::CoreObjectFactory::GetInstance()->SetDefaultProperties(this); } } else { m_Data = baseData; mitk::CoreObjectFactory::GetInstance()->SetDefaultProperties(this); } m_DataReferenceChangedTime.Modified(); Modified(); } } mitk::DataNode::DataNode() : m_PropertyList(PropertyList::New()), m_PropertyListModifiedObserverTag(0) { m_Mappers.resize(10); // subscribe for modified event itk::MemberCommand::Pointer _PropertyListModifiedCommand = itk::MemberCommand::New(); _PropertyListModifiedCommand->SetCallbackFunction(this, &mitk::DataNode::PropertyListModified); m_PropertyListModifiedObserverTag = m_PropertyList->AddObserver(itk::ModifiedEvent(), _PropertyListModifiedCommand); } mitk::DataNode::~DataNode() { if (m_PropertyList.IsNotNull()) m_PropertyList->RemoveObserver(m_PropertyListModifiedObserverTag); m_Mappers.clear(); m_Data = nullptr; } mitk::DataNode &mitk::DataNode::operator=(const DataNode &right) { mitk::DataNode *node = mitk::DataNode::New(); node->SetData(right.GetData()); return *node; } mitk::DataNode &mitk::DataNode::operator=(mitk::BaseData *right) { mitk::DataNode *node = mitk::DataNode::New(); node->SetData(right); return *node; } #if (_MSC_VER > 1200) || !defined(_MSC_VER) -MBI_STD::istream &mitk::operator>>(MBI_STD::istream &i, mitk::DataNode::Pointer &dtn) +std::istream &mitk::operator>>(std::istream &i, mitk::DataNode::Pointer &dtn) #endif #if ((defined(_MSC_VER)) && (_MSC_VER <= 1200)) - MBI_STD::istream & - operator>>(MBI_STD::istream &i, mitk::DataNode::Pointer &dtn) + std::istream & + operator>>(std::istream &i, mitk::DataNode::Pointer &dtn) #endif { dtn = mitk::DataNode::New(); // i >> av.get(); return i; } #if (_MSC_VER > 1200) || !defined(_MSC_VER) -MBI_STD::ostream &mitk::operator<<(MBI_STD::ostream &o, mitk::DataNode::Pointer &dtn) +std::ostream &mitk::operator<<(std::ostream &o, mitk::DataNode::Pointer &dtn) #endif #if ((defined(_MSC_VER)) && (_MSC_VER <= 1200)) - MBI_STD::ostream & - operator<<(MBI_STD::ostream &o, mitk::DataNode::Pointer &dtn) + std::ostream & + operator<<(std::ostream &o, mitk::DataNode::Pointer &dtn) #endif { if (dtn->GetData() != nullptr) o << dtn->GetData()->GetNameOfClass(); else o << "empty data"; return o; } void mitk::DataNode::SetMapper(MapperSlotId id, mitk::Mapper *mapper) { m_Mappers[id] = mapper; if (mapper != nullptr) mapper->SetDataNode(this); } void mitk::DataNode::UpdateOutputInformation() { if (this->GetSource()) { this->GetSource()->UpdateOutputInformation(); } } void mitk::DataNode::SetRequestedRegionToLargestPossibleRegion() { } bool mitk::DataNode::RequestedRegionIsOutsideOfTheBufferedRegion() { return false; } bool mitk::DataNode::VerifyRequestedRegion() { return true; } void mitk::DataNode::SetRequestedRegion(const itk::DataObject * /*data*/) { } mitk::DataNode::PropertyListKeyNames mitk::DataNode::GetPropertyListNames() const { PropertyListKeyNames result; for (auto entries : m_MapOfPropertyLists) result.push_back(entries.first); return result; } void mitk::DataNode::CopyInformation(const itk::DataObject * /*data*/) { } mitk::PropertyList *mitk::DataNode::GetPropertyList(const mitk::BaseRenderer *renderer) const { if (renderer == nullptr) return m_PropertyList; return this->GetPropertyList(renderer->GetName()); } mitk::PropertyList *mitk::DataNode::GetPropertyList(const std::string &rendererName) const { if (rendererName.empty()) return m_PropertyList; mitk::PropertyList::Pointer &propertyList = m_MapOfPropertyLists[rendererName]; if (propertyList.IsNull()) propertyList = mitk::PropertyList::New(); assert(m_MapOfPropertyLists[rendererName].IsNotNull()); return propertyList; } void mitk::DataNode::ConcatenatePropertyList(PropertyList *pList, bool replace) { m_PropertyList->ConcatenatePropertyList(pList, replace); } mitk::BaseProperty *mitk::DataNode::GetProperty(const char *propertyKey, const mitk::BaseRenderer *renderer, bool fallBackOnDataProperties) const { if (nullptr == propertyKey) return nullptr; if (nullptr != renderer) { auto it = m_MapOfPropertyLists.find(renderer->GetName()); if (m_MapOfPropertyLists.end() != it) { auto property = it->second->GetProperty(propertyKey); if (nullptr != property) return property; } } auto property = m_PropertyList->GetProperty(propertyKey); if (nullptr == property && fallBackOnDataProperties && m_Data.IsNotNull()) property = m_Data->GetProperty(propertyKey); return property; } mitk::DataNode::GroupTagList mitk::DataNode::GetGroupTags() const { GroupTagList groups; const PropertyList::PropertyMap *propertyMap = m_PropertyList->GetMap(); for (auto groupIter = propertyMap->begin(); // m_PropertyList is created in the constructor, so we don't check it here groupIter != propertyMap->end(); ++groupIter) { const BaseProperty *bp = groupIter->second; if (dynamic_cast(bp)) { groups.insert(groupIter->first); } } return groups; } bool mitk::DataNode::GetBoolProperty(const char *propertyKey, bool &boolValue, const mitk::BaseRenderer *renderer) const { mitk::BoolProperty::Pointer boolprop = dynamic_cast(GetProperty(propertyKey, renderer)); if (boolprop.IsNull()) return false; boolValue = boolprop->GetValue(); return true; } bool mitk::DataNode::GetIntProperty(const char *propertyKey, int &intValue, const mitk::BaseRenderer *renderer) const { mitk::IntProperty::Pointer intprop = dynamic_cast(GetProperty(propertyKey, renderer)); if (intprop.IsNull()) return false; intValue = intprop->GetValue(); return true; } bool mitk::DataNode::GetFloatProperty(const char *propertyKey, float &floatValue, const mitk::BaseRenderer *renderer) const { mitk::FloatProperty::Pointer floatprop = dynamic_cast(GetProperty(propertyKey, renderer)); if (floatprop.IsNull()) return false; floatValue = floatprop->GetValue(); return true; } bool mitk::DataNode::GetDoubleProperty(const char *propertyKey, double &doubleValue, const mitk::BaseRenderer *renderer) const { mitk::DoubleProperty::Pointer doubleprop = dynamic_cast(GetProperty(propertyKey, renderer)); if (doubleprop.IsNull()) { // try float instead float floatValue = 0; if (this->GetFloatProperty(propertyKey, floatValue, renderer)) { doubleValue = floatValue; return true; } return false; } doubleValue = doubleprop->GetValue(); return true; } bool mitk::DataNode::GetStringProperty(const char *propertyKey, std::string &string, const mitk::BaseRenderer *renderer) const { mitk::StringProperty::Pointer stringProp = dynamic_cast(GetProperty(propertyKey, renderer)); if (stringProp.IsNull()) { return false; } else { // memcpy((void*)string, stringProp->GetValue(), strlen(stringProp->GetValue()) + 1 ); // looks dangerous string = stringProp->GetValue(); return true; } } bool mitk::DataNode::GetColor(float rgb[3], const mitk::BaseRenderer *renderer, const char *propertyKey) const { mitk::ColorProperty::Pointer colorprop = dynamic_cast(GetProperty(propertyKey, renderer)); if (colorprop.IsNull()) return false; memcpy(rgb, colorprop->GetColor().GetDataPointer(), 3 * sizeof(float)); return true; } bool mitk::DataNode::GetOpacity(float &opacity, const mitk::BaseRenderer *renderer, const char *propertyKey) const { mitk::FloatProperty::Pointer opacityprop = dynamic_cast(GetProperty(propertyKey, renderer)); if (opacityprop.IsNull()) return false; opacity = opacityprop->GetValue(); return true; } bool mitk::DataNode::GetLevelWindow(mitk::LevelWindow &levelWindow, const mitk::BaseRenderer *renderer, const char *propertyKey) const { mitk::LevelWindowProperty::Pointer levWinProp = dynamic_cast(GetProperty(propertyKey, renderer)); if (levWinProp.IsNull()) return false; levelWindow = levWinProp->GetLevelWindow(); return true; } void mitk::DataNode::SetColor(const mitk::Color &color, const mitk::BaseRenderer *renderer, const char *propertyKey) { mitk::ColorProperty::Pointer prop; prop = mitk::ColorProperty::New(color); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetColor( float red, float green, float blue, const mitk::BaseRenderer *renderer, const char *propertyKey) { float color[3]; color[0] = red; color[1] = green; color[2] = blue; SetColor(color, renderer, propertyKey); } void mitk::DataNode::SetColor(const float rgb[3], const mitk::BaseRenderer *renderer, const char *propertyKey) { mitk::ColorProperty::Pointer prop; prop = mitk::ColorProperty::New(rgb); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetVisibility(bool visible, const mitk::BaseRenderer *renderer, const char *propertyKey) { mitk::BoolProperty::Pointer prop; prop = mitk::BoolProperty::New(visible); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetOpacity(float opacity, const mitk::BaseRenderer *renderer, const char *propertyKey) { mitk::FloatProperty::Pointer prop; prop = mitk::FloatProperty::New(opacity); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetLevelWindow(mitk::LevelWindow levelWindow, const mitk::BaseRenderer *renderer, const char *propertyKey) { mitk::LevelWindowProperty::Pointer prop; prop = mitk::LevelWindowProperty::New(levelWindow); GetPropertyList(renderer)->SetProperty(propertyKey, prop); } void mitk::DataNode::SetIntProperty(const char *propertyKey, int intValue, const mitk::BaseRenderer *renderer) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::IntProperty::New(intValue)); } void mitk::DataNode::SetBoolProperty(const char *propertyKey, bool boolValue, const mitk::BaseRenderer *renderer /*=nullptr*/) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::BoolProperty::New(boolValue)); } void mitk::DataNode::SetFloatProperty(const char *propertyKey, float floatValue, const mitk::BaseRenderer *renderer /*=nullptr*/) { if (dynamic_cast(this->GetProperty(propertyKey, renderer)) != nullptr) { MITK_WARN << "Setting float property " << propertyKey << " although a double property with the same name already exists"; } GetPropertyList(renderer)->SetProperty(propertyKey, mitk::FloatProperty::New(floatValue)); } void mitk::DataNode::SetDoubleProperty(const char *propertyKey, double doubleValue, const mitk::BaseRenderer *renderer) { if (dynamic_cast(this->GetProperty(propertyKey, renderer)) != nullptr) { MITK_WARN << "Setting double property " << propertyKey << " although a float property with the same name already exists"; } GetPropertyList(renderer)->SetProperty(propertyKey, mitk::DoubleProperty::New(doubleValue)); } void mitk::DataNode::SetStringProperty(const char *propertyKey, const char *stringValue, const mitk::BaseRenderer *renderer /*=nullptr*/) { GetPropertyList(renderer)->SetProperty(propertyKey, mitk::StringProperty::New(stringValue)); } void mitk::DataNode::SetProperty(const char *propertyKey, BaseProperty *propertyValue, const mitk::BaseRenderer *renderer) { GetPropertyList(renderer)->SetProperty(propertyKey, propertyValue); } void mitk::DataNode::ReplaceProperty(const char *propertyKey, BaseProperty *propertyValue, const mitk::BaseRenderer *renderer) { GetPropertyList(renderer)->ReplaceProperty(propertyKey, propertyValue); } void mitk::DataNode::AddProperty(const char *propertyKey, BaseProperty *propertyValue, const mitk::BaseRenderer *renderer, bool overwrite) { if ((overwrite) || (GetProperty(propertyKey, renderer) == nullptr)) { SetProperty(propertyKey, propertyValue, renderer); } } vtkLinearTransform *mitk::DataNode::GetVtkTransform(int t) const { assert(m_Data.IsNotNull()); mitk::BaseGeometry *geometry = m_Data->GetGeometry(t); if (geometry == nullptr) return nullptr; return geometry->GetVtkTransform(); } unsigned long mitk::DataNode::GetMTime() const { unsigned long time = Superclass::GetMTime(); if (m_Data.IsNotNull()) { if ((time < m_Data->GetMTime()) || ((m_Data->GetSource().IsNotNull()) && (time < m_Data->GetSource()->GetMTime()))) { Modified(); return Superclass::GetMTime(); } } return time; } void mitk::DataNode::SetSelected(bool selected, const mitk::BaseRenderer *renderer) { mitk::BoolProperty::Pointer selectedProperty = dynamic_cast(GetProperty("selected")); if (selectedProperty.IsNull()) { selectedProperty = mitk::BoolProperty::New(); selectedProperty->SetValue(false); SetProperty("selected", selectedProperty, renderer); } if (selectedProperty->GetValue() != selected) { selectedProperty->SetValue(selected); itk::ModifiedEvent event; InvokeEvent(event); } } /* class SelectedEvent : public itk::ModifiedEvent { public: typedef SelectedEvent Self; typedef itk::ModifiedEvent Superclass; SelectedEvent(DataNode* dataNode) { m_DataNode = dataNode; }; DataNode* GetDataNode() { return m_DataNode; }; virtual const char * GetEventName() const { return "SelectedEvent"; } virtual bool CheckEvent(const ::itk::EventObject* e) const { return dynamic_cast(e); } virtual ::itk::EventObject* MakeObject() const { return new Self(m_DataNode); } private: DataNode* m_DataNode; SelectedEvent(const Self& event) { m_DataNode = event.m_DataNode; }; void operator=(const Self& event) { m_DataNode = event.m_DataNode; } }; */ bool mitk::DataNode::IsSelected(const mitk::BaseRenderer *renderer) { bool selected; if (!GetBoolProperty("selected", selected, renderer)) return false; return selected; } void mitk::DataNode::SetDataInteractor(const DataInteractor::Pointer interactor) { if (m_DataInteractor == interactor) return; m_DataInteractor = interactor; this->Modified(); mitk::DataNode::InteractorChangedEvent changedEvent; this->InvokeEvent(changedEvent); } mitk::DataInteractor::Pointer mitk::DataNode::GetDataInteractor() const { return m_DataInteractor; } void mitk::DataNode::PropertyListModified(const itk::Object * /*caller*/, const itk::EventObject &) { Modified(); } mitk::BaseProperty::ConstPointer mitk::DataNode::GetConstProperty(const std::string &propertyKey, const std::string &contextName, bool fallBackOnDefaultContext) const { if (propertyKey.empty()) return nullptr; if (!contextName.empty()) { auto propertyListIter = m_MapOfPropertyLists.find(contextName); if (m_MapOfPropertyLists.end() != propertyListIter) { BaseProperty::ConstPointer property = propertyListIter->second->GetProperty(propertyKey); if (property.IsNotNull()) return property; } } if (contextName.empty() || fallBackOnDefaultContext) { BaseProperty::ConstPointer property = m_PropertyList->GetProperty(propertyKey); if (property.IsNull() && m_Data.IsNotNull()) property = m_Data->GetProperty(propertyKey.c_str()); return property; } return nullptr; } mitk::BaseProperty * mitk::DataNode::GetNonConstProperty(const std::string &propertyKey, const std::string &contextName, bool fallBackOnDefaultContext) { if (propertyKey.empty()) return nullptr; if (!contextName.empty()) { auto propertyListIter = m_MapOfPropertyLists.find(contextName); if (m_MapOfPropertyLists.end() != propertyListIter) { auto property = propertyListIter->second->GetProperty(propertyKey); if (nullptr != property) return property; } } if (contextName.empty() || fallBackOnDefaultContext) { auto property = m_PropertyList->GetProperty(propertyKey); if (nullptr == property && m_Data.IsNotNull()) property = m_Data->GetProperty(propertyKey.c_str()); return property; } return nullptr; } void mitk::DataNode::SetProperty(const std::string &propertyKey, BaseProperty *property, const std::string &contextName, bool fallBackOnDefaultContext) { if (propertyKey.empty()) mitkThrow() << "Property key is empty."; if (!contextName.empty()) { auto propertyListIter = m_MapOfPropertyLists.find(contextName); if (m_MapOfPropertyLists.end() != propertyListIter) { propertyListIter->second->SetProperty(propertyKey, property); return; } } if (contextName.empty() || fallBackOnDefaultContext) { m_PropertyList->SetProperty(propertyKey, property); return; } mitkThrow() << "Unknown property context."; } void mitk::DataNode::RemoveProperty(const std::string &propertyKey, const std::string &contextName, bool fallBackOnDefaultContext) { if (propertyKey.empty()) mitkThrow() << "Property key is empty."; if (!contextName.empty()) { auto propertyListIter = m_MapOfPropertyLists.find(contextName); if (m_MapOfPropertyLists.end() != propertyListIter) { propertyListIter->second->RemoveProperty(propertyKey); return; } } if (contextName.empty() || fallBackOnDefaultContext) { m_PropertyList->RemoveProperty(propertyKey); return; } mitkThrow() << "Unknown property context."; } std::vector mitk::DataNode::GetPropertyKeys(const std::string &contextName, bool includeDefaultContext) const { std::vector propertyKeys; if (contextName.empty()) { for (auto property : *m_PropertyList->GetMap()) propertyKeys.push_back(property.first); return propertyKeys; } auto propertyListIter = m_MapOfPropertyLists.find(contextName); if (m_MapOfPropertyLists.end() != propertyListIter) { for (auto property : *propertyListIter->second->GetMap()) propertyKeys.push_back(property.first); } if (includeDefaultContext) { for (auto property : *m_PropertyList->GetMap()) { auto propertyKeyIter = std::find(propertyKeys.begin(), propertyKeys.end(), property.first); if (propertyKeys.end() == propertyKeyIter) propertyKeys.push_back(property.first); } } return propertyKeys; } std::vector mitk::DataNode::GetPropertyContextNames() const { return this->GetPropertyListNames(); } diff --git a/Modules/Core/src/DataManagement/mitkSlicedData.cpp b/Modules/Core/src/DataManagement/mitkSlicedData.cpp index 23ac80f2f0..7d8796581e 100644 --- a/Modules/Core/src/DataManagement/mitkSlicedData.cpp +++ b/Modules/Core/src/DataManagement/mitkSlicedData.cpp @@ -1,361 +1,361 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "mitkSlicedData.h" #include "mitkAbstractTransformGeometry.h" #include "mitkBaseProcess.h" #include mitk::SlicedData::SlicedData() : m_RequestedRegionInitialized(false), m_UseLargestPossibleRegion(false) { unsigned int i; for (i = 0; i < 4; ++i) { m_LargestPossibleRegion.SetIndex(i, 0); m_LargestPossibleRegion.SetSize(i, 1); } } mitk::SlicedData::SlicedData(const SlicedData &other) : BaseData(other), m_LargestPossibleRegion(other.m_LargestPossibleRegion), m_RequestedRegion(other.m_RequestedRegion), m_RequestedRegionInitialized(other.m_RequestedRegionInitialized), m_BufferedRegion(other.m_BufferedRegion), m_UseLargestPossibleRegion(other.m_UseLargestPossibleRegion) { } mitk::SlicedData::~SlicedData() { } void mitk::SlicedData::UpdateOutputInformation() { Superclass::UpdateOutputInformation(); if (this->GetSource().IsNull()) // If we don't have a source, then let's make our Image // span our buffer { m_UseLargestPossibleRegion = true; } // Now we should know what our largest possible region is. If our // requested region was not set yet, (or has been set to something // invalid - with no data in it ) then set it to the largest possible // region. if (!m_RequestedRegionInitialized) { this->SetRequestedRegionToLargestPossibleRegion(); m_RequestedRegionInitialized = true; } m_LastRequestedRegionWasOutsideOfTheBufferedRegion = false; } void mitk::SlicedData::PrepareForNewData() { if (GetUpdateMTime() < GetPipelineMTime() || GetDataReleased()) { ReleaseData(); } } void mitk::SlicedData::SetRequestedRegionToLargestPossibleRegion() { m_UseLargestPossibleRegion = true; if (GetGeometry() == nullptr) return; unsigned int i; const RegionType::IndexType &index = GetLargestPossibleRegion().GetIndex(); const RegionType::SizeType &size = GetLargestPossibleRegion().GetSize(); for (i = 0; i < RegionDimension; ++i) { m_RequestedRegion.SetIndex(i, index[i]); m_RequestedRegion.SetSize(i, size[i]); } } bool mitk::SlicedData::RequestedRegionIsOutsideOfTheBufferedRegion() { // Is the requested region within the currently buffered data? // SlicedData and subclasses store entire volumes or slices. The // methods IsVolumeSet() and IsSliceSet are provided to check, // a volume or slice, respectively, is available. Thus, these // methods used here. const IndexType &requestedRegionIndex = m_RequestedRegion.GetIndex(); const SizeType &requestedRegionSize = m_RequestedRegion.GetSize(); const SizeType &largestPossibleRegionSize = GetLargestPossibleRegion().GetSize(); // are whole channels requested? int c, cEnd; c = requestedRegionIndex[4]; cEnd = c + static_cast(requestedRegionSize[4]); if (requestedRegionSize[3] == largestPossibleRegionSize[3]) { for (; c < cEnd; ++c) if (IsChannelSet(c) == false) return true; return false; } // are whole volumes requested? int t, tEnd; t = requestedRegionIndex[3]; tEnd = t + static_cast(requestedRegionSize[3]); if (requestedRegionSize[2] == largestPossibleRegionSize[2]) { for (; c < cEnd; ++c) for (; t < tEnd; ++t) if (IsVolumeSet(t, c) == false) return true; return false; } // ok, only slices are requested. Check if they are available. int s, sEnd; s = requestedRegionIndex[2]; sEnd = s + static_cast(requestedRegionSize[2]); for (; c < cEnd; ++c) for (; t < tEnd; ++t) for (; s < sEnd; ++s) if (IsSliceSet(s, t, c) == false) return true; return false; } bool mitk::SlicedData::VerifyRequestedRegion() { if (GetTimeGeometry() == nullptr) return false; unsigned int i; // Is the requested region within the LargestPossibleRegion? // Note that the test is indeed against the largest possible region // rather than the buffered region; see DataObject::VerifyRequestedRegion. const IndexType &requestedRegionIndex = m_RequestedRegion.GetIndex(); const IndexType &largestPossibleRegionIndex = GetLargestPossibleRegion().GetIndex(); const SizeType &requestedRegionSize = m_RequestedRegion.GetSize(); const SizeType &largestPossibleRegionSize = GetLargestPossibleRegion().GetSize(); for (i = 0; i < RegionDimension; ++i) { if ((requestedRegionIndex[i] < largestPossibleRegionIndex[i]) || ((requestedRegionIndex[i] + static_cast(requestedRegionSize[i])) > (largestPossibleRegionIndex[i] + static_cast(largestPossibleRegionSize[i])))) { return false; } } return true; } void mitk::SlicedData::SetRequestedRegion(const itk::DataObject *data) { m_UseLargestPossibleRegion = false; const auto *slicedData = dynamic_cast(data); if (slicedData) { m_RequestedRegion = slicedData->GetRequestedRegion(); m_RequestedRegionInitialized = true; } else { // pointer could not be cast back down itkExceptionMacro(<< "mitk::SlicedData::SetRequestedRegion(DataObject*) cannot cast " << typeid(data).name() << " to " << typeid(SlicedData *).name()); } } void mitk::SlicedData::SetRequestedRegion(SlicedData::RegionType *region) { m_UseLargestPossibleRegion = false; if (region != nullptr) { m_RequestedRegion = *region; m_RequestedRegionInitialized = true; } else { // pointer could not be cast back down itkExceptionMacro(<< "mitk::SlicedData::SetRequestedRegion(SlicedData::RegionType*) cannot cast " << typeid(region).name() << " to " << typeid(SlicedData *).name()); } } void mitk::SlicedData::SetLargestPossibleRegion(SlicedData::RegionType *region) { if (region != nullptr) { m_LargestPossibleRegion = *region; m_UseLargestPossibleRegion = true; } else { // pointer could not be cast back down itkExceptionMacro(<< "mitk::SlicedData::SetLargestPossibleRegion(SlicedData::RegionType*) cannot cast " << typeid(region).name() << " to " << typeid(SlicedData *).name()); } } void mitk::SlicedData::CopyInformation(const itk::DataObject *data) { // Standard call to the superclass' method Superclass::CopyInformation(data); const mitk::SlicedData *slicedData; slicedData = dynamic_cast(data); if (slicedData) { m_LargestPossibleRegion = slicedData->GetLargestPossibleRegion(); } else { // pointer could not be cast back down itkExceptionMacro(<< "mitk::SlicedData::CopyInformation(const DataObject *data) cannot cast " << typeid(data).name() << " to " << typeid(SlicedData *).name()); } } // const mitk::PlaneGeometry* mitk::SlicedData::GetPlaneGeometry(int s, int t) const //{ // const_cast(this)->SetRequestedRegionToLargestPossibleRegion(); // // const_cast(this)->UpdateOutputInformation(); // // return GetSlicedGeometry(t)->GetPlaneGeometry(s); //} // mitk::SlicedGeometry3D *mitk::SlicedData::GetSlicedGeometry(unsigned int t) const { if (GetTimeGeometry() == nullptr) return nullptr; return dynamic_cast(GetTimeGeometry()->GetGeometryForTimeStep(t).GetPointer()); } const mitk::SlicedGeometry3D *mitk::SlicedData::GetUpdatedSlicedGeometry(unsigned int t) { SetRequestedRegionToLargestPossibleRegion(); UpdateOutputInformation(); return GetSlicedGeometry(t); } void mitk::SlicedData::SetGeometry(BaseGeometry *aGeometry3D) { if (aGeometry3D != nullptr) { ProportionalTimeGeometry::Pointer timeGeometry = ProportionalTimeGeometry::New(); SlicedGeometry3D::Pointer slicedGeometry = dynamic_cast(aGeometry3D); if (slicedGeometry.IsNull()) { auto *geometry2d = dynamic_cast(aGeometry3D); if (geometry2d != nullptr && dynamic_cast(aGeometry3D) == nullptr) { if ((GetSlicedGeometry()->GetPlaneGeometry(0) == geometry2d) && (GetSlicedGeometry()->GetSlices() == 1)) return; slicedGeometry = SlicedGeometry3D::New(); slicedGeometry->InitializeEvenlySpaced(geometry2d, 1); } else { slicedGeometry = SlicedGeometry3D::New(); PlaneGeometry::Pointer planeGeometry = PlaneGeometry::New(); planeGeometry->InitializeStandardPlane(aGeometry3D); slicedGeometry->InitializeEvenlySpaced(planeGeometry, (unsigned int)(aGeometry3D->GetExtent(2))); } } assert(slicedGeometry.IsNotNull()); timeGeometry->Initialize(slicedGeometry, 1); Superclass::SetTimeGeometry(timeGeometry); } else { if (GetGeometry() == nullptr) return; Superclass::SetGeometry(nullptr); } } -void mitk::SlicedData::SetSpacing(const ScalarType aSpacing[3]) +void mitk::SlicedData::SetSpacing(const ScalarType aSpacing[]) { this->SetSpacing((mitk::Vector3D)aSpacing); } void mitk::SlicedData::SetOrigin(const mitk::Point3D &origin) { TimeGeometry *timeGeometry = GetTimeGeometry(); assert(timeGeometry != nullptr); mitk::SlicedGeometry3D *slicedGeometry; unsigned int steps = timeGeometry->CountTimeSteps(); for (unsigned int timestep = 0; timestep < steps; ++timestep) { slicedGeometry = GetSlicedGeometry(timestep); if (slicedGeometry != nullptr) { slicedGeometry->SetOrigin(origin); if (slicedGeometry->GetEvenlySpaced()) { mitk::PlaneGeometry *geometry2D = slicedGeometry->GetPlaneGeometry(0); geometry2D->SetOrigin(origin); slicedGeometry->InitializeEvenlySpaced(geometry2D, slicedGeometry->GetSlices()); } } // ProportionalTimeGeometry* timeGeometry = dynamic_cast(GetTimeGeometry()); // if(timeGeometry != nullptr) //{ // timeGeometry->Initialize(slicedGeometry, steps); // break; //} } } void mitk::SlicedData::SetSpacing(mitk::Vector3D aSpacing) { TimeGeometry *timeGeometry = GetTimeGeometry(); assert(timeGeometry != nullptr); unsigned int steps = timeGeometry->CountTimeSteps(); for (unsigned int timestep = 0; timestep < steps; ++timestep) { mitk::SlicedGeometry3D *slicedGeometry = GetSlicedGeometry(timestep); if (slicedGeometry != nullptr) { slicedGeometry->SetSpacing(aSpacing); } } timeGeometry->Update(); } diff --git a/Modules/CppMicroServices/core/src/service/usLDAPExpr.cpp b/Modules/CppMicroServices/core/src/service/usLDAPExpr.cpp index 3fd2d4186d..0d7a3ecd78 100644 --- a/Modules/CppMicroServices/core/src/service/usLDAPExpr.cpp +++ b/Modules/CppMicroServices/core/src/service/usLDAPExpr.cpp @@ -1,851 +1,809 @@ /*============================================================================ Library: CppMicroServices Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ============================================================================*/ #include "usLDAPExpr_p.h" #include "usAny.h" #include "usServicePropertiesImpl_p.h" #include #include #include #include #include #include #include US_BEGIN_NAMESPACE namespace LDAPExprConstants { static LDAPExpr::Byte WILDCARD() { static LDAPExpr::Byte b = std::numeric_limits::max(); return b; } static const std::string& WILDCARD_STRING() { static std::string s(1, WILDCARD()); return s; } static const std::string& nullptrQ() { static std::string s = "Null query"; return s; } static const std::string& GARBAGE() { static std::string s = "Trailing garbage"; return s; } static const std::string& EOS() { static std::string s = "Unexpected end of query"; return s; } static const std::string& MALFORMED() { static std::string s = "Malformed query"; return s; } static const std::string& OPERATOR() { static std::string s = "Undefined operator"; return s; } } bool stricomp(const std::string::value_type& v1, const std::string::value_type& v2) { return ::tolower(v1) == ::tolower(v2); } -//! Contains the current parser position and parsing utility methods. -class LDAPExpr::ParseState -{ - -private: - - std::size_t m_pos; - std::string m_str; - -public: - - ParseState(const std::string &str); - - //! Move m_pos to remove the prefix \a pre - bool prefix(const std::string &pre); - - /** Peek a char at m_pos - \note If index out of bounds, throw exception - */ - LDAPExpr::Byte peek(); - - //! Increment m_pos by n - void skip(int n); - - //! return string from m_pos until the end - std::string rest() const; - - //! Move m_pos until there's no spaces - void skipWhite(); - - //! Get string until special chars. Move m_pos - std::string getAttributeName(); - - //! Get string and convert * to WILDCARD - std::string getAttributeValue(); - - //! Throw InvalidSyntaxException exception - void error(const std::string &m) const; - -}; - - class LDAPExprData : public SharedData { public: LDAPExprData( int op, const std::vector& args ) : m_operator(op), m_args(args), m_attrName(), m_attrValue() { } LDAPExprData( int op, std::string attrName, const std::string& attrValue ) : m_operator(op), m_args(), m_attrName(attrName), m_attrValue(attrValue) { } LDAPExprData( const LDAPExprData& other ) : SharedData(other), m_operator(other.m_operator), m_args(other.m_args), m_attrName(other.m_attrName), m_attrValue(other.m_attrValue) { } int m_operator; std::vector m_args; std::string m_attrName; std::string m_attrValue; }; LDAPExpr::LDAPExpr() : d() { } LDAPExpr::LDAPExpr( const std::string &filter ) : d() { ParseState ps(filter); try { LDAPExpr expr = ParseExpr(ps); if (!Trim(ps.rest()).empty()) { ps.error(LDAPExprConstants::GARBAGE() + " '" + ps.rest() + "'"); } d = expr.d; } catch (const std::out_of_range&) { ps.error(LDAPExprConstants::EOS()); } } LDAPExpr::LDAPExpr( int op, const std::vector& args ) : d(new LDAPExprData(op, args)) { } LDAPExpr::LDAPExpr( int op, const std::string &attrName, const std::string &attrValue ) : d(new LDAPExprData(op, attrName, attrValue)) { } LDAPExpr::LDAPExpr( const LDAPExpr& other ) : d(other.d) { } LDAPExpr& LDAPExpr::operator=(const LDAPExpr& other) { d = other.d; return *this; } LDAPExpr::~LDAPExpr() { } std::string LDAPExpr::Trim(std::string str) { str.erase(0, str.find_first_not_of(' ')); str.erase(str.find_last_not_of(' ')+1); return str; } bool LDAPExpr::GetMatchedObjectClasses(ObjectClassSet& objClasses) const { if (d->m_operator == EQ) { if (d->m_attrName.length() == ServiceConstants::OBJECTCLASS().length() && std::equal(d->m_attrName.begin(), d->m_attrName.end(), ServiceConstants::OBJECTCLASS().begin(), stricomp) && d->m_attrValue.find(LDAPExprConstants::WILDCARD()) == std::string::npos) { objClasses.insert( d->m_attrValue ); return true; } return false; } else if (d->m_operator == AND) { bool result = false; for (std::size_t i = 0; i < d->m_args.size( ); i++) { LDAPExpr::ObjectClassSet r; if (d->m_args[i].GetMatchedObjectClasses(r)) { result = true; if (objClasses.empty()) { objClasses = r; } else { // if AND op and classes in several operands, // then only the intersection is possible. LDAPExpr::ObjectClassSet::iterator it1 = objClasses.begin(); LDAPExpr::ObjectClassSet::iterator it2 = r.begin(); while ( (it1 != objClasses.end()) && (it2 != r.end()) ) { if (*it1 < *it2) { objClasses.erase(it1++); } else if (*it2 < *it1) { ++it2; } else { // *it1 == *it2 ++it1; ++it2; } } // Anything left in set_1 from here on did not appear in set_2, // so we remove it. objClasses.erase(it1, objClasses.end()); } } } return result; } else if (d->m_operator == OR) { for (std::size_t i = 0; i < d->m_args.size( ); i++) { LDAPExpr::ObjectClassSet r; if (d->m_args[i].GetMatchedObjectClasses(r)) { std::copy(r.begin(), r.end(), std::inserter(objClasses, objClasses.begin())); } else { objClasses.clear(); return false; } } return true; } return false; } std::string LDAPExpr::ToLower(const std::string& str) { std::string lowerStr(str); std::transform(str.begin(), str.end(), lowerStr.begin(), ::tolower); return lowerStr; } bool LDAPExpr::IsSimple(const StringList& keywords, LocalCache& cache, bool matchCase ) const { if (cache.empty()) { cache.resize(keywords.size()); } if (d->m_operator == EQ) { StringList::const_iterator index; if ((index = std::find(keywords.begin(), keywords.end(), matchCase ? d->m_attrName : ToLower(d->m_attrName))) != keywords.end() && d->m_attrValue.find_first_of(LDAPExprConstants::WILDCARD()) == std::string::npos) { cache[index - keywords.begin()] = StringList(1, d->m_attrValue); return true; } } else if (d->m_operator == OR) { for (std::size_t i = 0; i < d->m_args.size( ); i++) { if (!d->m_args[i].IsSimple(keywords, cache, matchCase)) return false; } return true; } return false; } bool LDAPExpr::IsNull() const { return !d; } bool LDAPExpr::Query( const std::string& filter, const ServicePropertiesImpl& pd) { return LDAPExpr(filter).Evaluate(pd, false); } bool LDAPExpr::Evaluate( const ServicePropertiesImpl& p, bool matchCase ) const { if ((d->m_operator & SIMPLE) != 0) { // try case sensitive match first int index = p.FindCaseSensitive(d->m_attrName); if (index < 0 && !matchCase) index = p.Find(d->m_attrName); return index < 0 ? false : Compare(p.Value(index), d->m_operator, d->m_attrValue); } else { // (d->m_operator & COMPLEX) != 0 switch (d->m_operator) { case AND: for (std::size_t i = 0; i < d->m_args.size(); i++) { if (!d->m_args[i].Evaluate(p, matchCase)) return false; } return true; case OR: for (std::size_t i = 0; i < d->m_args.size(); i++) { if (d->m_args[i].Evaluate(p, matchCase)) return true; } return false; case NOT: return !d->m_args[0].Evaluate(p, matchCase); default: return false; // Cannot happen } } } bool LDAPExpr::Compare( const Any& obj, int op, const std::string& s ) const { if (obj.Empty()) return false; if (op == EQ && s == LDAPExprConstants::WILDCARD_STRING()) return true; try { const std::type_info& objType = obj.Type(); if (objType == typeid(std::string)) { return CompareString(ref_any_cast(obj), op, s); } else if (objType == typeid(std::vector)) { const std::vector& list = ref_any_cast >(obj); for (std::size_t it = 0; it != list.size(); it++) { if (CompareString(list[it], op, s)) return true; } } else if (objType == typeid(std::list)) { const std::list& list = ref_any_cast >(obj); for (std::list::const_iterator it = list.begin(); it != list.end(); ++it) { if (CompareString(*it, op, s)) return true; } } else if (objType == typeid(char)) { return CompareString(std::string(1, ref_any_cast(obj)), op, s); } else if (objType == typeid(bool)) { if (op==LE || op==GE) return false; std::string boolVal = any_cast(obj) ? "true" : "false"; return std::equal(s.begin(), s.end(), boolVal.begin(), stricomp); } else if (objType == typeid(short)) { return CompareIntegralType(obj, op, s); } else if (objType == typeid(int)) { return CompareIntegralType(obj, op, s); } else if (objType == typeid(long int)) { return CompareIntegralType(obj, op, s); } else if (objType == typeid(long long int)) { return CompareIntegralType(obj, op, s); } else if (objType == typeid(unsigned char)) { return CompareIntegralType(obj, op, s); } else if (objType == typeid(unsigned short)) { return CompareIntegralType(obj, op, s); } else if (objType == typeid(unsigned int)) { return CompareIntegralType(obj, op, s); } else if (objType == typeid(unsigned long int)) { return CompareIntegralType(obj, op, s); } else if (objType == typeid(unsigned long long int)) { return CompareIntegralType(obj, op, s); } else if (objType == typeid(float)) { errno = 0; char* endptr = nullptr; double sFloat = strtod(s.c_str(), &endptr); if ((errno == ERANGE && (sFloat == 0 || sFloat == HUGE_VAL || sFloat == -HUGE_VAL)) || (errno != 0 && sFloat == 0) || endptr == s.c_str()) { return false; } double floatVal = static_cast(any_cast(obj)); switch(op) { case LE: return floatVal <= sFloat; case GE: return floatVal >= sFloat; default: /*APPROX and EQ*/ double diff = floatVal - sFloat; return (diff < std::numeric_limits::epsilon()) && (diff > -std::numeric_limits::epsilon()); } } else if (objType == typeid(double)) { errno = 0; char* endptr = nullptr; double sDouble = strtod(s.c_str(), &endptr); if ((errno == ERANGE && (sDouble == 0 || sDouble == HUGE_VAL || sDouble == -HUGE_VAL)) || (errno != 0 && sDouble == 0) || endptr == s.c_str()) { return false; } double doubleVal = any_cast(obj); switch(op) { case LE: return doubleVal <= sDouble; case GE: return doubleVal >= sDouble; default: /*APPROX and EQ*/ double diff = doubleVal - sDouble; return (diff < std::numeric_limits::epsilon()) && (diff > -std::numeric_limits::epsilon()); } } else if (objType == typeid(std::vector)) { const std::vector& list = ref_any_cast >(obj); for (std::size_t it = 0; it != list.size(); it++) { if (Compare(list[it], op, s)) return true; } } } catch (...) { // This might happen if a std::string-to-datatype conversion fails // Just consider it a false match and ignore the exception } return false; } template bool LDAPExpr::CompareIntegralType(const Any& obj, const int op, const std::string& s) const { errno = 0; char* endptr = nullptr; long longInt = strtol(s.c_str(), &endptr, 10); if ((errno == ERANGE && (longInt == std::numeric_limits::max() || longInt == std::numeric_limits::min())) || (errno != 0 && longInt == 0) || endptr == s.c_str()) { return false; } T sInt = static_cast(longInt); T intVal = any_cast(obj); switch(op) { case LE: return intVal <= sInt; case GE: return intVal >= sInt; default: /*APPROX and EQ*/ return intVal == sInt; } } bool LDAPExpr::CompareString( const std::string& s1, int op, const std::string& s2 ) { switch(op) { case LE: return s1.compare(s2) <= 0; case GE: return s1.compare(s2) >= 0; case EQ: return PatSubstr(s1,s2); case APPROX: return FixupString(s2) == FixupString(s1); default: return false; } } std::string LDAPExpr::FixupString( const std::string& s ) { std::string sb; sb.reserve(s.size()); std::size_t len = s.length(); for(std::size_t i=0; im_operator std::vector v; do { v.push_back(ParseExpr(ps)); ps.skipWhite(); } while (ps.peek() == '('); std::size_t n = v.size(); if (!ps.prefix(")") || n == 0 || (op == NOT && n > 1)) ps.error(LDAPExprConstants::MALFORMED()); return LDAPExpr(op, v); } LDAPExpr LDAPExpr::ParseSimple( ParseState &ps ) { std::string attrName = ps.getAttributeName(); if (attrName.empty()) ps.error(LDAPExprConstants::MALFORMED()); int op = 0; if (ps.prefix("=")) op = EQ; else if (ps.prefix("<=")) op = LE; else if(ps.prefix(">=")) op = GE; else if(ps.prefix("~=")) op = APPROX; else { // System.out.println("undef op='" + ps.peek() + "'"); ps.error(LDAPExprConstants::OPERATOR()); // Does not return } std::string attrValue = ps.getAttributeValue(); if (!ps.prefix(")")) ps.error(LDAPExprConstants::MALFORMED()); return LDAPExpr(op, attrName, attrValue); } const std::string LDAPExpr::ToString() const { std::string res; res.append("("); if ((d->m_operator & SIMPLE) != 0) { res.append(d->m_attrName); switch (d->m_operator) { case EQ: res.append("="); break; case LE: res.append("<="); break; case GE: res.append(">="); break; case APPROX: res.append("~="); break; } for (std::size_t i = 0; i < d->m_attrValue.length(); i++) { Byte c = d->m_attrValue.at(i); if (c == '(' || c == ')' || c == '*' || c == '\\') { res.append(1, '\\'); } else if (c == LDAPExprConstants::WILDCARD()) { c = '*'; } res.append(1, c); } } else { switch (d->m_operator) { case AND: res.append("&"); break; case OR: res.append("|"); break; case NOT: res.append("!"); break; } for (std::size_t i = 0; i < d->m_args.size(); i++) { res.append(d->m_args[i].ToString()); } } res.append(")"); return res; } LDAPExpr::ParseState::ParseState( const std::string& str ) : m_pos(0), m_str() { if (str.empty()) { error(LDAPExprConstants::nullptrQ()); } m_str = str; } bool LDAPExpr::ParseState::prefix( const std::string& pre ) { std::string::iterator startIter = m_str.begin() + m_pos; if (!std::equal(pre.begin(), pre.end(), startIter)) return false; m_pos += pre.size(); return true; } char LDAPExpr::ParseState::peek() { if ( m_pos >= m_str.size() ) { throw std::out_of_range( "LDAPExpr" ); } return m_str.at(m_pos); } void LDAPExpr::ParseState::skip( int n ) { m_pos += n; } std::string LDAPExpr::ParseState::rest() const { return m_str.substr(m_pos); } void LDAPExpr::ParseState::skipWhite() { while (std::isspace(peek())) { m_pos++; } } std::string LDAPExpr::ParseState::getAttributeName() { std::size_t start = m_pos; std::size_t n = 0; bool nIsSet = false; for(;; m_pos++) { Byte c = peek(); if (c == '(' || c == ')' || c == '<' || c == '>' || c == '=' || c == '~') { break; } else if (!std::isspace(c)) { n = m_pos - start + 1; nIsSet = true; } } if (!nIsSet) { return std::string(); } return m_str.substr(start, n); } std::string LDAPExpr::ParseState::getAttributeValue() { std::string sb; bool exit = false; while( !exit ) { Byte c = peek( ); switch(c) { case '(': case ')': exit = true; break; case '*': sb.append(1, LDAPExprConstants::WILDCARD()); break; case '\\': sb.append(1, m_str.at(++m_pos)); break; default: sb.append(1, c); break; } if ( !exit ) { m_pos++; } } return sb; } void LDAPExpr::ParseState::error( const std::string &m ) const { std::string errorStr = m + ": " + (m_str.empty() ? "" : m_str.substr(m_pos)); throw std::invalid_argument(errorStr); } US_END_NAMESPACE diff --git a/Modules/CppMicroServices/core/src/service/usLDAPExpr_p.h b/Modules/CppMicroServices/core/src/service/usLDAPExpr_p.h index 1240592b0f..9264239350 100644 --- a/Modules/CppMicroServices/core/src/service/usLDAPExpr_p.h +++ b/Modules/CppMicroServices/core/src/service/usLDAPExpr_p.h @@ -1,178 +1,217 @@ /*============================================================================ Library: CppMicroServices Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ============================================================================*/ #ifndef USLDAPEXPR_H #define USLDAPEXPR_H #include #include "usSharedData.h" #include #include US_BEGIN_NAMESPACE class Any; class LDAPExprData; class ServicePropertiesImpl; /** * This class is not part of the public API. */ class LDAPExpr { public: const static int AND = 0; const static int OR = 1; const static int NOT = 2; const static int EQ = 4; const static int LE = 8; const static int GE = 16; const static int APPROX = 32; const static int COMPLEX = AND | OR | NOT; const static int SIMPLE = EQ | LE | GE | APPROX; typedef char Byte; typedef std::vector StringList; typedef std::vector LocalCache; typedef US_UNORDERED_SET_TYPE ObjectClassSet; /** * Creates an invalid LDAPExpr object. Use with care. * * @see IsNull() */ LDAPExpr(); LDAPExpr(const std::string& filter); LDAPExpr(const LDAPExpr& other); LDAPExpr& operator=(const LDAPExpr& other); ~LDAPExpr(); /** * Get object class set matched by this LDAP expression. This will not work * with wildcards and NOT expressions. If a set can not be determined return false. * * \param objClasses The set of matched classes will be added to objClasses. * \return If the set cannot be determined, false is returned, true otherwise. */ bool GetMatchedObjectClasses(ObjectClassSet& objClasses) const; /** * Checks if this LDAP expression is "simple". The definition of * a simple filter is: *
    *
  • (name=value) is simple if * name is a member of the provided keywords, * and value does not contain a wildcard character;
  • *
  • (| EXPR+ ) is simple if all EXPR * expressions are simple;
  • *
  • No other expressions are simple.
  • *
* If the filter is found to be simple, the cache is * filled with mappings from the provided keywords to lists * of attribute values. The keyword-value-pairs are the ones that * satisfy this expression, for the given keywords. * * @param keywords The keywords to look for. * @param cache An array (indexed by the keyword indexes) of lists to * fill in with values saturating this expression. * @return true if this expression is simple, * false otherwise. */ bool IsSimple( const StringList& keywords, LocalCache& cache, bool matchCase) const; /** * Returns true if this instance is invalid, i.e. it was * constructed using LDAPExpr(). * * @return true if the expression is invalid, * false otherwise. */ bool IsNull() const; //! static bool Query(const std::string& filter, const ServicePropertiesImpl& pd); //! Evaluate this LDAP filter. bool Evaluate(const ServicePropertiesImpl& p, bool matchCase) const; //! const std::string ToString() const; private: - class ParseState; + //! Contains the current parser position and parsing utility methods. + class ParseState + { + + private: + + std::size_t m_pos; + std::string m_str; + + public: + + ParseState(const std::string& str); + + //! Move m_pos to remove the prefix \a pre + bool prefix(const std::string& pre); + + /** Peek a char at m_pos + \note If index out of bounds, throw exception + */ + LDAPExpr::Byte peek(); + + //! Increment m_pos by n + void skip(int n); + + //! return string from m_pos until the end + std::string rest() const; + + //! Move m_pos until there's no spaces + void skipWhite(); + + //! Get string until special chars. Move m_pos + std::string getAttributeName(); + + //! Get string and convert * to WILDCARD + std::string getAttributeValue(); + + //! Throw InvalidSyntaxException exception + void error(const std::string& m) const; + + }; //! LDAPExpr(int op, const std::vector& args); //! LDAPExpr(int op, const std::string& attrName, const std::string& attrValue); //! static LDAPExpr ParseExpr(ParseState& ps); //! static LDAPExpr ParseSimple(ParseState& ps); static std::string Trim(std::string str); static std::string ToLower(const std::string& str); //! bool Compare(const Any& obj, int op, const std::string& s) const; //! template bool CompareIntegralType(const Any& obj, const int op, const std::string& s) const; //! static bool CompareString(const std::string& s1, int op, const std::string& s2); //! static std::string FixupString(const std::string &s); //! static bool PatSubstr(const std::string& s, const std::string& pat); //! static bool PatSubstr(const std::string& s, int si, const std::string& pat, int pi); //! Shared pointer SharedDataPointer d; }; US_END_NAMESPACE #endif // USLDAPEXPR_H diff --git a/Modules/PhotoacousticsLib/MitkSpectralUnmixing/SpectralUnmixingAppTimeEval.cpp b/Modules/PhotoacousticsLib/MitkSpectralUnmixing/SpectralUnmixingAppTimeEval.cpp index bed21f5d1e..1c484128ba 100644 --- a/Modules/PhotoacousticsLib/MitkSpectralUnmixing/SpectralUnmixingAppTimeEval.cpp +++ b/Modules/PhotoacousticsLib/MitkSpectralUnmixing/SpectralUnmixingAppTimeEval.cpp @@ -1,325 +1,325 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ //#include #include #include #include "mitkPALinearSpectralUnmixingFilter.h" #include "mitkPASpectralUnmixingFilterBase.h" #include "mitkPASpectralUnmixingFilterVigra.h" #include "mitkPASpectralUnmixingSO2.h" #include #include #include #include #include #include "mitkPreferenceListReaderOptionsFunctor.h" struct InputParameters { std::string inputPath; std::string outputPath; int numberOfInputs; }; InputParameters parseInput(int argc, char *argv[]) { MITK_INFO << "Parsing arguments..."; mitkCommandLineParser parser; parser.setCategory("MITK-Photoacoustics"); parser.setTitle("Mitk Spectral Unmixing App"); parser.setDescription("Batch processing for spectral unmixing."); parser.setContributor("Computer Assisted Medical Interventions, DKFZ"); parser.setArgumentPrefix("--", "-"); parser.beginGroup("Required parameters"); parser.addArgument("inputPath", "i", mitkCommandLineParser::Directory, "Input folder (directory)", "input folder", us::Any(), false, false, false, mitkCommandLineParser::Input); parser.addArgument("outputPath", "o", mitkCommandLineParser::Directory, "Input save folder (directory)", "input save folder", us::Any(), false, false, false, mitkCommandLineParser::Output); parser.addArgument("numberOfInputs", "n", mitkCommandLineParser::Int, "Number of Input files", "number of inputs", us::Any(), false); parser.endGroup(); InputParameters input; std::map parsedArgs = parser.parseArguments(argc, argv); if (argc == 0) exit(-1); for (int i = 0; i < argc; ++i) { MITK_INFO << argv[i]; } if (parsedArgs.count("inputPath")) { input.inputPath = us::any_cast(parsedArgs["inputPath"]); } else { MITK_ERROR << "Error: No inputPath"; mitkThrow() << "Error: No inputPath"; } if (parsedArgs.count("outputPath")) { input.outputPath = us::any_cast(parsedArgs["outputPath"]); } else { MITK_ERROR << "Error: No outputPath"; mitkThrow() << "Error: No outputPath"; } if (parsedArgs.count("numberOfInputs")) { input.numberOfInputs = us::any_cast(parsedArgs["numberOfInputs"]); } else { MITK_ERROR << "Error: No number of Inputs"; mitkThrow() << "Error: No number of Inputs"; } MITK_INFO << "Parsing arguments...[Done]"; return input; } mitk::pa::SpectralUnmixingFilterBase::Pointer GetFilterInstance(std::string algorithm) { mitk::pa::SpectralUnmixingFilterBase::Pointer spectralUnmixingFilter; if (algorithm == "QR") { spectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); dynamic_cast(spectralUnmixingFilter.GetPointer()) ->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::HOUSEHOLDERQR); } else if (algorithm == "SVD") { spectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); dynamic_cast(spectralUnmixingFilter.GetPointer()) ->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::JACOBISVD); } else if (algorithm == "LU") { spectralUnmixingFilter = mitk::pa::LinearSpectralUnmixingFilter::New(); dynamic_cast(spectralUnmixingFilter.GetPointer()) ->SetAlgorithm(mitk::pa::LinearSpectralUnmixingFilter::AlgortihmType::FULLPIVLU); } else if (algorithm == "NNLS") { spectralUnmixingFilter = mitk::pa::SpectralUnmixingFilterVigra::New(); dynamic_cast(spectralUnmixingFilter.GetPointer()) ->SetAlgorithm(mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::LARS); } else if (algorithm == "WLS") { spectralUnmixingFilter = mitk::pa::SpectralUnmixingFilterVigra::New(); dynamic_cast(spectralUnmixingFilter.GetPointer()) ->SetAlgorithm(mitk::pa::SpectralUnmixingFilterVigra::VigraAlgortihmType::WEIGHTED); /*std::vector weigthVec = {39, 45, 47}; for (int i = 0; i < 3; ++i) { dynamic_cast(spectralUnmixingFilter.GetPointer()) ->AddWeight(weigthVec[i]); }*/ } return spectralUnmixingFilter; } void add_weight(int weights, mitk::pa::SpectralUnmixingFilterBase::Pointer m_SpectralUnmixingFilter) { std::vector weigthVec = { 30, 32, 33, 35, 37, 38, 40, 41, 43, 44, 45, 46, 47, 47, 47, 47, 47, 46, 46, 45, 44, 44, 43, 42, 42, 41 }; for (int i = 0; i < weights; ++i) { dynamic_cast(m_SpectralUnmixingFilter.GetPointer()) ->AddWeight(weigthVec[i]); } } int main(int argc, char *argv[]) { auto input = parseInput(argc, argv); std::string inputDir = input.inputPath; std::string outputDir = input.outputPath; unsigned int N = input.numberOfInputs; /* //maybee try with "itk system tools" //auto test = itksys::SystemTools::GetFilenameName(argv[0]).c_str(); //MITK_INFO << "test: " << test; / +++ temporary solution BEGIN +++ std::vector files; std::string file; for (int i = 1; i < 34; ++i) { if (i < 10) { file = "E:/NHDATA/sdmas_beamformed/merged/static-oxy_sdmas_00" + std::to_string(i) + "_merged.nrrd"; } else { file = "E:/NHDATA/sdmas_beamformed/merged/static-oxy_sdmas_0" + std::to_string(i) + "_merged.nrrd"; } files.push_back(file); } / +++ temporary solution END +++ std::vector files; std::string file; for (int i = 0; i < 7; ++i) { file = "E:/NHCAMI/cami-experimental/PAI/spectralUnmixing/inSilico/paImages/selection/noiselevel1_rep1000_wavelength_selction_data_" + std::to_string(i) + ".nrrd"; files.push_back(file); } std::vector files; std::string file; file = "E:/NHCAMI/cami-experimental/PAI/spectralUnmixing/inSilico/paImages/selection/noiselevel1_rep1000_wavelength_selction_data.nrrd"; files.push_back(file);*/ std::vector algorithms = { "QR", "LU", "SVD", "NNLS", "WLS" }; int repetition = 6000; for (unsigned alg = 0; alg < 5; ++alg) { ofstream myerrorfile; myerrorfile.open("E:/NHDATA/time/time_evaluation_" + std::to_string(repetition)+"_" + algorithms[alg] + "_new02.txt"); int ctr = 0; for(int i = 2; i < 27; ++i) { myerrorfile << std::to_string(i) + "\t"; std::string file; if (i < 10) file = "E:/NHDATA/time/input/time_0" + std::to_string(i) + ".nrrd"; else file = "E:/NHDATA/time/input/time_" + std::to_string(i) + ".nrrd"; auto m_inputImage = mitk::IOUtil::Load(file); MITK_INFO << "File: " << i; for (int j = 0; j < repetition; ++j) { std::chrono::steady_clock::time_point _start; _start = std::chrono::steady_clock::now(); mitk::pa::SpectralUnmixingFilterBase::Pointer m_SpectralUnmixingFilter = GetFilterInstance(algorithms[alg]); m_SpectralUnmixingFilter->SetInput(m_inputImage); m_SpectralUnmixingFilter->AddOutputs(2); m_SpectralUnmixingFilter->Verbose(false); m_SpectralUnmixingFilter->RelativeError(false); m_SpectralUnmixingFilter->AddChromophore(mitk::pa::PropertyCalculator::ChromophoreType::OXYGENATED); m_SpectralUnmixingFilter->AddChromophore(mitk::pa::PropertyCalculator::ChromophoreType::DEOXYGENATED); for (int wl = 0; wl < i; ++wl) { m_SpectralUnmixingFilter->AddWavelength(700 + wl * 10); } if (alg == 4) { add_weight(i, m_SpectralUnmixingFilter); } m_SpectralUnmixingFilter->Update(); auto output1 = m_SpectralUnmixingFilter->GetOutput(0); auto output2 = m_SpectralUnmixingFilter->GetOutput(1); m_SpectralUnmixingFilter = nullptr; std::chrono::steady_clock::time_point _end(std::chrono::steady_clock::now()); myerrorfile << std::chrono::duration_cast>(_end - _start).count() << "\t"; /*std::string unmixingOutputHbO2 = "E:/NHDATA/time/output/time_" + std::to_string(i) + ".nrrd"; std::string unmixingOutputHb = "E:/NHDATA/time/output/time_" + std::to_string(i) + ".nrrd"; mitk::IOUtil::Save(output1, unmixingOutputHbO2); - mitk::IOUtil::Save(output2, unmixingOutputHb);/* -/* + mitk::IOUtil::Save(output2, unmixingOutputHb); + //auto m_sO2 = mitk::pa::SpectralUnmixingSO2::New(); //m_sO2->Verbose(false); //auto output1 = m_SpectralUnmixingFilter->GetOutput(0); //auto output2 = m_SpectralUnmixingFilter->GetOutput(1); //std::string unmixingOutputHbO2 ="E:/NHDATA/time/input/time_" + std::to_string(i) + ".nrrd"; //std::string unmixingOutputHb = outputDir + "/SUOutput/" + "Hb_" + algorithms[alg] + "_" + str_ctr + ".nrrd"; //mitk::IOUtil::Save(output1, unmixingOutputHbO2); //mitk::IOUtil::Save(output2, unmixingOutputHb); //m_sO2->SetInput(0, output1); //m_sO2->SetInput(1, output2); //m_sO2->Update(); //mitk::Image::Pointer sO2 = m_sO2->GetOutput(0); //sO2->SetSpacing(output1->GetGeometry()->GetSpacing()); //std::string outputSo2 = outputDir + "/So2/" + algorithms[alg] + "/So2_" + algorithms[alg] + "_" + str_ctr + ".nrrd"; //std::string outputSo2 = outputDir + "/" + algorithms[alg] + "_sel_" + str_ctr + ".nrrd"; //std::string outputSo2 = outputDir + "/" + algorithms[alg] + "_sel.nrrd"; //mitk::IOUtil::Save(sO2, outputSo2); //std::string outputSo2 = "E:/NHDATA/time/output/time_" + std::to_string(i) + algorithms[alg] + ".nrrd"; //mitk::IOUtil::Save(sO2, outputSo2);*/ } myerrorfile << "\n"; } myerrorfile.close(); } MITK_INFO << "Spectral Unmixing DONE"; } diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoObject.h b/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoObject.h index 567bf2b9ff..a5b8d0f1b3 100644 --- a/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoObject.h +++ b/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoObject.h @@ -1,53 +1,54 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef _MITK_MAP_ALGORITHM_INFO_OBJECT_H #define _MITK_MAP_ALGORITHM_INFO_OBJECT_H #include #include #include #include "org_mitk_matchpoint_core_helper_Export.h" namespace mitk { /** - * @Class berry wrapper for a MatchPoint algorithm deployment info + * \brief berry wrapper for a MatchPoint algorithm deployment info + * * Used by mitk::MAPAlgorithmInfoSelection. */ class MITK_MATCHPOINT_CORE_HELPER_EXPORT MAPAlgorithmInfoObject : public berry::Object { public: berryObjectMacro(mitk::MAPAlgorithmInfoObject); MAPAlgorithmInfoObject(); MAPAlgorithmInfoObject(::map::deployment::DLLInfo::ConstPointer info); const ::map::deployment::DLLInfo* GetInfo() const; bool operator==(const berry::Object* obj) const override; private: ::map::deployment::DLLInfo::ConstPointer m_Info; }; } #endif diff --git a/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoSelection.h b/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoSelection.h index 26d85d844c..1efbea3402 100644 --- a/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoSelection.h +++ b/Plugins/org.mitk.matchpoint.core.helper/src/mitkMAPAlgorithmInfoSelection.h @@ -1,68 +1,69 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #ifndef _MITK_MAP_ALGORITHM_INFO_SELECTION_H #define _MITK_MAP_ALGORITHM_INFO_SELECTION_H #include #include #include "org_mitk_matchpoint_core_helper_Export.h" namespace mitk { /** - * @class Used by plugins to communicate selections of deployed algorithms - * E.G. used by the algorithm browser to inform about the currently selected algorithm. + * \brief Used by plugins to communicate selections of deployed algorithms + * + * For example used by the algorithm browser to inform about the currently selected algorithm. */ class MITK_MATCHPOINT_CORE_HELPER_EXPORT MAPAlgorithmInfoSelection : public virtual berry::IStructuredSelection { public: berryObjectMacro(MAPAlgorithmInfoSelection); typedef ::map::deployment::DLLInfo AlgorithmInfoType; typedef std::vector AlgorithmInfoVectorType; MAPAlgorithmInfoSelection(); MAPAlgorithmInfoSelection(AlgorithmInfoType::ConstPointer info); MAPAlgorithmInfoSelection(const AlgorithmInfoVectorType& infos); Object::Pointer GetFirstElement() const override; iterator Begin() const override; iterator End() const override; int Size() const override; ContainerType::Pointer ToVector() const override; AlgorithmInfoVectorType GetSelectedAlgorithmInfo() const; /** * @see berry::ISelection::IsEmpty() */ bool IsEmpty() const override; bool operator==(const berry::Object* obj) const override; protected: ContainerType::Pointer m_Selection; }; } #endif