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
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)