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