diff --git a/Modules/Core/src/DataManagement/mitkPropertyNameHelper.cpp b/Modules/Core/src/DataManagement/mitkPropertyNameHelper.cpp index ff1e0deb04..393ae32dc2 100644 --- a/Modules/Core/src/DataManagement/mitkPropertyNameHelper.cpp +++ b/Modules/Core/src/DataManagement/mitkPropertyNameHelper.cpp @@ -1,56 +1,57 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY { } without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkPropertyNameHelper.h" #include #include #include std::string mitk::GeneratePropertyNameForDICOMTag(unsigned int group, unsigned int element) { std::ostringstream nameStream; - nameStream << "DICOM." << std::setw(4) << std::setfill('0') << std::hex << group << "." << std::setw(4) - << std::setfill('0') << std::hex << element; + nameStream << "DICOM." + << std::setw(4) << std::setfill('0') << std::hex << std::uppercase << group << std::nouppercase << "." + << std::setw(4) << std::setfill('0') << std::hex << std::uppercase << element; return nameStream.str(); }; bool mitk::GetBackwardsCompatibleDICOMProperty(unsigned int group, unsigned int element, std::string const &backwardsCompatiblePropertyName, mitk::PropertyList const *propertyList, std::string &propertyValue) { propertyValue = ""; BaseProperty *prop = propertyList->GetProperty(mitk::GeneratePropertyNameForDICOMTag(group, element).c_str()); if (prop) { // may not be a string property so use the generic access. propertyValue = prop->GetValueAsString(); } if (!propertyValue.empty() || propertyList->GetStringProperty(backwardsCompatiblePropertyName.c_str(), propertyValue)) // 2nd part is for backwards compatibility with the old property naming style { return true; } return false; }; diff --git a/Modules/DICOMReader/include/mitkDICOMTagPath.h b/Modules/DICOMReader/include/mitkDICOMTagPath.h index c5173ee0fd..c877341417 100644 --- a/Modules/DICOMReader/include/mitkDICOMTagPath.h +++ b/Modules/DICOMReader/include/mitkDICOMTagPath.h @@ -1,180 +1,180 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkDICOMTagPath_h #define mitkDICOMTagPath_h #include #include #include namespace mitk { /** @brief Class is used to identify (nested) attributes in a DICOM dataset. * In contrast to the class DICOMTag, which only specifies one specific tag, * the tag path can identify nested attributes (like items in a DICOM sequence). * In addition you may also specify wildcards for the selection index or * complete elements of the path. * @remark If you want to keep the DICOMTagPath compatible to the dcmtk search path * format, you may *not* use element wild cards (this IsExplicit() or HasItemSelectionWildcardsOnly() * must return true). */ class MITKDICOMREADER_EXPORT DICOMTagPath { public: typedef int ItemSelectionIndex; struct MITKDICOMREADER_EXPORT NodeInfo { enum class NodeType { Invalid = 0, //*< Node is non existant or invalid. Element, //*< Selects an specific element given the node name. SequenceSelection, //*< Selects an specific item in a sequence of items and has a item selector ("[n]"). AnySelection, //*< Selects all items of a specific element ("[*]"). AnyElement, //*< Selects any element/item. Node name is wildcarded ("*"); item selection as well implictily. }; NodeType type; DICOMTag tag; ItemSelectionIndex selection; NodeInfo(); NodeInfo(const DICOMTag& tag, NodeType type = NodeType::Element, ItemSelectionIndex index = 0); bool Matches(const NodeInfo& right) const; bool operator == (const NodeInfo& right) const; }; typedef std::vector NodeInfoVectorType; typedef NodeInfoVectorType::size_type PathIndexType; /** Returns if the DICOMTagPath is empty.*/ bool IsEmpty() const; /** Returns if the path is explicit (has no wildcards).*/ bool IsExplicit() const; /** Returns if the path has any nodes with item selection wild cards ([*]).*/ bool HasItemSelectionWildcardsOnly() const; /** Number of path nodes the DICOMTagPath contains.*/ PathIndexType Size() const; /** Adds a new node to the end of the path. \param [in] newNode Reference to the node that should be added. \return Returns the index of the newly added node.*/ PathIndexType AddNode(const NodeInfo& newNode); /** Function returns the node info of a path node specified by the index * within the DICOMTagPath. * \pre Passed index must not be out of bound. * \param [in] index Index of the node whose info should be retrieved. * \return Info of the specified path node. If the index is out of bound an InvalidPathNode exception will be thrown.*/ const NodeInfo& GetNode(const PathIndexType& index) const; /** Function returns the node info of a path node specified by the index * within the DICOMTagPath. * \pre Passed index must not be out of bound. * \param [in] index Index of the node whose info should be retrieved. * \return Info of the specified path node. If the index is out of bound an InvalidPathNode exception will be thrown.*/ NodeInfo& GetNode(const PathIndexType& index); /** Function returns the node info of the first path node within the DICOMTagPath. * \pre DICOMTagPath must not be empty. * \return Info of the first path node. If the path is empty, an InvalidPathNode exception will be thrown.*/ NodeInfo& GetFirstNode(); /** Function returns the node info of the first path node within the DICOMTagPath. * \pre DICOMTagPath must not be empty. * \return Info of the first path node. If the path is empty, an InvalidPathNode exception will be thrown.*/ const NodeInfo& GetFirstNode() const; /** Function returns the node info of the last path node within the DICOMTagPath. * \pre DICOMTagPath must not be empty. * \return Info of the first path node. If the path is empty, an InvalidPathNode exception will be thrown.*/ NodeInfo& GetLastNode(); /** Function returns the node info of the last path node within the DICOMTagPath. * \pre DICOMTagPath must not be empty. * \return Info of the first path node. If the path is empty, an InvalidPathNode exception will be thrown.*/ const NodeInfo& GetLastNode() const; const NodeInfoVectorType& GetNodes() const; std::string ToStr() const; DICOMTagPath& FromStr(const std::string& pathStr); /**Compares two DICOMTagPaths for real equality. So its a string compare of their string conversion*/ bool operator == (const DICOMTagPath& path) const; /**Operation equals like comparing the ToStr() results with operator <.*/ bool operator < (const DICOMTagPath& right) const; /**Checks if to DICOMTagPathes are specify the same node. Hence all wildcards will be processed.\n * E.G.: "item1/child1/grandChild2" == ".//item1//grandChild2" is true. * \remark If you want to check if to pathes are "truely" equal and not only equal in terms of * pointing to the same node, use the member function Equals()*/ bool Equals(const DICOMTagPath& path) const; DICOMTagPath& operator = (const DICOMTagPath& path); DICOMTagPath& AddAnyElement(); DICOMTagPath& AddElement(unsigned int group, unsigned int element); DICOMTagPath& AddAnySelection(unsigned int group, unsigned int element); DICOMTagPath& AddSelection(unsigned int group, unsigned int element, ItemSelectionIndex index); DICOMTagPath(); DICOMTagPath(const DICOMTagPath& path); DICOMTagPath(const DICOMTag& tag); explicit DICOMTagPath(unsigned int group, unsigned int element); ~DICOMTagPath(); virtual void Reset(); protected: NodeInfoVectorType m_NodeInfos; static bool DICOMTagPathesMatch(const DICOMTagPath& left, const DICOMTagPath& right); }; typedef std::vector DICOMTagPathList; MITKDICOMREADER_EXPORT std::ostream& operator<<(std::ostream& os, const DICOMTagPath& path); - MITKDICOMREADER_EXPORT std::string DICOMTagPathToPropertRegEx(const DICOMTagPath& tagPath); + MITKDICOMREADER_EXPORT std::string DICOMTagPathToPropertyRegEx(const DICOMTagPath& tagPath); MITKDICOMREADER_EXPORT std::string DICOMTagPathToPersistenceKeyRegEx(const DICOMTagPath& tagPath); MITKDICOMREADER_EXPORT std::string DICOMTagPathToPersistenceKeyTemplate(const DICOMTagPath& tagPath); MITKDICOMREADER_EXPORT std::string DICOMTagPathToPersistenceNameTemplate(const DICOMTagPath& tagPath); /** Converts a passed path into a search string for the DCMTK DcmPathProcessor. @pre tagPath must be an explicit (DICOMTagPath::IsExplicit()) path or must only contain selection wild cards (DICOMTagPath::HasItemSelectionWildcardsOnly()).*/ MITKDICOMREADER_EXPORT std::string DICOMTagPathToDCMTKSearchPath(const DICOMTagPath& tagPath); /** Converts the passed property name into a tag path. If the property name cannot be converted into a valid path, the returned path is empty.*/ MITKDICOMREADER_EXPORT DICOMTagPath PropertyNameToDICOMTagPath(const std::string& propertyName); /** returns the correct property name for a given DICOMTagPath instance. */ MITKDICOMREADER_EXPORT std::string DICOMTagPathToPropertyName(const DICOMTagPath& tagPath); } #endif diff --git a/Modules/DICOMReader/src/mitkDICOMTagPath.cpp b/Modules/DICOMReader/src/mitkDICOMTagPath.cpp index b4d25047d4..a1f8f8f35d 100644 --- a/Modules/DICOMReader/src/mitkDICOMTagPath.cpp +++ b/Modules/DICOMReader/src/mitkDICOMTagPath.cpp @@ -1,690 +1,729 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include #include #include #include #include +namespace +{ + std::string GenerateRegExForNumber(unsigned int tagNumber) + { + std::ostringstream resultRegEx; + + std::ostringstream hexNumber; + hexNumber << std::hex << tagNumber; // default std::hex output is lowercase + std::regex reg_character("([a-f]+)"); // so only check for lowercase characters here + if (std::regex_search(hexNumber.str(), reg_character)) + { + // hexNumber contains a characters from a-f + // needs to be generated with lowercase and uppercase characters + resultRegEx << "(" + << std::setw(4) << std::setfill('0') << std::hex << tagNumber + << "|" + << std::setw(4) << std::setfill('0') << std::hex << std::uppercase << tagNumber << std::nouppercase + << ")"; + } + else + { + // only decimal values (0-9) contained in hexNumber - no need to modify the result + resultRegEx << std::setw(4) << std::setfill('0') << std::hex << tagNumber; + } + + return resultRegEx.str(); + } +} + namespace mitk { DICOMTagPath::NodeInfo:: NodeInfo() : type(NodeType::Invalid), tag(0, 0), selection(0) { ; }; DICOMTagPath::NodeInfo:: NodeInfo(const DICOMTag& aTag, NodeType aType, ItemSelectionIndex index) : type(aType), tag(aTag), selection(index) {}; bool DICOMTagPath::NodeInfo::operator == (const NodeInfo& right) const { if (!(this->tag == right.tag)) return false; if (this->type != right.type) return false; if (this->selection != right.selection) return false; return true; }; bool DICOMTagPath::NodeInfo:: Matches(const NodeInfo& right) const { if (type == NodeType::AnyElement || right.type == NodeType::AnyElement) { return true; } else if (tag == right.tag && type != NodeType::Invalid && right.type != NodeType::Invalid) { if (type == NodeType::Element && right.type == NodeType::Element) { return true; } else if(selection == right.selection || type == NodeType::AnySelection || right.type == NodeType::AnySelection) { return true; } } return false; }; bool DICOMTagPath::IsEmpty() const { return m_NodeInfos.empty(); }; bool DICOMTagPath:: IsExplicit() const { for (const auto & pos : m_NodeInfos) { if ((pos.type == NodeInfo::NodeType::AnySelection) || (pos.type == NodeInfo::NodeType::AnyElement)) return false; } return true; }; bool DICOMTagPath:: HasItemSelectionWildcardsOnly() const { bool result = false; for (const auto & pos : m_NodeInfos) { if (pos.type == NodeInfo::NodeType::AnyElement) return false; result = result || pos.type == NodeInfo::NodeType::AnySelection; } return result; }; DICOMTagPath::PathIndexType DICOMTagPath::Size() const { return m_NodeInfos.size(); } DICOMTagPath::PathIndexType DICOMTagPath:: AddNode(const NodeInfo& newNode) { m_NodeInfos.push_back(newNode); return m_NodeInfos.size() - 1; }; const DICOMTagPath::NodeInfo& DICOMTagPath:: GetNode(const PathIndexType& index) const { if (index >= Size()) { mitkThrow() << "Error. Cannot return info of path node. Node index is out of bound. Index: " << index << "; Path: " << this->ToStr(); } return m_NodeInfos[index]; }; DICOMTagPath::NodeInfo& DICOMTagPath:: GetNode(const PathIndexType& index) { if (index >= Size()) { mitkThrow() << "Error. Cannot return info of path node. Node index is out of bound. Index: " << index << "; Path: " << this->ToStr(); } return m_NodeInfos[index]; }; const DICOMTagPath::NodeInfo& DICOMTagPath:: GetFirstNode() const { return GetNode(0); }; const DICOMTagPath::NodeInfo& DICOMTagPath:: GetLastNode() const { return GetNode(Size() - 1); }; DICOMTagPath::NodeInfo& DICOMTagPath:: GetLastNode() { return GetNode(Size() - 1); }; const DICOMTagPath::NodeInfoVectorType& DICOMTagPath:: GetNodes() const { return m_NodeInfos; }; std::string DICOMTagPath:: ToStr() const { std::ostringstream nameStream; if (this->Size() == 0) return nameStream.str(); PathIndexType i = 0; for (const auto& node : m_NodeInfos) { if (i) { nameStream << "."; } ++i; if (node.type == NodeInfo::NodeType::AnyElement) { nameStream << "*"; } else if (node.type != NodeInfo::NodeType::Invalid) { - nameStream << "(" << std::setw(4) << std::setfill('0') << std::hex << node.tag.GetGroup() << "," << std::setw(4) << std::setfill('0') << std::hex << node.tag.GetElement()<<")"; + nameStream << "(" + << std::setw(4) << std::setfill('0') << std::hex << std::uppercase << node.tag.GetGroup() << std::nouppercase + << "," + << std::setw(4) << std::setfill('0') << std::hex << std::uppercase << node.tag.GetElement() << std::nouppercase + << ")"; if (node.type == NodeInfo::NodeType::SequenceSelection) { nameStream << "[" << node.selection << "]"; } else if (node.type == NodeInfo::NodeType::AnySelection) { nameStream << "[*]"; } } else { nameStream << "INVALID_NODE"; } } return nameStream.str(); }; bool DICOMTagPath:: operator == (const DICOMTagPath& path) const { return this->m_NodeInfos == path.m_NodeInfos; }; bool DICOMTagPath:: operator < (const DICOMTagPath& right) const { auto rightIter = right.m_NodeInfos.cbegin(); const auto rightEnd = right.m_NodeInfos.cend(); for (const auto& leftPos : m_NodeInfos) { if (rightIter == rightEnd) return false; if (leftPos.tag.GetElement() < rightIter->tag.GetElement()) return true; if (rightIter->tag.GetElement() < leftPos.tag.GetElement()) return false; if (leftPos.tag.GetGroup() < rightIter->tag.GetGroup()) return true; if (rightIter->tag.GetGroup()< leftPos.tag.GetGroup()) return false; if (leftPos.type < rightIter->type) return true; if (rightIter->type< leftPos.type) return false; if (leftPos.selection < rightIter->selection) return true; if (rightIter->selection< leftPos.selection) return false; ++rightIter; } return rightIter != rightEnd; } bool DICOMTagPath:: Equals(const DICOMTagPath& path) const { return DICOMTagPathesMatch(*this, path); }; DICOMTagPath& DICOMTagPath:: operator = (const DICOMTagPath& path) { if (&path == this) return *this; this->m_NodeInfos = path.m_NodeInfos; return *this; }; DICOMTagPath& DICOMTagPath::AddAnyElement() { m_NodeInfos.emplace_back(DICOMTag(0,0), NodeInfo::NodeType::AnyElement); return *this; }; DICOMTagPath& DICOMTagPath::AddElement(unsigned int group, unsigned int element) { m_NodeInfos.emplace_back(DICOMTag(group, element), NodeInfo::NodeType::Element); return *this; }; DICOMTagPath& DICOMTagPath::AddAnySelection(unsigned int group, unsigned int element) { m_NodeInfos.emplace_back(DICOMTag(group, element), NodeInfo::NodeType::AnySelection); return *this; }; DICOMTagPath& DICOMTagPath::AddSelection(unsigned int group, unsigned int element, ItemSelectionIndex index) { m_NodeInfos.emplace_back(DICOMTag(group, element), NodeInfo::NodeType::SequenceSelection, index); return *this; }; DICOMTagPath& DICOMTagPath:: FromStr(const std::string& pathStr) { NodeInfoVectorType result; std::istringstream f(pathStr); std::string subStr; while (getline(f, subStr, '.')) { NodeInfo info; if (subStr == "*") { info.type = NodeInfo::NodeType::AnyElement; } else { - std::regex reg_element("\\((\\d{4}),(\\d{4})\\)"); - std::regex reg_anySelection("\\((\\d{4}),(\\d{4})\\)\\[\\*\\]"); - std::regex reg_Selection("\\((\\d{4}),(\\d{4})\\)\\[(\\d+)\\]"); + std::regex reg_element("\\(([A - Fa - f\\d]{4}),([A - Fa - f\\d]{4})\\)"); + std::regex reg_anySelection("\\(([A - Fa - f\\d]{4}),([A - Fa - f\\d]{4})\\)\\[\\*\\]"); + std::regex reg_Selection("\\(([A - Fa - f\\d]{4}),([A - Fa - f\\d]{4})\\)\\[(\\d+)\\]"); std::smatch sm; if (std::regex_match(subStr, sm, reg_anySelection)) { info.type = NodeInfo::NodeType::AnySelection; info.tag = DICOMTag(std::stoul(sm[1], nullptr, 16), std::stoul(sm[2], nullptr, 16)); } else if (std::regex_match(subStr, sm, reg_Selection)) { info.type = NodeInfo::NodeType::SequenceSelection; info.tag = DICOMTag(std::stoul(sm[1], nullptr, 16), std::stoul(sm[2], nullptr, 16)); info.selection = std::stoi(sm[3]); } else if (std::regex_match(subStr, sm, reg_element)) { info.type = NodeInfo::NodeType::Element; info.tag = DICOMTag(std::stoul(sm[1], nullptr, 16), std::stoul(sm[2], nullptr, 16)); } } result.push_back(info); } this->m_NodeInfos.swap(result); return *this; }; DICOMTagPath::DICOMTagPath() { Reset(); }; DICOMTagPath:: DICOMTagPath(const DICOMTagPath& path) { *this = path; }; DICOMTagPath:: DICOMTagPath(const DICOMTag& tag) { m_NodeInfos.emplace_back(tag, NodeInfo::NodeType::Element); }; DICOMTagPath::DICOMTagPath(unsigned int group, unsigned int element) { m_NodeInfos.emplace_back(DICOMTag(group,element)); }; DICOMTagPath:: ~DICOMTagPath() {}; void DICOMTagPath:: Reset() { this->m_NodeInfos.clear(); }; bool DICOMTagPath:: DICOMTagPathesMatch(const DICOMTagPath& left, const DICOMTagPath& right) { NodeInfoVectorType::const_iterator leftPos = left.GetNodes().cbegin(); NodeInfoVectorType::const_iterator rightPos = right.GetNodes().cbegin(); NodeInfoVectorType::const_iterator leftEnd = left.GetNodes().cend(); NodeInfoVectorType::const_iterator rightEnd = right.GetNodes().cend(); while (leftPos != leftEnd && rightPos != rightEnd) { if (!leftPos->Matches(*rightPos)) break; ++leftPos; ++rightPos; } if (leftPos == leftEnd && rightPos == rightEnd) return true; else return false; }; std::ostream & operator<<(std::ostream &os, const DICOMTagPath &value) { os << value.ToStr(); return os; }; - - std::string DICOMTagPathToDCMTKSearchPath(const DICOMTagPath& tagPath) - { - if (!tagPath.IsExplicit() && !tagPath.HasItemSelectionWildcardsOnly()) - { - mitkThrow() << "Cannot convert DICOMTagPath into DCMTK search path. Path has element wild cards. Path: " << tagPath.ToStr(); - } - - return tagPath.ToStr(); - }; - - std::string DICOMTagPathToPropertRegEx(const DICOMTagPath& tagPath) + std::string DICOMTagPathToPropertyRegEx(const DICOMTagPath& tagPath) { std::ostringstream nameStream; nameStream << "DICOM"; for (const auto& node : tagPath.GetNodes()) { nameStream << "\\."; if (node.type == DICOMTagPath::NodeInfo::NodeType::AnyElement) { - nameStream << "(\\d{4})\\.(\\d{4})"; + nameStream << "([A-Fa-f\\d]{4})\\.([A-Fa-f\\d]{4})"; } else if (node.type != DICOMTagPath::NodeInfo::NodeType::Invalid) { - nameStream << std::setw(4) << std::setfill('0') << std::hex << node.tag.GetGroup() << "\\." << std::setw(4) << std::setfill('0') << std::hex << node.tag.GetElement(); + nameStream << GenerateRegExForNumber(node.tag.GetGroup()) + << "\\." + << GenerateRegExForNumber(node.tag.GetElement()); if (node.type == DICOMTagPath::NodeInfo::NodeType::SequenceSelection) { nameStream << "\\.\\[" << node.selection << "\\]"; } else if (node.type == DICOMTagPath::NodeInfo::NodeType::AnySelection) { nameStream << "\\.\\[(\\d*)\\]"; } } else { nameStream << "INVALIDNODE"; } } return nameStream.str(); }; std::string DICOMTagPathToPersistenceKeyRegEx(const DICOMTagPath& tagPath) { std::ostringstream nameStream; nameStream << "DICOM"; for (const auto& node : tagPath.GetNodes()) { nameStream << "_"; if (node.type == DICOMTagPath::NodeInfo::NodeType::AnyElement) { - nameStream << "(\\d{4})_(\\d{4})"; + nameStream << "([A-Fa-f\\d]{4})_([A-Fa-f\\d]{4})"; } else if (node.type != DICOMTagPath::NodeInfo::NodeType::Invalid) { - nameStream << std::setw(4) << std::setfill('0') << std::hex << node.tag.GetGroup() << "_" << std::setw(4) << std::setfill('0') << std::hex << node.tag.GetElement(); + nameStream << GenerateRegExForNumber(node.tag.GetGroup()) + << "_" + << GenerateRegExForNumber(node.tag.GetElement()); if (node.type == DICOMTagPath::NodeInfo::NodeType::SequenceSelection) { nameStream << "_\\[" << node.selection << "\\]"; } else if (node.type == DICOMTagPath::NodeInfo::NodeType::AnySelection) { nameStream << "_\\[(\\d*)\\]"; } } else { nameStream << "INVALIDNODE"; } } return nameStream.str(); }; std::string DICOMTagPathToPersistenceKeyTemplate(const DICOMTagPath& tagPath) { std::ostringstream nameStream; nameStream << "DICOM"; int captureGroup = 1; for (const auto& node : tagPath.GetNodes()) { nameStream << "_"; if (node.type == DICOMTagPath::NodeInfo::NodeType::AnyElement) { nameStream << "$" << captureGroup++; nameStream << "_$" << captureGroup++; } else if (node.type != DICOMTagPath::NodeInfo::NodeType::Invalid) { - nameStream << std::setw(4) << std::setfill('0') << std::hex << node.tag.GetGroup() << "_" << std::setw(4) << std::setfill('0') << std::hex << node.tag.GetElement(); + nameStream << std::setw(4) << std::setfill('0') << std::hex << std::uppercase << node.tag.GetGroup() << std::nouppercase << "_" + << std::setw(4) << std::setfill('0') << std::hex << std::uppercase << node.tag.GetElement(); if (node.type == DICOMTagPath::NodeInfo::NodeType::SequenceSelection) { nameStream << "_[" << node.selection << "]"; } else if (node.type == DICOMTagPath::NodeInfo::NodeType::AnySelection) { nameStream << "_[$" << captureGroup++ << "]"; } } else { nameStream << "INVALID_NODE"; } } return nameStream.str(); }; std::string DICOMTagPathToPersistenceNameTemplate(const DICOMTagPath& tagPath) { std::ostringstream nameStream; nameStream << "DICOM"; int captureGroup = 1; for (const auto& node : tagPath.GetNodes()) { nameStream << "."; if (node.type == DICOMTagPath::NodeInfo::NodeType::AnyElement) { nameStream << "$" << captureGroup++; nameStream << ".$" << captureGroup++; } else if (node.type != DICOMTagPath::NodeInfo::NodeType::Invalid) { - nameStream << std::setw(4) << std::setfill('0') << std::hex << node.tag.GetGroup() << "." << std::setw(4) << std::setfill('0') << std::hex << node.tag.GetElement(); + nameStream << std::setw(4) << std::setfill('0') << std::hex << std::uppercase << node.tag.GetGroup() << std::nouppercase << "." + << std::setw(4) << std::setfill('0') << std::hex << std::uppercase << node.tag.GetElement(); if (node.type == DICOMTagPath::NodeInfo::NodeType::SequenceSelection) { nameStream << ".[" << node.selection << "]"; } else if (node.type == DICOMTagPath::NodeInfo::NodeType::AnySelection) { nameStream << ".[$"< + class mitkDICOMTagPathTestSuite : public mitk::TestFixture { CPPUNIT_TEST_SUITE(mitkDICOMTagPathTestSuite); - MITK_TEST(DICOMTagPathToPropertRegEx); + MITK_TEST(DICOMTagPathToPropertyRegEx); MITK_TEST(DICOMTagPathToPersistenceKeyRegEx); MITK_TEST(DICOMTagPathToPersistenceKeyTemplate); MITK_TEST(DICOMTagPathToPersistenceNameTemplate); MITK_TEST(DICOMTagPathToDCMTKSearchPath); MITK_TEST(PropertyNameToDICOMTagPath); MITK_TEST(DICOMTagPathToPropertyName); + MITK_TEST(ExecutePropertyRegEx); CPPUNIT_TEST_SUITE_END(); private: mitk::DICOMTagPath simplePath; mitk::DICOMTagPath deepPath; mitk::DICOMTagPath deepPath_withAnyElement; mitk::DICOMTagPath deepPath_withAnySelection; mitk::DICOMTagPath deepPath_withSelection; mitk::DICOMTagPath verydeepPath; mitk::DICOMTagPath emptyPath; public: void setUp() override { - simplePath.AddElement(0x0010, 0x0010); + simplePath.AddElement(0x0010, 0x0011); deepPath.AddElement(0x0010, 0x0011); deepPath.AddElement(0x0020, 0x0022); - deepPath.AddElement(0x0030, 0x0033); + deepPath.AddElement(0x003A, 0x0033); deepPath_withAnyElement.AddElement(0x0010, 0x0011); deepPath_withAnyElement.AddAnyElement(); - deepPath_withAnyElement.AddElement(0x0030, 0x0033); + deepPath_withAnyElement.AddElement(0x003a, 0x003f); deepPath_withAnySelection.AddElement(0x0010, 0x0011); - deepPath_withAnySelection.AddAnySelection(0x0020, 0x0022); + deepPath_withAnySelection.AddAnySelection(0x002B, 0x002E); deepPath_withAnySelection.AddElement(0x0030, 0x0033); deepPath_withSelection.AddElement(0x0010, 0x0011); deepPath_withSelection.AddSelection(0x0020, 0x0022, 6); - deepPath_withSelection.AddElement(0x0030, 0x0033); + deepPath_withSelection.AddElement(0x003b, 0x003e); verydeepPath.AddAnySelection(0x0010, 0x0011); verydeepPath.AddAnyElement(); verydeepPath.AddElement(0x0030, 0x0033); - verydeepPath.AddSelection(0x0040, 0x0044, 4); + verydeepPath.AddSelection(0x004c, 0x004d, 4); verydeepPath.AddElement(0x0050, 0x0055); } void tearDown() override { } - void DICOMTagPathToPropertRegEx() + void DICOMTagPathToPropertyRegEx() { - std::string result = mitk::DICOMTagPathToPropertRegEx(simplePath); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertRegEx() with '(0010,0010)'", result, std::string("DICOM\\.0010\\.0010")); - result = mitk::DICOMTagPathToPropertRegEx(deepPath); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertRegEx() with '(0010,0010).(0020,0022).(0030,0033)'", result, std::string("DICOM\\.0010\\.0011\\.0020\\.0022\\.0030\\.0033")); - result = mitk::DICOMTagPathToPropertRegEx(deepPath_withAnyElement); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertRegEx() with '(0010,0010).*.(0030,0033)'", result, std::string("DICOM\\.0010\\.0011\\.(\\d{4})\\.(\\d{4})\\.0030\\.0033")); - result = mitk::DICOMTagPathToPropertRegEx(deepPath_withAnySelection); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertRegEx() with '(0010,0010).(0020,0022)[*].(0030,0033)'", result, std::string("DICOM\\.0010\\.0011\\.0020\\.0022\\.\\[(\\d*)\\]\\.0030\\.0033")); - result = mitk::DICOMTagPathToPropertRegEx(deepPath_withSelection); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertRegEx() with '(0010,0010).(0020,0022)[6].(0030,0033)'", result, std::string("DICOM\\.0010\\.0011\\.0020\\.0022\\.\\[6\\]\\.0030\\.0033")); - result = mitk::DICOMTagPathToPropertRegEx(verydeepPath); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertRegEx() with '(0010,0010)[*].*.(0030,0033).(0040,0044)[4].(0050,0055)'", result, std::string("DICOM\\.0010\\.0011\\.\\[(\\d*)\\]\\.(\\d{4})\\.(\\d{4})\\.0030\\.0033\\.0040\\.0044\\.\\[4\\]\\.0050\\.0055")); + std::string result = mitk::DICOMTagPathToPropertyRegEx(simplePath); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertyRegEx() with '(0010,0011)'", std::string("DICOM\\.0010\\.0011"), result); + result = mitk::DICOMTagPathToPropertyRegEx(deepPath); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertyRegEx() with '(0010,0011).(0020,0022).(003A,0033)'", std::string("DICOM\\.0010\\.0011\\.0020\\.0022\\.(003a|003A)\\.0033"), result); + result = mitk::DICOMTagPathToPropertyRegEx(deepPath_withAnyElement); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertyRegEx() with '(0010,0011).*.(003a,003f)'", std::string("DICOM\\.0010\\.0011\\.([A-Fa-f\\d]{4})\\.([A-Fa-f\\d]{4})\\.(003a|003A)\\.(003f|003F)"), result); + result = mitk::DICOMTagPathToPropertyRegEx(deepPath_withAnySelection); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertyRegEx() with '(0010,0011).(002B,002E)[*].(0030,0033)'", std::string("DICOM\\.0010\\.0011\\.(002b|002B)\\.(002e|002E)\\.\\[(\\d*)\\]\\.0030\\.0033"), result); + result = mitk::DICOMTagPathToPropertyRegEx(deepPath_withSelection); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertyRegEx() with '(0010,0011).(0020,0022)[6].(003b,003e)'", std::string("DICOM\\.0010\\.0011\\.0020\\.0022\\.\\[6\\]\\.(003b|003B)\\.(003e|003E)"), result); + result = mitk::DICOMTagPathToPropertyRegEx(verydeepPath); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertyRegEx() with '(0010,0011)[*].*.(0030,0033).(004c,004d)[4].(0050,0055)'", std::string("DICOM\\.0010\\.0011\\.\\[(\\d*)\\]\\.([A-Fa-f\\d]{4})\\.([A-Fa-f\\d]{4})\\.0030\\.0033\\.(004c|004C)\\.(004d|004D)\\.\\[4\\]\\.0050\\.0055"), result); } - void DICOMTagPathToPersistenceKeyRegEx() { std::string result = mitk::DICOMTagPathToPersistenceKeyRegEx(simplePath); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyRegEx() with '(0010,0010)'", result, std::string("DICOM_0010_0010")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyRegEx() with '(0010,0011)'", std::string("DICOM_0010_0011"), result); result = mitk::DICOMTagPathToPersistenceKeyRegEx(deepPath); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyRegEx() with '(0010,0010).(0020,0022).(0030,0033)'", result, std::string("DICOM_0010_0011_0020_0022_0030_0033")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyRegEx() with '(0010,0011).(0020,0022).(003A,0033)'", std::string("DICOM_0010_0011_0020_0022_(003a|003A)_0033"), result); result = mitk::DICOMTagPathToPersistenceKeyRegEx(deepPath_withAnyElement); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyRegEx() with '(0010,0010).*.(0030,0033)'", result, std::string("DICOM_0010_0011_(\\d{4})_(\\d{4})_0030_0033")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyRegEx() with '(0010,0011).*.(003a,003f)'", std::string("DICOM_0010_0011_([A-Fa-f\\d]{4})_([A-Fa-f\\d]{4})_(003a|003A)_(003f|003F)"), result); result = mitk::DICOMTagPathToPersistenceKeyRegEx(deepPath_withAnySelection); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyRegEx() with '(0010,0010).(0020,0022)[*].(0030,0033)'", result, std::string("DICOM_0010_0011_0020_0022_\\[(\\d*)\\]_0030_0033")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyRegEx() with '(0010,0011).(002B,002E)[*].(0030,0033)'", std::string("DICOM_0010_0011_(002b|002B)_(002e|002E)_\\[(\\d*)\\]_0030_0033"), result); result = mitk::DICOMTagPathToPersistenceKeyRegEx(deepPath_withSelection); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyRegEx() with '(0010,0010).(0020,0022)[6].(0030,0033)'", result, std::string("DICOM_0010_0011_0020_0022_\\[6\\]_0030_0033")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyRegEx() with '(0010,0011).(0020,0022)[6].(003b,003e)'", std::string("DICOM_0010_0011_0020_0022_\\[6\\]_(003b|003B)_(003e|003E)"), result); result = mitk::DICOMTagPathToPersistenceKeyRegEx(verydeepPath); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyRegEx() with '(0010,0010)[*].*.(0030,0033).(0040,0044)[4].(0050,0055)'", result, std::string("DICOM_0010_0011_\\[(\\d*)\\]_(\\d{4})_(\\d{4})_0030_0033_0040_0044_\\[4\\]_0050_0055")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyRegEx() with '(0010,0011)[*].*.(0030,0033).(004c,004d)[4].(0050,0055)'", std::string("DICOM_0010_0011_\\[(\\d*)\\]_([A-Fa-f\\d]{4})_([A-Fa-f\\d]{4})_0030_0033_(004c|004C)_(004d|004D)_\\[4\\]_0050_0055"), result); } void DICOMTagPathToPersistenceKeyTemplate() { std::string result = mitk::DICOMTagPathToPersistenceKeyTemplate(simplePath); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyTemplate() with '(0010,0010)'", result, std::string("DICOM_0010_0010")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyTemplate() with '(0010,0011)'", std::string("DICOM_0010_0011"), result); result = mitk::DICOMTagPathToPersistenceKeyTemplate(deepPath); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyTemplate() with '(0010,0010).(0020,0022).(0030,0033)'", result, std::string("DICOM_0010_0011_0020_0022_0030_0033")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyTemplate() with '(0010,0011).(0020,0022).(003A,0033)'", std::string("DICOM_0010_0011_0020_0022_003A_0033"), result); result = mitk::DICOMTagPathToPersistenceKeyTemplate(deepPath_withAnyElement); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyTemplate() with '(0010,0010).*.(0030,0033)'", result, std::string("DICOM_0010_0011_$1_$2_0030_0033")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyTemplate() with '(0010,0011).*.(003a,003f)'", std::string("DICOM_0010_0011_$1_$2_003A_003F"), result); result = mitk::DICOMTagPathToPersistenceKeyTemplate(deepPath_withAnySelection); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyTemplate() with '(0010,0010).(0020,0022)[*].(0030,0033)'", result, std::string("DICOM_0010_0011_0020_0022_[$1]_0030_0033")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyTemplate() with '(0010,0011).(002B,002E)[*].(0030,0033)'", std::string("DICOM_0010_0011_002B_002E_[$1]_0030_0033"), result); result = mitk::DICOMTagPathToPersistenceKeyTemplate(deepPath_withSelection); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyTemplate() with '(0010,0010).(0020,0022)[6].(0030,0033)'", result, std::string("DICOM_0010_0011_0020_0022_[6]_0030_0033")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyTemplate() with '(0010,0011).(0020,0022)[6].(003b,003e)'", std::string("DICOM_0010_0011_0020_0022_[6]_003B_003E"), result); result = mitk::DICOMTagPathToPersistenceKeyTemplate(verydeepPath); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyTemplate() with '(0010,0010)[*].*.(0030,0033).(0040,0044)[4].(0050,0055)'", result, std::string("DICOM_0010_0011_[$1]_$2_$3_0030_0033_0040_0044_[4]_0050_0055")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceKeyTemplate() with '(0010,0011)[*].*.(0030,0033).(004c,004d)[4].(0050,0055)'", std::string("DICOM_0010_0011_[$1]_$2_$3_0030_0033_004C_004D_[4]_0050_0055"), result); } void DICOMTagPathToPersistenceNameTemplate() { std::string result = mitk::DICOMTagPathToPersistenceNameTemplate(simplePath); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceNameTemplate() with '(0010,0010)'", result, std::string("DICOM.0010.0010")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceNameTemplate() with '(0010,0011)'", std::string("DICOM.0010.0011"), result); result = mitk::DICOMTagPathToPersistenceNameTemplate(deepPath); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceNameTemplate() with '(0010,0010).(0020,0022).(0030,0033)'", result, std::string("DICOM.0010.0011.0020.0022.0030.0033")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceNameTemplate() with '(0010,0011).(0020,0022).(003A,0033)'", std::string("DICOM.0010.0011.0020.0022.003A.0033"), result); result = mitk::DICOMTagPathToPersistenceNameTemplate(deepPath_withAnyElement); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceNameTemplate() with '(0010,0010).*.(0030,0033)'", result, std::string("DICOM.0010.0011.$1.$2.0030.0033")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceNameTemplate() with '(0010,0011).*.(003a,003f)'", std::string("DICOM.0010.0011.$1.$2.003A.003F"), result); result = mitk::DICOMTagPathToPersistenceNameTemplate(deepPath_withAnySelection); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceNameTemplate() with '(0010,0010).(0020,0022)[*].(0030,0033)'", result, std::string("DICOM.0010.0011.0020.0022.[$1].0030.0033")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceNameTemplate() with '(0010,0011).(002B,002E)[*].(0030,0033)'", std::string("DICOM.0010.0011.002B.002E.[$1].0030.0033"), result); result = mitk::DICOMTagPathToPersistenceNameTemplate(deepPath_withSelection); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceNameTemplate() with '(0010,0010).(0020,0022)[6].(0030,0033)'", result, std::string("DICOM.0010.0011.0020.0022.[6].0030.0033")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceNameTemplate() with '(0010,0011).(0020,0022)[6].(003b,003e)'", std::string("DICOM.0010.0011.0020.0022.[6].003B.003E"), result); result = mitk::DICOMTagPathToPersistenceNameTemplate(verydeepPath); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceNameTemplate() with '(0010,0010)[*].*.(0030,0033).(0040,0044)[4].(0050,0055)'", result, std::string("DICOM.0010.0011.[$1].$2.$3.0030.0033.0040.0044.[4].0050.0055")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPersistenceNameTemplate() with '(0010,0011)[*].*.(0030,0033).(004c,004d)[4].(0050,0055)'", std::string("DICOM.0010.0011.[$1].$2.$3.0030.0033.004C.004D.[4].0050.0055"), result); } void DICOMTagPathToDCMTKSearchPath() { std::string result = mitk::DICOMTagPathToDCMTKSearchPath(simplePath); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToDCMTKSearchPath() with '(0010,0010)'", result, std::string("(0010,0010)")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToDCMTKSearchPath() with '(0010,0011)'", std::string("(0010,0011)"), result); result = mitk::DICOMTagPathToDCMTKSearchPath(deepPath); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToDCMTKSearchPath() with '(0010,0011).(0020,0022).(0030,0033)'", result, std::string("(0010,0011).(0020,0022).(0030,0033)")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToDCMTKSearchPath() with '(0010,0011).(0020,0022).(003A,0033)'", std::string("(0010,0011).(0020,0022).(003A,0033)"), result); CPPUNIT_ASSERT_THROW(mitk::DICOMTagPathToDCMTKSearchPath(deepPath_withAnyElement), mitk::Exception); result = mitk::DICOMTagPathToDCMTKSearchPath(deepPath_withAnySelection); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToDCMTKSearchPath() with '(0010,0011).(0020,0022)[*].(0030,0033)'", result, std::string("(0010,0011).(0020,0022)[*].(0030,0033)")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToDCMTKSearchPath() with '(0010,0011).(002B,002E)[*].(0030,0033)'", std::string("(0010,0011).(002B,002E)[*].(0030,0033)"), result); result = mitk::DICOMTagPathToDCMTKSearchPath(deepPath_withSelection); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToDCMTKSearchPath() with '(0010,0011).(0020,0022)[6].(0030,0033)'", result, std::string("(0010,0011).(0020,0022)[6].(0030,0033)")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToDCMTKSearchPath() with '(0010,0011).(0020,0022)[6].(003b,003e)'", std::string("(0010,0011).(0020,0022)[6].(003B,003E)"), result); CPPUNIT_ASSERT_THROW(mitk::DICOMTagPathToDCMTKSearchPath(verydeepPath), mitk::Exception); } void PropertyNameToDICOMTagPath() { - mitk::DICOMTagPath result = mitk::PropertyNameToDICOMTagPath("DICOM.0010.0010"); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing PropertyNameToDICOMTagPath() with '(0010,0010)'", simplePath, result); - result = mitk::PropertyNameToDICOMTagPath("DICOM.0010.0011.0020.0022.0030.0033"); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing PropertyNameToDICOMTagPath() with '(0010,0010).(0020,0022).(0030,0033)'", deepPath, result); - result = mitk::PropertyNameToDICOMTagPath("DICOM.0010.0011.*.0030.0033"); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing PropertyNameToDICOMTagPath() with '(0010,0010).*.(0030,0033)'", deepPath_withAnyElement, result); - result = mitk::PropertyNameToDICOMTagPath("DICOM.0010.0011.0020.0022.[*].0030.0033"); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing PropertyNameToDICOMTagPath() with '(0010,0010).(0020,0022)[*].(0030,0033)'", deepPath_withAnySelection, result); - result = mitk::PropertyNameToDICOMTagPath("DICOM.0010.0011.0020.0022.[6].0030.0033"); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing PropertyNameToDICOMTagPath() with '(0010,0010).(0020,0022)[6].(0030,0033)'", deepPath_withSelection, result); - result = mitk::PropertyNameToDICOMTagPath("DICOM.0010.0011.[*].*.0030.0033.0040.0044.[4].0050.0055"); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing PropertyNameToDICOMTagPath() with '(0010,0010)[*].*.(0030,0033).(0040,0044)[4].(0050,0055)'", verydeepPath, result); + mitk::DICOMTagPath result = mitk::PropertyNameToDICOMTagPath("DICOM.0010.0011"); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing PropertyNameToDICOMTagPath() with '(0010,0011)'", simplePath, result); + result = mitk::PropertyNameToDICOMTagPath("DICOM.0010.0011.0020.0022.003A.0033"); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing PropertyNameToDICOMTagPath() with '(0010,0011).(0020,0022).(003A,0033)'", deepPath, result); + result = mitk::PropertyNameToDICOMTagPath("DICOM.0010.0011.*.003a.003f"); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing PropertyNameToDICOMTagPath() with '(0010,0011).*.(003a,003f)'", deepPath_withAnyElement, result); + result = mitk::PropertyNameToDICOMTagPath("DICOM.0010.0011.002B.002E.[*].0030.0033"); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing PropertyNameToDICOMTagPath() with '(0010,0011).(002B,002E)[*].(0030,0033)'", deepPath_withAnySelection, result); + result = mitk::PropertyNameToDICOMTagPath("DICOM.0010.0011.0020.0022.[6].003b.003e"); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing PropertyNameToDICOMTagPath() with '(0010,0011).(0020,0022)[6].(003b,003e)'", deepPath_withSelection, result); + result = mitk::PropertyNameToDICOMTagPath("DICOM.0010.0011.[*].*.0030.0033.004c.004d.[4].0050.0055"); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing PropertyNameToDICOMTagPath() with '(0010,0011)[*].*.(0030,0033).(004c,004d)[4].(0050,0055)'", verydeepPath, result); result = mitk::PropertyNameToDICOMTagPath("WRONG.0010.0011.0020.0022.0030.0033"); CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing PropertyNameToDICOMTagPath() with wrong path", emptyPath, result); } void DICOMTagPathToPropertyName() { std::string result = mitk::DICOMTagPathToPropertyName(simplePath); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertyName() with '(0010,0010)'", result, std::string("DICOM.0010.0010")); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertyName() with '(0010,0011)'", result, std::string("DICOM.0010.0011")); + result = mitk::DICOMTagPathToPropertyName(deepPath); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertyName() with '(0010,0011).(0020,0022).(003A,0033)'", result, std::string("DICOM.0010.0011.0020.0022.003A.0033")); + result = mitk::DICOMTagPathToPropertyName(deepPath_withAnyElement); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertyName() with '(0010,0011).*.(003a,003f)'", result, std::string("DICOM.0010.0011.*.003A.003F")); + result = mitk::DICOMTagPathToPropertyName(deepPath_withAnySelection); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertyName() with '(0010,0011).(002B,002E)[*].(0030,0033)'", result, std::string("DICOM.0010.0011.002B.002E.[*].0030.0033")); + result = mitk::DICOMTagPathToPropertyName(deepPath_withSelection); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertyName() with '(0010,0011).(0020,0022)[6].(003b,003e)'", result, std::string("DICOM.0010.0011.0020.0022.[6].003B.003E")); + result = mitk::DICOMTagPathToPropertyName(verydeepPath); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertyName() with '(0010,0011)[*].*.(0030,0033).(004c,004d)[4].(0050,0055)'", result, std::string("DICOM.0010.0011.[*].*.0030.0033.004C.004D.[4].0050.0055")); + } + + void ExecutePropertyRegEx() + { + std::regex regEx(mitk::DICOMTagPathToPropertyRegEx(simplePath)); + std::string result = mitk::DICOMTagPathToPropertyName(simplePath); + CPPUNIT_ASSERT(std::regex_match(result, regEx)); + regEx = std::regex(mitk::DICOMTagPathToPropertyRegEx(deepPath)); result = mitk::DICOMTagPathToPropertyName(deepPath); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertyName() with '(0010,0010).(0020,0022).(0030,0033)'", result, std::string("DICOM.0010.0011.0020.0022.0030.0033")); + CPPUNIT_ASSERT(std::regex_match(result, regEx)); + regEx = std::regex(mitk::DICOMTagPathToPropertyRegEx(deepPath_withAnyElement)); result = mitk::DICOMTagPathToPropertyName(deepPath_withAnyElement); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertyName() with '(0010,0010).*.(0030,0033)'", result, std::string("DICOM.0010.0011.*.0030.0033")); + int position = result.find("*"); + if (std::string::npos != position) + { + result.replace(position, 1, "1234.ABCD"); + CPPUNIT_ASSERT(std::regex_match(result, regEx)); + } + regEx = std::regex(mitk::DICOMTagPathToPropertyRegEx(deepPath_withAnySelection)); result = mitk::DICOMTagPathToPropertyName(deepPath_withAnySelection); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertyName() with '(0010,0010).(0020,0022)[*].(0030,0033)'", result, std::string("DICOM.0010.0011.0020.0022.[*].0030.0033")); + position = result.find("[*]"); + if (std::string::npos != position) + { + result.replace(position, 3, "[10]"); + CPPUNIT_ASSERT(std::regex_match(result, regEx)); + } + regEx = std::regex(mitk::DICOMTagPathToPropertyRegEx(deepPath_withSelection)); result = mitk::DICOMTagPathToPropertyName(deepPath_withSelection); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertyName() with '(0010,0010).(0020,0022)[6].(0030,0033)'", result, std::string("DICOM.0010.0011.0020.0022.[6].0030.0033")); + CPPUNIT_ASSERT(std::regex_match(result, regEx)); + regEx = std::regex(mitk::DICOMTagPathToPropertyRegEx(verydeepPath)); result = mitk::DICOMTagPathToPropertyName(verydeepPath); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Testing DICOMTagPathToPropertyName() with '(0010,0010)[*].*.(0030,0033).(0040,0044)[4].(0050,0055)'", result, std::string("DICOM.0010.0011.[*].*.0030.0033.0040.0044.[4].0050.0055")); + position = result.find("[*]"); + if (std::string::npos != position) + { + result.replace(position, 3, "[1]"); + position = result.find("*"); + if (std::string::npos != position) + { + result.replace(position, 1, "abcd.1234"); + CPPUNIT_ASSERT(std::regex_match(result, regEx)); + } + } } }; MITK_TEST_SUITE_REGISTRATION(mitkDICOMTagPath) diff --git a/Modules/DICOMReaderServices/src/mitkDICOMTagsOfInterestService.cpp b/Modules/DICOMReaderServices/src/mitkDICOMTagsOfInterestService.cpp index cf2df109f6..89a786b2a3 100644 --- a/Modules/DICOMReaderServices/src/mitkDICOMTagsOfInterestService.cpp +++ b/Modules/DICOMReaderServices/src/mitkDICOMTagsOfInterestService.cpp @@ -1,184 +1,184 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkDICOMTagsOfInterestService.h" #include "usModuleContext.h" #include "usGetModuleContext.h" #include "mitkIPropertyDescriptions.h" #include "mitkIPropertyPersistence.h" #include "mitkTemporoSpatialStringProperty.h" mitk::IPropertyDescriptions* GetDescriptionsService() { mitk::IPropertyDescriptions* result = nullptr; std::vector > descriptionRegisters = us::GetModuleContext()->GetServiceReferences(); if (!descriptionRegisters.empty()) { if (descriptionRegisters.size() > 1) { MITK_WARN << "Multiple property description services found. Using just one."; } result = us::GetModuleContext()->GetService(descriptionRegisters.front()); } return result; }; mitk::IPropertyPersistence* GetPersistenceService() { mitk::IPropertyPersistence* result = nullptr; std::vector > persRegisters = us::GetModuleContext()->GetServiceReferences(); if (!persRegisters.empty()) { if (persRegisters.size() > 1) { MITK_WARN << "Multiple property description services found. Using just one."; } result = us::GetModuleContext()->GetService(persRegisters.front()); } return result; }; mitk::DICOMTagsOfInterestService:: DICOMTagsOfInterestService() { }; mitk::DICOMTagsOfInterestService:: ~DICOMTagsOfInterestService() { }; void mitk::DICOMTagsOfInterestService:: AddTagOfInterest(const DICOMTagPath& tagPath, bool makePersistant) { if (tagPath.Size() == 0) { MITK_DEBUG << "Indication for wrong DICOMTagsOfInterestService::AddTagOfInterest() usage. Empty DICOM tag path was passed."; return; } MutexHolder lock(m_Lock); - std::string propRegEx = mitk::DICOMTagPathToPropertRegEx(tagPath); + std::string propRegEx = mitk::DICOMTagPathToPropertyRegEx(tagPath); this->m_Tags.insert(tagPath); mitk::IPropertyDescriptions* descriptionSrv = GetDescriptionsService(); if (descriptionSrv) { descriptionSrv->AddDescriptionRegEx(propRegEx, "DICOM tag: " + tagPath.GetLastNode().tag.GetName()); } mitk::IPropertyPersistence* persSrv = GetPersistenceService(); if (persSrv && makePersistant) { PropertyPersistenceInfo::Pointer info = PropertyPersistenceInfo::New(); if (tagPath.IsExplicit()) { std::string name = mitk::DICOMTagPathToPropertyName(tagPath); std::string key = name; std::replace(key.begin(), key.end(), '.', '_'); info->SetNameAndKey(name, key); } else { std::string key = mitk::DICOMTagPathToPersistenceKeyRegEx(tagPath); std::string keyTemplate = mitk::DICOMTagPathToPersistenceKeyTemplate(tagPath); std::string propTemplate = mitk::DICOMTagPathToPersistenceNameTemplate(tagPath); info->UseRegEx(propRegEx, propTemplate, key, keyTemplate); } info->SetDeserializationFunction(mitk::PropertyPersistenceDeserialization::deserializeJSONToTemporoSpatialStringProperty); info->SetSerializationFunction(mitk::PropertyPersistenceSerialization::serializeTemporoSpatialStringPropertyToJSON); persSrv->AddInfo(info); } }; mitk::DICOMTagPathMapType mitk::DICOMTagsOfInterestService:: GetTagsOfInterest() const { MutexHolder lock(m_Lock); DICOMTagPathMapType result; for (auto tag : this->m_Tags) { result.insert(std::make_pair(tag, "")); } return result; }; bool mitk::DICOMTagsOfInterestService:: HasTag(const DICOMTagPath& tag) const { return this->m_Tags.find(tag) != this->m_Tags.cend(); }; void mitk::DICOMTagsOfInterestService:: RemoveTag(const DICOMTagPath& tag) { MutexHolder lock(m_Lock); this->m_Tags.erase(tag); - std::string propRegEx = mitk::DICOMTagPathToPropertRegEx(tag); + std::string propRegEx = mitk::DICOMTagPathToPropertyRegEx(tag); mitk::IPropertyDescriptions* descriptionSrv = GetDescriptionsService(); if (descriptionSrv) { descriptionSrv->RemoveDescription(propRegEx); } mitk::IPropertyPersistence* persSrv = GetPersistenceService(); if (persSrv) { persSrv->RemoveInfo(propRegEx); } }; void mitk::DICOMTagsOfInterestService:: RemoveAllTags() { MutexHolder lock(m_Lock); mitk::IPropertyDescriptions* descriptionSrv = GetDescriptionsService(); mitk::IPropertyPersistence* persSrv = GetPersistenceService(); for (const auto& tag : m_Tags) { - std::string propRegEx = mitk::DICOMTagPathToPropertRegEx(tag); + std::string propRegEx = mitk::DICOMTagPathToPropertyRegEx(tag); if (descriptionSrv) { descriptionSrv->RemoveDescription(propRegEx); } if (persSrv) { persSrv->RemoveInfo(propRegEx); } } this->m_Tags.clear(); };