Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkDiffusionImageNrrdReaderService.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #ifndef __mitkDiffusionImageNrrdReaderService_cpp
18 #define __mitkDiffusionImageNrrdReaderService_cpp
19 
21 
22 #include <iostream>
23 #include <fstream>
24 
25 
26 // Diffusion properties
28 #include <mitkBValueMapProperty.h>
30 #include <mitkProperties.h>
31 
32 // ITK includes
33 #include <itkImageRegionIterator.h>
34 #include <itkMetaDataObject.h>
35 #include "itksys/SystemTools.hxx"
36 #include "itkImageFileReader.h"
37 #include "itkMetaDataObject.h"
38 #include "itkNrrdImageIO.h"
39 
40 #include "mitkCustomMimeType.h"
42 
43 #include <mitkITKImageImport.h>
44 #include <mitkImageWriteAccessor.h>
45 #include <mitkImageDataItem.h>
46 #include "mitkIOUtil.h"
47 #include <mitkLocaleSwitch.h>
48 
49 namespace mitk
50 {
51 
54  : AbstractFileReader(other)
55  {
56  }
57 
58 
59  DiffusionImageNrrdReaderService* DiffusionImageNrrdReaderService::Clone() const
60  {
61  return new DiffusionImageNrrdReaderService(*this);
62  }
63 
64 
67  {}
68 
71  : mitk::AbstractFileReader( CustomMimeType( mitk::DiffusionCoreIOMimeTypes::DWI_NRRD_MIMETYPE() ), mitk::DiffusionCoreIOMimeTypes::DWI_NRRD_MIMETYPE_DESCRIPTION() )
72  {
73  m_ServiceReg = this->RegisterService();
74  }
75 
76  std::vector<itk::SmartPointer<mitk::BaseData> >
79  {
80  std::vector<itk::SmartPointer<mitk::BaseData> > result;
81 
82  // Since everything is completely read in GenerateOutputInformation() it is stored
83  // in a cache variable. A timestamp is associated.
84  // If the timestamp of the cache variable is newer than the MTime, we only need to
85  // assign the cache variable to the DataObject.
86  // Otherwise, the tree must be read again from the file and OuputInformation must
87  // be updated!
88 
89  if(m_OutputCache.IsNull()) InternalRead();
90 
91  result.push_back(m_OutputCache.GetPointer());
92  return result;
93  }
94 
95 
97  {
98  OutputType::Pointer outputForCache = OutputType::New();
99  if ( this->GetInputLocation() == "")
100  {
101  throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, the filename to be read is empty!");
102  }
103  else
104  {
105  try
106  {
107  mitk::LocaleSwitch localeSwitch("C");
108 
109  MITK_INFO << "DiffusionImageNrrdReaderService: reading image information";
110  VectorImageType::Pointer itkVectorImage;
111 
112  std::string ext = this->GetMimeType()->GetExtension( this->GetInputLocation() );
113  ext = itksys::SystemTools::LowerCase( ext );
114 
115  if (ext == ".hdwi" || ext == ".dwi" || ext == ".nrrd")
116  {
117  typedef itk::ImageFileReader<VectorImageType> FileReaderType;
119  reader->SetFileName(this->GetInputLocation());
121  reader->SetImageIO(io);
122  reader->Update();
123  itkVectorImage = reader->GetOutput();
124  }
125 
126  // Diffusion Image information START
129  MeasurementFrameType MeasurementFrame;
130  float BValue = -1;
131  // Diffusion Image information END
132 
133  if (ext == ".hdwi" || ext == ".dwi" || ext == ".nrrd")
134  {
135 
136  itk::MetaDataDictionary imgMetaDictionary = itkVectorImage->GetMetaDataDictionary();
137  std::vector<std::string> imgMetaKeys = imgMetaDictionary.GetKeys();
138  std::vector<std::string>::const_iterator itKey = imgMetaKeys.begin();
139  std::string metaString;
140 
141  GradientDirectionType vect3d;
142 
143  int numberOfImages = 0;
144  int numberOfGradientImages = 0;
145  bool readb0 = false;
146  double xx, xy, xz, yx, yy, yz, zx, zy, zz;
147 
148  for (; itKey != imgMetaKeys.end(); itKey ++)
149  {
150  double x,y,z;
151 
152  itk::ExposeMetaData<std::string> (imgMetaDictionary, *itKey, metaString);
153  if (itKey->find("DWMRI_gradient") != std::string::npos)
154  {
155  sscanf(metaString.c_str(), "%lf %lf %lf\n", &x, &y, &z);
156  vect3d[0] = x; vect3d[1] = y; vect3d[2] = z;
157  DiffusionVectors->InsertElement( numberOfImages, vect3d );
158  ++numberOfImages;
159  // If the direction is 0.0, this is a reference image
160  if (vect3d[0] == 0.0 &&
161  vect3d[1] == 0.0 &&
162  vect3d[2] == 0.0)
163  {
164  continue;
165  }
166  ++numberOfGradientImages;;
167  }
168  else if (itKey->find("DWMRI_b-value") != std::string::npos)
169  {
170  readb0 = true;
171  BValue = atof(metaString.c_str());
172  }
173  else if (itKey->find("measurement frame") != std::string::npos)
174  {
175  sscanf(metaString.c_str(), " ( %lf , %lf , %lf ) ( %lf , %lf , %lf ) ( %lf , %lf , %lf ) \n", &xx, &xy, &xz, &yx, &yy, &yz, &zx, &zy, &zz);
176 
177  if (xx>10e-10 || xy>10e-10 || xz>10e-10 ||
178  yx>10e-10 || yy>10e-10 || yz>10e-10 ||
179  zx>10e-10 || zy>10e-10 || zz>10e-10 )
180  {
181  MeasurementFrame(0,0) = xx;
182  MeasurementFrame(0,1) = xy;
183  MeasurementFrame(0,2) = xz;
184  MeasurementFrame(1,0) = yx;
185  MeasurementFrame(1,1) = yy;
186  MeasurementFrame(1,2) = yz;
187  MeasurementFrame(2,0) = zx;
188  MeasurementFrame(2,1) = zy;
189  MeasurementFrame(2,2) = zz;
190  }
191  else
192  {
193  MeasurementFrame(0,0) = 1;
194  MeasurementFrame(0,1) = 0;
195  MeasurementFrame(0,2) = 0;
196  MeasurementFrame(1,0) = 0;
197  MeasurementFrame(1,1) = 1;
198  MeasurementFrame(1,2) = 0;
199  MeasurementFrame(2,0) = 0;
200  MeasurementFrame(2,1) = 0;
201  MeasurementFrame(2,2) = 1;
202  }
203  }
204  }
205 
206  if(!readb0)
207  {
208  MITK_INFO << "BValue not specified in header file";
209  }
210 
211  }
212 
213  outputForCache = mitk::GrabItkImageMemory( itkVectorImage);
214 
215  // create BValueMap
217  outputForCache->SetProperty( mitk::DiffusionPropertyHelper::GRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( DiffusionVectors ) );
218  outputForCache->SetProperty( mitk::DiffusionPropertyHelper::ORIGINALGRADIENTCONTAINERPROPERTYNAME.c_str(), mitk::GradientDirectionsProperty::New( OriginalDiffusionVectors ) );
219  outputForCache->SetProperty( mitk::DiffusionPropertyHelper::MEASUREMENTFRAMEPROPERTYNAME.c_str(), mitk::MeasurementFrameProperty::New( MeasurementFrame ) );
220  outputForCache->SetProperty( mitk::DiffusionPropertyHelper::BVALUEMAPPROPERTYNAME.c_str(), mitk::BValueMapProperty::New( BValueMap ) );
221  outputForCache->SetProperty( mitk::DiffusionPropertyHelper::REFERENCEBVALUEPROPERTYNAME.c_str(), mitk::FloatProperty::New( BValue ) );
222 
223 
224  // Since we have already read the tree, we can store it in a cache variable
225  // so that it can be assigned to the DataObject in GenerateData();
226  m_OutputCache = outputForCache;
227  m_CacheTime.Modified();
228 
229  }
230  catch(std::exception& e)
231  {
232  MITK_INFO << "Std::Exception while reading file!!";
233  MITK_INFO << e.what();
234  throw itk::ImageFileReaderException(__FILE__, __LINE__, e.what());
235  }
236  catch(...)
237  {
238  MITK_INFO << "Exception while reading file!!";
239  throw itk::ImageFileReaderException(__FILE__, __LINE__, "Sorry, an error occurred while reading the requested vessel tree file!");
240  }
241  }
242  }
243 
244 } //namespace MITK
245 
246 #endif
static const std::string REFERENCEBVALUEPROPERTYNAME
itk::SmartPointer< Self > Pointer
std::map< unsigned int, std::vector< unsigned int > > BValueMap
The BValueMap contains seperated IndicesVectors for each b value (index for GradientDirectionContaine...
#define MITK_INFO
Definition: mitkLogMacros.h:22
static BValueMap CreateBValueMap(const GradientDirectionsContainerType *gdc, float referenceBValue)
DataCollection - Class to facilitate loading/accessing structured data.
mitk::DiffusionPropertyHelper::GradientDirectionType GradientDirectionType
virtual std::vector< itk::SmartPointer< BaseData > > Read() override
Reads a path or stream and creates a list of BaseData objects.
Image::Pointer GrabItkImageMemory(itk::SmartPointer< ItkOutputImageType > &itkimage, mitk::Image *mitkImage=nullptr, const BaseGeometry *geometry=nullptr, bool update=true)
Grabs the memory of an itk::Image (with a specific type) and puts it into an mitk::Image.The memory is managed by the mitk::Image after calling this function. The itk::Image remains valid until the mitk::Image decides to free the memory.
static const std::string MEASUREMENTFRAMEPROPERTYNAME
The CustomMimeType class represents a custom mime-type which may be registered as a service object...
us::ServiceRegistration< IFileReader > RegisterService(us::ModuleContext *context=us::GetModuleContext())
Convenience class to temporarily change the current locale.
const CustomMimeType * GetMimeType() const
mitk::DiffusionPropertyHelper::MeasurementFrameType MeasurementFrameType
static Pointer New()
static Pointer New()
Base class for creating mitk::BaseData objects from files or streams.
std::string GetExtension(const std::string &path) const
Provides the first matching extension.
virtual std::string GetInputLocation() const override
Get the current input location.
static const std::string GRADIENTCONTAINERPROPERTYNAME
static const std::string BVALUEMAPPROPERTYNAME
static const std::string ORIGINALGRADIENTCONTAINERPROPERTYNAME
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.