void mitk::CollectionGrayOpening::PerformGrayOpening(mitk::DataCollection *dataCollection,
                                                     std::string name,
                                                     std::string suffix)
{
  for (size_t patient = 0; patient < dataCollection->Size(); ++patient)
  {
    DataCollection *dataPatient = dynamic_cast<DataCollection *>(dataCollection->GetData(patient).GetPointer());
    if (dataPatient == nullptr)
      MITK_ERROR << "PerformGrayOpening - Structure of DataCollection is invalid at patient level. Data inconsistent!";

    if (dataPatient->Size() == 0)
      MITK_ERROR << "Empty Patient Collective. Probably Fatal.";

    for (size_t timeStep = 0; timeStep < dataPatient->Size(); ++timeStep)
    {
      DataCollection *dataTimeStep = dynamic_cast<DataCollection *>(dataPatient->GetData(timeStep).GetPointer());
      if (dataTimeStep == nullptr)
        MITK_ERROR
          << "DilateBinaryByName- Structure of DataCollection is invalid at time step level. Data inconsistent!";

      // BinaryImage::Pointer itkImage = BinaryImage::New();
      ImageType::Pointer itkImage = ImageType::New();
      Image::Pointer tmp = dataTimeStep->GetMitkImage(name).GetPointer();
      if (tmp.IsNull())
        MITK_ERROR << "null";
      CastToItkImage(tmp, itkImage);
      if (itkImage.IsNull())
        MITK_ERROR << "Image " << name << " does not exist. Fatal.";

      typedef itk::FlatStructuringElement<3> StructuringElementType;
      StructuringElementType::RadiusType elementRadius;
      elementRadius.Fill(1);
      elementRadius[2] = 0;
      StructuringElementType structuringElement = StructuringElementType::Box(elementRadius);

      typedef itk::GrayscaleMorphologicalOpeningImageFilter<ImageType, ImageType, StructuringElementType>
        DilateImageFilterType;

      DilateImageFilterType::Pointer dilateFilter0 = DilateImageFilterType::New();
      dilateFilter0->SetInput(itkImage);
      dilateFilter0->SetKernel(structuringElement);
      dilateFilter0->Update();

      DilateImageFilterType::Pointer dilateFilter1 = DilateImageFilterType::New();
      dilateFilter1->SetInput(dilateFilter0->GetOutput());
      dilateFilter1->SetKernel(structuringElement);
      dilateFilter1->Update();

      Image::Pointer dil = GrabItkImageMemory(dilateFilter1->GetOutput());
      dataTimeStep->AddData(dil.GetPointer(), name + suffix, "");
    }
  }
}
void mitk::TumorInvasionClassification::DescriptionToLogFile(mitk::DataCollection *collection, std::string outputFile)
{
  std::ofstream fileStream;
  fileStream.open(outputFile.c_str(),std::ios_base::app);

  fileStream << "Configuration:" << std::endl;
  for (size_t patient = 0; patient < collection->Size(); ++patient)
  {
    DataCollection* dataPatient = dynamic_cast<DataCollection*>(collection->GetData(patient).GetPointer());
    fileStream << "Name : " << dataPatient->GetName() << " with time steps:"  << std::endl;
    for (size_t timeStep = 0; timeStep < dataPatient->Size(); ++timeStep)
    {
      fileStream << dataPatient->IndexToName(timeStep)<< "-" << std::endl;
      DataCollection* dataTS = dynamic_cast<DataCollection*>(dataPatient->GetData(timeStep).GetPointer());
      for (size_t ts = 0; ts < dataTS->Size(); ++ts)
        fileStream << dataTS->IndexToName(ts)<< "-" << std::endl;
    }
  }
}
bool mitk::DiffusionCollectionWriter::ExportCollectionToFolder(DataCollection *dataCollection, std::string xmlFile, std::vector<std::string> filter)
{
  // Quick and Dirty: Assumes three level DataCollection
  QDir fileName = QFileInfo(xmlFile.c_str()).absoluteDir();
  std::string outputFolder = fileName.path().toStdString() + QDir::separator().toLatin1();
  QDir baseFolder(outputFolder.c_str());
  baseFolder.mkpath(outputFolder.c_str());

  std::ofstream xmlFileStream;
  xmlFileStream.open (xmlFile.c_str());
  xmlFileStream << "<!-- MITK - DataCollection - File Version 1.0 --> \n";
  xmlFileStream << "<" << COLLECTION << " " << NAME << "=\"" << dataCollection->GetName() << "\" >\n";
  unsigned int subColId = 0;

  unsigned int dataId = 0;

  QDir dir(QString::fromStdString(outputFolder));
  for (size_t i = 0 ; i < dataCollection->Size(); ++i)
  {
    // Write Subcollection tag
    xmlFileStream << "  <" << SUBCOLLECTION <<  " " << NAME << "=\"" << dataCollection->IndexToName(i) << "\" " <<  FILEPATH << "=\"" << dataCollection->GetDataFilePath(i) << "\" id=\"Col" << subColId << "\" >\n";
    // Create Sub-Folder
    dir.mkpath(QString::fromStdString(dataCollection->IndexToName(i)));

    // Herein create data folders
    DataCollection* subCollections = dynamic_cast<DataCollection*> (dataCollection->GetData(i).GetPointer());
    if (subCollections == nullptr)
    {
      MITK_ERROR<< "mitk::DiffusionCollectionWriter::SaveCollectionToFolder: Container is illformed. Aborting";
      return false;
    }

    for (size_t d = 0; d < subCollections->Size(); d++ )
    {
      // Create Sub Paths
      QString subPath = QString::fromStdString(dataCollection->IndexToName(i))+"/"+QString::fromStdString(subCollections->IndexToName(d));
      dir.mkpath(subPath);
      xmlFileStream << "  <" << DATA <<  " " << NAME << "=\"" << subCollections->IndexToName(d) << "\" " <<  FILEPATH << "=\"" << subCollections->GetDataFilePath(d) << "\" id=\"Data" << dataId << "\" >\n";

      DataCollection* itemCollections = dynamic_cast<DataCollection*> (subCollections->GetData(d).GetPointer());
      if (itemCollections == nullptr)
      {
        MITK_ERROR<< "mitk::DiffusionCollectionWriter::SaveCollectionToFolder: Container is illformed. Aborting";
        return false;
      }

      for (size_t s = 0; s < itemCollections->Size(); s++)
      {
        if (filter.size() > 0)
        {
          bool isSelected = false;
          for (size_t f = 0; f < filter.size(); f++)
          {
            if (filter.at(f) == itemCollections->IndexToName(s) )
            {
              isSelected = true;
              break;
            }
          }
          if (isSelected == false)
            continue;
        }
        Image* image = dynamic_cast<Image*> (itemCollections->GetData(s).GetPointer());
        QString fileName = dir.path() + dir.separator() + subPath + dir.separator() +  QString::fromStdString(dataCollection->IndexToName(i)) + "_" + QString::fromStdString(subCollections->IndexToName(d)) + "_" + QString::fromStdString(itemCollections->IndexToName(s));
        try
        {
          if (itemCollections->IndexToName(s) == "DTI" || itemCollections->IndexToName(s) == "DTIFWE")
          {
            fileName += ".dti";
            IOUtil::Save(image,fileName.toStdString());
          }
          else if (itemCollections->IndexToName(s) == "FIB")
          {
            fileName += ".fib";
            FiberBundle* fib = dynamic_cast<FiberBundle*> (itemCollections->GetData(s).GetPointer());
            IOUtil::Save(fib, fileName.toStdString());
          }
          else if (itemCollections->IndexToName(s) == "DWI")
          {
            fileName += ".dwi";
            IOUtil::Save(image,fileName.toStdString());
          }
          else
          {
            fileName += ".nrrd";
            Image::Pointer image = itemCollections->GetMitkImage(s).GetPointer();
            IOUtil::Save(image,fileName.toStdString());
          }
        }
        catch( const std::exception& e)
        {
          MITK_ERROR << "Caught exception: " << e.what();
        }

        std::string relativeFilename = baseFolder.relativeFilePath(fileName).toStdString();
        xmlFileStream << "    <" << ITEM <<  " " << NAME << "=\"" <<itemCollections->IndexToName(s) << "\" " <<  FILEPATH << "=\""  << "\" " << LINK << "=\"" << relativeFilename << "\" />\n";
      }
      xmlFileStream << "  </" << DATA << ">\n";
      dataId++;
    }

    xmlFileStream << "  </" << SUBCOLLECTION << ">\n";
    subColId++;
  }
  xmlFileStream << "</" << COLLECTION << ">\n";
  xmlFileStream.flush();
  xmlFileStream.close();
  return true;
}