7 #include "fwGdcmIO/helper/SegmentedPropertyRegistry.hpp" 9 #include "fwGdcmIO/helper/CsvIO.hpp" 10 #include "fwGdcmIO/helper/DicomCodedAttribute.hpp" 12 #include <fwLog/Logger.hpp> 14 #include <boost/filesystem/operations.hpp> 24 {{
"(111176;DCM;Unspecified)",
"(T-D000A;SRT;Anatomical Structure)",
"",
"",
""}};
34 bool checkAndFormatEntry(
const std::string& structureType,
36 const ::fwLog::Logger::sptr& logger)
41 auto checkCondition = [&](
bool condition,
const std::string& msg)
46 if(!condition && logger)
48 logger->critical(msg);
53 checkCondition(!structureType.empty(),
"Structure type of registry entries shall not be empty.");
56 std::string& propertyType = entry[0];
57 checkCondition(!propertyType.empty(),
"Property Type shall not be empty for '" + structureType +
"'.");
58 checkCondition(propertyType.empty() ||
60 "Coded entry is badly formatted : '" + propertyType +
"'. Please check registry.");
63 std::string& propertyCategory = entry[1];
64 checkCondition(!propertyCategory.empty(),
"Property Category shall not be empty for '" + structureType +
"'.");
65 checkCondition(propertyCategory.empty() ||
67 "Coded entry is badly formatted : '" + propertyCategory +
"'. Please check registry.");
70 std::string& propertyTypeModifiers = entry[2];
71 checkCondition(propertyTypeModifiers.empty() ||
73 "Coded entry is badly formatted : '" + propertyTypeModifiers +
"'. Please check registry.");
76 std::string& anatomicRegion = entry[3];
77 checkCondition(propertyCategory !=
"(M-01000;SRT;Morphologically Altered Structure)" || !anatomicRegion.empty(),
78 "Anatomic Region shall not be empty for altered structures. See '" + structureType +
"'.");
79 checkCondition(anatomicRegion.empty() ||
81 "Coded entry is badly formatted : '" + anatomicRegion +
"'. Please check registry.");
84 std::string& anatomicRegionModifiers = entry[4];
85 checkCondition(anatomicRegionModifiers.empty() ||
87 "Coded entry is badly formatted : '" + anatomicRegionModifiers +
"'. Please check registry.");
96 const ::fwLog::Logger::sptr& logger)
98 const std::string filepathStr = filepath.string();
99 if(::boost::filesystem::exists(filepath))
101 std::ifstream csvStream(filepathStr);
111 const ::fwLog::Logger::sptr& logger)
118 const std::string separator =
"|";
119 auto tokens = reader.
getLine(separator);
124 tokens = reader.
getLine(separator);
127 while(!tokens.empty())
129 const std::string structureType = tokens[0];
131 if(tokens.size() >= 6)
134 std::copy_n(tokens.begin()+1, 5, entry.begin());
135 if(checkAndFormatEntry(structureType, entry, logger))
137 m_registry[structureType] = entry;
146 logger->critical(
"Entry badly formatted for structure '" + structureType +
"'.");
150 tokens = reader.
getLine(separator);
154 std::set< EntryType > uniquenessSet;
155 for(
const auto& entry : m_registry)
157 if(uniquenessSet.find(entry.second) != uniquenessSet.end())
159 const std::string msg =
"Several structure types have the same attribute combination : {" +
160 entry.second[0] +
";" +
161 entry.second[1] +
";" +
162 entry.second[2] +
";" +
163 entry.second[3] +
";" +
164 entry.second[4] +
"}";
169 logger->critical(msg);
175 uniquenessSet.insert(entry.second);
187 return m_registry.empty();
194 return m_registry.size();
208 return m_registry.find(structureType) != m_registry.end();
215 const auto it = m_registry.find(structureType);
216 if(it != m_registry.end())
220 return s_DEFAULT_ENTRY_VALUE;
225 #define GET_ENTRY_VALUE(index) \ 226 const auto it = m_registry.find(structureType); \ 227 if(it != m_registry.end()) \ 229 return it->second[index]; \ 231 return s_DEFAULT_ENTRY_VALUE[index]; 268 #undef GET_ENTRY_VALUE 273 const std::string& propertyCategory,
274 const std::string& propertyTypeModifiers,
275 const std::string& anatomicRegion,
276 const std::string& anatomicRegionModifiers)
const 281 propertyTypeModifiers,
283 anatomicRegionModifiers }};
286 const auto predicate = [&](
const EntryRegistryType::value_type& value) ->
bool 288 return value.second == entry;
292 const auto it = std::find_if(m_registry.begin(), m_registry.end(), predicate);
294 return (it != m_registry.end()) ? it->first :
"";
FWGDCMIO_API std::string getPropertyCategory(const std::string &structureType) const
Getters for entry's attributes.
FWGDCMIO_API TokenContainerType getLine(const std::string &separator=",")
Returns tokens on next line to read, using comma separator.
FWGDCMIO_API std::string getPropertyType(const std::string &structureType) const
Getters for entry's attributes.
The namespace fwGdcmIO contains reader, writer and helper for dicom data.
FWGDCMIO_API EntryType getEntry(const std::string &structureType) const
Returns matching entry for the corresponding structure type.
FWGDCMIO_API std::string getPropertyTypeModifiers(const std::string &structureType) const
Getters for entry's attributes.
FWGDCMIO_API std::string getAnatomicRegion(const std::string &structureType) const
Getters for entry's attributes.
FWGDCMIO_API SegmentedPropertyRegistry()
Constructor.
static FWGDCMIO_API bool checkAndFormatEntry(std::string &entry, bool multipleValue=false)
Retrieve '(AAA;BBB;CCC)' patterns inside of the entry string. Remove spaces or other characters that ...
FWGDCMIO_API bool empty() const
Returns whether the registry is empty or not.
#define SLM_ERROR_IF(message, cond)
FWGDCMIO_API std::string getStructureType(const std::string &propertyType, const std::string &propertyCategory, const std::string &propertyTypeModifiers, const std::string &anatomicRegion, const std::string &anatomicRegionModifiers) const
Returns the structure type associated to the attribute list. If no match is found, it returns an empty string.
FWGDCMIO_API std::string getAnatomicRegionModifiers(const std::string &structureType) const
Getters for entry's attributes.
FWGDCMIO_API void clear()
Clear the registry.
FWGDCMIO_API bool readSegmentedPropertyRegistryFile(const ::boost::filesystem::path &filepath, bool omitFirstLine=false, const std::shared_ptr< ::fwLog::Logger > &logger=0)
Read an extract registry values from a CSV file Each lines shall contain at least 6 elements : ...
Read CSV file and returns parsed tokens. The input file is supposed to use comma separator, but another separator can be used when reading file.
FWGDCMIO_API std::size_t count() const
Returns the number of entries.
std::array< std::string, 5 > EntryType
Entry containing the 5 attributes of a structure type.
FWGDCMIO_API bool hasEntry(const std::string &structureType) const
Check if there is an entry for the corresponding structure type.