Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
mitkDiffusionImageNiftiWriterService.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 __mitkDiffusionImageNiftiWriterService__cpp
18 #define __mitkDiffusionImageNiftiWriterService__cpp
19 
21 #include "itkMetaDataDictionary.h"
22 #include "itkMetaDataObject.h"
23 #include "itkNiftiImageIO.h"
24 #include "itkImageFileWriter.h"
25 #include "itksys/SystemTools.hxx"
27 #include "mitkImageCast.h"
28 #include <mitkLocaleSwitch.h>
29 
30 #include <iostream>
31 #include <fstream>
32 
33 
35  : AbstractFileWriter(mitk::Image::GetStaticNameOfClass(), CustomMimeType( mitk::DiffusionCoreIOMimeTypes::DWI_NIFTI_MIMETYPE() ), mitk::DiffusionCoreIOMimeTypes::DWI_NIFTI_MIMETYPE_DESCRIPTION())
36 {
38 }
39 
41  : AbstractFileWriter(other)
42 {
43 }
44 
46 {}
47 
49 {
50  mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image *>(this->GetInput());
51 
53  mitk::CastToItkImage(input,itkImg);
54 
55  if (input.IsNull())
56  {
57  MITK_ERROR <<"Sorry, input to DiffusionImageNiftiWriterService is NULL!";
58  return;
59  }
60  if ( this->GetOutputLocation().empty() )
61  {
62  MITK_ERROR << "Sorry, filename has not been set!";
63  return ;
64  }
65  mitk::LocaleSwitch localeSwitch("C");
66 
67  char keybuffer[512];
68  char valbuffer[512];
69 
70  //itk::MetaDataDictionary dic = input->GetImage()->GetMetaDataDictionary();
71 
72  vnl_matrix_fixed<double,3,3> measurementFrame = mitk::DiffusionPropertyHelper::GetMeasurementFrame(input);
73  if (measurementFrame(0,0) || measurementFrame(0,1) || measurementFrame(0,2) ||
74  measurementFrame(1,0) || measurementFrame(1,1) || measurementFrame(1,2) ||
75  measurementFrame(2,0) || measurementFrame(2,1) || measurementFrame(2,2))
76  {
77  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));
78  itk::EncapsulateMetaData<std::string>(itkImg->GetMetaDataDictionary(),std::string("measurement frame"),std::string(valbuffer));
79  }
80 
81  sprintf( valbuffer, "DWMRI");
82  itk::EncapsulateMetaData<std::string>(itkImg->GetMetaDataDictionary(),std::string("modality"),std::string(valbuffer));
83 
85  {
86  sprintf( valbuffer, "%1f", mitk::DiffusionPropertyHelper::GetReferenceBValue(input) );
87  itk::EncapsulateMetaData<std::string>(itkImg->GetMetaDataDictionary(),std::string("DWMRI_b-value"),std::string(valbuffer));
88  }
89 
90  for(unsigned int i=0; i<mitk::DiffusionPropertyHelper::GetGradientContainer(input)->Size(); i++)
91  {
92  sprintf( keybuffer, "DWMRI_gradient_%04d", i );
93 
94  /*if(itk::ExposeMetaData<std::string>(input->GetMetaDataDictionary(),
95  std::string(keybuffer),tmp))
96  continue;*/
97 
98  sprintf( valbuffer, "%1f %1f %1f", mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).get(0),
100 
101  itk::EncapsulateMetaData<std::string>(itkImg->GetMetaDataDictionary(),std::string(keybuffer),std::string(valbuffer));
102  }
103 
104  typedef itk::VectorImage<short,3> ImageType;
105 
106  std::string ext = this->GetMimeType()->GetExtension(this->GetOutputLocation());
107  ext = itksys::SystemTools::LowerCase(ext);
108 
109  // default extension is .nii
110  if( ext == "")
111  {
112  ext = ".nii";
113  this->SetOutputLocation(this->GetOutputLocation() + ext);
114  }
115  if (ext == ".fsl" || ext == ".fslgz")
116  {
117  MITK_INFO << "Writing Nifti-Image for FSL";
118 
119  typedef itk::Image<short,4> ImageType4D;
121 
122  ImageType::SpacingType spacing = itkImg->GetSpacing();
123  ImageType4D::SpacingType spacing4;
124  for(int i=0; i<3; i++)
125  spacing4[i] = spacing[i];
126  spacing4[3] = 1;
127  img4->SetSpacing( spacing4 ); // Set the image spacing
128 
129  ImageType::PointType origin = itkImg->GetOrigin();
130  ImageType4D::PointType origin4;
131  for(int i=0; i<3; i++)
132  origin4[i] = origin[i];
133  origin4[3] = 0;
134  img4->SetOrigin( origin4 ); // Set the image origin
135 
136  ImageType::DirectionType direction = itkImg->GetDirection();
137  ImageType4D::DirectionType direction4;
138  for(int i=0; i<3; i++)
139  for(int j=0; j<3; j++)
140  direction4[i][j] = direction[i][j];
141  for(int i=0; i<4; i++)
142  direction4[i][3] = 0;
143  for(int i=0; i<4; i++)
144  direction4[3][i] = 0;
145  direction4[3][3] = 1;
146  img4->SetDirection( direction4 ); // Set the image direction
147 
148  ImageType::RegionType region = itkImg->GetLargestPossibleRegion();
149  ImageType4D::RegionType region4;
150 
151  ImageType::RegionType::SizeType size = region.GetSize();
152  ImageType4D::RegionType::SizeType size4;
153 
154  for(int i=0; i<3; i++)
155  size4[i] = size[i];
156  size4[3] = itkImg->GetVectorLength();
157 
158  ImageType::RegionType::IndexType index = region.GetIndex();
159  ImageType4D::RegionType::IndexType index4;
160  for(int i=0; i<3; i++)
161  index4[i] = index[i];
162  index4[3] = 0;
163 
164  region4.SetSize(size4);
165  region4.SetIndex(index4);
166  img4->SetRegions( region4 );
167 
168  img4->Allocate();
169 
170  itk::ImageRegionIterator<ImageType> it (itkImg, itkImg->GetLargestPossibleRegion() );
171  typedef ImageType::PixelType VecPixType;
172 
173  for (it.GoToBegin(); !it.IsAtEnd(); ++it)
174  {
175  VecPixType vec = it.Get();
176  ImageType::IndexType currentIndex = it.GetIndex();
177  for(unsigned int ind=0; ind<vec.Size(); ind++)
178  {
179 
180  for(int i=0; i<3; i++)
181  index4[i] = currentIndex[i];
182  index4[3] = ind;
183  img4->SetPixel(index4, vec[ind]);
184  }
185  }
186 
187  // create copy of file with correct ending for mitk
188  std::string fname3 = this->GetOutputLocation();
189  std::string::iterator itend = fname3.end();
190  if (ext == ".fsl")
191  fname3.replace( itend-3, itend, "nii");
192  else
193  fname3.replace( itend-5, itend, "nii.gz");
194 
196 
197  typedef itk::ImageFileWriter<ImageType4D> WriterType4;
198  WriterType4::Pointer nrrdWriter4 = WriterType4::New();
199  nrrdWriter4->UseInputMetaDataDictionaryOn();
200  nrrdWriter4->SetInput( img4 );
201  nrrdWriter4->SetFileName(fname3);
202  nrrdWriter4->UseCompressionOn();
203  nrrdWriter4->SetImageIO(io4);
204  try
205  {
206  nrrdWriter4->Update();
207  }
208  catch (itk::ExceptionObject e)
209  {
210  std::cout << e << std::endl;
211  throw;
212  }
213 
214  itksys::SystemTools::CopyAFile(fname3.c_str(), this->GetOutputLocation().c_str());
215 
217  {
218  std::ofstream myfile;
219  std::string fname = this->GetOutputLocation();
220  fname += ".bvals";
221  myfile.open (fname.c_str());
222  for(unsigned int i=0; i<mitk::DiffusionPropertyHelper::GetGradientContainer(input)->Size(); i++)
223  {
224  double twonorm = mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).two_norm();
225  myfile << mitk::DiffusionPropertyHelper::GetReferenceBValue(input)*twonorm*twonorm << " ";
226  }
227  myfile.close();
228 
229  std::ofstream myfile2;
230  std::string fname2 = this->GetOutputLocation();
231  fname2 += ".bvecs";
232  myfile2.open (fname2.c_str());
233  for(int j=0; j<3; j++)
234  {
235  for(unsigned int i=0; i<mitk::DiffusionPropertyHelper::GetGradientContainer(input)->Size(); i++)
236  {
237  //need to modify the length
239  GradientDirectionType direction = grads->ElementAt(i);
240  direction.normalize();
241  myfile2 << direction.get(j) << " ";
242  //myfile2 << input->GetDirections()->ElementAt(i).get(j) << " ";
243  }
244  myfile2 << std::endl;
245  }
246 
247  std::ofstream myfile3;
248  std::string fname4 = this->GetOutputLocation();
249  fname4 += ".ttk";
250  myfile3.open (fname4.c_str());
251  for(unsigned int i=0; i<mitk::DiffusionPropertyHelper::GetGradientContainer(input)->Size(); i++)
252  {
253  for(int j=0; j<3; j++)
254  {
255  myfile3 << mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).get(j) << " ";
256  }
257  myfile3 << std::endl;
258  }
259  }
260  }
261  else if (ext == ".nii" || ext == ".nii.gz")
262  {
263  MITK_INFO << "Writing Nifti-Image";
264 
265  typedef itk::Image<short,4> ImageType4D;
267 
268  ImageType::SpacingType spacing = itkImg->GetSpacing();
269  ImageType4D::SpacingType spacing4;
270  for(int i=0; i<3; i++)
271  spacing4[i] = spacing[i];
272  spacing4[3] = 1;
273  img4->SetSpacing( spacing4 ); // Set the image spacing
274 
275  ImageType::PointType origin = itkImg->GetOrigin();
276  ImageType4D::PointType origin4;
277  for(int i=0; i<3; i++)
278  origin4[i] = origin[i];
279  origin4[3] = 0;
280  img4->SetOrigin( origin4 ); // Set the image origin
281 
282  ImageType::DirectionType direction = itkImg->GetDirection();
283  ImageType4D::DirectionType direction4;
284  for(int i=0; i<3; i++)
285  for(int j=0; j<3; j++)
286  direction4[i][j] = direction[i][j];
287  for(int i=0; i<4; i++)
288  direction4[i][3] = 0;
289  for(int i=0; i<4; i++)
290  direction4[3][i] = 0;
291  direction4[3][3] = 1;
292  img4->SetDirection( direction4 ); // Set the image direction
293 
294  ImageType::RegionType region = itkImg->GetLargestPossibleRegion();
295  ImageType4D::RegionType region4;
296 
297  ImageType::RegionType::SizeType size = region.GetSize();
298  ImageType4D::RegionType::SizeType size4;
299 
300  for(int i=0; i<3; i++)
301  size4[i] = size[i];
302  size4[3] = itkImg->GetVectorLength();
303 
304  ImageType::RegionType::IndexType index = region.GetIndex();
305  ImageType4D::RegionType::IndexType index4;
306  for(int i=0; i<3; i++)
307  index4[i] = index[i];
308  index4[3] = 0;
309 
310  region4.SetSize(size4);
311  region4.SetIndex(index4);
312  img4->SetRegions( region4 );
313 
314  img4->Allocate();
315 
316  itk::ImageRegionIterator<ImageType> it (itkImg, itkImg->GetLargestPossibleRegion() );
317  typedef ImageType::PixelType VecPixType;
318 
319  for (it.GoToBegin(); !it.IsAtEnd(); ++it)
320  {
321  VecPixType vec = it.Get();
322  ImageType::IndexType currentIndex = it.GetIndex();
323  for(unsigned int ind=0; ind<vec.Size(); ind++)
324  {
325 
326  for(int i=0; i<3; i++)
327  index4[i] = currentIndex[i];
328  index4[3] = ind;
329  img4->SetPixel(index4, vec[ind]);
330  }
331  }
332 
334 
335  typedef itk::ImageFileWriter<ImageType4D> WriterType4;
336  WriterType4::Pointer nrrdWriter4 = WriterType4::New();
337  nrrdWriter4->UseInputMetaDataDictionaryOn();
338  nrrdWriter4->SetInput( img4 );
339  nrrdWriter4->SetFileName(this->GetOutputLocation());
340  nrrdWriter4->UseCompressionOn();
341  nrrdWriter4->SetImageIO(io4);
342  try
343  {
344  nrrdWriter4->Update();
345  }
346  catch (itk::ExceptionObject e)
347  {
348  std::cout << e << std::endl;
349  throw;
350  }
351 
352 
354  {
355  std::ofstream myfile;
356  std::string fname = itksys::SystemTools::GetFilenamePath( this->GetOutputLocation() ) + "/"
357  + this->GetMimeType()->GetFilenameWithoutExtension( this->GetOutputLocation() );
358  fname += ".bvals";
359  myfile.open (fname.c_str());
360  for(unsigned int i=0; i<mitk::DiffusionPropertyHelper::GetGradientContainer(input)->Size(); i++)
361  {
362  double twonorm = mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).two_norm();
363  myfile << mitk::DiffusionPropertyHelper::GetReferenceBValue(input)*twonorm*twonorm << " ";
364  }
365  myfile.close();
366 
367  std::ofstream myfile2;
368  std::string fname2 = itksys::SystemTools::GetFilenamePath( this->GetOutputLocation() ) + "/"
369  + this->GetMimeType()->GetFilenameWithoutExtension( this->GetOutputLocation() );
370  fname2 += ".bvecs";
371  myfile2.open (fname2.c_str());
372  for(int j=0; j<3; j++)
373  {
374  for(unsigned int i=0; i<mitk::DiffusionPropertyHelper::GetGradientContainer(input)->Size(); i++)
375  {
376  //need to modify the length
378  GradientDirectionType direction = grads->ElementAt(i);
379  direction.normalize();
380  myfile2 << direction.get(j) << " ";
381  //myfile2 << input->GetDirections()->ElementAt(i).get(j) << " ";
382  }
383  myfile2 << std::endl;
384  }
385 
386  std::ofstream myfile3;
387  std::string fname4 = itksys::SystemTools::GetFilenamePath( this->GetOutputLocation() ) + "/"
388  + this->GetMimeType()->GetFilenameWithoutExtension( this->GetOutputLocation() );
389  fname4 += ".ttk";
390  myfile3.open (fname4.c_str());
391  for(unsigned int i=0; i<mitk::DiffusionPropertyHelper::GetGradientContainer(input)->Size(); i++)
392  {
393  for(int j=0; j<3; j++)
394  {
395  myfile3 << mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).get(j) << " ";
396  }
397  myfile3 << std::endl;
398  }
399  }
400  }
401 }
402 
404 {
405  return new DiffusionImageNiftiWriterService(*this);
406 }
407 
409 {
410  mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image*>(this->GetInput());
411  if (input.IsNull() || !mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( input ) )
412  {
413  return Unsupported;
414  }
415  else
416  {
417  return Supported;
418  }
419 }
420 
421 #endif //__mitkDiffusionImageNiftiWriterService__cpp
const MeasurementFrameType & GetMeasurementFrame() const
mitk::Point3D PointType
itk::SmartPointer< Self > Pointer
virtual void Write() override
Write the base data to the specified location or output stream.
mitk::DiffusionPropertyHelper::GradientDirectionType GradientDirectionType
#define MITK_INFO
Definition: mitkLogMacros.h:22
#define MITK_ERROR
Definition: mitkLogMacros.h:24
virtual ConfidenceLevel GetConfidenceLevel() const override
The confidence level of the reader or writer implementation.
DataCollection - Class to facilitate loading/accessing structured data.
The CustomMimeType class represents a custom mime-type which may be registered as a service object...
map::core::discrete::Elements< 3 >::InternalImageType ImageType
Convenience class to temporarily change the current locale.
virtual mitk::DiffusionImageNiftiWriterService * Clone() const override
Image class for storing images.
Definition: mitkImage.h:76
static const char * GetStaticNameOfClass()
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
us::ServiceRegistration< IFileWriter > RegisterService(us::ModuleContext *context=us::GetModuleContext())
GradientDirectionsContainerType::Pointer GetGradientContainer() const
unsigned short PixelType
ConfidenceLevel
A confidence level describing the confidence of the reader or writer in handling the given data...
Definition: mitkIFileIO.h:49
Base class for writing mitk::BaseData objects to files or streams.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.