text:
/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

// Blueberry
#include <berryISelectionService.h>
#include <berryIWorkbenchPart.h>
#include <berryIWorkbenchWindow.h>

// Qmitk
#include "QmitkFiberProcessingView.h"

#include <QMessageBox>

#include <mitkNodePredicateProperty.h>
#include <mitkImageCast.h>
#include <mitkPointSet.h>
#include <mitkPlanarCircle.h>
#include <mitkPlanarPolygon.h>
#include <mitkPlanarRectangle.h>
#include <mitkPlanarFigureInteractor.h>
#include <mitkImageAccessByItk.h>
#include <mitkDataNodeObject.h>
#include <mitkTensorImage.h>
#include "usModuleRegistry.h"
#include <itkFiberCurvatureFilter.h>

#include "mitkNodePredicateDataType.h"
#include <mitkNodePredicateProperty.h>
#include <mitkNodePredicateAnd.h>
#include <mitkNodePredicateNot.h>
#include <mitkNodePredicateOr.h>

#include <itkResampleImageFilter.h>
#include <itkGaussianInterpolateImageFunction.h>
#include <itkImageRegionIteratorWithIndex.h>
#include <itkTractsToFiberEndingsImageFilter.h>
#include <itkTractDensityImageFilter.h>
#include <itkImageRegion.h>
#include <itkTractsToRgbaImageFilter.h>
#include <itkFiberExtractionFilter.h>

#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>

const std::string QmitkFiberProcessingView::VIEW_ID = "org.mitk.views.fiberprocessing";
const std::string id_DataManager = "org.mitk.views.datamanager";
using namespace mitk;

QmitkFiberProcessingView::QmitkFiberProcessingView()
  : QmitkAbstractView()
  , m_Controls( 0 )
  , m_CircleCounter(0)
  , m_PolygonCounter(0)
  , m_UpsamplingFactor(1)
{

}

// Destructor
QmitkFiberProcessingView::~QmitkFiberProcessingView()
{
  RemoveObservers();
}

void QmitkFiberProcessingView::CreateQtPartControl( QWidget *parent )
{
  // build up qt view, unless already done
  if ( !m_Controls )
  {
    // create GUI widgets from the Qt Designer's .ui file
    m_Controls = new Ui::QmitkFiberProcessingViewControls;
    m_Controls->setupUi( parent );

    connect( m_Controls->m_CircleButton, SIGNAL( clicked() ), this, SLOT( OnDrawCircle() ) );
    connect( m_Controls->m_PolygonButton, SIGNAL( clicked() ), this, SLOT( OnDrawPolygon() ) );
    connect(m_Controls->PFCompoANDButton, SIGNAL(clicked()), this, SLOT(GenerateAndComposite()) );
    connect(m_Controls->PFCompoORButton, SIGNAL(clicked()), this, SLOT(GenerateOrComposite()) );
    connect(m_Controls->PFCompoNOTButton, SIGNAL(clicked()), this, SLOT(GenerateNotComposite()) );
    connect(m_Controls->m_GenerateRoiImage, SIGNAL(clicked()), this, SLOT(GenerateRoiImage()) );

    connect(m_Controls->m_JoinBundles, SIGNAL(clicked()), this, SLOT(JoinBundles()) );
    connect(m_Controls->m_SubstractBundles, SIGNAL(clicked()), this, SLOT(SubstractBundles()) );
    connect(m_Controls->m_CopyBundle, SIGNAL(clicked()), this, SLOT(CopyBundles()) );

    connect(m_Controls->m_ExtractFibersButton, SIGNAL(clicked()), this, SLOT(Extract()));
    connect(m_Controls->m_RemoveButton, SIGNAL(clicked()), this, SLOT(Remove()));
    connect(m_Controls->m_ModifyButton, SIGNAL(clicked()), this, SLOT(Modify()));

    connect(m_Controls->m_ExtractionMethodBox, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateGui()));
    connect(m_Controls->m_RemovalMethodBox, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateGui()));
    connect(m_Controls->m_ModificationMethodBox, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateGui()));
    connect(m_Controls->m_ExtractionBoxMask, SIGNAL(currentIndexChanged(int)), this, SLOT(OnMaskExtractionChanged()));

    m_Controls->m_ColorMapBox->SetDataStorage(this->GetDataStorage());
    mitk::TNodePredicateDataType<mitk::Image>::Pointer isMitkImage = mitk::TNodePredicateDataType<mitk::Image>::New();
    mitk::NodePredicateDataType::Pointer isDwi = mitk::NodePredicateDataType::New("DiffusionImage");
    mitk::NodePredicateDataType::Pointer isDti = mitk::NodePredicateDataType::New("TensorImage");
    mitk::NodePredicateDataType::Pointer isOdf = mitk::NodePredicateDataType::New("OdfImage");
    mitk::NodePredicateOr::Pointer isDiffusionImage = mitk::NodePredicateOr::New(isDwi, isDti);
    isDiffusionImage = mitk::NodePredicateOr::New(isDiffusionImage, isOdf);
    mitk::NodePredicateNot::Pointer noDiffusionImage = mitk::NodePredicateNot::New(isDiffusionImage);
    mitk::NodePredicateAnd::Pointer finalPredicate = mitk::NodePredicateAnd::New(isMitkImage, noDiffusionImage);
    m_Controls->m_ColorMapBox->SetPredicate(finalPredicate);
  }

  UpdateGui();
  OnMaskExtractionChanged();
}

void QmitkFiberProcessingView::OnMaskExtractionChanged()
{
  m_Controls->m_FiberExtractionFractionLabel->setVisible(false);
  m_Controls->m_FiberExtractionFractionBox->setVisible(false);

  m_Controls->m_FiberExtractionThresholdLabel->setVisible(false);
  m_Controls->m_FiberExtractionThresholdBox->setVisible(false);

  m_Controls->m_InterpolateRoiBox->setVisible(false);
  m_Controls->m_BothEnds->setVisible(false);

  m_Controls->m_LabelsBox->setVisible(false);
  m_Controls->m_LabelsLabel->setVisible(false);

  if (m_Controls->m_ExtractionBoxMask->currentIndex() == 2 || m_Controls->m_ExtractionBoxMask->currentIndex() == 3)
  {
    m_Controls->m_FiberExtractionFractionLabel->setVisible(true);
    m_Controls->m_FiberExtractionFractionBox->setVisible(true);

    m_Controls->m_FiberExtractionThresholdLabel->setVisible(true);
    m_Controls->m_FiberExtractionThresholdBox->setVisible(true);

    m_Controls->m_InterpolateRoiBox->setVisible(true);
  }
  else if (m_Controls->m_ExtractionBoxMask->currentIndex() == 0 || m_Controls->m_ExtractionBoxMask->currentIndex() == 1)
  {
    if (m_Controls->m_ExtractionBoxMask->currentIndex() != 3)
      m_Controls->m_BothEnds->setVisible(true);
    m_Controls->m_InterpolateRoiBox->setVisible(true);

    m_Controls->m_FiberExtractionThresholdLabel->setVisible(true);
    m_Controls->m_FiberExtractionThresholdBox->setVisible(true);
  }
  else if (m_Controls->m_ExtractionBoxMask->currentIndex() == 4)
  {
    m_Controls->m_BothEnds->setVisible(true);

    m_Controls->m_LabelsBox->setVisible(true);
    m_Controls->m_LabelsLabel->setVisible(true);
  }
}

void QmitkFiberProcessingView::SetFocus()
{
  m_Controls->toolBoxx->setFocus();
}

void QmitkFiberProcessingView::Modify()
{
  switch (m_Controls->m_ModificationMethodBox->currentIndex())
  {
  case 0:
  {
    ResampleSelectedBundlesSpline();
    break;
  }
  case 1:
  {
    ResampleSelectedBundlesLinear();
    break;
  }
  case 2:
  {
    CompressSelectedBundles();
    break;
  }
  case 3:
  {
    DoImageColorCoding();
    break;
  }
  case 4:
  {
    MirrorFibers();
    break;
  }
  case 5:
  {
    WeightFibers();
    break;
  }
  case 6:
  {
    DoCurvatureColorCoding();
    break;
  }
  case 7:
  {
    DoWeightColorCoding();
    break;
  }
  case 8:
  {
    DoLengthColorCoding();
    break;
  }
  }
}

void QmitkFiberProcessingView::WeightFibers()
{
  float weight = this->m_Controls->m_BundleWeightBox->value();
  for (auto node : m_SelectedFB)
  {
    mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());
    fib->SetFiberWeights(weight);
  }

}

void QmitkFiberProcessingView::Remove()
{
  switch (m_Controls->m_RemovalMethodBox->currentIndex())
  {
  case 0:
  {
    RemoveDir();
    break;
  }
  case 1:
  {
    PruneBundle();
    break;
  }
  case 2:
  {
    ApplyCurvatureThreshold();
    break;
  }
  case 3:
  {
    RemoveWithMask(false);
    break;
  }
  case 4:
  {
    RemoveWithMask(true);
    break;
  }
  case 5:
  {
    ApplyWeightThreshold();
    break;
  }
  case 6:
  {
    ApplyDensityThreshold();
    break;
  }
  }
}

void QmitkFiberProcessingView::Extract()
{
  switch (m_Controls->m_ExtractionMethodBox->currentIndex())
  {
  case 0:
  {
    ExtractWithPlanarFigure();
    break;
  }
  case 1:
  {
    switch (m_Controls->m_ExtractionBoxMask->currentIndex())
    {
    {
    case 0:
        ExtractWithMask(true, false, false);
        break;
    }
    {
    case 1:
        ExtractWithMask(true, true, false);
        break;
    }
    {
    case 2:
        ExtractWithMask(false, false, false);
        break;
    }
    {
    case 3:
        ExtractWithMask(false, true, false);
        break;
    }
    {
    case 4:
        ExtractWithMask(true, false, true);
        break;
    }
    }
    break;
  }
  }
}

void QmitkFiberProcessingView::PruneBundle()
{
  int minLength = this->m_Controls->m_PruneFibersMinBox->value();
  int maxLength = this->m_Controls->m_PruneFibersMaxBox->value();
  for (auto node : m_SelectedFB)
  {
    mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());
    if (!fib->RemoveShortFibers(minLength))
      QMessageBox::information(nullptr, "No output generated:", "The resulting fiber bundle contains no fibers.");
    else if (!fib->RemoveLongFibers(maxLength))
      QMessageBox::information(nullptr, "No output generated:", "The resulting fiber bundle contains no fibers.");
  }
  RenderingManager::GetInstance()->RequestUpdateAll();
}

void QmitkFiberProcessingView::ApplyWeightThreshold()
{
  float thr = this->m_Controls->m_WeightThresholdBox->value();
  std::vector< DataNode::Pointer > nodes = m_SelectedFB;
  for (auto node : nodes)
  {
    mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());

    mitk::FiberBundle::Pointer newFib = fib->FilterByWeights(thr);
    if (newFib->GetNumFibers()>0)
    {
      newFib->ColorFibersByFiberWeights(false, true);
      node->SetData(newFib);
    }
    else
      QMessageBox::information(nullptr, "No output generated:", "The resulting fiber bundle contains no fibers.");
  }
  RenderingManager::GetInstance()->RequestUpdateAll();
}

void QmitkFiberProcessingView::ApplyDensityThreshold()
{
  float thr = this->m_Controls->m_DensityThresholdBox->value();
  float ol = this->m_Controls->m_DensityOverlapBox->value();
  std::vector< DataNode::Pointer > nodes = m_SelectedFB;
  for (auto node : nodes)
  {
    mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());

    itk::TractDensityImageFilter< ItkFloatImageType >::Pointer generator = itk::TractDensityImageFilter< ItkFloatImageType >::New();
    generator->SetFiberBundle(fib);
    generator->SetBinaryOutput(false);
    generator->SetOutputAbsoluteValues(false);
    generator->Update();

    itk::FiberExtractionFilter<float>::Pointer extractor = itk::FiberExtractionFilter<float>::New();
    extractor->SetRoiImages({generator->GetOutput()});
    extractor->SetInputFiberBundle(fib);
    extractor->SetOverlapFraction(ol);
    extractor->SetInterpolate(true);
    extractor->SetThreshold(thr);
    extractor->SetNoNegatives(true);
    extractor->Update();

    if (extractor->GetPositives().empty())
    {
      QMessageBox::information(nullptr, "No output generated:", "The resulting fiber bundle contains no fibers.");
      continue;
    }

    mitk::FiberBundle::Pointer newFib = extractor->GetPositives().at(0);
    if (newFib->GetNumFibers()>0)
      node->SetData(newFib);
    else
      QMessageBox::information(nullptr, "No output generated:", "The resulting fiber bundle contains no fibers.");
  }
  RenderingManager::GetInstance()->RequestUpdateAll();
}

void QmitkFiberProcessingView::ApplyCurvatureThreshold()
{
  int angle = this->m_Controls->m_CurvSpinBox->value();
  int dist = this->m_Controls->m_CurvDistanceSpinBox->value();
  std::vector< DataNode::Pointer > nodes = m_SelectedFB;
  for (auto node : nodes)
  {
    mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());

    itk::FiberCurvatureFilter::Pointer filter = itk::FiberCurvatureFilter::New();
    filter->SetInputFiberBundle(fib);
    filter->SetAngularDeviation(angle);
    filter->SetDistance(dist);
    filter->SetRemoveFibers(m_Controls->m_RemoveCurvedFibersBox->isChecked());
    filter->Update();
    mitk::FiberBundle::Pointer newFib = filter->GetOutputFiberBundle();
    if (newFib->GetNumFibers()>0)
    {
      newFib->ColorFibersByOrientation();
      node->SetData(newFib);
    }
    else
      QMessageBox::information(nullptr, "No output generated:", "The resulting fiber bundle contains no fibers.");
  }
  RenderingManager::GetInstance()->RequestUpdateAll();
}

void QmitkFiberProcessingView::RemoveDir()
{
  for (auto node : m_SelectedFB)
  {
    mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());
    vnl_vector_fixed<double,3> dir;
    dir[0] = m_Controls->m_ExtractDirX->value();
    dir[1] = m_Controls->m_ExtractDirY->value();
    dir[2] = m_Controls->m_ExtractDirZ->value();
    fib->RemoveDir(dir,cos((float)m_Controls->m_ExtractAngle->value()*itk::Math::pi/180));
  }
  RenderingManager::GetInstance()->RequestUpdateAll();
}

void QmitkFiberProcessingView::RemoveWithMask(bool removeInside)
{
  if (m_RoiImageNode.IsNull())
    return;

  mitk::Image::Pointer mitkMask = dynamic_cast<mitk::Image*>(m_RoiImageNode->GetData());
  for (auto node : m_SelectedFB)
  {
    mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());

    ItkUCharImageType::Pointer mask = ItkUCharImageType::New();
    mitk::CastToItkImage(mitkMask, mask);
    mitk::FiberBundle::Pointer newFib = fib->RemoveFibersOutside(mask, removeInside);
    if (newFib->GetNumFibers()<=0)
    {
      QMessageBox::information(nullptr, "No output generated:", "The resulting fiber bundle contains no fibers.");
      continue;
    }
    node->SetData(newFib);
  }
  RenderingManager::GetInstance()->RequestUpdateAll();
}

void QmitkFiberProcessingView::ExtractWithMask(bool onlyEnds, bool invert, bool labelmap)
{
  if (m_RoiImageNode.IsNull())
    return;

  mitk::Image::Pointer mitkMask = dynamic_cast<mitk::Image*>(m_RoiImageNode->GetData());
  for (auto node : m_SelectedFB)
  {
    std::string roi_name = m_RoiImageNode->GetName();
    mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());
    ItkFloatImageType::Pointer mask = ItkFloatImageType::New();
    mitk::CastToItkImage(mitkMask, mask);

    itk::FiberExtractionFilter<float>::Pointer extractor = itk::FiberExtractionFilter<float>::New();
    extractor->SetInputFiberBundle(fib);
    extractor->SetRoiImages({mask});
    extractor->SetRoiImageNames({roi_name});
    extractor->SetThreshold(m_Controls->m_FiberExtractionThresholdBox->value());
    extractor->SetOverlapFraction(m_Controls->m_FiberExtractionFractionBox->value());
    extractor->SetBothEnds(m_Controls->m_BothEnds->isChecked());
    extractor->SetInterpolate(m_Controls->m_InterpolateRoiBox->isChecked());
    extractor->SetMinFibersPerTract(m_Controls->m_MinExtractedFibersBox->value());
    extractor->SetSplitByRoi(true);
    if (invert)
      extractor->SetNoPositives(true);
    else
      extractor->SetNoNegatives(true);

    if (labelmap)
    {
      std::string labels_string = m_Controls->m_LabelsBox->text().toStdString();
      if (labels_string!="ALL")
      {
        std::vector<std::string> strs;
        boost::split(strs,labels_string,boost::is_any_of(" ,;\t"));

        std::vector< unsigned short > labels_vector;
        for (auto v : strs)
        {
          try{
            unsigned short l = boost::lexical_cast<unsigned short>(v);
            labels_vector.push_back(l);
          }
          catch(...)
          {

          }
        }
        extractor->SetLabels(labels_vector);
      }

      extractor->SetInterpolate(false);
      extractor->SetInputType(itk::FiberExtractionFilter<float>::INPUT::LABEL_MAP);
      extractor->SetSplitLabels(true);
      onlyEnds = true;
    }

    if (onlyEnds)
      extractor->SetMode(itk::FiberExtractionFilter<float>::MODE::ENDPOINTS);
    extractor->Update();

    std::vector< mitk::FiberBundle::Pointer > newFibs;
    if (invert)
      newFibs = extractor->GetNegatives();
    else
      newFibs = extractor->GetPositives();

    if (newFibs.empty())
    {
      QMessageBox::information(nullptr, "No output generated:", "No fibers could be extracted.");
      continue;
    }

    auto labels = extractor->GetPositiveLabels();
    MITK_INFO << labels.size();

    for (unsigned int i=0; i<newFibs.size(); ++i)
    {
      DataNode::Pointer newNode = DataNode::New();
      auto fib = newFibs.at(i);

      newNode->SetData(fib);
      std::string name = roi_name;
      if (i<labels.size())
        name = labels.at(i);

      if (invert)
      {
        if (onlyEnds)
          name = "not-ending-in-" + name;
        else
          name = "not-passing-" + name;
      }
      else if (!labelmap)
      {
        if (onlyEnds)
          name = "ending-in-" + name;
        else
          name = "passing-" + name;
      }

      newNode->SetName(name);
      GetDataStorage()->Add(newNode, node);
    }
    node->SetVisibility(false);
  }
}

void QmitkFiberProcessingView::GenerateRoiImage()
{
  if (m_SelectedPF.empty())
    return;

  mitk::BaseGeometry::Pointer geometry;
  if (!m_SelectedFB.empty())
  {
    mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(m_SelectedFB.front()->GetData());
    geometry = fib->GetGeometry();
  }
  else if (m_SelectedImage)
    geometry = m_SelectedImage->GetGeometry();
  else
    return;

  itk::Vector<double,3> spacing = geometry->GetSpacing();
  spacing /= m_UpsamplingFactor;

  mitk::Point3D newOrigin = geometry->GetOrigin();
  mitk::Geometry3D::BoundsArrayType bounds = geometry->GetBounds();
  newOrigin[0] += bounds.GetElement(0);
  newOrigin[1] += bounds.GetElement(2);
  newOrigin[2] += bounds.GetElement(4);

  itk::Matrix<double, 3, 3> direction;
  itk::ImageRegion<3> imageRegion;
  for (int i=0; i<3; i++)
    for (int j=0; j<3; j++)
      direction[j][i] = geometry->GetMatrixColumn(i)[j]/spacing[j];
  imageRegion.SetSize(0, geometry->GetExtent(0)*m_UpsamplingFactor);
  imageRegion.SetSize(1, geometry->GetExtent(1)*m_UpsamplingFactor);
  imageRegion.SetSize(2, geometry->GetExtent(2)*m_UpsamplingFactor);

  m_PlanarFigureImage = ItkUCharImageType::New();
  m_PlanarFigureImage->SetSpacing( spacing );   // Set the image spacing
  m_PlanarFigureImage->SetOrigin( newOrigin );     // Set the image origin
  m_PlanarFigureImage->SetDirection( direction );  // Set the image direction
  m_PlanarFigureImage->SetRegions( imageRegion );
  m_PlanarFigureImage->Allocate();
  m_PlanarFigureImage->FillBuffer( 0 );

  Image::Pointer tmpImage = Image::New();
  tmpImage->InitializeByItk(m_PlanarFigureImage.GetPointer());
  tmpImage->SetVolume(m_PlanarFigureImage->GetBufferPointer());

  std::string name = m_SelectedPF.at(0)->GetName();
  WritePfToImage(m_SelectedPF.at(0), tmpImage);
  for (unsigned int i=1; i<m_SelectedPF.size(); i++)
  {
    name += "+";
    name += m_SelectedPF.at(i)->GetName();
    WritePfToImage(m_SelectedPF.at(i), tmpImage);
  }

  DataNode::Pointer node = DataNode::New();
  tmpImage = Image::New();
  tmpImage->InitializeByItk(m_PlanarFigureImage.GetPointer());
  tmpImage->SetVolume(m_PlanarFigureImage->GetBufferPointer());
  node->SetData(tmpImage);
  node->SetName(name);
  this->GetDataStorage()->Add(node);
}

void QmitkFiberProcessingView::WritePfToImage(mitk::DataNode::Pointer node, mitk::Image* image)
{
  if (dynamic_cast<mitk::PlanarFigure*>(node->GetData()))
  {
    m_PlanarFigure = dynamic_cast<mitk::PlanarFigure*>(node->GetData());
    AccessFixedDimensionByItk_2(
          image,
          InternalReorientImagePlane, 3,
          m_PlanarFigure->GetGeometry(), -1);

    AccessFixedDimensionByItk_2(
          m_InternalImage,
          InternalCalculateMaskFromPlanarFigure,
          3, 2, node->GetName() );
  }
  else if (dynamic_cast<mitk::PlanarFigureComposite*>(node->GetData()))
  {
    DataStorage::SetOfObjects::ConstPointer children = GetDataStorage()->GetDerivations(node);
    for (unsigned int i=0; i<children->Size(); i++)
    {
      WritePfToImage(children->at(i), image);
    }
  }
}

template < typename TPixel, unsigned int VImageDimension >
void QmitkFiberProcessingView::InternalReorientImagePlane( const itk::Image< TPixel, VImageDimension > *image, mitk::BaseGeometry* planegeo3D, int additionalIndex )
{
  typedef itk::Image< TPixel, VImageDimension > ImageType;
  typedef itk::Image< float, VImageDimension > FloatImageType;

  typedef itk::ResampleImageFilter<ImageType, FloatImageType, double> ResamplerType;
  typename ResamplerType::Pointer resampler = ResamplerType::New();

  mitk::PlaneGeometry* planegeo = dynamic_cast<mitk::PlaneGeometry*>(planegeo3D);

  float upsamp = m_UpsamplingFactor;
  float gausssigma = 0.5;

  // Spacing
  typename ResamplerType::SpacingType spacing = planegeo->GetSpacing();
  spacing[0] = image->GetSpacing()[0] / upsamp;
  spacing[1] = image->GetSpacing()[1] / upsamp;
  spacing[2] = image->GetSpacing()[2];
  resampler->SetOutputSpacing( spacing );

  // Size
  typename ResamplerType::SizeType size;
  size[0] = planegeo->GetExtentInMM(0) / spacing[0];
  size[1] = planegeo->GetExtentInMM(1) / spacing[1];
  size[2] = 1;
  resampler->SetSize( size );

  // Origin
  typename mitk::Point3D orig = planegeo->GetOrigin();
  typename mitk::Point3D corrorig;
  planegeo3D->WorldToIndex(orig,corrorig);
  corrorig[0] += 0.5/upsamp;
  corrorig[1] += 0.5/upsamp;
  corrorig[2] += 0;
  planegeo3D->IndexToWorld(corrorig,corrorig);
  resampler->SetOutputOrigin(corrorig );

  // Direction
  typename ResamplerType::DirectionType direction;
  typename mitk::AffineTransform3D::MatrixType matrix = planegeo->GetIndexToWorldTransform()->GetMatrix();
  for(unsigned int c=0; c<matrix.ColumnDimensions; c++)
  {
    double sum = 0;
    for(unsigned int r=0; r<matrix.RowDimensions; r++)
      sum += matrix(r,c)*matrix(r,c);
    for(unsigned int r=0; r<matrix.RowDimensions; r++)
      direction(r,c) = matrix(r,c)/sqrt(sum);
  }
  resampler->SetOutputDirection( direction );

  // Gaussian interpolation
  if(gausssigma != 0)
  {
    double sigma[3];
    for( unsigned int d = 0; d < 3; d++ )
      sigma[d] = gausssigma * image->GetSpacing()[d];
    double alpha = 2.0;
    typedef itk::GaussianInterpolateImageFunction<ImageType, double> GaussianInterpolatorType;
    typename GaussianInterpolatorType::Pointer interpolator = GaussianInterpolatorType::New();
    interpolator->SetInputImage( image );
    interpolator->SetParameters( sigma, alpha );
    resampler->SetInterpolator( interpolator );
  }
  else
  {
    typedef typename itk::LinearInterpolateImageFunction<ImageType, double> InterpolatorType;
    typename InterpolatorType::Pointer interpolator = InterpolatorType::New();
    interpolator->SetInputImage( image );
    resampler->SetInterpolator( interpolator );
  }

  resampler->SetInput( image );
  resampler->SetDefaultPixelValue(0);
  resampler->Update();

  if(additionalIndex < 0)
  {
    this->m_InternalImage = mitk::Image::New();
    this->m_InternalImage->InitializeByItk( resampler->GetOutput() );
    this->m_InternalImage->SetVolume( resampler->GetOutput()->GetBufferPointer() );
  }
}

template < typename TPixel, unsigned int VImageDimension >
void QmitkFiberProcessingView::InternalCalculateMaskFromPlanarFigure( itk::Image< TPixel, VImageDimension > *image, unsigned int axis, std::string )
{
  typedef itk::Image< TPixel, VImageDimension > ImageType;

  // Generate mask image as new image with same header as input image and
  // initialize with "1".
  ItkUCharImageType::Pointer newMaskImage = ItkUCharImageType::New();
  newMaskImage->SetSpacing( image->GetSpacing() );   // Set the image spacing
  newMaskImage->SetOrigin( image->GetOrigin() );     // Set the image origin
  newMaskImage->SetDirection( image->GetDirection() );  // Set the image direction
  newMaskImage->SetRegions( image->GetLargestPossibleRegion() );
  newMaskImage->Allocate();
  newMaskImage->FillBuffer( 1 );

  // Generate VTK polygon from (closed) PlanarFigure polyline
  // (The polyline points are shifted by -0.5 in z-direction to make sure
  // that the extrusion filter, which afterwards elevates all points by +0.5
  // in z-direction, creates a 3D object which is cut by the the plane z=0)
  const PlaneGeometry *planarFigurePlaneGeometry = m_PlanarFigure->GetPlaneGeometry();
  const PlanarFigure::PolyLineType planarFigurePolyline = m_PlanarFigure->GetPolyLine( 0 );
  const BaseGeometry *imageGeometry3D = m_InternalImage->GetGeometry( 0 );

  vtkPolyData *polyline = vtkPolyData::New();
  polyline->Allocate( 1, 1 );

  // Determine x- and y-dimensions depending on principal axis
  int i0, i1;
  switch ( axis )
  {
  case 0:
    i0 = 1;
    i1 = 2;
    break;
  case 1:
    i0 = 0;
    i1 = 2;
    break;
  case 2:
  default:
    i0 = 0;
    i1 = 1;
    break;
  }

  // Create VTK polydata object of polyline contour
  vtkPoints *points = vtkPoints::New();
  PlanarFigure::PolyLineType::const_iterator it;
  unsigned int numberOfPoints = 0;

  for ( it = planarFigurePolyline.begin(); it != planarFigurePolyline.end(); ++it )
  {
    Point3D point3D;

    // Convert 2D point back to the local index coordinates of the selected image
    Point2D point2D = *it;
    planarFigurePlaneGeometry->WorldToIndex(point2D, point2D);
    point2D[0] -= 0.5/m_UpsamplingFactor;
    point2D[1] -= 0.5/m_UpsamplingFactor;
    planarFigurePlaneGeometry->IndexToWorld(point2D, point2D);
    planarFigurePlaneGeometry->Map( point2D, point3D );

    // Polygons (partially) outside of the image bounds can not be processed further due to a bug in vtkPolyDataToImageStencil
    if ( !imageGeometry3D->IsInside( point3D ) )
    {
      float bounds[2] = {0,0};
      bounds[0] =
          this->m_InternalImage->GetLargestPossibleRegion().GetSize().GetElement(i0);
      bounds[1] =
          this->m_InternalImage->GetLargestPossibleRegion().GetSize().GetElement(i1);

      imageGeometry3D->WorldToIndex( point3D, point3D );

      if (point3D[i0]<0)
        point3D[i0] = 0.0;
      else if (point3D[i0]>bounds[0])
        point3D[i0] = bounds[0]-0.001;

      if (point3D[i1]<0)
        point3D[i1] = 0.0;
      else if (point3D[i1]>bounds[1])
        point3D[i1] = bounds[1]-0.001;

      points->InsertNextPoint( point3D[i0], point3D[i1], -0.5 );
      numberOfPoints++;
    }
    else
    {
      imageGeometry3D->WorldToIndex( point3D, point3D );
      // Add point to polyline array
      points->InsertNextPoint( point3D[i0], point3D[i1], -0.5 );
      numberOfPoints++;
    }
  }
  polyline->SetPoints( points );
  points->Delete();

  vtkIdType *ptIds = new vtkIdType[numberOfPoints];
  for ( vtkIdType i = 0; i < numberOfPoints; ++i )
    ptIds[i] = i;
  polyline->InsertNextCell( VTK_POLY_LINE, numberOfPoints, ptIds );

  // Extrude the generated contour polygon
  vtkLinearExtrusionFilter *extrudeFilter = vtkLinearExtrusionFilter::New();
  extrudeFilter->SetInputData( polyline );
  extrudeFilter->SetScaleFactor( 1 );
  extrudeFilter->SetExtrusionTypeToNormalExtrusion();
  extrudeFilter->SetVector( 0.0, 0.0, 1.0 );

  // Make a stencil from the extruded polygon
  vtkPolyDataToImageStencil *polyDataToImageStencil = vtkPolyDataToImageStencil::New();
  polyDataToImageStencil->SetInputConnection( extrudeFilter->GetOutputPort() );

  // Export from ITK to VTK (to use a VTK filter)
  typedef itk::VTKImageImport< ItkUCharImageType > ImageImportType;
  typedef itk::VTKImageExport< ItkUCharImageType > ImageExportType;

  typename ImageExportType::Pointer itkExporter = ImageExportType::New();
  itkExporter->SetInput( newMaskImage );

  vtkImageImport *vtkImporter = vtkImageImport::New();
  this->ConnectPipelines( itkExporter, vtkImporter );
  vtkImporter->Update();

  // Apply the generated image stencil to the input image
  vtkImageStencil *imageStencilFilter = vtkImageStencil::New();
  imageStencilFilter->SetInputConnection( vtkImporter->GetOutputPort() );
  imageStencilFilter->SetStencilConnection(polyDataToImageStencil->GetOutputPort() );
  imageStencilFilter->ReverseStencilOff();
  imageStencilFilter->SetBackgroundValue( 0 );
  imageStencilFilter->Update();

  // Export from VTK back to ITK
  vtkImageExport *vtkExporter = vtkImageExport::New();
  vtkExporter->SetInputConnection( imageStencilFilter->GetOutputPort() );
  vtkExporter->Update();

  typename ImageImportType::Pointer itkImporter = ImageImportType::New();
  this->ConnectPipelines( vtkExporter, itkImporter );
  itkImporter->Update();

  // calculate cropping bounding box
  m_InternalImageMask3D = itkImporter->GetOutput();
  m_InternalImageMask3D->SetDirection(image->GetDirection());

  itk::ImageRegionConstIterator<ItkUCharImageType>
      itmask(m_InternalImageMask3D, m_InternalImageMask3D->GetLargestPossibleRegion());
  itk::ImageRegionIterator<ImageType>
      itimage(image, image->GetLargestPossibleRegion());

  itmask.GoToBegin();
  itimage.GoToBegin();

  typename ImageType::SizeType lowersize = {{itk::NumericTraits<unsigned long>::max(),itk::NumericTraits<unsigned long>::max(),itk::NumericTraits<unsigned long>::max()}};
  typename ImageType::SizeType uppersize = {{0,0,0}};
  while( !itmask.IsAtEnd() )
  {
    if(itmask.Get() == 0)
      itimage.Set(0);
    else
    {
      typename ImageType::IndexType index = itimage.GetIndex();
      typename ImageType::SizeType signedindex;
      signedindex[0] = index[0];
      signedindex[1] = index[1];
      signedindex[2] = index[2];

      lowersize[0] = signedindex[0] < lowersize[0] ? signedindex[0] : lowersize[0];
      lowersize[1] = signedindex[1] < lowersize[1] ? signedindex[1] : lowersize[1];
      lowersize[2] = signedindex[2] < lowersize[2] ? signedindex[2] : lowersize[2];

      uppersize[0] = signedindex[0] > uppersize[0] ? signedindex[0] : uppersize[0];
      uppersize[1] = signedindex[1] > uppersize[1] ? signedindex[1] : uppersize[1];
      uppersize[2] = signedindex[2] > uppersize[2] ? signedindex[2] : uppersize[2];
    }

    ++itmask;
    ++itimage;
  }

  typename ImageType::IndexType index;
  index[0] = lowersize[0];
  index[1] = lowersize[1];
  index[2] = lowersize[2];

  typename ImageType::SizeType size;
  size[0] = uppersize[0] - lowersize[0] + 1;
  size[1] = uppersize[1] - lowersize[1] + 1;
  size[2] = uppersize[2] - lowersize[2] + 1;

  itk::ImageRegion<3> cropRegion = itk::ImageRegion<3>(index, size);

  // crop internal mask
  typedef itk::RegionOfInterestImageFilter< ItkUCharImageType, ItkUCharImageType > ROIMaskFilterType;
  typename ROIMaskFilterType::Pointer roi2 = ROIMaskFilterType::New();
  roi2->SetRegionOfInterest(cropRegion);
  roi2->SetInput(m_InternalImageMask3D);
  roi2->Update();
  m_InternalImageMask3D = roi2->GetOutput();

  Image::Pointer tmpImage = Image::New();
  tmpImage->InitializeByItk(m_InternalImageMask3D.GetPointer());
  tmpImage->SetVolume(m_InternalImageMask3D->GetBufferPointer());

  Image::Pointer tmpImage2 = Image::New();
  tmpImage2->InitializeByItk(m_PlanarFigureImage.GetPointer());
  const BaseGeometry *pfImageGeometry3D = tmpImage2->GetGeometry( 0 );

  const BaseGeometry *intImageGeometry3D = tmpImage->GetGeometry( 0 );

  typedef itk::ImageRegionIteratorWithIndex<ItkUCharImageType> IteratorType;
  IteratorType imageIterator (m_InternalImageMask3D, m_InternalImageMask3D->GetRequestedRegion());
  imageIterator.GoToBegin();
  while ( !imageIterator.IsAtEnd() )
  {
    unsigned char val = imageIterator.Value();
    if (val>0)
    {
      itk::Index<3> index = imageIterator.GetIndex();
      Point3D point;
      point[0] = index[0];
      point[1] = index[1];
      point[2] = index[2];

      intImageGeometry3D->IndexToWorld(point, point);
      pfImageGeometry3D->WorldToIndex(point, point);

      point[i0] += 0.5;
      point[i1] += 0.5;

      index[0] = point[0];
      index[1] = point[1];
      index[2] = point[2];

      if (pfImageGeometry3D->IsIndexInside(index))
        m_PlanarFigureImage->SetPixel(index, 1);
    }
    ++imageIterator;
  }

  // Clean up VTK objects
  polyline->Delete();
  extrudeFilter->Delete();
  polyDataToImageStencil->Delete();
  vtkImporter->Delete();
  imageStencilFilter->Delete();
  //vtkExporter->Delete(); // TODO: crashes when outcommented; memory leak??
  delete[] ptIds;
}

void QmitkFiberProcessingView::UpdateGui()
{
  m_Controls->m_FibLabel->setText("<font color='red'>mandatory</font>");
  m_Controls->m_PfLabel->setText("<font color='grey'>needed for extraction</font>");
  m_Controls->m_InputData->setTitle("Please Select Input Data");

  m_Controls->m_RemoveButton->setEnabled(false);

  m_Controls->m_PlanarFigureButtonsFrame->setEnabled(false);
  m_Controls->PFCompoANDButton->setEnabled(false);
  m_Controls->PFCompoORButton->setEnabled(false);
  m_Controls->PFCompoNOTButton->setEnabled(false);

  m_Controls->m_GenerateRoiImage->setEnabled(false);
  m_Controls->m_ExtractFibersButton->setEnabled(false);
  m_Controls->m_ModifyButton->setEnabled(false);

  m_Controls->m_CopyBundle->setEnabled(false);
  m_Controls->m_JoinBundles->setEnabled(false);
  m_Controls->m_SubstractBundles->setEnabled(false);

  // disable alle frames
  m_Controls->m_BundleWeightFrame->setVisible(false);
  m_Controls->m_ExtactionFramePF->setVisible(false);
  m_Controls->m_RemoveDirectionFrame->setVisible(false);
  m_Controls->m_RemoveLengthFrame->setVisible(false);
  m_Controls->m_RemoveCurvatureFrame->setVisible(false);
  m_Controls->m_RemoveByWeightFrame->setVisible(false);
  m_Controls->m_RemoveByDensityFrame->setVisible(false);
  m_Controls->m_SmoothFibersFrame->setVisible(false);
  m_Controls->m_CompressFibersFrame->setVisible(false);
  m_Controls->m_ColorFibersFrame->setVisible(false);
  m_Controls->m_MirrorFibersFrame->setVisible(false);
  m_Controls->m_MaskExtractionFrame->setVisible(false);
  m_Controls->m_ColorMapBox->setVisible(false);

  bool pfSelected = !m_SelectedPF.empty();
  bool fibSelected = !m_SelectedFB.empty();
  bool multipleFibsSelected = (m_SelectedFB.size()>1);
  bool maskSelected = m_RoiImageNode.IsNotNull();
  bool imageSelected = m_SelectedImage.IsNotNull();

  // toggle visibility of elements according to selected method
  switch ( m_Controls->m_ExtractionMethodBox->currentIndex() )
  {
  case 0:
    m_Controls->m_ExtactionFramePF->setVisible(true);
    break;
  case 1:
    m_Controls->m_MaskExtractionFrame->setVisible(true);
    break;
  }

  switch ( m_Controls->m_RemovalMethodBox->currentIndex() )
  {
  case 0:
    m_Controls->m_RemoveDirectionFrame->setVisible(true);
    if ( fibSelected )
      m_Controls->m_RemoveButton->setEnabled(true);
    break;
  case 1:
    m_Controls->m_RemoveLengthFrame->setVisible(true);
    if ( fibSelected )
      m_Controls->m_RemoveButton->setEnabled(true);
    break;
  case 2:
    m_Controls->m_RemoveCurvatureFrame->setVisible(true);
    if ( fibSelected )
      m_Controls->m_RemoveButton->setEnabled(true);
    break;
  case 3:
    break;
  case 4:
    break;
  case 5:
    m_Controls->m_RemoveByWeightFrame->setVisible(true);
    if ( fibSelected )
      m_Controls->m_RemoveButton->setEnabled(true);
    break;
  case 6:
    m_Controls->m_RemoveByDensityFrame->setVisible(true);
    if ( fibSelected )
      m_Controls->m_RemoveButton->setEnabled(true);
    break;
  }

  switch ( m_Controls->m_ModificationMethodBox->currentIndex() )
  {
  case 0:
    m_Controls->m_SmoothFibersFrame->setVisible(true);
    break;
  case 1:
    m_Controls->m_SmoothFibersFrame->setVisible(true);
    break;
  case 2:
    m_Controls->m_CompressFibersFrame->setVisible(true);
    break;
  case 3:
    m_Controls->m_ColorFibersFrame->setVisible(true);
    m_Controls->m_ColorMapBox->setVisible(true);
    break;
  case 4:
    m_Controls->m_MirrorFibersFrame->setVisible(true);
    if (m_SelectedSurfaces.size()>0)
      m_Controls->m_ModifyButton->setEnabled(true);
    break;
  case 5:
    m_Controls->m_BundleWeightFrame->setVisible(true);
    break;
  case 6:
    m_Controls->m_ColorFibersFrame->setVisible(true);
    break;
  case 7:
    m_Controls->m_ColorFibersFrame->setVisible(true);
    break;
  case 8:
    m_Controls->m_ColorFibersFrame->setVisible(true);
    break;
  }

  // are fiber bundles selected?
  if ( fibSelected )
  {
    m_Controls->m_CopyBundle->setEnabled(true);
    m_Controls->m_ModifyButton->setEnabled(true);
    m_Controls->m_PlanarFigureButtonsFrame->setEnabled(true);
    m_Controls->m_FibLabel->setText(QString(m_SelectedFB.at(0)->GetName().c_str()));

    // one bundle and one planar figure needed to extract fibers
    if (pfSelected && m_Controls->m_ExtractionMethodBox->currentIndex()==0)
    {
      m_Controls->m_InputData->setTitle("Input Data");
      m_Controls->m_PfLabel->setText(QString(m_SelectedPF.at(0)->GetName().c_str()));
      m_Controls->m_ExtractFibersButton->setEnabled(true);
    }

    // more than two bundles needed to join/subtract
    if (multipleFibsSelected)
    {
      m_Controls->m_FibLabel->setText("multiple bundles selected");

      m_Controls->m_JoinBundles->setEnabled(true);
      m_Controls->m_SubstractBundles->setEnabled(true);
    }

    if (maskSelected && m_Controls->m_ExtractionMethodBox->currentIndex()==1)
    {
      m_Controls->m_InputData->setTitle("Input Data");
      m_Controls->m_PfLabel->setText(QString(m_RoiImageNode->GetName().c_str()));
      m_Controls->m_ExtractFibersButton->setEnabled(true);
    }

    if (maskSelected && (m_Controls->m_RemovalMethodBox->currentIndex()==3 || m_Controls->m_RemovalMethodBox->currentIndex()==4) )
    {
      m_Controls->m_InputData->setTitle("Input Data");
      m_Controls->m_PfLabel->setText(QString(m_RoiImageNode->GetName().c_str()));
      m_Controls->m_RemoveButton->setEnabled(true);
    }
  }

  // are planar figures selected?
  if (pfSelected)
  {
    if ( fibSelected || m_SelectedImage.IsNotNull())
      m_Controls->m_GenerateRoiImage->setEnabled(true);

    if (m_SelectedPF.size() > 1)
    {
      m_Controls->PFCompoANDButton->setEnabled(true);
      m_Controls->PFCompoORButton->setEnabled(true);
    }
    else
      m_Controls->PFCompoNOTButton->setEnabled(true);
  }

  // is image selected
  if (imageSelected || maskSelected)
  {
    m_Controls->m_PlanarFigureButtonsFrame->setEnabled(true);
  }
}

void QmitkFiberProcessingView::NodeRemoved(const mitk::DataNode* node )
{
  for (auto fnode: m_SelectedFB)
    if (node == fnode)
    {
      m_SelectedFB.clear();
      break;
    }

  berry::IWorkbenchPart::Pointer nullPart;
  QList<mitk::DataNode::Pointer> nodes;
  OnSelectionChanged(nullPart, nodes);
}

void QmitkFiberProcessingView::NodeAdded(const mitk::DataNode* )
{
  if (!m_Controls->m_InteractiveBox->isChecked())
  {
    berry::IWorkbenchPart::Pointer nullPart;
    QList<mitk::DataNode::Pointer> nodes;
    OnSelectionChanged(nullPart, nodes);
  }
}

void QmitkFiberProcessingView::OnEndInteraction()
{
  if (m_Controls->m_InteractiveBox->isChecked())
    ExtractWithPlanarFigure(true);
}

void QmitkFiberProcessingView::AddObservers()
{
  typedef itk::SimpleMemberCommand< QmitkFiberProcessingView > SimpleCommandType;
  for (auto node : m_SelectedPF)
  {
    mitk::PlanarFigure* figure = dynamic_cast<mitk::PlanarFigure*>(node->GetData());
    if (figure!=nullptr)
    {
      figure->RemoveAllObservers();

      // add observer for event when interaction with figure starts
      SimpleCommandType::Pointer endInteractionCommand = SimpleCommandType::New();
      endInteractionCommand->SetCallbackFunction( this, &QmitkFiberProcessingView::OnEndInteraction);
      m_EndInteractionObserverTag = figure->AddObserver( mitk::EndInteractionPlanarFigureEvent(), endInteractionCommand );
    }
  }
}

void QmitkFiberProcessingView::RemoveObservers()
{
  for (auto node : m_SelectedPF)
  {
    mitk::PlanarFigure* figure = dynamic_cast<mitk::PlanarFigure*>(node->GetData());
    if (figure!=nullptr)
      figure->RemoveAllObservers();
  }
}

void QmitkFiberProcessingView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*part*/, const QList<mitk::DataNode::Pointer>& nodes)
{
  RemoveObservers();

  //reset existing Vectors containing FiberBundles and PlanarFigures from a previous selection
  std::vector<mitk::DataNode::Pointer>  lastSelectedFB = m_SelectedFB;
  m_SelectedFB.clear();
  m_SelectedPF.clear();
  m_SelectedSurfaces.clear();
  m_SelectedImage = nullptr;
  m_RoiImageNode = nullptr;

  for (auto node: nodes)
  {
    if ( dynamic_cast<mitk::FiberBundle*>(node->GetData()) )
      m_SelectedFB.push_back(node);
    else if (dynamic_cast<mitk::PlanarPolygon*>(node->GetData()) || dynamic_cast<mitk::PlanarFigureComposite*>(node->GetData()) || dynamic_cast<mitk::PlanarCircle*>(node->GetData()))
      m_SelectedPF.push_back(node);
    else if (dynamic_cast<mitk::Image*>(node->GetData()))
    {
      m_SelectedImage = dynamic_cast<mitk::Image*>(node->GetData());
      if (m_SelectedImage->GetDimension()==3)
        m_RoiImageNode = node;
    }
    else if (dynamic_cast<mitk::Surface*>(node->GetData()))
      m_SelectedSurfaces.push_back(dynamic_cast<mitk::Surface*>(node->GetData()));
  }

  // if we perform interactive fiber extraction, we want to avoid auto-selection of the extracted bundle
  if (m_SelectedFB.empty() && m_Controls->m_InteractiveBox->isChecked())
    m_SelectedFB = lastSelectedFB;

  // if no fibers or surfaces are selected, select topmost
  if (m_SelectedFB.empty() && m_SelectedSurfaces.empty())
  {
    int maxLayer = 0;
    itk::VectorContainer<unsigned int, mitk::DataNode::Pointer>::ConstPointer nodes = this->GetDataStorage()->GetAll();
    for (unsigned int i=0; i<nodes->Size(); i++)
      if (dynamic_cast<mitk::FiberBundle*>(nodes->at(i)->GetData()))
      {
        mitk::DataStorage::SetOfObjects::ConstPointer sources = GetDataStorage()->GetSources(nodes->at(i));
        if (sources->Size()>0)
          continue;

        int layer = 0;
        nodes->at(i)->GetPropertyValue("layer", layer);
        if (layer>=maxLayer)
        {
          maxLayer = layer;
          m_SelectedFB.clear();
          m_SelectedFB.push_back(nodes->at(i));
        }
      }
  }

  // if no plar figure is selected, select topmost
  if (m_SelectedPF.empty())
  {
    int maxLayer = 0;
    itk::VectorContainer<unsigned int, mitk::DataNode::Pointer>::ConstPointer nodes = this->GetDataStorage()->GetAll();
    for (unsigned int i=0; i<nodes->Size(); i++)
      if (dynamic_cast<mitk::PlanarPolygon*>(nodes->at(i)->GetData()) || dynamic_cast<mitk::PlanarFigureComposite*>(nodes->at(i)->GetData()) || dynamic_cast<mitk::PlanarCircle*>(nodes->at(i)->GetData()))
      {
        mitk::DataStorage::SetOfObjects::ConstPointer sources = GetDataStorage()->GetSources(nodes->at(i));
        if (sources->Size()>0)
          continue;

        int layer = 0;
        nodes->at(i)->GetPropertyValue("layer", layer);
        if (layer>=maxLayer)
        {
          maxLayer = layer;
          m_SelectedPF.clear();
          m_SelectedPF.push_back(nodes->at(i));
        }
      }
  }

  AddObservers();
  UpdateGui();
}

void QmitkFiberProcessingView::OnDrawPolygon()
{
  mitk::PlanarPolygon::Pointer figure = mitk::PlanarPolygon::New();
  figure->ClosedOn();
  this->AddFigureToDataStorage(figure, QString("Polygon%1").arg(++m_PolygonCounter));
}

void QmitkFiberProcessingView::OnDrawCircle()
{
  mitk::PlanarCircle::Pointer figure = mitk::PlanarCircle::New();
  this->AddFigureToDataStorage(figure, QString("Circle%1").arg(++m_CircleCounter));
}

void QmitkFiberProcessingView::AddFigureToDataStorage(mitk::PlanarFigure* figure, const QString& name, const char *, mitk::BaseProperty* )
{
  // initialize figure's geometry with empty geometry
  mitk::PlaneGeometry::Pointer emptygeometry = mitk::PlaneGeometry::New();
  figure->SetPlaneGeometry( emptygeometry );

  //set desired data to DataNode where Planarfigure is stored
  mitk::DataNode::Pointer newNode = mitk::DataNode::New();
  newNode->SetName(name.toStdString());
  newNode->SetData(figure);
  newNode->SetBoolProperty("planarfigure.3drendering", true);
  newNode->SetBoolProperty("planarfigure.3drendering.fill", true);

  mitk::PlanarFigureInteractor::Pointer figureInteractor = dynamic_cast<mitk::PlanarFigureInteractor*>(newNode->GetDataInteractor().GetPointer());
  if(figureInteractor.IsNull())
  {
    figureInteractor = mitk::PlanarFigureInteractor::New();
    us::Module* planarFigureModule = us::ModuleRegistry::GetModule( "MitkPlanarFigure" );
    figureInteractor->LoadStateMachine("PlanarFigureInteraction.xml", planarFigureModule );
    figureInteractor->SetEventConfig( "PlanarFigureConfig.xml", planarFigureModule );
    figureInteractor->SetDataNode(newNode);
  }

  // figure drawn on the topmost layer / image
  GetDataStorage()->Add(newNode );

  RemoveObservers();
  for(unsigned int i = 0; i < m_SelectedPF.size(); i++)
    m_SelectedPF[i]->SetSelected(false);

  newNode->SetSelected(true);
  m_SelectedPF.clear();
  m_SelectedPF.push_back(newNode);
  AddObservers();
  UpdateGui();
}

void QmitkFiberProcessingView::ExtractWithPlanarFigure(bool interactive)
{
  if ( m_SelectedFB.empty() || m_SelectedPF.empty() ){
    QMessageBox::information( nullptr, "Warning", "No fibe bundle selected!");
    return;
  }

  try
  {
    std::vector<mitk::DataNode::Pointer> fiberBundles = m_SelectedFB;
    mitk::DataNode::Pointer planarFigure = m_SelectedPF.at(0);
    for (unsigned int i=0; i<fiberBundles.size(); i++)
    {
      mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(fiberBundles.at(i)->GetData());
      mitk::FiberBundle::Pointer extFB = fib->ExtractFiberSubset(planarFigure, GetDataStorage());

      if (interactive && m_Controls->m_InteractiveBox->isChecked())
      {
        if (m_InteractiveNode.IsNull())
        {
          m_InteractiveNode = mitk::DataNode::New();
          QString name("Interactive");
          m_InteractiveNode->SetName(name.toStdString());
          GetDataStorage()->Add(m_InteractiveNode);
        }
        float op = 5.0/sqrt(fib->GetNumFibers());
        float currentOp = 0;
        fiberBundles.at(i)->GetFloatProperty("opacity", currentOp);

        if (currentOp!=op)
        {
          fib->SetFiberColors(255, 255, 255);
          fiberBundles.at(i)->SetFloatProperty("opacity", op);
          fiberBundles.at(i)->SetBoolProperty("Fiber2DfadeEFX", false);
        }
        m_InteractiveNode->SetData(extFB);
      }
      else
      {
        if (extFB->GetNumFibers()<=0)
        {
          QMessageBox::information(nullptr, "No output generated:", "The resulting fiber bundle contains no fibers.");
          continue;
        }

        mitk::DataNode::Pointer node;
        node = mitk::DataNode::New();
        node->SetData(extFB);
        QString name(fiberBundles.at(i)->GetName().c_str());
        name += "*";
        node->SetName(name.toStdString());
        fiberBundles.at(i)->SetVisibility(false);
        GetDataStorage()->Add(node);
      }
    }
  }
  catch(const std::out_of_range& )
  {
    QMessageBox::warning( nullptr, "Fiber extraction failed", "Did you only create the planar figure, using the circle or polygon button, but forgot to actually place it in the image afterwards? \nAfter creating a planar figure, simply left-click at the desired position in the image or on the tractogram to place it.");
  }
}

void QmitkFiberProcessingView::GenerateAndComposite()
{
  mitk::PlanarFigureComposite::Pointer PFCAnd = mitk::PlanarFigureComposite::New();
  PFCAnd->setOperationType(mitk::PlanarFigureComposite::AND);

  mitk::DataNode::Pointer newPFCNode;
  newPFCNode = mitk::DataNode::New();
  newPFCNode->SetName("AND");
  newPFCNode->SetData(PFCAnd);

  AddCompositeToDatastorage(newPFCNode, m_SelectedPF);
  RemoveObservers();
  m_SelectedPF.clear();
  m_SelectedPF.push_back(newPFCNode);
  AddObservers();
  UpdateGui();
}

void QmitkFiberProcessingView::GenerateOrComposite()
{
  mitk::PlanarFigureComposite::Pointer PFCOr = mitk::PlanarFigureComposite::New();
  PFCOr->setOperationType(mitk::PlanarFigureComposite::OR);

  mitk::DataNode::Pointer newPFCNode;
  newPFCNode = mitk::DataNode::New();
  newPFCNode->SetName("OR");
  newPFCNode->SetData(PFCOr);

  RemoveObservers();
  AddCompositeToDatastorage(newPFCNode, m_SelectedPF);
  m_SelectedPF.clear();
  m_SelectedPF.push_back(newPFCNode);
  UpdateGui();
}

void QmitkFiberProcessingView::GenerateNotComposite()
{
  mitk::PlanarFigureComposite::Pointer PFCNot = mitk::PlanarFigureComposite::New();
  PFCNot->setOperationType(mitk::PlanarFigureComposite::NOT);

  mitk::DataNode::Pointer newPFCNode;
  newPFCNode = mitk::DataNode::New();
  newPFCNode->SetName("NOT");
  newPFCNode->SetData(PFCNot);

  RemoveObservers();
  AddCompositeToDatastorage(newPFCNode, m_SelectedPF);
  m_SelectedPF.clear();
  m_SelectedPF.push_back(newPFCNode);
  AddObservers();
  UpdateGui();
}

void QmitkFiberProcessingView::AddCompositeToDatastorage(mitk::DataNode::Pointer pfc, std::vector<mitk::DataNode::Pointer> children, mitk::DataNode::Pointer parentNode )
{
  pfc->SetSelected(true);
  if (parentNode.IsNotNull())
    GetDataStorage()->Add(pfc, parentNode);
  else
    GetDataStorage()->Add(pfc);

  for (auto child : children)
  {
    if (dynamic_cast<PlanarFigure*>(child->GetData()))
    {
      mitk::DataNode::Pointer newChild;
      newChild = mitk::DataNode::New();
      newChild->SetData(dynamic_cast<PlanarFigure*>(child->GetData()));
      newChild->SetName( child->GetName() );
      newChild->SetBoolProperty("planarfigure.3drendering", true);
      newChild->SetBoolProperty("planarfigure.3drendering.fill", true);

      GetDataStorage()->Add(newChild, pfc);
      GetDataStorage()->Remove(child);
    }
    else if (dynamic_cast<PlanarFigureComposite*>(child->GetData()))
    {
      mitk::DataNode::Pointer newChild;
      newChild = mitk::DataNode::New();
      newChild->SetData(dynamic_cast<PlanarFigureComposite*>(child->GetData()));
      newChild->SetName( child->GetName() );

      std::vector< mitk::DataNode::Pointer > grandChildVector;
      mitk::DataStorage::SetOfObjects::ConstPointer grandchildren = GetDataStorage()->GetDerivations(child);
      for( mitk::DataStorage::SetOfObjects::const_iterator it = grandchildren->begin(); it != grandchildren->end(); ++it )
        grandChildVector.push_back(*it);

      AddCompositeToDatastorage(newChild, grandChildVector, pfc);
      GetDataStorage()->Remove(child);
    }
  }
  UpdateGui();
}

void QmitkFiberProcessingView::CopyBundles()
{
  if ( m_SelectedFB.empty() ){
    QMessageBox::information( nullptr, "Warning", "Select at least one fiber bundle!");
    MITK_WARN("QmitkFiberProcessingView") << "Select at least one fiber bundle!";
    return;
  }

  for (auto node : m_SelectedFB)
  {
    mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());
    mitk::FiberBundle::Pointer newFib = fib->GetDeepCopy();

    node->SetVisibility(false);
    QString name("");
    name += QString(m_SelectedFB.at(0)->GetName().c_str());
    name += "_copy";

    mitk::DataNode::Pointer fbNode = mitk::DataNode::New();
    fbNode->SetData(newFib);
    fbNode->SetName(name.toStdString());
    fbNode->SetVisibility(true);
    GetDataStorage()->Add(fbNode);
  }
  UpdateGui();
}

void QmitkFiberProcessingView::JoinBundles()
{
  if ( m_SelectedFB.size()<2 ){
    QMessageBox::information( nullptr, "Warning", "Select at least two fiber bundles!");
    MITK_WARN("QmitkFiberProcessingView") << "Select at least two fiber bundles!";
    return;
  }

  m_SelectedFB.at(0)->SetVisibility(false);
  mitk::FiberBundle::Pointer newBundle = dynamic_cast<mitk::FiberBundle*>(m_SelectedFB.at(0)->GetData());

  std::vector< mitk::FiberBundle::Pointer > tractograms;
  for (unsigned int i=1; i<m_SelectedFB.size(); i++)
  {
    m_SelectedFB.at(i)->SetVisibility(false);
    tractograms.push_back(dynamic_cast<mitk::FiberBundle*>(m_SelectedFB.at(i)->GetData()));
  }
  newBundle = newBundle->AddBundles(tractograms);

  mitk::DataNode::Pointer fbNode = mitk::DataNode::New();
  fbNode->SetData(newBundle);
  fbNode->SetName("Joined_Tractograms");
  fbNode->SetVisibility(true);
  GetDataStorage()->Add(fbNode);
  UpdateGui();
}

void QmitkFiberProcessingView::SubstractBundles()
{
  if ( m_SelectedFB.size()<2 ){
    QMessageBox::information( nullptr, "Warning", "Select at least two fiber bundles!");
    MITK_WARN("QmitkFiberProcessingView") << "Select at least two fiber bundles!";
    return;
  }

  mitk::FiberBundle::Pointer newBundle = dynamic_cast<mitk::FiberBundle*>(m_SelectedFB.at(0)->GetData());
  m_SelectedFB.at(0)->SetVisibility(false);
  QString name("");
  name += QString(m_SelectedFB.at(0)->GetName().c_str());
  for (unsigned int i=1; i<m_SelectedFB.size(); i++)
  {
    newBundle = newBundle->SubtractBundle(dynamic_cast<mitk::FiberBundle*>(m_SelectedFB.at(i)->GetData()));
    if (newBundle.IsNull())
      break;
    name += "-"+QString(m_SelectedFB.at(i)->GetName().c_str());
    m_SelectedFB.at(i)->SetVisibility(false);
  }
  if (newBundle.IsNull())
  {
    QMessageBox::information(nullptr, "No output generated:", "The resulting fiber bundle contains no fibers. Did you select the fiber bundles in the correct order? X-Y is not equal to Y-X!");
    return;
  }

  mitk::DataNode::Pointer fbNode = mitk::DataNode::New();
  fbNode->SetData(newBundle);
  fbNode->SetName(name.toStdString());
  fbNode->SetVisibility(true);
  GetDataStorage()->Add(fbNode);
  UpdateGui();
}

void QmitkFiberProcessingView::ResampleSelectedBundlesSpline()
{
  double factor = this->m_Controls->m_SmoothFibersBox->value();
  for (auto node : m_SelectedFB)
  {
    mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());
    fib->ResampleSpline(factor);
  }
  RenderingManager::GetInstance()->RequestUpdateAll();
}

void QmitkFiberProcessingView::ResampleSelectedBundlesLinear()
{
  double factor = this->m_Controls->m_SmoothFibersBox->value();
  for (auto node : m_SelectedFB)
  {
    mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());
    fib->ResampleLinear(factor);
  }
  RenderingManager::GetInstance()->RequestUpdateAll();
}

void QmitkFiberProcessingView::CompressSelectedBundles()
{
  double factor = this->m_Controls->m_ErrorThresholdBox->value();
  for (auto node : m_SelectedFB)
  {
    mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());
    fib->Compress(factor);
    fib->ColorFibersByOrientation();
  }
  RenderingManager::GetInstance()->RequestUpdateAll();
}

void QmitkFiberProcessingView::DoImageColorCoding()
{
  if (m_Controls->m_ColorMapBox->GetSelectedNode().IsNull())
  {
    QMessageBox::information(nullptr, "Bundle coloring aborted:", "No image providing the scalar values for coloring the selected bundle available.");
    return;
  }

  for (auto node : m_SelectedFB)
  {
    mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());
    fib->ColorFibersByScalarMap(dynamic_cast<mitk::Image*>(m_Controls->m_ColorMapBox->GetSelectedNode()->GetData()), m_Controls->m_FiberOpacityBox->isChecked(), m_Controls->m_NormalizeColorValues->isChecked());
  }

  if (auto renderWindowPart = this->GetRenderWindowPart())
  {
    renderWindowPart->RequestUpdate();
  }
}

void QmitkFiberProcessingView::DoCurvatureColorCoding()
{
  for (auto node : m_SelectedFB)
  {
    mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());
    fib->ColorFibersByCurvature(m_Controls->m_FiberOpacityBox->isChecked(), m_Controls->m_NormalizeColorValues->isChecked());
  }

  if (auto renderWindowPart = this->GetRenderWindowPart())
  {
    renderWindowPart->RequestUpdate();
  }
}

void QmitkFiberProcessingView::DoLengthColorCoding()
{
  for (auto node : m_SelectedFB)
  {
    mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());
    fib->ColorFibersByLength(m_Controls->m_FiberOpacityBox->isChecked(), m_Controls->m_NormalizeColorValues->isChecked());
  }

  if (auto renderWindowPart = this->GetRenderWindowPart())
  {
    renderWindowPart->RequestUpdate();
  }
}

void QmitkFiberProcessingView::DoWeightColorCoding()
{
  for (auto node : m_SelectedFB)
  {
    mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());
    fib->ColorFibersByFiberWeights(m_Controls->m_FiberOpacityBox->isChecked(), m_Controls->m_NormalizeColorValues->isChecked());
  }

  if (auto renderWindowPart = this->GetRenderWindowPart())
  {
    renderWindowPart->RequestUpdate();
  }
}

void QmitkFiberProcessingView::MirrorFibers()
{
  unsigned int axis = this->m_Controls->m_MirrorFibersBox->currentIndex();
  for (auto node : m_SelectedFB)
  {
    mitk::FiberBundle::Pointer fib = dynamic_cast<mitk::FiberBundle*>(node->GetData());
    if (m_SelectedImage.IsNotNull())
      fib->SetReferenceGeometry(m_SelectedImage->GetGeometry());
    fib->MirrorFibers(axis);
  }

  for (auto surf : m_SelectedSurfaces)
  {
    vtkSmartPointer<vtkPolyData> poly = surf->GetVtkPolyData();
    vtkSmartPointer<vtkPoints> vtkNewPoints = vtkSmartPointer<vtkPoints>::New();

    for (int i=0; i<poly->GetNumberOfPoints(); i++)
    {
      double* point = poly->GetPoint(i);
      point[axis] *= -1;
      vtkNewPoints->InsertNextPoint(point);
    }
    poly->SetPoints(vtkNewPoints);
    surf->CalculateBoundingBox();
  }

  if (auto renderWindowPart = this->GetRenderWindowPart())
  {
    renderWindowPart->RequestUpdate();
  }
}

max_stars_repo_name: wyyrepo/MITK

max_issues_repo_name: wyyrepo/MITK

max_forks_repo_name: wyyrepo/MITK


text: #include <boost/geometry/algorithms/buffer.hpp>

ext: hpp

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
#ifndef WAVE_INTEGRALS_HPP
#define WAVE_INTEGRALS_HPP

#include <Eigen/Core>
#include "wave/utils/utils.hpp"

namespace wave {

/**
 * This class implements the integrand for the covariance of constant acceleration priors
 */
class ConstantAccelerationCovariance {
 private:
    /// Power spectral density matrix on acceleration noise
    const Mat6 Qc;
    const double tmax;
    /// Rotational velocity
    const Vec6 w;

    /**
     * This is to calculate what I've been calling gamma in my head.
     * It's similar to the Rodrigez formula, and pops out of the NL-SDE that
     * models constant acceleration.
     * @param deltaT required
     * @return
     */
    void evaluateGamma(const double &deltaT, Mat6 &gamma);

 public:
    ConstantAccelerationCovariance(Mat6 QC, double Tmax, Vec6 omega) : Qc(QC), tmax(Tmax), w(omega) {}

    /**
     * Numerically integrate using trapezoidal rule to get Qtotal
     * @param Qtotal Covariance
     * @param slices How many discrete chunks to use when integrating
     */
    void calculateCovariance(Mat6 &Qtotal, const int& slices = 50);
};
}

#endif  // WAVE_INTEGRALS_HPP

max_stars_repo_name: Jebediah/libwave

max_issues_repo_name: Jebediah/libwave

max_forks_repo_name: Jebediah/libwave


text:
#ifndef _LIBRE_CHART_IMPL_HPP
#define _LIBRE_CHART_IMPL_HPP

//          Copyright Anurag Ghosh 2015.
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          http://www.boost.org/LICENSE_1_0.txt)

#include <string>

#include <boost/shared_ptr.hpp>
#include <boost/pointer_cast.hpp>
#include <boost/make_shared.hpp>
#include <boost/filesystem.hpp>

#include <boost/document/detail/document_exception.hpp>

#include <boost/document/detail/chart_interface.hpp>
#include <boost/document/detail/chart_type.hpp>
#include <boost/document/detail/chart_axis.hpp>

#include <boost/document/detail/libre_api/libre_chart_func.hpp>

namespace boost { namespace detail {

class libre_chart: public chart_interface {

protected:
    std::string name_, cell_range_;
    ::com::sun::star::uno::Reference < com::sun::star::chart::XChartDocument > xChart_;
    ::com::sun::star::uno::Reference < com::sun::star::sheet::XSpreadsheet > xSheet_;
    std::size_t left_, top_, width_, height_;
    boost::chart_type::type t_;
    bool enable_3d_, legend_;

public:
    libre_chart(::com::sun::star::uno::Reference < com::sun::star::chart::XChartDocument > xChart,
        ::com::sun::star::uno::Reference < com::sun::star::sheet::XSpreadsheet > xSheet,
        const std::string& name, const std::string& cell_range,
        std::size_t left, std::size_t top, std::size_t width, std::size_t height) {
        this->xChart_ = xChart;
        this->xSheet_ = xSheet;
        this->cell_range_ = cell_range;
        this->name_ = name;
        this->left_ = left;
        this->top_ = top;
        this->width_ = width;
        this->height_ = height;
        this->legend_ = true;
        //this->enable_3d_ = false;
    }

    void set_title(const std::string& title) {
            boost::doc::libre_chart_func::set_title(xChart_, title);
    }

    void set_axis_title(boost::chart_axis::type t, const std::string& title) {
            boost::doc::libre_chart_func::set_axis_title(xChart_, t, title);
    }

    void set_type(boost::chart_type::type t, bool enable_3d) {
            boost::doc::libre_chart_func::set_type(xChart_, t, enable_3d);
            t_ = t;
            enable_3d_ = enable_3d;
    }

    void set_legend(bool set) {
            boost::doc::libre_chart_func::set_legend(xChart_, set);
            legend_ = set;
    }

    void set_axis_orientation(boost::chart_axis::type t, bool set) {
            boost::doc::libre_chart_func::set_axis_orientation(xChart_, t, set);
    }

    void set_range(const std::string& cell_range) {
            cell_range_ = cell_range;
            boost::doc::libre_chart_func::set_cell_range(xChart_, xSheet_, name_, cell_range_);
    }

    void set_position(std::size_t top, std::size_t left) {
            left_ = left;
            top_ = top;
            boost::doc::libre_chart_func::set_rectangle(xChart_, xSheet_, (int)top_, (int)left_, (int)width_, (int)height_);
    }

    void set_size(std::size_t width, std::size_t height) {
            width_ = width;
            height_ = height;
            boost::doc::libre_chart_func::set_rectangle(xChart_, xSheet_, (int)top_, (int)left_, (int)width_, (int)height_);
    }

    ~libre_chart() {
    }

};

}} // namespace boost::detail

#endif

max_stars_repo_name: anuragxel/generic-document-library

max_issues_repo_name: anuragxel/generic-document-library

max_forks_repo_name: anuragxel/generic-document-library


text:
/*
 * Copyright 2014,2015 Free Software Foundation, Inc.
 *
 * This file is part of GNU Radio
 *
 * GNU Radio is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3, or (at your option)
 * any later version.
 *
 * GNU Radio is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Radio; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street,
 * Boston, MA 02110-1301, USA.
 */

#include <boost/assign/ptr_map_inserter.hpp>
#include <gnuradio/rpcpmtconverters_thrift.h>
#include <gnuradio/gr_complex.h>
#include "thrift/gnuradio_types.h"
#include <iostream>

GNURadio::Knob
rpcpmtconverter::from_pmt(const pmt::pmt_t& knob)
{
  if(pmt::is_real(knob)) {
    GNURadio::Knob result;
    result.type = GNURadio::BaseTypes::DOUBLE;
    result.value.__set_a_double(pmt::to_double(knob));
    return result;
  }
  else if(pmt::is_symbol(knob)) {
    std::string value = pmt::symbol_to_string(knob);
    GNURadio::Knob result;
    result.type = GNURadio::BaseTypes::STRING;
    result.value.__set_a_string(value);
    return result;
  }
  else if(pmt::is_integer(knob)) {
    GNURadio::Knob result;
    result.type = GNURadio::BaseTypes::LONG;
    result.value.__set_a_long(pmt::to_long(knob));
    return result;
  }
  else if(pmt::is_bool(knob)) {
    GNURadio::Knob result;
    result.type = GNURadio::BaseTypes::BOOL;
    result.value.__set_a_bool(pmt::to_bool(knob));
    return result;
  }
  else if(pmt::is_uint64(knob)) {
    GNURadio::Knob result;
    result.type = GNURadio::BaseTypes::LONG;
    result.value.__set_a_long(pmt::to_uint64(knob));
    return result;
  }
  else if(pmt::is_complex(knob)) {
    GNURadio::Knob result;
    result.type = GNURadio::BaseTypes::COMPLEX;
    std::complex<double> tmp = pmt::to_complex(knob);
    GNURadio::complex cpx;
    cpx.re = tmp.real();
    cpx.im = tmp.imag();
    result.value.__set_a_complex(cpx);
    return result;
  }
  else if(pmt::is_f32vector(knob)) {
    GNURadio::Knob result;
    result.type = GNURadio::BaseTypes::F32VECTOR;
    size_t size(pmt::length(knob));
    const float* start((const float*)pmt::f32vector_elements(knob,size));
    result.value.__set_a_f32vector(std::vector<double>(start,start+size));
    return result;
  }
  else if(pmt::is_f64vector(knob)) {
    GNURadio::Knob result;
    result.type = GNURadio::BaseTypes::F64VECTOR;
    size_t size(pmt::length(knob));
    const double* start((const double*)pmt::f64vector_elements(knob,size));
    result.value.__set_a_f64vector(std::vector<double>(start,start+size));
    return result;
  }
  else if(pmt::is_s64vector(knob)) {
    GNURadio::Knob result;
    result.type = GNURadio::BaseTypes::S64VECTOR;
    size_t size(pmt::length(knob));
    const int64_t* start((const int64_t*)pmt::s64vector_elements(knob,size));
    result.value.__set_a_s64vector(std::vector<int64_t>(start,start+size));
    return result;
  }
  else if(pmt::is_s32vector(knob)) {
    GNURadio::Knob result;
    result.type = GNURadio::BaseTypes::S32VECTOR;
    size_t size(pmt::length(knob));
    const int32_t* start((const int32_t*)pmt::s32vector_elements(knob,size));
    result.value.__set_a_s32vector(std::vector<int32_t>(start,start+size));
    return result;
  }
  else if(pmt::is_s16vector(knob)) {
    GNURadio::Knob result;
    result.type = GNURadio::BaseTypes::S16VECTOR;
    size_t size(pmt::length(knob));
    const int16_t* start((const int16_t*)pmt::s16vector_elements(knob,size));
    result.value.__set_a_s16vector(std::vector<int16_t>(start,start+size));
    return result;
  }
  else if(pmt::is_s8vector(knob)) {
    GNURadio::Knob result;
    result.type = GNURadio::BaseTypes::S8VECTOR;
    size_t size(pmt::length(knob));
    const int8_t* start((const int8_t*)pmt::s8vector_elements(knob,size));
    result.value.__set_a_s8vector(std::basic_string<char>(start,start+size));
    return result;
  }
  else if(pmt::is_c32vector(knob)) {
    std::vector< GNURadio::complex > z;

    GNURadio::Knob result;
    result.type = GNURadio::BaseTypes::C32VECTOR;
    size_t size(pmt::length(knob));
    const gr_complex* start((const gr_complex*)pmt::c32vector_elements(knob,size));
    for(size_t s = 0; s < size; s++) {
      GNURadio::complex z0;
      gr_complex z1 = gr_complex(*(start+s));
      z0.__set_re(z1.real());
      z0.__set_im(z1.imag());
      z.push_back(z0);
    }
    result.value.__set_a_c32vector(z);
    return result;
  }
  else {
    std::cerr << "Error: Don't know how to handle Knob Type (from): " << knob << std::endl;
    assert(0);
  }
  return GNURadio::Knob();
}

pmt::pmt_t
rpcpmtconverter::to_pmt_byte_f::operator()(const GNURadio::Knob& knob)
{
  return pmt::mp(knob.value.a_byte);
}

pmt::pmt_t
rpcpmtconverter::to_pmt_short_f::operator()(const GNURadio::Knob& knob)
{
  return pmt::mp(knob.value.a_short);
}

pmt::pmt_t
rpcpmtconverter::to_pmt_int_f::operator()(const GNURadio::Knob& knob)
{
  return pmt::mp(knob.value.a_int);
}

pmt::pmt_t
rpcpmtconverter::to_pmt_long_f::operator()(const GNURadio::Knob& knob)
{
  return pmt::from_long(knob.value.a_long);
}

pmt::pmt_t
rpcpmtconverter::to_pmt_double_f::operator()(const GNURadio::Knob& knob)
{
  return pmt::mp(knob.value.a_double);
}

pmt::pmt_t
rpcpmtconverter::to_pmt_string_f::operator()(const GNURadio::Knob& knob)
{
  return pmt::string_to_symbol(knob.value.a_string);
}

pmt::pmt_t
rpcpmtconverter::to_pmt_bool_f::operator()(const GNURadio::Knob& knob)
{
  if(knob.value.a_bool)
    return pmt::PMT_T;
  else
    return pmt::PMT_F;
}

pmt::pmt_t
rpcpmtconverter::to_pmt_complex_f::operator()(const GNURadio::Knob& knob)
{
  gr_complexd cpx(knob.value.a_complex.re, knob.value.a_complex.im);
  return pmt::from_complex(cpx);
}

pmt::pmt_t
rpcpmtconverter::to_pmt_f32vect_f::operator()(const GNURadio::Knob& knob)
{
  std::vector<double> v_double = knob.value.a_f32vector;
  std::vector<float> v(v_double.begin(), v_double.end());
  return pmt::init_f32vector(v.size(), v);
}

pmt::pmt_t
rpcpmtconverter::to_pmt_f64vect_f::operator()(const GNURadio::Knob& knob)
{
  std::vector<double> v = knob.value.a_f64vector;
  return pmt::init_f64vector(v.size(), v);
}

pmt::pmt_t
rpcpmtconverter::to_pmt_s64vect_f::operator()(const GNURadio::Knob& knob)
{
  std::vector<int64_t> v = knob.value.a_s64vector;
  return pmt::init_s64vector(v.size(), v);
}

pmt::pmt_t
rpcpmtconverter::to_pmt_s32vect_f::operator()(const GNURadio::Knob& knob)
{
  std::vector<int32_t> v = knob.value.a_s32vector;
  return pmt::init_s32vector(v.size(), v);
}

pmt::pmt_t
rpcpmtconverter::to_pmt_s16vect_f::operator()(const GNURadio::Knob& knob)
{
  std::vector<int16_t> v = knob.value.a_s16vector;
  return pmt::init_s16vector(v.size(), v);
}

pmt::pmt_t
rpcpmtconverter::to_pmt_s8vect_f::operator()(const GNURadio::Knob& knob)
{
  std::basic_string<char> v = knob.value.a_s8vector;
  return pmt::init_s8vector(v.size(), reinterpret_cast<const int8_t*>(v.data()));
}

pmt::pmt_t
rpcpmtconverter::to_pmt_c32vect_f::operator()(const GNURadio::Knob& knob)
{
  std::vector<GNURadio::complex> v0 = knob.value.a_c32vector;
  std::vector<GNURadio::complex>::iterator vitr;
  std::vector<gr_complex> v;
  for(vitr = v0.begin(); vitr != v0.end(); vitr++) {
    v.push_back(gr_complex(vitr->re, vitr->im));
  }
  return pmt::init_c32vector(v.size(), v);
}

rpcpmtconverter::To_PMT rpcpmtconverter::To_PMT::instance;

rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_bool_f>    reg_bool(rpcpmtconverter::To_PMT::instance,
                                                                        GNURadio::BaseTypes::BOOL);
rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_byte_f>    reg_byte(rpcpmtconverter::To_PMT::instance,
                                                                        GNURadio::BaseTypes::BYTE);
rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_short_f>   reg_short(rpcpmtconverter::To_PMT::instance,
                                                                         GNURadio::BaseTypes::SHORT);
rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_int_f>     reg_int(rpcpmtconverter::To_PMT::instance,
                                                                       GNURadio::BaseTypes::INT);
rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_long_f>    reg_long(rpcpmtconverter::To_PMT::instance,
                                                                        GNURadio::BaseTypes::LONG);
rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_double_f>  reg_double(rpcpmtconverter::To_PMT::instance,
                                                                          GNURadio::BaseTypes::DOUBLE);
rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_string_f>  reg_string(rpcpmtconverter::To_PMT::instance,
                                                                          GNURadio::BaseTypes::STRING);
rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_complex_f> reg_complex(rpcpmtconverter::To_PMT::instance,
                                                                           GNURadio::BaseTypes::COMPLEX);
rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_f32vect_f> reg_f32v(rpcpmtconverter::To_PMT::instance,
                                                                        GNURadio::BaseTypes::F32VECTOR);
rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_f64vect_f> reg_f64v(rpcpmtconverter::To_PMT::instance,
                                                                        GNURadio::BaseTypes::F64VECTOR);
rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_s64vect_f> reg_s64v(rpcpmtconverter::To_PMT::instance,
                                                                        GNURadio::BaseTypes::S64VECTOR);
rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_s32vect_f> reg_s32v(rpcpmtconverter::To_PMT::instance,
                                                                        GNURadio::BaseTypes::S32VECTOR);
rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_s16vect_f> reg_s16v(rpcpmtconverter::To_PMT::instance,
                                                                        GNURadio::BaseTypes::S16VECTOR);
rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_s8vect_f>  reg_s8v(rpcpmtconverter::To_PMT::instance,
                                                                       GNURadio::BaseTypes::S8VECTOR);
rpcpmtconverter::to_pmt_reg<rpcpmtconverter::to_pmt_c32vect_f> reg_c32v(rpcpmtconverter::To_PMT::instance,
                                                                        GNURadio::BaseTypes::C32VECTOR);

template<typename TO_PMT_F>
rpcpmtconverter::to_pmt_reg<TO_PMT_F>::to_pmt_reg(To_PMT& instance,
                                                  const GNURadio::BaseTypes::type type)
{
  boost::assign::ptr_map_insert<TO_PMT_F>(instance.to_pmt_map)(type);
}

pmt::pmt_t
rpcpmtconverter::to_pmt_f::operator()(const GNURadio::Knob& knob)
{
  std::cerr << "Error: Don't know how to handle Knob Type: " << knob.type << std::endl;
  assert(0);
  return pmt::pmt_t();
}

pmt::pmt_t
rpcpmtconverter::To_PMT::operator()(const GNURadio::Knob& knob)
{
  return to_pmt_map[knob.type](knob);
}

ext: cc


text:
#include <gtest/gtest.h>
#include "scheme/util/SimpleArray.hh"
#include <boost/foreach.hpp>

namespace scheme {
namespace util {

using std::cout;
using std::endl;

TEST(SimpleArray,bounds_check){
	SimpleArray<3,int> a;
	a[3]; // non-bounds checked
	#ifndef NDEBUG
	#ifndef CXX14
	ASSERT_DEATH( a.at(3), ".*" );
	#endif
	#endif
}

TEST(SimpleArray,iteration){
	SimpleArray<3,int> a;
	int v;
	v = 0; BOOST_FOREACH(int & i, std::make_pair(a.begin(),a.end()) ) i = ++v;
	v = 0; BOOST_FOREACH(int i, std::make_pair(a.begin(),a.end()) ) ASSERT_EQ( ++v, i );
	v = 0; BOOST_FOREACH(int i, a ) ASSERT_EQ( ++v, i );
	SimpleArray<3,int> const & r = a;
	v = 0; BOOST_FOREACH(int i, std::make_pair(r.begin(),r.end()) ) ASSERT_EQ( ++v, i );
	v = 0; BOOST_FOREACH(int const & i, r ) ASSERT_EQ( ++v, i );
}

}
}

max_stars_repo_name: YaoYinYing/rifdock

max_issues_repo_name: YaoYinYing/rifdock

max_forks_repo_name: YaoYinYing/rifdock