Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkDICOMSortByTag.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 #include "mitkDICOMSortByTag.h"
18 
19 #include "ofstd.h"
20 
22 ::DICOMSortByTag(const DICOMTag& tag, DICOMSortCriterion::Pointer secondaryCriterion)
23 :DICOMSortCriterion(secondaryCriterion)
24 ,m_Tag(tag)
25 {
26 }
27 
30 {
31 }
32 
35 :DICOMSortCriterion(other)
36 ,m_Tag(other.m_Tag)
37 {
38 }
39 
43 {
44  if (this != &other)
45  {
47  m_Tag = other.m_Tag;
48  }
49  return *this;
50 }
51 
52 bool
54 ::operator==(const DICOMSortCriterion& other) const
55 {
56  if (const DICOMSortByTag* otherSelf = dynamic_cast<const DICOMSortByTag*>(&other))
57  {
58  if (!(this->m_Tag == otherSelf->m_Tag)) return false;
59 
60  if (this->m_SecondaryCriterion.IsNull() && otherSelf->m_SecondaryCriterion.IsNull()) return true;
61 
62  if (this->m_SecondaryCriterion.IsNull() || otherSelf->m_SecondaryCriterion.IsNull()) return false;
63 
64  return *(this->m_SecondaryCriterion) == *(otherSelf->m_SecondaryCriterion);
65  }
66  else
67  {
68  return false;
69  }
70 }
71 
72 void
74 ::Print(std::ostream& os) const
75 {
76  m_Tag.Print(os);
77 }
78 
79 
83 {
84  DICOMTagList list;
85  list.push_back(m_Tag);
86  return list;
87 }
88 
89 bool
92 {
93  return this->NumericCompare(left, right, m_Tag);
94 }
95 
96 bool
98 ::StringCompare(const mitk::DICOMDatasetAccess* left, const mitk::DICOMDatasetAccess* right, const DICOMTag& tag) const
99 {
100  assert(left);
101  assert(right);
102 
103  DICOMDatasetFinding leftFinding = left->GetTagValueAsString(tag);
104  DICOMDatasetFinding rightFinding = right->GetTagValueAsString(tag);
105  //Doesn't care if findings are valid or not. If they are not valid,
106  //value is empty, thats enough.
107  if (leftFinding.value != rightFinding.value)
108  {
109  return leftFinding.value.compare(rightFinding.value) < 0;
110  }
111  else
112  {
113  return this->NextLevelIsLeftBeforeRight(left, right);
114  }
115 }
116 
117 bool
120 {
121  assert(left);
122  assert(right);
123 
124  const DICOMDatasetFinding leftFinding = left->GetTagValueAsString(tag);
125  const DICOMDatasetFinding rightFinding = right->GetTagValueAsString(tag);
126  //Doesn't care if findings are valid or not. If they are not valid,
127  //value is empty, thats enough.
128 
129  double leftDouble( 0 );
130  double rightDouble( 0 );
131 
132  try
133  {
134  leftDouble = OFStandard::atof( leftFinding.value.c_str() );
135  rightDouble = OFStandard::atof(rightFinding.value.c_str());
136  }
137  catch ( const std::exception& /*e*/ )
138  {
139  return this->StringCompare(left,right, tag); // fallback to string compare
140  }
141 
142 
143  if ( leftDouble != rightDouble ) // can we decide?
144  {
145  return leftDouble < rightDouble;
146  }
147  else // ask secondary criterion
148  {
149  return this->NextLevelIsLeftBeforeRight( left, right );
150  }
151 }
152 
153 double
156 {
157  assert(from);
158  assert(to);
159 
160  const DICOMDatasetFinding fromFinding = from->GetTagValueAsString(m_Tag);
161  const DICOMDatasetFinding toFinding = to->GetTagValueAsString(m_Tag);
162  //Doesn't care if findings are valid or not. If they are not valid,
163  //value is empty, thats enough.
164 
165  double fromDouble(0);
166  double toDouble(0);
167 
168  try
169  {
170  fromDouble = OFStandard::atof(fromFinding.value.c_str());
171  toDouble = OFStandard::atof(toFinding.value.c_str());
172  }
173  catch ( const std::exception& /*e*/ )
174  {
175  MITK_WARN << "NO NUMERIC DISTANCE between '" << fromFinding.value << "' and '" << toFinding.value << "'";
176  return 0;
177  }
178 
179  return toDouble - fromDouble;
180  // TODO second-level compare?
181 }
itk::SmartPointer< Self > Pointer
std::vector< DICOMTag > DICOMTagList
Definition: mitkDICOMTag.h:64
bool NumericCompare(const mitk::DICOMDatasetAccess *left, const mitk::DICOMDatasetAccess *right, const DICOMTag &tag) const
Representation of a DICOM tag.
Definition: mitkDICOMTag.h:37
virtual void Print(std::ostream &os) const override
brief describe this class in given stream.
DICOMSortCriterion & operator=(const DICOMSortCriterion &other)
Interface to datasets that is presented to sorting classes such as DICOMDatasetSorter.
virtual double NumericDistance(const mitk::DICOMDatasetAccess *from, const mitk::DICOMDatasetAccess *to) const override
Calculate a distance between two datasets. This ansers the question of consecutive datasets...
#define MITK_WARN
Definition: mitkLogMacros.h:23
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...
DICOMSortByTag & operator=(const DICOMSortByTag &other)
virtual bool operator==(const DICOMSortCriterion &other) const override
Compare two datasets by the value of a single tag (for use in DICOMTagBasedSorter).
bool StringCompare(const mitk::DICOMDatasetAccess *left, const mitk::DICOMDatasetAccess *right, const DICOMTag &tag) const
A tag based sorting criterion for use in DICOMTagBasedSorter.
DICOMSortByTag(const DICOMTag &tag, DICOMSortCriterion::Pointer secondaryCriterion=nullptr)
virtual bool IsLeftBeforeRight(const mitk::DICOMDatasetAccess *left, const mitk::DICOMDatasetAccess *right) const override
Answer the sorting question.
virtual DICOMTagList GetTagsOfInterest() const override
Tags used for comparison.