diff --git a/Modules/DiffusionImaging/DiffusionIO/mitkDiffusionIOMimeTypes.cpp b/Modules/DiffusionImaging/DiffusionIO/mitkDiffusionIOMimeTypes.cpp index 20ac728707..b841391c67 100644 --- a/Modules/DiffusionImaging/DiffusionIO/mitkDiffusionIOMimeTypes.cpp +++ b/Modules/DiffusionImaging/DiffusionIO/mitkDiffusionIOMimeTypes.cpp @@ -1,233 +1,259 @@ /*=================================================================== 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. ===================================================================*/ #include "mitkDiffusionIOMimeTypes.h" #include "mitkIOMimeTypes.h" #include #include #include #include #include namespace mitk { std::vector DiffusionIOMimeTypes::Get() { std::vector mimeTypes; // order matters here (descending rank for mime types) mimeTypes.push_back(DWI_MIMETYPE().Clone()); mimeTypes.push_back(DTI_MIMETYPE().Clone()); mimeTypes.push_back(QBI_MIMETYPE().Clone()); mimeTypes.push_back(FIBERBUNDLE_MIMETYPE().Clone()); mimeTypes.push_back(CONNECTOMICS_MIMETYPE().Clone()); return mimeTypes; } // Mime Types CustomMimeType DiffusionIOMimeTypes::FIBERBUNDLE_MIMETYPE() { CustomMimeType mimeType(FIBERBUNDLE_MIMETYPE_NAME()); std::string category = "Fiber Bundle File"; mimeType.SetComment("Fiber Bundles"); mimeType.SetCategory(category); mimeType.AddExtension("fib"); mimeType.AddExtension("trk"); //mimeType.AddExtension("vtk"); return mimeType; } DiffusionIOMimeTypes::DwiMimeType::DwiMimeType() : CustomMimeType(DWI_MIMETYPE_NAME()) { std::string category = "Diffusion Weighted Image"; this->SetCategory(category); this->SetComment("Diffusion Weighted Images"); this->AddExtension("dwi"); this->AddExtension("hdwi"); this->AddExtension("fsl"); this->AddExtension("fslgz"); this->AddExtension("nrrd"); + this->AddExtension("nii"); + this->AddExtension("nii.gz"); } bool DiffusionIOMimeTypes::DwiMimeType::AppliesTo(const std::string &path) const { bool canRead( CustomMimeType::AppliesTo(path) ); // fix for bug 18572 // Currently this function is called for writing as well as reading, in that case // the image information can of course not be read // This is a bug, this function should only be called for reading. if( ! itksys::SystemTools::FileExists( path.c_str() ) ) { return canRead; } //end fix for bug 18572 - std::string ext = itksys::SystemTools::GetFilenameLastExtension( path ); + std::string ext = this->GetExtension( path ); ext = itksys::SystemTools::LowerCase( ext ); // Simple NRRD files should only be considered for this mime type if they contain // corresponding tags if( ext == ".nrrd" ) { itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New(); io->SetFileName(path); try { io->ReadImageInformation(); itk::MetaDataDictionary imgMetaDictionary = io->GetMetaDataDictionary(); std::vector imgMetaKeys = imgMetaDictionary.GetKeys(); std::vector::const_iterator itKey = imgMetaKeys.begin(); std::string metaString; for (; itKey != imgMetaKeys.end(); itKey ++) { itk::ExposeMetaData (imgMetaDictionary, *itKey, metaString); if (itKey->find("modality") != std::string::npos) { if (metaString.find("DWMRI") != std::string::npos) { return canRead; } } } } catch( const itk::ExceptionObject &e ) { MITK_ERROR << "ITK Exception: " << e.what(); } canRead = false; } + // Nifti files should only be considered for this mime type if they are + // accompanied by bvecs and bvals files defining the diffusion information + if( ext == ".nii" || ext == ".nii.gz" ) + { + std::string base = itksys::SystemTools::GetFilenamePath( path ) + "/" + + this->GetFilenameWithoutExtension( path ); + + if( itksys::SystemTools::FileExists( std::string( base + ".bvec").c_str() ) + && itksys::SystemTools::FileExists( std::string( base + ".bval").c_str() ) + ) + { + return canRead; + } + + if( itksys::SystemTools::FileExists( std::string( base + ".bvecs").c_str() ) + && itksys::SystemTools::FileExists( std::string( base + ".bvals").c_str() ) + ) + { + return canRead; + } + + canRead = false; + } + return canRead; } DiffusionIOMimeTypes::DwiMimeType* DiffusionIOMimeTypes::DwiMimeType::Clone() const { return new DwiMimeType(*this); } DiffusionIOMimeTypes::DwiMimeType DiffusionIOMimeTypes::DWI_MIMETYPE() { return DwiMimeType(); } CustomMimeType DiffusionIOMimeTypes::DTI_MIMETYPE() { CustomMimeType mimeType(DTI_MIMETYPE_NAME()); std::string category = "Tensor Images"; mimeType.SetComment("Diffusion Tensor Images"); mimeType.SetCategory(category); mimeType.AddExtension("dti"); mimeType.AddExtension("hdti"); return mimeType; } CustomMimeType DiffusionIOMimeTypes::QBI_MIMETYPE() { CustomMimeType mimeType(QBI_MIMETYPE_NAME()); std::string category = "Q-Ball Images"; mimeType.SetComment("Diffusion Q-Ball Images"); mimeType.SetCategory(category); mimeType.AddExtension("qbi"); mimeType.AddExtension("hqbi"); return mimeType; } CustomMimeType DiffusionIOMimeTypes::CONNECTOMICS_MIMETYPE() { CustomMimeType mimeType(CONNECTOMICS_MIMETYPE_NAME()); std::string category = "Connectomics Networks"; mimeType.SetComment("Connectomics Networks"); mimeType.SetCategory(category); mimeType.AddExtension("cnf"); return mimeType; } // Names std::string DiffusionIOMimeTypes::DWI_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".dwi"; return name; } std::string DiffusionIOMimeTypes::DTI_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".dti"; return name; } std::string DiffusionIOMimeTypes::QBI_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".qbi"; return name; } std::string DiffusionIOMimeTypes::FIBERBUNDLE_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".fib"; return name; } std::string DiffusionIOMimeTypes::CONNECTOMICS_MIMETYPE_NAME() { static std::string name = IOMimeTypes::DEFAULT_BASE_NAME() + ".cnf"; return name; } // Descriptions std::string DiffusionIOMimeTypes::FIBERBUNDLE_MIMETYPE_DESCRIPTION() { static std::string description = "Fiberbundles"; return description; } std::string DiffusionIOMimeTypes::DWI_MIMETYPE_DESCRIPTION() { static std::string description = "Diffusion Weighted Images"; return description; } std::string DiffusionIOMimeTypes::DTI_MIMETYPE_DESCRIPTION() { static std::string description = "Diffusion Tensor Images"; return description; } std::string DiffusionIOMimeTypes::QBI_MIMETYPE_DESCRIPTION() { static std::string description = "Q-Ball Images"; return description; } std::string DiffusionIOMimeTypes::CONNECTOMICS_MIMETYPE_DESCRIPTION() { static std::string description = "Connectomics Networks"; return description; } } diff --git a/Modules/DiffusionImaging/DiffusionIO/mitkNrrdDiffusionImageReader.cpp b/Modules/DiffusionImaging/DiffusionIO/mitkNrrdDiffusionImageReader.cpp index a2b29fd956..ed1c1db483 100644 --- a/Modules/DiffusionImaging/DiffusionIO/mitkNrrdDiffusionImageReader.cpp +++ b/Modules/DiffusionImaging/DiffusionIO/mitkNrrdDiffusionImageReader.cpp @@ -1,434 +1,549 @@ /*=================================================================== 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. ===================================================================*/ #ifndef __mitkNrrdDiffusionImageReader_cpp #define __mitkNrrdDiffusionImageReader_cpp #include "mitkNrrdDiffusionImageReader.h" #include #include // Diffusion properties #include #include #include #include // ITK includes #include #include #include "itksys/SystemTools.hxx" #include "itkImageFileReader.h" #include "itkMetaDataObject.h" #include "itkNrrdImageIO.h" #include "itkNiftiImageIO.h" #include "mitkCustomMimeType.h" #include "mitkDiffusionIOMimeTypes.h" #include #include #include #include #include "mitkIOUtil.h" namespace mitk { NrrdDiffusionImageReader:: NrrdDiffusionImageReader(const NrrdDiffusionImageReader & other) : AbstractFileReader(other) { } NrrdDiffusionImageReader* NrrdDiffusionImageReader::Clone() const { return new NrrdDiffusionImageReader(*this); } NrrdDiffusionImageReader:: ~NrrdDiffusionImageReader() {} NrrdDiffusionImageReader:: NrrdDiffusionImageReader() : mitk::AbstractFileReader( CustomMimeType( mitk::DiffusionIOMimeTypes::DWI_MIMETYPE() ), mitk::DiffusionIOMimeTypes::DWI_MIMETYPE_DESCRIPTION() ) { m_ServiceReg = this->RegisterService(); } std::vector > NrrdDiffusionImageReader:: Read() { std::vector > result; // Since everything is completely read in GenerateOutputInformation() it is stored // in a cache variable. A timestamp is associated. // If the timestamp of the cache variable is newer than the MTime, we only need to // assign the cache variable to the DataObject. // Otherwise, the tree must be read again from the file and OuputInformation must // be updated! if(m_OutputCache.IsNull()) InternalRead(); result.push_back(m_OutputCache.GetPointer()); return result; } void NrrdDiffusionImageReader::InternalRead() { OutputType::Pointer outputForCache = OutputType::New(); if ( this->GetInputLocation() == "") { throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, the filename to be read is empty!"); } else { try { const std::string& locale = "C"; const std::string& currLocale = setlocale( LC_ALL, NULL ); if ( locale.compare(currLocale)!=0 ) { try { setlocale(LC_ALL, locale.c_str()); } catch(...) { MITK_INFO << "Could not set locale " << locale; } } MITK_INFO << "NrrdDiffusionImageReader: reading image information"; VectorImageType::Pointer itkVectorImage; - std::string ext = itksys::SystemTools::GetFilenameLastExtension(this->GetInputLocation()); - ext = itksys::SystemTools::LowerCase(ext); + std::string ext = this->GetMimeType()->GetExtension( this->GetInputLocation() ); + ext = itksys::SystemTools::LowerCase( ext ); + if (ext == ".hdwi" || ext == ".dwi" || ext == ".nrrd") { typedef itk::ImageFileReader FileReaderType; FileReaderType::Pointer reader = FileReaderType::New(); reader->SetFileName(this->GetInputLocation()); itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New(); reader->SetImageIO(io); reader->Update(); itkVectorImage = reader->GetOutput(); } else if(ext == ".fsl" || ext == ".fslgz") { // create temporary file with correct ending for nifti-io std::string fname3 = "temp_dwi"; fname3 += ext == ".fsl" ? ".nii" : ".nii.gz"; itksys::SystemTools::CopyAFile(this->GetInputLocation().c_str(), fname3.c_str()); // create reader and read file typedef itk::Image ImageType4D; itk::NiftiImageIO::Pointer io2 = itk::NiftiImageIO::New(); typedef itk::ImageFileReader FileReaderType; FileReaderType::Pointer reader = FileReaderType::New(); reader->SetFileName(fname3); reader->SetImageIO(io2); reader->Update(); ImageType4D::Pointer img4 = reader->GetOutput(); // delete temporary file itksys::SystemTools::RemoveFile(fname3.c_str()); + // convert 4D file to vector image + itkVectorImage = VectorImageType::New(); + + VectorImageType::SpacingType spacing; + ImageType4D::SpacingType spacing4 = img4->GetSpacing(); + for(int i=0; i<3; i++) + spacing[i] = spacing4[i]; + itkVectorImage->SetSpacing( spacing ); // Set the image spacing + + VectorImageType::PointType origin; + ImageType4D::PointType origin4 = img4->GetOrigin(); + for(int i=0; i<3; i++) + origin[i] = origin4[i]; + itkVectorImage->SetOrigin( origin ); // Set the image origin + + VectorImageType::DirectionType direction; + ImageType4D::DirectionType direction4 = img4->GetDirection(); + for(int i=0; i<3; i++) + for(int j=0; j<3; j++) + direction[i][j] = direction4[i][j]; + itkVectorImage->SetDirection( direction ); // Set the image direction + + VectorImageType::RegionType region; + ImageType4D::RegionType region4 = img4->GetLargestPossibleRegion(); + + VectorImageType::RegionType::SizeType size; + ImageType4D::RegionType::SizeType size4 = region4.GetSize(); + + for(int i=0; i<3; i++) + size[i] = size4[i]; + + VectorImageType::RegionType::IndexType index; + ImageType4D::RegionType::IndexType index4 = region4.GetIndex(); + for(int i=0; i<3; i++) + index[i] = index4[i]; + + region.SetSize(size); + region.SetIndex(index); + itkVectorImage->SetRegions( region ); + + itkVectorImage->SetVectorLength(size4[3]); + itkVectorImage->Allocate(); + + itk::ImageRegionIterator it ( itkVectorImage, itkVectorImage->GetLargestPossibleRegion() ); + typedef VectorImageType::PixelType VecPixType; + for (it.GoToBegin(); !it.IsAtEnd(); ++it) + { + VecPixType vec = it.Get(); + VectorImageType::IndexType currentIndex = it.GetIndex(); + for(int i=0; i<3; i++) + index4[i] = currentIndex[i]; + for(unsigned int ind=0; indGetPixel(index4); + } + it.Set(vec); + } + } + else if(ext == ".nii" || ext == ".nii.gz") + { + // create reader and read file + typedef itk::Image ImageType4D; + itk::NiftiImageIO::Pointer io2 = itk::NiftiImageIO::New(); + typedef itk::ImageFileReader FileReaderType; + FileReaderType::Pointer reader = FileReaderType::New(); + reader->SetFileName( this->GetInputLocation() ); + reader->SetImageIO(io2); + reader->Update(); + ImageType4D::Pointer img4 = reader->GetOutput(); + + // convert 4D file to vector image itkVectorImage = VectorImageType::New(); VectorImageType::SpacingType spacing; ImageType4D::SpacingType spacing4 = img4->GetSpacing(); for(int i=0; i<3; i++) spacing[i] = spacing4[i]; itkVectorImage->SetSpacing( spacing ); // Set the image spacing VectorImageType::PointType origin; ImageType4D::PointType origin4 = img4->GetOrigin(); for(int i=0; i<3; i++) origin[i] = origin4[i]; itkVectorImage->SetOrigin( origin ); // Set the image origin VectorImageType::DirectionType direction; ImageType4D::DirectionType direction4 = img4->GetDirection(); for(int i=0; i<3; i++) for(int j=0; j<3; j++) direction[i][j] = direction4[i][j]; itkVectorImage->SetDirection( direction ); // Set the image direction VectorImageType::RegionType region; ImageType4D::RegionType region4 = img4->GetLargestPossibleRegion(); VectorImageType::RegionType::SizeType size; ImageType4D::RegionType::SizeType size4 = region4.GetSize(); for(int i=0; i<3; i++) size[i] = size4[i]; VectorImageType::RegionType::IndexType index; ImageType4D::RegionType::IndexType index4 = region4.GetIndex(); for(int i=0; i<3; i++) index[i] = index4[i]; region.SetSize(size); region.SetIndex(index); itkVectorImage->SetRegions( region ); itkVectorImage->SetVectorLength(size4[3]); itkVectorImage->Allocate(); itk::ImageRegionIterator it ( itkVectorImage, itkVectorImage->GetLargestPossibleRegion() ); typedef VectorImageType::PixelType VecPixType; for (it.GoToBegin(); !it.IsAtEnd(); ++it) { VecPixType vec = it.Get(); VectorImageType::IndexType currentIndex = it.GetIndex(); for(int i=0; i<3; i++) index4[i] = currentIndex[i]; for(unsigned int ind=0; indGetPixel(index4); } it.Set(vec); } } // Diffusion Image information START GradientDirectionContainerType::Pointer DiffusionVectors = GradientDirectionContainerType::New(); GradientDirectionContainerType::Pointer OriginalDiffusionVectors = GradientDirectionContainerType::New(); MeasurementFrameType MeasurementFrame; float BValue = -1; // Diffusion Image information END if (ext == ".hdwi" || ext == ".dwi" || ext == ".nrrd") { itk::MetaDataDictionary imgMetaDictionary = itkVectorImage->GetMetaDataDictionary(); std::vector imgMetaKeys = imgMetaDictionary.GetKeys(); std::vector::const_iterator itKey = imgMetaKeys.begin(); std::string metaString; GradientDirectionType vect3d; int numberOfImages = 0; int numberOfGradientImages = 0; bool readb0 = false; double xx, xy, xz, yx, yy, yz, zx, zy, zz; for (; itKey != imgMetaKeys.end(); itKey ++) { double x,y,z; itk::ExposeMetaData (imgMetaDictionary, *itKey, metaString); if (itKey->find("DWMRI_gradient") != std::string::npos) { sscanf(metaString.c_str(), "%lf %lf %lf\n", &x, &y, &z); vect3d[0] = x; vect3d[1] = y; vect3d[2] = z; DiffusionVectors->InsertElement( numberOfImages, vect3d ); ++numberOfImages; // If the direction is 0.0, this is a reference image if (vect3d[0] == 0.0 && vect3d[1] == 0.0 && vect3d[2] == 0.0) { continue; } ++numberOfGradientImages;; } else if (itKey->find("DWMRI_b-value") != std::string::npos) { readb0 = true; BValue = atof(metaString.c_str()); } else if (itKey->find("measurement frame") != std::string::npos) { sscanf(metaString.c_str(), " ( %lf , %lf , %lf ) ( %lf , %lf , %lf ) ( %lf , %lf , %lf ) \n", &xx, &xy, &xz, &yx, &yy, &yz, &zx, &zy, &zz); if (xx>10e-10 || xy>10e-10 || xz>10e-10 || yx>10e-10 || yy>10e-10 || yz>10e-10 || zx>10e-10 || zy>10e-10 || zz>10e-10 ) { MeasurementFrame(0,0) = xx; MeasurementFrame(0,1) = xy; MeasurementFrame(0,2) = xz; MeasurementFrame(1,0) = yx; MeasurementFrame(1,1) = yy; MeasurementFrame(1,2) = yz; MeasurementFrame(2,0) = zx; MeasurementFrame(2,1) = zy; MeasurementFrame(2,2) = zz; } else { MeasurementFrame(0,0) = 1; MeasurementFrame(0,1) = 0; MeasurementFrame(0,2) = 0; MeasurementFrame(1,0) = 0; MeasurementFrame(1,1) = 1; MeasurementFrame(1,2) = 0; MeasurementFrame(2,0) = 0; MeasurementFrame(2,1) = 0; MeasurementFrame(2,2) = 1; } } } if(!readb0) { MITK_INFO << "BValue not specified in header file"; } } - else if(ext == ".fsl" || ext == ".fslgz") + else if(ext == ".fsl" || ext == ".fslgz" || ext == ".nii" || ext == ".nii.gz") { + // some parsing depending on the extension + bool useFSLstyle( true ); + std::string bvecsExtension(""); + std::string bvalsExtension(""); + + std::string base = itksys::SystemTools::GetFilenamePath( this->GetInputLocation() ) + "/" + + this->GetMimeType()->GetFilenameWithoutExtension( this->GetInputLocation() ); + + // check for possible file names + { + if( useFSLstyle && itksys::SystemTools::FileExists( std::string( base + ".bvec").c_str() ) + && itksys::SystemTools::FileExists( std::string( base + ".bval").c_str() ) + ) + { + useFSLstyle = false; + bvecsExtension = ".bvec"; + bvalsExtension = ".bval"; + } + + if( useFSLstyle && itksys::SystemTools::FileExists( std::string( base + ".bvecs").c_str() ) + && itksys::SystemTools::FileExists( std::string( base + ".bvals").c_str() ) + ) + { + useFSLstyle = false; + bvecsExtension = ".bvecs"; + bvalsExtension = ".bvals"; + } + } std::string line; std::vector bvec_entries; std::string fname = this->GetInputLocation(); - fname += ".bvecs"; + if( useFSLstyle ) + { + fname += ".bvecs"; + } + else + { + fname = std::string( base + bvecsExtension); + } std::ifstream myfile (fname.c_str()); if (myfile.is_open()) { while ( myfile.good() ) { getline (myfile,line); char* pch = strtok (const_cast(line.c_str())," "); while (pch != NULL) { bvec_entries.push_back(atof(pch)); pch = strtok (NULL, " "); } } myfile.close(); } else { MITK_INFO << "Unable to open bvecs file"; } std::vector bval_entries; std::string fname2 = this->GetInputLocation(); - fname2 += ".bvals"; + if( useFSLstyle ) + { + fname2 += ".bvals"; + } + else + { + fname2 = std::string( base + bvalsExtension); + } std::ifstream myfile2 (fname2.c_str()); if (myfile2.is_open()) { while ( myfile2.good() ) { getline (myfile2,line); char* pch = strtok (const_cast(line.c_str())," "); while (pch != NULL) { bval_entries.push_back(atof(pch)); pch = strtok (NULL, " "); } } myfile2.close(); } else { MITK_INFO << "Unable to open bvals file"; } BValue = -1; unsigned int numb = bval_entries.size(); for(unsigned int i=0; i vec; vec[0] = bvec_entries.at(i); vec[1] = bvec_entries.at(i+numb); vec[2] = bvec_entries.at(i+2*numb); // Adjust the vector length to encode gradient strength float factor = b_val/BValue; if(vec.magnitude() > 0) { vec[0] = sqrt(factor)*vec[0]; vec[1] = sqrt(factor)*vec[1]; vec[2] = sqrt(factor)*vec[2]; } DiffusionVectors->InsertElement(i,vec); } for(int i=0; i<3; i++) for(int j=0; j<3; j++) MeasurementFrame[i][j] = i==j ? 1 : 0; } outputForCache = mitk::GrabItkImageMemory( itkVectorImage); // create BValueMap mitk::BValueMapProperty::BValueMap BValueMap = mitk::BValueMapProperty::CreateBValueMap(DiffusionVectors,BValue); outputForCache->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( DiffusionVectors ) ); outputForCache->SetProperty( mitk::DiffusionPropertyHelper::ORIGINALGRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( OriginalDiffusionVectors ) ); outputForCache->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( MeasurementFrame ) ); outputForCache->SetProperty( mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str(), mitk::BValueMapProperty::New( BValueMap ) ); outputForCache->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( BValue ) ); // Since we have already read the tree, we can store it in a cache variable // so that it can be assigned to the DataObject in GenerateData(); m_OutputCache = outputForCache; m_CacheTime.Modified(); try { setlocale(LC_ALL, currLocale.c_str()); } catch(...) { MITK_INFO << "Could not reset locale " << currLocale; } } catch(std::exception& e) { MITK_INFO << "Std::Exception while reading file!!"; MITK_INFO << e.what(); throw itk::ImageFileReaderException(__FILE__, __LINE__, e.what()); } catch(...) { MITK_INFO << "Exception while reading file!!"; throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, an error occurred while reading the requested vessel tree file!"); } } } } //namespace MITK #endif diff --git a/Modules/DiffusionImaging/DiffusionIO/mitkNrrdDiffusionImageWriter.cpp b/Modules/DiffusionImaging/DiffusionIO/mitkNrrdDiffusionImageWriter.cpp index 179126a472..09272b6ca1 100644 --- a/Modules/DiffusionImaging/DiffusionIO/mitkNrrdDiffusionImageWriter.cpp +++ b/Modules/DiffusionImaging/DiffusionIO/mitkNrrdDiffusionImageWriter.cpp @@ -1,332 +1,473 @@ /*=================================================================== 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. ===================================================================*/ #ifndef __mitkNrrdDiffusionImageWriter__cpp #define __mitkNrrdDiffusionImageWriter__cpp #include "mitkNrrdDiffusionImageWriter.h" #include "itkMetaDataDictionary.h" #include "itkMetaDataObject.h" #include "itkNrrdImageIO.h" #include "itkNiftiImageIO.h" #include "itkImageFileWriter.h" #include "itksys/SystemTools.hxx" #include "mitkDiffusionIOMimeTypes.h" #include "mitkImageCast.h" #include #include mitk::NrrdDiffusionImageWriter::NrrdDiffusionImageWriter() : AbstractFileWriter(mitk::Image::GetStaticNameOfClass(), CustomMimeType( mitk::DiffusionIOMimeTypes::DWI_MIMETYPE() ), mitk::DiffusionIOMimeTypes::DWI_MIMETYPE_DESCRIPTION()) { RegisterService(); } mitk::NrrdDiffusionImageWriter::NrrdDiffusionImageWriter(const mitk::NrrdDiffusionImageWriter& other) : AbstractFileWriter(other) { } mitk::NrrdDiffusionImageWriter::~NrrdDiffusionImageWriter() {} void mitk::NrrdDiffusionImageWriter::Write() { mitk::Image::ConstPointer input = dynamic_cast(this->GetInput()); VectorImageType::Pointer itkImg; mitk::CastToItkImage(input,itkImg); if (input.IsNull()) { MITK_ERROR <<"Sorry, input to NrrdDiffusionImageWriter is NULL!"; return; } if ( this->GetOutputLocation().empty() ) { MITK_ERROR << "Sorry, filename has not been set!"; return ; } const std::string& locale = "C"; const std::string& currLocale = setlocale( LC_ALL, NULL ); if ( locale.compare(currLocale)!=0 ) { try { setlocale(LC_ALL, locale.c_str()); } catch(...) { MITK_INFO << "Could not set locale " << locale; } } char keybuffer[512]; char valbuffer[512]; //itk::MetaDataDictionary dic = input->GetImage()->GetMetaDataDictionary(); vnl_matrix_fixed measurementFrame = mitk::DiffusionPropertyHelper::GetMeasurementFrame(input); if (measurementFrame(0,0) || measurementFrame(0,1) || measurementFrame(0,2) || measurementFrame(1,0) || measurementFrame(1,1) || measurementFrame(1,2) || measurementFrame(2,0) || measurementFrame(2,1) || measurementFrame(2,2)) { sprintf( valbuffer, " (%lf,%lf,%lf) (%lf,%lf,%lf) (%lf,%lf,%lf)", measurementFrame(0,0), measurementFrame(0,1), measurementFrame(0,2), measurementFrame(1,0), measurementFrame(1,1), measurementFrame(1,2), measurementFrame(2,0), measurementFrame(2,1), measurementFrame(2,2)); itk::EncapsulateMetaData(itkImg->GetMetaDataDictionary(),std::string("measurement frame"),std::string(valbuffer)); } sprintf( valbuffer, "DWMRI"); itk::EncapsulateMetaData(itkImg->GetMetaDataDictionary(),std::string("modality"),std::string(valbuffer)); if(mitk::DiffusionPropertyHelper::GetGradientContainer(input)->Size()) { sprintf( valbuffer, "%1f", mitk::DiffusionPropertyHelper::GetReferenceBValue(input) ); itk::EncapsulateMetaData(itkImg->GetMetaDataDictionary(),std::string("DWMRI_b-value"),std::string(valbuffer)); } for(unsigned int i=0; iSize(); i++) { sprintf( keybuffer, "DWMRI_gradient_%04d", i ); /*if(itk::ExposeMetaData(input->GetMetaDataDictionary(), std::string(keybuffer),tmp)) continue;*/ sprintf( valbuffer, "%1f %1f %1f", mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).get(0), mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).get(1), mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).get(2)); itk::EncapsulateMetaData(itkImg->GetMetaDataDictionary(),std::string(keybuffer),std::string(valbuffer)); } typedef itk::VectorImage ImageType; - std::string ext = itksys::SystemTools::GetFilenameLastExtension(this->GetOutputLocation()); + std::string ext = this->GetMimeType()->GetExtension(this->GetOutputLocation()); ext = itksys::SystemTools::LowerCase(ext); // default extension is .dwi if( ext == "") { ext = ".nrrd"; this->SetOutputLocation(this->GetOutputLocation() + ext); } if (ext == ".hdwi" || ext == ".nrrd" || ext == ".dwi") { MITK_INFO << "Extension " << ext; itk::NrrdImageIO::Pointer io = itk::NrrdImageIO::New(); //io->SetNrrdVectorType( nrrdKindList ); io->SetFileType( itk::ImageIOBase::Binary ); io->UseCompressionOn(); typedef itk::ImageFileWriter WriterType; WriterType::Pointer nrrdWriter = WriterType::New(); nrrdWriter->UseInputMetaDataDictionaryOn(); nrrdWriter->SetInput( itkImg ); nrrdWriter->SetImageIO(io); nrrdWriter->SetFileName(this->GetOutputLocation()); nrrdWriter->UseCompressionOn(); nrrdWriter->SetImageIO(io); try { nrrdWriter->Update(); } catch (itk::ExceptionObject e) { std::cout << e << std::endl; throw; } } else if (ext == ".fsl" || ext == ".fslgz") { MITK_INFO << "Writing Nifti-Image for FSL"; typedef itk::Image ImageType4D; ImageType4D::Pointer img4 = ImageType4D::New(); ImageType::SpacingType spacing = itkImg->GetSpacing(); ImageType4D::SpacingType spacing4; for(int i=0; i<3; i++) spacing4[i] = spacing[i]; spacing4[3] = 1; img4->SetSpacing( spacing4 ); // Set the image spacing ImageType::PointType origin = itkImg->GetOrigin(); ImageType4D::PointType origin4; for(int i=0; i<3; i++) origin4[i] = origin[i]; origin4[3] = 0; img4->SetOrigin( origin4 ); // Set the image origin ImageType::DirectionType direction = itkImg->GetDirection(); ImageType4D::DirectionType direction4; for(int i=0; i<3; i++) for(int j=0; j<3; j++) direction4[i][j] = direction[i][j]; for(int i=0; i<4; i++) direction4[i][3] = 0; for(int i=0; i<4; i++) direction4[3][i] = 0; direction4[3][3] = 1; img4->SetDirection( direction4 ); // Set the image direction ImageType::RegionType region = itkImg->GetLargestPossibleRegion(); ImageType4D::RegionType region4; ImageType::RegionType::SizeType size = region.GetSize(); ImageType4D::RegionType::SizeType size4; for(int i=0; i<3; i++) size4[i] = size[i]; size4[3] = itkImg->GetVectorLength(); ImageType::RegionType::IndexType index = region.GetIndex(); ImageType4D::RegionType::IndexType index4; for(int i=0; i<3; i++) index4[i] = index[i]; index4[3] = 0; region4.SetSize(size4); region4.SetIndex(index4); img4->SetRegions( region4 ); img4->Allocate(); itk::ImageRegionIterator it (itkImg, itkImg->GetLargestPossibleRegion() ); typedef ImageType::PixelType VecPixType; for (it.GoToBegin(); !it.IsAtEnd(); ++it) { VecPixType vec = it.Get(); ImageType::IndexType currentIndex = it.GetIndex(); for(unsigned int ind=0; indSetPixel(index4, vec[ind]); } } // create copy of file with correct ending for mitk std::string fname3 = this->GetOutputLocation(); std::string::iterator itend = fname3.end(); if (ext == ".fsl") fname3.replace( itend-3, itend, "nii"); else fname3.replace( itend-5, itend, "nii.gz"); itk::NiftiImageIO::Pointer io4 = itk::NiftiImageIO::New(); typedef itk::VectorImage ImageType; typedef itk::ImageFileWriter WriterType4; WriterType4::Pointer nrrdWriter4 = WriterType4::New(); nrrdWriter4->UseInputMetaDataDictionaryOn(); nrrdWriter4->SetInput( img4 ); nrrdWriter4->SetFileName(fname3); nrrdWriter4->UseCompressionOn(); nrrdWriter4->SetImageIO(io4); try { nrrdWriter4->Update(); } catch (itk::ExceptionObject e) { std::cout << e << std::endl; throw; } itksys::SystemTools::CopyAFile(fname3.c_str(), this->GetOutputLocation().c_str()); if(mitk::DiffusionPropertyHelper::GetGradientContainer(input)->Size()) { std::ofstream myfile; std::string fname = this->GetOutputLocation(); fname += ".bvals"; myfile.open (fname.c_str()); for(unsigned int i=0; iSize(); i++) { double twonorm = mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).two_norm(); myfile << mitk::DiffusionPropertyHelper::GetReferenceBValue(input)*twonorm*twonorm << " "; } myfile.close(); std::ofstream myfile2; std::string fname2 = this->GetOutputLocation(); fname2 += ".bvecs"; myfile2.open (fname2.c_str()); for(int j=0; j<3; j++) { for(unsigned int i=0; iSize(); i++) { //need to modify the length GradientDirectionContainerType::Pointer grads = mitk::DiffusionPropertyHelper::GetGradientContainer(input); GradientDirectionType direction = grads->ElementAt(i); direction.normalize(); myfile2 << direction.get(j) << " "; //myfile2 << input->GetDirections()->ElementAt(i).get(j) << " "; } myfile2 << std::endl; } std::ofstream myfile3; std::string fname4 = this->GetOutputLocation(); fname4 += ".ttk"; myfile3.open (fname4.c_str()); for(unsigned int i=0; iSize(); i++) { for(int j=0; j<3; j++) { myfile3 << mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).get(j) << " "; } myfile3 << std::endl; } } } + else if (ext == ".nii" || ext == ".nii.gz") + { + MITK_INFO << "Writing Nifti-Image"; + + typedef itk::Image ImageType4D; + ImageType4D::Pointer img4 = ImageType4D::New(); + + ImageType::SpacingType spacing = itkImg->GetSpacing(); + ImageType4D::SpacingType spacing4; + for(int i=0; i<3; i++) + spacing4[i] = spacing[i]; + spacing4[3] = 1; + img4->SetSpacing( spacing4 ); // Set the image spacing + + ImageType::PointType origin = itkImg->GetOrigin(); + ImageType4D::PointType origin4; + for(int i=0; i<3; i++) + origin4[i] = origin[i]; + origin4[3] = 0; + img4->SetOrigin( origin4 ); // Set the image origin + + ImageType::DirectionType direction = itkImg->GetDirection(); + ImageType4D::DirectionType direction4; + for(int i=0; i<3; i++) + for(int j=0; j<3; j++) + direction4[i][j] = direction[i][j]; + for(int i=0; i<4; i++) + direction4[i][3] = 0; + for(int i=0; i<4; i++) + direction4[3][i] = 0; + direction4[3][3] = 1; + img4->SetDirection( direction4 ); // Set the image direction + + ImageType::RegionType region = itkImg->GetLargestPossibleRegion(); + ImageType4D::RegionType region4; + + ImageType::RegionType::SizeType size = region.GetSize(); + ImageType4D::RegionType::SizeType size4; + + for(int i=0; i<3; i++) + size4[i] = size[i]; + size4[3] = itkImg->GetVectorLength(); + + ImageType::RegionType::IndexType index = region.GetIndex(); + ImageType4D::RegionType::IndexType index4; + for(int i=0; i<3; i++) + index4[i] = index[i]; + index4[3] = 0; + + region4.SetSize(size4); + region4.SetIndex(index4); + img4->SetRegions( region4 ); + + img4->Allocate(); + + itk::ImageRegionIterator it (itkImg, itkImg->GetLargestPossibleRegion() ); + typedef ImageType::PixelType VecPixType; + + for (it.GoToBegin(); !it.IsAtEnd(); ++it) + { + VecPixType vec = it.Get(); + ImageType::IndexType currentIndex = it.GetIndex(); + for(unsigned int ind=0; indSetPixel(index4, vec[ind]); + } + } + + itk::NiftiImageIO::Pointer io4 = itk::NiftiImageIO::New(); + + typedef itk::VectorImage ImageType; + typedef itk::ImageFileWriter WriterType4; + WriterType4::Pointer nrrdWriter4 = WriterType4::New(); + nrrdWriter4->UseInputMetaDataDictionaryOn(); + nrrdWriter4->SetInput( img4 ); + nrrdWriter4->SetFileName(this->GetOutputLocation()); + nrrdWriter4->UseCompressionOn(); + nrrdWriter4->SetImageIO(io4); + try + { + nrrdWriter4->Update(); + } + catch (itk::ExceptionObject e) + { + std::cout << e << std::endl; + throw; + } + + + if(mitk::DiffusionPropertyHelper::GetGradientContainer(input)->Size()) + { + std::ofstream myfile; + std::string fname = itksys::SystemTools::GetFilenamePath( this->GetOutputLocation() ) + "/" + + this->GetMimeType()->GetFilenameWithoutExtension( this->GetOutputLocation() ); + fname += ".bvals"; + myfile.open (fname.c_str()); + for(unsigned int i=0; iSize(); i++) + { + double twonorm = mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).two_norm(); + myfile << mitk::DiffusionPropertyHelper::GetReferenceBValue(input)*twonorm*twonorm << " "; + } + myfile.close(); + + std::ofstream myfile2; + std::string fname2 = itksys::SystemTools::GetFilenamePath( this->GetOutputLocation() ) + "/" + + this->GetMimeType()->GetFilenameWithoutExtension( this->GetOutputLocation() ); + fname2 += ".bvecs"; + myfile2.open (fname2.c_str()); + for(int j=0; j<3; j++) + { + for(unsigned int i=0; iSize(); i++) + { + //need to modify the length + GradientDirectionContainerType::Pointer grads = mitk::DiffusionPropertyHelper::GetGradientContainer(input); + GradientDirectionType direction = grads->ElementAt(i); + direction.normalize(); + myfile2 << direction.get(j) << " "; + //myfile2 << input->GetDirections()->ElementAt(i).get(j) << " "; + } + myfile2 << std::endl; + } + + std::ofstream myfile3; + std::string fname4 = itksys::SystemTools::GetFilenamePath( this->GetOutputLocation() ) + "/" + + this->GetMimeType()->GetFilenameWithoutExtension( this->GetOutputLocation() ); + fname4 += ".ttk"; + myfile3.open (fname4.c_str()); + for(unsigned int i=0; iSize(); i++) + { + for(int j=0; j<3; j++) + { + myfile3 << mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).get(j) << " "; + } + myfile3 << std::endl; + } + } + } try { setlocale(LC_ALL, currLocale.c_str()); } catch(...) { MITK_INFO << "Could not reset locale " << currLocale; } } mitk::NrrdDiffusionImageWriter* mitk::NrrdDiffusionImageWriter::Clone() const { return new NrrdDiffusionImageWriter(*this); } mitk::IFileWriter::ConfidenceLevel mitk::NrrdDiffusionImageWriter::GetConfidenceLevel() const { mitk::Image::ConstPointer input = dynamic_cast(this->GetInput()); if (input.IsNull() || !mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( input ) ) { return Unsupported; } else { return Supported; } } #endif //__mitkNrrdDiffusionImageWriter__cpp