Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkDiffusionHeaderSiemensDICOMFileReader.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 
20 
21 #include "gdcmScanner.h"
22 #include "gdcmReader.h"
23 
24 #include <vnl/vnl_math.h>
25 
26 static bool GetTagFromHierarchy( std::vector< gdcm::Tag > hierarchy, const gdcm::Tag& t_tag, const gdcm::DataSet& dataset, gdcm::DataSet& target)
27 {
28  if( hierarchy.empty() )
29  return false;
30 
31  const gdcm::DataElement& de = dataset.GetDataElement( hierarchy.at(0) );
32  const auto seq = de.GetValueAsSQ();
33 
34  // last level of hierarchy, retrieve the first apperance
35  if( hierarchy.size() == 1 )
36  {
37  gdcm::Item& item2 = seq->GetItem(1);
38  gdcm::DataSet& nestedds2 = item2.GetNestedDataSet();
39 
40  const gdcm::DataElement& nde2 = nestedds2.GetDataElement( t_tag );
41 
42  if( !nde2.IsEmpty() )
43  {
44  target = nestedds2;
45  return true;
46  }
47  else
48  {
49  return false;
50  }
51  }
52  else
53  {
54  if( seq->FindDataElement( hierarchy.at(1) ) )
55  {
56  for( gdcm::SequenceOfItems::SizeType i=1; i< seq->GetNumberOfItems(); i++ )
57  {
58  gdcm::Item& item = seq->GetItem(i);
59  gdcm::DataSet &nestedds = item.GetNestedDataSet();
60 
61  // recursive call
62  return GetTagFromHierarchy( std::vector< gdcm::Tag >( hierarchy.begin() + 1, hierarchy.end() ), t_tag, nestedds, target);
63  }
64  }
65 
66  return false;
67  }
68 
69 }
70 
76 {
77  SiemensDiffusionHeaderType hformat = mitk::GetHeaderType( tag_value );
78  Siemens_Header_Format specs = this->m_SiemensFormatsCollection.at( hformat );
79 
80  MITK_DEBUG << " Header format: " << hformat;
81  MITK_DEBUG << " :: Retrieving b value. ";
82 
83  std::string::size_type tag_position =
84  tag_value.find( "B_value", 0 );
85 
86  if( tag_position == std::string::npos )
87  {
88  MITK_ERROR << "No b value information found. ";
89  return false;
90  }
91 
92  std::string value_string = tag_value.substr( tag_position, tag_value.size() - tag_position + 1 );
93 
94  std::vector<double> value_array;
95  if( ParseInputString(value_string, value_array, specs) )
96  {
97  values.b_value = value_array.at(0);
98  }
99  else
100  {
101  MITK_INFO("diffusion.dicomreader.siemens") << "No b-value tag found. ";
102  return false;
103  }
104 
105  // search for GradientDirectionInformation if the bvalue is not null
106  if( values.b_value > 0 )
107  {
108  std::string::size_type tag_position = tag_value.find( "DiffusionGradientDirection", 0 );
109  // Possibly it is a IVIM dataset, i.e. the gradient direction is not relevant
110  // and possibly either not set or set to zero
111  if( tag_position == std::string::npos )
112  {
113  MITK_WARN << "No gradient direction information, but non-zero b-value. Possibly an IVIM dataset. " << "\n"
114  << "Setting gradient to (1,1,1).";
115 
116  values.isotropic = true;
117  values.g_vector.fill(1);
118  return false;
119  }
120 
121  value_array.clear();
122  std::string gradient_direction_str = tag_value.substr( tag_position, tag_value.size() - tag_position + 1 );
123 
124  if( ParseInputString(gradient_direction_str, value_array, specs) )
125  {
126  if( value_array.size() != 3 )
127  {
128  MITK_ERROR << " Retrieved gradient information of length " << value_array.size();
129  return false;
130  }
131 
132  for( unsigned int i=0; i<value_array.size(); i++)
133  {
134  values.g_vector[i] = value_array.at(i);
135  }
136 
137  // Test for isotropic data (i.e. IVIM)
138  if( values.g_vector.two_norm() < vnl_math::eps )
139  {
140  values.g_vector.fill(1);
141  values.isotropic = true;
142  }
143  }
144 
145  }
146  else
147  {
148  values.baseline = true;
149  }
150 
151  return true;
152 }
153 
156 {
157  Siemens_Header_Format Siemens_CSA1_Format( 64, sizeof(int32_t), 4, sizeof(int32_t), sizeof(int32_t) );
158  Siemens_Header_Format Siemens_CSA2_Format( 64, sizeof(int32_t), 4, sizeof(int32_t), sizeof(int32_t) );
159 
160  m_SiemensFormatsCollection.push_back( Siemens_CSA1_Format );
161  m_SiemensFormatsCollection.push_back( Siemens_CSA2_Format );
162 }
163 
166 {
167 
168 }
169 
172 {
173  gdcm::Reader gdcmReader;
174  gdcmReader.SetFileName( filename.c_str() );
175 
176  gdcmReader.Read();
177 
178  MITK_INFO << " -- Analyzing: " << filename;
179 
180  bool retVal = false;
181 
182  const gdcm::DataSet& dataset = gdcmReader.GetFile().GetDataSet();
183 
184  const gdcm::Tag t_sie_diffusion( 0x0029,0x1010 );
185  //const gdcm::Tag t_sie_diffusion_vec( 0x0029,0x100e );
186  //const gdcm::Tag t_sie_diffusion2( 0x0029,0x100c );
187 
188  std::string siemens_diffusionheader_str;
189  if( RevealBinaryTag( t_sie_diffusion, dataset, siemens_diffusionheader_str ) )
190  {
192  this->ExtractSiemensDiffusionTagInformation( siemens_diffusionheader_str, values );
193 
194  m_HeaderInformationList.push_back( values );
195  retVal = true;
196  }
197  else
198  {
199  const gdcm::Tag t_sie_bvalue( 0x0018, 0x9087);
200  const gdcm::Tag t_sie_gradient( 0x0021, 0x1146);
201 
202  std::vector< gdcm::Tag > bv_hierarchy;
203  bv_hierarchy.push_back( gdcm::Tag(0x5200,0x9230) );
204  bv_hierarchy.push_back( gdcm::Tag(0x0018,0x9117) );
205 
206  gdcm::DataSet bvalueset;
207  GetTagFromHierarchy( bv_hierarchy, t_sie_bvalue, dataset, bvalueset );
208 
210  double dbvalue = 0;
211  if( mitk::RevealBinaryTagC( t_sie_bvalue, bvalueset, (char*) &dbvalue) )
212  {
213  MITK_INFO("siemens.dicom.diffusion.bvalue") << dbvalue;
214  values.b_value = std::ceil( dbvalue );
215 
216  if( values.b_value == 0)
217  values.baseline = true;
218  }
219 
220  if( !values.baseline )
221  {
222  std::vector< gdcm::Tag > g_hierarchy;
223  g_hierarchy.push_back( gdcm::Tag(0x5200,0x9230) );
224  g_hierarchy.push_back( gdcm::Tag(0x0021,0x11fe) );
225 
226  GetTagFromHierarchy( g_hierarchy, t_sie_gradient, dataset, bvalueset );
227 
228  double gr_dir_arr[3] = {1,0,-1};
229  if( mitk::RevealBinaryTagC( t_sie_gradient, bvalueset, (char*) &gr_dir_arr ) )
230  {
231  MITK_INFO("siemens.dicom.diffusion.gradient") << "(" << gr_dir_arr[0] <<"," << gr_dir_arr[1] <<"," <<gr_dir_arr[2] <<")";
232  }
233 
234  values.g_vector.copy_in( &gr_dir_arr[0] );
235  }
236 
237  if( 1 )
238  {
239  m_HeaderInformationList.push_back( values );
240  retVal = true;
241  }
242  }
243 
244  return retVal;
245 
246 
247 }
bool ParseInputString(std::string input, std::vector< double > &values, Siemens_Header_Format format_specs)
#define MITK_INFO
Definition: mitkLogMacros.h:22
bool RevealBinaryTag(const gdcm::Tag tag, const gdcm::DataSet &dataset, std::string &target)
Retrieve the value of a gdcm tag to the given string.
#define MITK_ERROR
Definition: mitkLogMacros.h:24
#define MITK_DEBUG
Definition: mitkLogMacros.h:26
The DiffusionImageHeaderInformation struct.
#define MITK_WARN
Definition: mitkLogMacros.h:23
bool ExtractSiemensDiffusionTagInformation(std::string tag_value, mitk::DiffusionImageDICOMHeaderInformation &values)
Extract b value from the siemens diffusion tag.
static const std::string filename
static bool GetTagFromHierarchy(std::vector< gdcm::Tag > hierarchy, const gdcm::Tag &t_tag, const gdcm::DataSet &dataset, gdcm::DataSet &target)
MITKCORE_EXPORT const ScalarType eps
bool RevealBinaryTagC(const gdcm::Tag tag, const gdcm::DataSet &dataset, char *target_array)
SiemensDiffusionHeaderType GetHeaderType(std::string header)