Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkSiemensMosaicDicomDiffusionImageHeaderReader.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 
19 
20 #include "gdcmGlobal.h"
21 //#include "gdcmVersion.h"
22 
23 #include "gdcmFile.h"
24 #include "gdcmImageReader.h"
25 #include "gdcmDict.h"
26 #include "gdcmDicts.h"
27 #include "gdcmDictEntry.h"
28 #include "gdcmDictEntry.h"
29 #include "gdcmDict.h"
30 #include "gdcmFile.h"
31 #include "gdcmSerieHelper.h"
32 
33 
35 {
36 }
37 
39 {
40 }
41 
42 int mitk::SiemensMosaicDicomDiffusionImageHeaderReader::ExtractSiemensDiffusionInformation( std::string tagString, std::string nameString, std::vector<double>& valueArray )
43 {
44  std::string::size_type atPosition = tagString.find( nameString );
45  if ( atPosition == std::string::npos)
46  {
47  return 0;
48  }
49  else
50  {
51  std::string infoAsString = tagString.substr( atPosition, tagString.size()-atPosition+1 );
52  const char * infoAsCharPtr = infoAsString.c_str();
53 
54  int vm = *(infoAsCharPtr+64);
55  std::string vr = infoAsString.substr( 68, 4 );
56  //int syngodt = *(infoAsCharPtr+72);
57  //int nItems = *(infoAsCharPtr+76);
58  //int localDummy = *(infoAsCharPtr+80);
59 
60  int offset = 84;
61  for (int k = 0; k < vm; k++)
62  {
63  int itemLength = *(infoAsCharPtr+offset+4);
64  int strideSize = static_cast<int> (ceil(static_cast<double>(itemLength)/4) * 4);
65  std::string valueString = infoAsString.substr( offset+16, itemLength );
66  valueArray.push_back( atof(valueString.c_str()) );
67  offset += 16+strideSize;
68  }
69  return vm;
70  }
71 }
72 
73 // do the work
75 {
76 
77  // check if there are filenames
78  if(m_DicomFilenames.size())
79  {
80  // adapted from namic-sandbox
81  // DicomToNrrdConverter.cxx
82 
83  VolumeReaderType::DictionaryArrayRawPointer inputDict
84  = m_VolumeReader->GetMetaDataDictionaryArray();
85 
86  ReadPublicTags();
87 
88  int mMosaic = 0; // number of raws in each mosaic block;
89  int nMosaic = 0; // number of columns in each mosaic block
90 
91  std::cout << "Siemens SliceMosaic......" << std::endl;
92 
93  m_SliceOrderIS = false;
94 
95  // for siemens mosaic image, figure out mosaic slice order from 0029|1010
96  std::string tag;
97  tag.clear();
98 
99  gdcm::ImageReader reader;
100  reader.SetFileName( m_DicomFilenames[0].c_str() );
101  if( !reader.Read() )
102  {
103  itkExceptionMacro(<< "Cannot read requested file");
104  }
105  const gdcm::File &f = reader.GetFile();
106  const gdcm::DataSet &ds = f.GetDataSet();
107 
108  // gdcm::DataSet ds = header0->GetDataSet();
109  auto it = ds.Begin();
110 
111  // Copy of the header->content
112  // copy information stored in 0029,1010 into a string for parsing
113  for(; it != ds.End(); ++it)
114  {
115  const gdcm::DataElement &ref = *it;
116  if (ref.GetTag() == gdcm::Tag(0x0029,0x1010)) {
117  tag = std::string(ref.GetByteValue()->GetPointer(),ref.GetByteValue()->GetLength());
118  }
119  }
120 
121  // parse SliceNormalVector from 0029,1010 tag
122  std::vector<double> valueArray(0);
123  int nItems = ExtractSiemensDiffusionInformation(tag, "SliceNormalVector", valueArray);
124  if (nItems != 3) // did not find enough information
125  {
126  std::cout << "Warning: Cannot find complete information on SliceNormalVector in 0029|1010\n";
127  std::cout << " Slice order may be wrong.\n";
128  }
129  else if (valueArray[2] > 0)
130  {
131  m_SliceOrderIS = true;
132  }
133 
134  // parse NumberOfImagesInMosaic from 0029,1010 tag
135  valueArray.resize(0);
136  nItems = ExtractSiemensDiffusionInformation(tag, "NumberOfImagesInMosaic", valueArray);
137 
138  // Hot-Fix for Bug 14459, no valid Tag (0029,1010)
139  if (valueArray.size() < 1) // NO data was found
140  {
141  MITK_ERROR << "MOSAIC Image has no valid tag (0029,1010). ABORTING" << std::endl;
142  mitkThrow() << "MOSAIC Image has no valid tag (0029,1010). ABORTING";
143  return;
144  }
145  if (nItems == 0) // did not find enough information
146  {
147  std::cout << "Warning: Cannot find complete information on NumberOfImagesInMosaic in 0029|1010\n";
148  std::cout << " Resulting image may contain empty slices.\n";
149  }
150  else
151  {
152  this->m_Output->nSliceInVolume = static_cast<int>(valueArray[0]);
153  mMosaic = static_cast<int> (ceil(sqrt(valueArray[0])));
154  nMosaic = mMosaic;
155  }
156  std::cout << "Mosaic in " << mMosaic << " X " << nMosaic << " blocks (total number of blocks = " << valueArray[0] << ").\n";
157 
158 
159  ReadPublicTags2();
160 
161  int nStride = 1;
162 
163  std::cout << "Data in Siemens Mosaic Format\n";
164  //nVolume = nSlice;
165  //std::cout << "Number of Volume: " << nVolume << std::endl;
166  std::cout << "Number of Slices in each volume: " << this->m_Output->nSliceInVolume << std::endl;
167  nStride = 1;
168 
169  for (int k = 0; k < m_nSlice; k += nStride )
170  {
171  gdcm::ImageReader reader;
172  reader.SetFileName( m_DicomFilenames[0].c_str() );
173  if( !reader.Read() )
174  {
175  itkExceptionMacro(<< "Cannot read requested file");
176  }
177  const gdcm::File &f = reader.GetFile();
178  const gdcm::DataSet &ds = f.GetDataSet();
179 
180  // gdcm::DataSet ds = header0->GetDataSet();
181  auto it = ds.Begin();
182 
183  // Copy of the header->content
184  // copy information stored in 0029,1010 into a string for parsing
185  for(; it != ds.End(); ++it)
186  {
187  const gdcm::DataElement &ref = *it;
188  if (ref.GetTag() == gdcm::Tag(0x0029,0x1010)) {
189  tag = std::string(ref.GetByteValue()->GetPointer(),ref.GetByteValue()->GetLength());
190  }
191  }
192 
193  // parse B_value from 0029,1010 tag
194  std::vector<double> valueArray(0);
195  vnl_vector_fixed<double, 3> vect3d;
196  int nItems = ExtractSiemensDiffusionInformation(tag, "B_value", valueArray);
197  if (nItems != 1 || valueArray[0] == 0) // did not find enough information
198  {
199  MITK_INFO << "Reading diffusion info from 0019|100c and 0019|100e tags";
200  tag.clear();
201  bool success = itk::ExposeMetaData<std::string> ( *(*inputDict)[0], "0019|100c", tag );
202  if(success)
203  {
204  this->m_Output->bValue = atof( tag.c_str() );
205  tag.clear();
206  success = itk::ExposeMetaData<std::string> ( *(*inputDict)[k], "0019|100e", tag);
207  if(success)
208  {
209  memcpy( &vect3d[0], tag.c_str()+0, 8 );
210  memcpy( &vect3d[1], tag.c_str()+8, 8 );
211  memcpy( &vect3d[2], tag.c_str()+16, 8 );
212  vect3d.normalize();
213  this->m_Output->DiffusionVector = vect3d;
214  TransformGradients();
215  MITK_INFO << "BV: " << this->m_Output->bValue;
216  MITK_INFO << " GD: " << this->m_Output->DiffusionVector << std::endl;
217  continue;
218  }
219  }
220  }
221  else
222  {
223  MITK_INFO << "Reading diffusion info from 0029|1010 tags";
224  this->m_Output->bValue = valueArray[0];
225 
226  // parse DiffusionGradientDirection from 0029,1010 tag
227  valueArray.resize(0);
228  nItems = ExtractSiemensDiffusionInformation(tag, "DiffusionGradientDirection", valueArray);
229  if (nItems == 3)
230  {
231  vect3d[0] = valueArray[0];
232  vect3d[1] = valueArray[1];
233  vect3d[2] = valueArray[2];
234  vect3d.normalize();
235  this->m_Output->DiffusionVector = vect3d;
236  TransformGradients();
237  MITK_INFO << "BV: " << this->m_Output->bValue;
238  MITK_INFO << " GD: " << this->m_Output->DiffusionVector;
239  continue;
240  }
241  }
242 
243  MITK_ERROR << "No diffusion info found, assuming BASELINE" << std::endl;
244  this->m_Output->bValue = 0.0;
245  vect3d.fill( 0.0 );
246  this->m_Output->DiffusionVector = vect3d;
247 
248  }
249 
250  }
251 }
#define MITK_INFO
Definition: mitkLogMacros.h:22
#define MITK_ERROR
Definition: mitkLogMacros.h:24
int ExtractSiemensDiffusionInformation(std::string tagString, std::string nameString, std::vector< double > &valueArray)
static Vector3D offset
#define mitkThrow()