void MrtrixPeakImageConverter< PixelType >
::GenerateData()
{
    // output vector field
    vtkSmartPointer<vtkCellArray> m_VtkCellArray = vtkSmartPointer<vtkCellArray>::New();
    vtkSmartPointer<vtkPoints>    m_VtkPoints = vtkSmartPointer<vtkPoints>::New();

    Vector<float, 4> spacing4 = m_InputImage->GetSpacing();
    Point<float, 4> origin4 = m_InputImage->GetOrigin();
    Matrix<double, 4, 4> direction4 = m_InputImage->GetDirection();
    ImageRegion<4> imageRegion4 = m_InputImage->GetLargestPossibleRegion();

    Vector<float, 3> spacing3;
    Point<float, 3> origin3;
    Matrix<double, 3, 3> direction3;
    ImageRegion<3> imageRegion3;

    spacing3[0] = spacing4[0]; spacing3[1] = spacing4[1]; spacing3[2] = spacing4[2];
    origin3[0] = origin4[0]; origin3[1] = origin4[1]; origin3[2] = origin4[2];
    for (int r=0; r<3; r++)
        for (int c=0; c<3; c++)
            direction3[r][c] = direction4[r][c];
    imageRegion3.SetSize(0, imageRegion4.GetSize()[0]);
    imageRegion3.SetSize(1, imageRegion4.GetSize()[1]);
    imageRegion3.SetSize(2, imageRegion4.GetSize()[2]);

    double minSpacing = spacing3[0];
    if (spacing3[1]<minSpacing)
        minSpacing = spacing3[1];
    if (spacing3[2]<minSpacing)
        minSpacing = spacing3[2];

    m_DirectionImageContainer = DirectionImageContainerType::New();

    typedef ImageRegionConstIterator< InputImageType > InputIteratorType;

    int x = m_InputImage->GetLargestPossibleRegion().GetSize(0);
    int y = m_InputImage->GetLargestPossibleRegion().GetSize(1);
    int z = m_InputImage->GetLargestPossibleRegion().GetSize(2);
    int numDirs = m_InputImage->GetLargestPossibleRegion().GetSize(3)/3;

    m_NumDirectionsImage = ItkUcharImgType::New();
    m_NumDirectionsImage->SetSpacing( spacing3 );
    m_NumDirectionsImage->SetOrigin( origin3 );
    m_NumDirectionsImage->SetDirection( direction3 );
    m_NumDirectionsImage->SetRegions( imageRegion3 );
    m_NumDirectionsImage->Allocate();
    m_NumDirectionsImage->FillBuffer(0);

    for (int i=0; i<numDirs; i++)
    {
        ItkDirectionImageType::Pointer directionImage = ItkDirectionImageType::New();
        directionImage->SetSpacing( spacing3 );
        directionImage->SetOrigin( origin3 );
        directionImage->SetDirection( direction3 );
        directionImage->SetRegions( imageRegion3 );
        directionImage->Allocate();
        Vector< PixelType, 3 > nullVec; nullVec.Fill(0.0);
        directionImage->FillBuffer(nullVec);

        for (int a=0; a<x; a++)
            for (int b=0; b<y; b++)
                for (int c=0; c<z; c++)
                {
                    // generate vector field
                    typename InputImageType::IndexType index;
                    index.SetElement(0,a);
                    index.SetElement(1,b);
                    index.SetElement(2,c);
                    vnl_vector<double> dirVec; dirVec.set_size(4);
                    for (int k=0; k<3; k++)
                    {
                        index.SetElement(3,k+i*3);
                        dirVec[k] = m_InputImage->GetPixel(index);
                    }
                    dirVec[3] = 0;

                    vtkSmartPointer<vtkPolyLine> container = vtkSmartPointer<vtkPolyLine>::New();
                    itk::ContinuousIndex<double, 4> center;
                    center[0] = index[0];
                    center[1] = index[1];
                    center[2] = index[2];
                    center[3] = 0;
                    itk::Point<double, 4> worldCenter;
                    m_InputImage->TransformContinuousIndexToPhysicalPoint( center, worldCenter );

                    switch (m_NormalizationMethod)
                    {
                    case NO_NORM:
                        break;
                    case SINGLE_VEC_NORM:
                        dirVec.normalize();
                        break;
                    }
                    dirVec.normalize();
                    dirVec = m_InputImage->GetDirection()*dirVec;

                    itk::Point<double> worldStart;
                    worldStart[0] = worldCenter[0]-dirVec[0]/2 * minSpacing;
                    worldStart[1] = worldCenter[1]-dirVec[1]/2 * minSpacing;
                    worldStart[2] = worldCenter[2]-dirVec[2]/2 * minSpacing;
                    vtkIdType id = m_VtkPoints->InsertNextPoint(worldStart.GetDataPointer());
                    container->GetPointIds()->InsertNextId(id);
                    itk::Point<double> worldEnd;
                    worldEnd[0] = worldCenter[0]+dirVec[0]/2 * minSpacing;
                    worldEnd[1] = worldCenter[1]+dirVec[1]/2 * minSpacing;
                    worldEnd[2] = worldCenter[2]+dirVec[2]/2 * minSpacing;
                    id = m_VtkPoints->InsertNextPoint(worldEnd.GetDataPointer());
                    container->GetPointIds()->InsertNextId(id);
                    m_VtkCellArray->InsertNextCell(container);

                    // generate direction image
                    typename ItkDirectionImageType::IndexType index2;
                    index2[0] = a; index2[1] = b; index2[2] = c;


                    Vector< PixelType, 3 > pixel;
                    pixel.SetElement(0, dirVec[0]);
                    pixel.SetElement(1, dirVec[1]);
                    pixel.SetElement(2, dirVec[2]);
                    directionImage->SetPixel(index2, pixel);

                    if (dirVec.magnitude()>0.0001)
                        m_NumDirectionsImage->SetPixel(index2, m_NumDirectionsImage->GetPixel(index2)+1);
                }
        m_DirectionImageContainer->InsertElement(m_DirectionImageContainer->Size(), directionImage);
    }

    vtkSmartPointer<vtkPolyData> directionsPolyData = vtkSmartPointer<vtkPolyData>::New();
    directionsPolyData->SetPoints(m_VtkPoints);
    directionsPolyData->SetLines(m_VtkCellArray);
    m_OutputFiberBundle = mitk::FiberBundleX::New(directionsPolyData);
}
void ShCoefficientImageExporter< PixelType, ShOrder >
::GenerateData()
{
    if (m_InputImage.IsNull())
        return;

    Vector<double, 4> spacing4;
    Point<float, 4> origin4;
    Matrix<double, 4, 4> direction4; direction4.SetIdentity();
    ImageRegion<4> imageRegion4;

    Vector<double, 3> spacing3 = m_InputImage->GetSpacing();
    Point<float, 3> origin3 = m_InputImage->GetOrigin();
    Matrix<double, 3, 3> direction3 = m_InputImage->GetDirection();
    ImageRegion<3> imageRegion3 = m_InputImage->GetLargestPossibleRegion();

    spacing4[0] = spacing3[0]; spacing4[1] = spacing3[1]; spacing4[2] = spacing3[2]; spacing4[3] = 1;
    origin4[0] = origin3[0]; origin4[1] = origin3[1]; origin4[2] = origin3[2]; origin4[3] = 0;
    for (int r=0; r<3; r++)
        for (int c=0; c<3; c++)
            direction4[r][c] = direction3[r][c];

    imageRegion4.SetSize(0, imageRegion3.GetSize()[0]);
    imageRegion4.SetSize(1, imageRegion3.GetSize()[1]);
    imageRegion4.SetSize(2, imageRegion3.GetSize()[2]);
    imageRegion4.SetSize(3, (ShOrder*ShOrder + ShOrder + 2)/2 + ShOrder );

    m_OutputImage = CoefficientImageType::New();
    m_OutputImage->SetSpacing( spacing4 );
    m_OutputImage->SetOrigin( origin4 );
    m_OutputImage->SetDirection( direction4 );
    m_OutputImage->SetRegions( imageRegion4 );
    m_OutputImage->Allocate();
    m_OutputImage->FillBuffer(0.0);

    typedef ImageRegionConstIterator< InputImageType > InputIteratorType;
    InputIteratorType it(m_InputImage, m_InputImage->GetLargestPossibleRegion());
    int numCoeffs = imageRegion4.GetSize(3);

    int x = imageRegion3.GetSize(0);
    int y = imageRegion3.GetSize(1);
    int z = imageRegion3.GetSize(2);

#ifdef WIN32
#pragma omp parallel for
#else
#pragma omp parallel for collapse(3)
#endif
  for (int a=0; a<x; a++)
    for (int b=0; b<y; b++)
      for (int c=0; c<z; c++)
      {
        typename InputImageType::IndexType index3;
        index3.SetElement(0,a);
        index3.SetElement(1,b);
        index3.SetElement(2,c);

        CoefficientImageType::IndexType index4;
        index4[0] = index3[0];
        index4[1] = index3[1];
        index4[2] = index3[2];

        typename InputImageType::PixelType pix = m_InputImage->GetPixel(index3);
        for (int i=0; i<numCoeffs; i++)
        {
            index4[3] = i;
            m_OutputImage->SetPixel(index4, pix[i]);
        }
    }
}