Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkNormalDirectionConsistencySorter.cpp
Go to the documentation of this file.
1 /*=================================================================== The Medical Imaging Interaction Toolkit (MITK)
2 
3 Copyright (c) German Cancer Research Center,
4 Division of Medical and Biological Informatics.
5 All rights reserved.
6 
7 This software is distributed WITHOUT ANY WARRANTY; without
8 even the implied warranty of MERCHANTABILITY or FITNESS FOR
9 A PARTICULAR PURPOSE.
10 
11 See LICENSE.txt or http://www.mitk.org for details.
12 
13 ===================================================================*/
14 
15 //#define MBILOG_ENABLE_DEBUG
16 
18 
19 #include <algorithm>
20 
24 {
25 }
26 
29 :DICOMDatasetSorter(other)
30 {
31 }
32 
35 {
36 }
37 
38 void
40 ::PrintConfiguration(std::ostream& os, const std::string& indent) const
41 {
42  os << indent << "NormalDirectionConsistencySorter" << std::endl;
43 }
44 
45 
49 {
50  if (this != &other)
51  {
53  }
54  return *this;
55 }
56 
57 bool
59 ::operator==(const DICOMDatasetSorter& other) const
60 {
61  return dynamic_cast<const NormalDirectionConsistencySorter*>(&other) != nullptr;
62 }
63 
64 
68 {
69  DICOMTagList tags;
70  tags.push_back( DICOMTag(0x0020, 0x0032) ); // ImagePositionPatient
71  tags.push_back( DICOMTag(0x0020, 0x0037) ); // ImageOrientationPatient
72 
73  return tags;
74 }
75 
76 void
79 {
80  DICOMDatasetList datasets = GetInput();
81 
82  if (datasets.size() > 1)
83  {
84  // at some point in the code, there is the expectation that
85  // the direction of the slice normals is the same as the direction between
86  // first and last slice origin. We need to make this sure here, because
87  // we want to feed the files into itk::ImageSeriesReader with the consistent
88  // setting of ReverseOrderOff.
89 
90  static const DICOMTag tagImagePositionPatient = DICOMTag(0x0020,0x0032); // Image Position (Patient)
91  static const DICOMTag tagImageOrientation = DICOMTag(0x0020, 0x0037); // Image Orientation
92 
93  DICOMDatasetAccess* firstDS = datasets.front();
94  DICOMDatasetAccess* lastDS = datasets.back();
95 
96  // make sure here that the direction from slice to slice is the direction of
97  // image normals...
98  const std::string imageOrientationString = firstDS->GetTagValueAsString( tagImageOrientation ).value;
99  const std::string imagePositionPatientFirst = firstDS->GetTagValueAsString(tagImagePositionPatient).value;
100  const std::string imagePositionPatientLast = lastDS->GetTagValueAsString(tagImagePositionPatient).value;
101 
102  Vector3D right; right.Fill(0.0);
103  Vector3D up; up.Fill(0.0);
104  bool hasOrientation(false);
105  DICOMStringToOrientationVectors( imageOrientationString,
106  right, up, hasOrientation );
107 
108  Point3D firstOrigin; firstOrigin.Fill(0.0f);
109  bool firstHasOrigin(false);
110  firstOrigin = DICOMStringToPoint3D( imagePositionPatientFirst, firstHasOrigin );
111 
112  Point3D lastOrigin; lastOrigin.Fill(0.0f);
113  bool lastHasOrigin(false);
114  lastOrigin = DICOMStringToPoint3D( imagePositionPatientLast, lastHasOrigin );
115 
116  Vector3D normal;
117  normal[0] = right[1] * up[2] - right[2] * up[1];
118  normal[1] = right[2] * up[0] - right[0] * up[2];
119  normal[2] = right[0] * up[1] - right[1] * up[0];
120  normal.Normalize();
121 
122  Vector3D directionOfSlices;
123  directionOfSlices = lastOrigin - firstOrigin;
124  directionOfSlices.Normalize();
125 
126  double projection = normal * directionOfSlices;
127 
128  MITK_DEBUG << "Making sense of \norientation '" << imageOrientationString
129  << "'\nfirst position '" << imagePositionPatientFirst
130  << "'\nlast position '" << imagePositionPatientLast << "'";
131  MITK_DEBUG << "Normal: " << normal;
132  MITK_DEBUG << "Direction of slices: " << directionOfSlices;
133  MITK_DEBUG << "Projection of direction onto slice normal: " << projection;
134 
135  if ( projection < 0.0 )
136  {
137  MITK_DEBUG << "Need to reverse filenames";
138  std::reverse( datasets.begin(), datasets.end() );
139 
141  imagePositionPatientLast,
142  imagePositionPatientFirst,
143  imageOrientationString,
144  datasets.size() - 1
145  );
146  }
147  else
148  {
150  imagePositionPatientFirst,
151  imagePositionPatientLast,
152  imageOrientationString,
153  datasets.size() - 1
154  );
155  }
156  }
157  else // just ONE dataset, do not forget to reset tilt information
158  {
159  m_TiltInfo = GantryTiltInformation(); // empty info
160  }
161 
162  this->SetNumberOfOutputs(1);
163  this->SetOutput(0, datasets);
164 }
165 
169 {
170  return m_TiltInfo;
171 }
NormalDirectionConsistencySorter & operator=(const NormalDirectionConsistencySorter &other)
The sorting/splitting building-block of DICOMITKSeriesGDCMReader.
std::vector< DICOMTag > DICOMTagList
Definition: mitkDICOMTag.h:64
void DICOMStringToOrientationVectors(const std::string &s, Vector3D &right, Vector3D &up, bool &successful)
Convert DICOM string describing a point two Vector3D.
Representation of a DICOM tag.
Definition: mitkDICOMTag.h:37
#define MITK_DEBUG
Definition: mitkLogMacros.h:26
virtual void PrintConfiguration(std::ostream &os, const std::string &indent="") const override
Print configuration details into stream.
Interface to datasets that is presented to sorting classes such as DICOMDatasetSorter.
virtual DICOMDatasetFinding GetTagValueAsString(const DICOMTag &tag) const =0
Return a DICOMDatasetFinding instance of the tag. The return containes (if valid) the raw value of th...
Makes sure that the order of files is along the image plane normals.
virtual void Sort() override
See class description.
GantryTiltInformation GetTiltInformation() const
See class description and DICOMITKSeriesGDCMReader.
static GantryTiltInformation MakeFromTagValues(const std::string &origin1String, const std::string &origin2String, const std::string orientationString, unsigned int numberOfSlicesApart)
Factory method to create GantryTiltInformation from tag values (strings).
Gantry tilt analysis result.
virtual bool operator==(const DICOMDatasetSorter &other) const override
Point3D DICOMStringToPoint3D(const std::string &s, bool &successful)
Convert DICOM string describing a point to Point3D.
DICOMDatasetSorter & operator=(const DICOMDatasetSorter &other)
std::vector< DICOMDatasetAccess * > DICOMDatasetList