Medical Imaging Interaction Toolkit  2018.4.99-12ad79a3
Medical Imaging Interaction Toolkit
mitkNormalDirectionConsistencySorter.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 (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 //#define MBILOG_ENABLE_DEBUG
14 
16 
17 #include <algorithm>
18 
22 {
23 }
24 
27 :DICOMDatasetSorter(other)
28 {
29 }
30 
33 {
34 }
35 
36 void
38 ::PrintConfiguration(std::ostream& os, const std::string& indent) const
39 {
40  os << indent << "NormalDirectionConsistencySorter" << std::endl;
41 }
42 
43 
47 {
48  if (this != &other)
49  {
51  }
52  return *this;
53 }
54 
55 bool
57 ::operator==(const DICOMDatasetSorter& other) const
58 {
59  return dynamic_cast<const NormalDirectionConsistencySorter*>(&other) != nullptr;
60 }
61 
62 
66 {
67  DICOMTagList tags;
68  tags.push_back( DICOMTag(0x0020, 0x0032) ); // ImagePositionPatient
69  tags.push_back( DICOMTag(0x0020, 0x0037) ); // ImageOrientationPatient
70 
71  return tags;
72 }
73 
74 void
77 {
78  DICOMDatasetList datasets = GetInput();
79 
80  if (datasets.size() > 1)
81  {
82  // at some point in the code, there is the expectation that
83  // the direction of the slice normals is the same as the direction between
84  // first and last slice origin. We need to make this sure here, because
85  // we want to feed the files into itk::ImageSeriesReader with the consistent
86  // setting of ReverseOrderOff.
87 
88  static const DICOMTag tagImagePositionPatient = DICOMTag(0x0020,0x0032); // Image Position (Patient)
89  static const DICOMTag tagImageOrientation = DICOMTag(0x0020, 0x0037); // Image Orientation
90 
91  DICOMDatasetAccess* firstDS = datasets.front();
92  DICOMDatasetAccess* lastDS = datasets.back();
93 
94  // make sure here that the direction from slice to slice is the direction of
95  // image normals...
96  const std::string imageOrientationString = firstDS->GetTagValueAsString( tagImageOrientation ).value;
97  const std::string imagePositionPatientFirst = firstDS->GetTagValueAsString(tagImagePositionPatient).value;
98  const std::string imagePositionPatientLast = lastDS->GetTagValueAsString(tagImagePositionPatient).value;
99 
100  Vector3D right; right.Fill(0.0);
101  Vector3D up; up.Fill(0.0);
102  bool hasOrientation(false);
103  DICOMStringToOrientationVectors( imageOrientationString,
104  right, up, hasOrientation );
105 
106  Point3D firstOrigin; firstOrigin.Fill(0.0f);
107  bool firstHasOrigin(false);
108  firstOrigin = DICOMStringToPoint3D( imagePositionPatientFirst, firstHasOrigin );
109 
110  Point3D lastOrigin; lastOrigin.Fill(0.0f);
111  bool lastHasOrigin(false);
112  lastOrigin = DICOMStringToPoint3D( imagePositionPatientLast, lastHasOrigin );
113 
114  Vector3D normal;
115  normal[0] = right[1] * up[2] - right[2] * up[1];
116  normal[1] = right[2] * up[0] - right[0] * up[2];
117  normal[2] = right[0] * up[1] - right[1] * up[0];
118  normal.Normalize();
119 
120  Vector3D directionOfSlices;
121  directionOfSlices = lastOrigin - firstOrigin;
122  directionOfSlices.Normalize();
123 
124  double projection = normal * directionOfSlices;
125 
126  MITK_DEBUG << "Making sense of \norientation '" << imageOrientationString
127  << "'\nfirst position '" << imagePositionPatientFirst
128  << "'\nlast position '" << imagePositionPatientLast << "'";
129  MITK_DEBUG << "Normal: " << normal;
130  MITK_DEBUG << "Direction of slices: " << directionOfSlices;
131  MITK_DEBUG << "Projection of direction onto slice normal: " << projection;
132 
133  if ( projection < 0.0 )
134  {
135  MITK_DEBUG << "Need to reverse filenames";
136  std::reverse( datasets.begin(), datasets.end() );
137 
139  imagePositionPatientLast,
140  imagePositionPatientFirst,
141  imageOrientationString,
142  datasets.size() - 1
143  );
144  }
145  else
146  {
148  imagePositionPatientFirst,
149  imagePositionPatientLast,
150  imageOrientationString,
151  datasets.size() - 1
152  );
153  }
154  }
155  else // just ONE dataset, do not forget to reset tilt information
156  {
157  m_TiltInfo = GantryTiltInformation(); // empty info
158  }
159 
160  this->SetNumberOfOutputs(1);
161  this->SetOutput(0, datasets);
162 }
163 
167 {
168  return m_TiltInfo;
169 }
NormalDirectionConsistencySorter & operator=(const NormalDirectionConsistencySorter &other)
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).
The sorting/splitting building-block of DICOMITKSeriesGDCMReader.
std::vector< DICOMTag > DICOMTagList
Definition: mitkDICOMTag.h:59
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:32
#define MITK_DEBUG
Definition: mitkLogMacros.h:22
void PrintConfiguration(std::ostream &os, const std::string &indent="") const override
Print configuration details into stream.
void SetNumberOfOutputs(unsigned int numberOfOutputs)
const DICOMDatasetList & GetInput() const
Input for sorting.
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.
Gantry tilt analysis result.
bool operator==(const DICOMDatasetSorter &other) const override
GantryTiltInformation GetTiltInformation() const
See class description and DICOMITKSeriesGDCMReader.
Point3D DICOMStringToPoint3D(const std::string &s, bool &successful)
Convert DICOM string describing a point to Point3D.
void SetOutput(unsigned int index, const DICOMDatasetList &output)
DICOMDatasetSorter & operator=(const DICOMDatasetSorter &other)
std::vector< DICOMDatasetAccess * > DICOMDatasetList