diff --git a/Modules/Core/Common/include/itkAnatomicalOrientation.h b/Modules/Core/Common/include/itkAnatomicalOrientation.h new file mode 100644 index 00000000000..b3678a2bf4a --- /dev/null +++ b/Modules/Core/Common/include/itkAnatomicalOrientation.h @@ -0,0 +1,584 @@ +/*========================================================================= + * + * Copyright NumFOCUS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ +#ifndef itkAnatomicalOrientation_h +#define itkAnatomicalOrientation_h + +#include "ITKCommonExport.h" +#include "itkImageBase.h" +#ifndef ITK_FUTURE_LEGACY_REMOVE +# include "itkSpatialOrientation.h" +#endif +#include +#include + +namespace itk +{ + +/** \class AnatomicalOrientation + * \brief Representations of anatomical orientations and methods to convert between conventions. + * + * Defines patient specific anatomical names to the XYZ axes of a 3D image. + * + * A class instances holds the patient orientation stored as an enumerated type. Conversion to different representations + * such as strings and direction cosine matrices are supported. + * + * The use of unambiguous anatomical orientation names such as "RightToLeft" is preferred, where "Right" is the + * "from direction" and the negative direction of the coordinates, while "Left" is the "to direction" and the positive + * direction. The following is an unambiguous construction of an AnatomicalOrientation object: + * + * \code + * AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::RightToLeft, + * AnatomicalOrientation::CoordinateEnum::AnteriorToPosterior, + * AnatomicalOrientation::CoordinateEnum::InferiorToSuperior); + * \endcode + * + * + * \ingroup ITKCommon + */ +class ITKCommon_EXPORT AnatomicalOrientation +{ +public: + static constexpr unsigned int Dimension = 3; + using DirectionType = typename ImageBase::DirectionType; + static constexpr unsigned int ImageDimension = Dimension; + +#ifndef ITK_FUTURE_LEGACY_REMOVE + using LegacyOrientationType = SpatialOrientationEnums::ValidCoordinateOrientations; +#endif + + // Anatomical names for an axis. + // + enum class CoordinateEnum : uint8_t + { + UNKNOWN = 0, + RightToLeft = 2, ///< 0b0010 + LeftToRight = 3, + PosteriorToAnterior = 4, ///< to front - 0b0100 + AnteriorToPosterior = 5, ///< to back + InferiorToSuperior = 8, ///< to head - 0b1000 + SuperiorToInferior = 9, ///< to foot + }; + +protected: + enum class CoordinateMajornessTermsEnum : uint8_t + { + PrimaryMinor = 0, + SecondaryMinor = 8, + TertiaryMinor = 16 + }; + + template + static constexpr uint32_t m_OrientationValue = + (static_cast(VPrimary) << static_cast(CoordinateMajornessTermsEnum::PrimaryMinor)) + + (static_cast(VSecondary) << static_cast(CoordinateMajornessTermsEnum::SecondaryMinor)) + + (static_cast(VTertiary) << static_cast(CoordinateMajornessTermsEnum::TertiaryMinor)); + + CoordinateEnum + GetCoordinateTerm(CoordinateMajornessTermsEnum cmt) const; + +public: + // Enumerated acronyms based on the positive or "To" direction of the anatomical coordinates. + enum class PositiveEnum : uint32_t + + { + INVALID = 0, + + RIP = m_OrientationValue, + LIP = m_OrientationValue, + RSP = m_OrientationValue, + LSP = m_OrientationValue, + RIA = m_OrientationValue, + LIA = m_OrientationValue, + RSA = m_OrientationValue, + LSA = m_OrientationValue, + + IRP = m_OrientationValue, + ILP = m_OrientationValue, + SRP = m_OrientationValue, + SLP = m_OrientationValue, + IRA = m_OrientationValue, + ILA = m_OrientationValue, + SRA = m_OrientationValue, + SLA = m_OrientationValue, + + RPI = m_OrientationValue, + LPI = m_OrientationValue, + RAI = m_OrientationValue, + LAI = m_OrientationValue, + RPS = m_OrientationValue, + LPS = m_OrientationValue, + RAS = m_OrientationValue, + LAS = m_OrientationValue, + + PRI = m_OrientationValue, + PLI = m_OrientationValue, + ARI = m_OrientationValue, + ALI = m_OrientationValue, + PRS = m_OrientationValue, + PLS = m_OrientationValue, + ARS = m_OrientationValue, + ALS = m_OrientationValue, + + IPR = m_OrientationValue, + SPR = m_OrientationValue, + IAR = m_OrientationValue, + SAR = m_OrientationValue, + IPL = m_OrientationValue, + SPL = m_OrientationValue, + IAL = m_OrientationValue, + SAL = m_OrientationValue, + + PIR = m_OrientationValue, + PSR = m_OrientationValue, + AIR = m_OrientationValue, + ASR = m_OrientationValue, + PIL = m_OrientationValue, + PSL = m_OrientationValue, + AIL = m_OrientationValue, + ASL = m_OrientationValue + }; + + // Enumerated acronyms based on the negative or "From" direction of the anatomical coordinates. + enum class NegativeEnum : uint32_t + + { + INVALID = 0, + + RIP = m_OrientationValue, + LIP = m_OrientationValue, + RSP = m_OrientationValue, + LSP = m_OrientationValue, + RIA = m_OrientationValue, + LIA = m_OrientationValue, + RSA = m_OrientationValue, + LSA = m_OrientationValue, + + IRP = m_OrientationValue, + ILP = m_OrientationValue, + SRP = m_OrientationValue, + SLP = m_OrientationValue, + IRA = m_OrientationValue, + ILA = m_OrientationValue, + SRA = m_OrientationValue, + SLA = m_OrientationValue, + + RPI = m_OrientationValue, + LPI = m_OrientationValue, + RAI = m_OrientationValue, + LAI = m_OrientationValue, + RPS = m_OrientationValue, + LPS = m_OrientationValue, + RAS = m_OrientationValue, + LAS = m_OrientationValue, + + PRI = m_OrientationValue, + PLI = m_OrientationValue, + ARI = m_OrientationValue, + ALI = m_OrientationValue, + PRS = m_OrientationValue, + PLS = m_OrientationValue, + ARS = m_OrientationValue, + ALS = m_OrientationValue, + + IPR = m_OrientationValue, + SPR = m_OrientationValue, + IAR = m_OrientationValue, + SAR = m_OrientationValue, + IPL = m_OrientationValue, + SPL = m_OrientationValue, + IAL = m_OrientationValue, + SAL = m_OrientationValue, + + PIR = m_OrientationValue, + PSR = m_OrientationValue, + AIR = m_OrientationValue, + ASR = m_OrientationValue, + PIL = m_OrientationValue, + PSL = m_OrientationValue, + AIL = m_OrientationValue, + ASL = m_OrientationValue + + }; + + + /** \brief Initialize with CoordinateEnum's from separate axes. + * + * If multiple CoordinateEnums are from the same axes then the Orientation value is INVALID. + */ + constexpr AnatomicalOrientation(CoordinateEnum primary, CoordinateEnum secondary, CoordinateEnum tertiary) + : m_Value( + SameOrientationAxes(primary, secondary) || SameOrientationAxes(primary, tertiary) || + SameOrientationAxes(secondary, tertiary) + ? PositiveEnum::INVALID + : static_cast( + (static_cast(primary) << static_cast(CoordinateMajornessTermsEnum::PrimaryMinor)) + + (static_cast(secondary) << static_cast(CoordinateMajornessTermsEnum::SecondaryMinor)) + + (static_cast(tertiary) << static_cast(CoordinateMajornessTermsEnum::TertiaryMinor)))) + {} + + + constexpr AnatomicalOrientation(PositiveEnum toOrientation) + : m_Value(toOrientation) + {} + + + constexpr AnatomicalOrientation(NegativeEnum fromOrientation) + : m_Value(PositiveEnum(static_cast(fromOrientation))) + {} + +#ifndef ITK_FUTURE_LEGACY_REMOVE + /** \brief Conversion from Legacy SpatialOrientation + * + * @param legacyOrientation + */ +# if defined(ITK_LEGACY_REMOVE) && !defined(ITK_LEGACY_SILENT) + [[deprecated("Use the AnatomicalOrientation::FromEnum type instead.")]] +# endif + AnatomicalOrientation(LegacyOrientationType legacyOrientation); +#endif + + /** Conversion for a Direction Cosine Matrix to the closest anatomical orientation. Any partial axis rotations are + * rounded to the nearest axis, and lost in this conversion. + */ + explicit AnatomicalOrientation(const DirectionType & d) + : m_Value(ConvertDirectionToPositiveEnum(d)) + {} + + /** Creates a AnatomicalOrientation from a string with the PositiveEnum encoding. The string is case-insensitive. If + * the string is not a valid encoding then the orientation is set to INVALID. + */ + static AnatomicalOrientation + CreateFromPositiveStringEncoding(std::string str); + + // Same as CreateFromPositiveStringEncoding but for the NegativeEnum encoding. + static AnatomicalOrientation + CreateFromNegativeStringEncoding(std::string str); + + operator PositiveEnum() const { return m_Value; } + + /** Returns the PositiveEnum encoding as a string. The string is always upper case. */ + std::string + GetAsPositiveStringEncoding() const; + + /** Returns the NegativeEnum encoding as a string. The string is always upper case. */ + std::string + GetAsNegativeStringEncoding() const; + + /** An involution to convert between "positive" and "negative" single character encoding strings. + * + * For example the string "RAS" is converted to "LPI" and vice versa. + * + * The input maybe upper or lower case, while the output is always upper case. + * There is no check that the input is a valid encoding. + * + * */ + static std::string + ConvertStringEncoding(std::string str); + + /** \brief Return the direction cosine matrix for the orientation. */ + DirectionType + GetAsDirection() const + { + return ConvertPositiveEnumToDirection(m_Value); + } + + PositiveEnum + GetAsPositiveOrientation() const + { + return m_Value; + } + + NegativeEnum + GetAsNegativeOrientation() const + { + return NegativeEnum(uint32_t(this->m_Value)); + } + + CoordinateEnum + GetPrimaryTerm() const + { + return GetCoordinateTerm(CoordinateMajornessTermsEnum::PrimaryMinor); + } + + CoordinateEnum + GetSecondaryTerm() const + { + return GetCoordinateTerm(CoordinateMajornessTermsEnum::SecondaryMinor); + } + + CoordinateEnum + GetTertiaryTerm() const + { + return GetCoordinateTerm(CoordinateMajornessTermsEnum::TertiaryMinor); + } + + std::array + GetTerms() const + { + return { GetPrimaryTerm(), GetSecondaryTerm(), GetTertiaryTerm() }; + } + + static constexpr bool + SameOrientationAxes(CoordinateEnum a, CoordinateEnum b) + { + const uint8_t AxisField = ~1; // mask the lowest bit + return (static_cast(a) & AxisField) == (static_cast(b) & AxisField); + } + + + friend ITKCommon_EXPORT std::ostream & + operator<<(std::ostream & out, PositiveEnum value); + +protected: + /** \brief Return the direction cosine matrix for a orientation. */ + static DirectionType ConvertPositiveEnumToDirection(PositiveEnum); + + + /** \brief Return the closest orientation for a direction cosine matrix. */ + static PositiveEnum + ConvertDirectionToPositiveEnum(const DirectionType & dir); + + + /** \brief Return the global instance of the map from orientation enum to strings. + * + * The implementation uses a function static local variable so the global is created only if needed, only once. + */ + static const std::map & + GetCodeToString(); + + /** \brief Return the global instance of the map from string to orientation enum. + */ + static const std::map & + GetStringToCode(); + + PositiveEnum m_Value; +}; + +/** Outputs unambiguous anatomical orientation names such as "right-to-left". */ +ITKCommon_EXPORT std::ostream & + operator<<(std::ostream & out, typename AnatomicalOrientation::CoordinateEnum value); + +/** Outputs the PositiveEnum encoding as a string such as "LPS". */ +ITKCommon_EXPORT std::ostream & + operator<<(std::ostream & out, typename AnatomicalOrientation::PositiveEnum value); + + +/** Outputs the NegativeEnum encoding as a string such as "RAI" */ +ITKCommon_EXPORT std::ostream & + operator<<(std::ostream & out, typename AnatomicalOrientation::NegativeEnum value); + +ITKCommon_EXPORT std::ostream & + operator<<(std::ostream & out, const AnatomicalOrientation & orientation); + + +} // end namespace itk + + +#endif diff --git a/Modules/Core/Common/src/CMakeLists.txt b/Modules/Core/Common/src/CMakeLists.txt index 74f031b08d1..8c018b33814 100644 --- a/Modules/Core/Common/src/CMakeLists.txt +++ b/Modules/Core/Common/src/CMakeLists.txt @@ -145,7 +145,9 @@ set(ITKCommon_SRCS itkFrustumSpatialFunction.cxx itkObjectStore.cxx itkGaussianDerivativeOperator.cxx - itkSpatialOrientation.cxx) + itkSpatialOrientation.cxx + itkAnatomicalOrientation.cxx +) if(WIN32) list(APPEND ITKCommon_SRCS itkWin32OutputWindow.cxx) diff --git a/Modules/Core/Common/src/itkAnatomicalOrientation.cxx b/Modules/Core/Common/src/itkAnatomicalOrientation.cxx new file mode 100644 index 00000000000..ab13b29c870 --- /dev/null +++ b/Modules/Core/Common/src/itkAnatomicalOrientation.cxx @@ -0,0 +1,328 @@ +/*========================================================================= + * + * Copyright NumFOCUS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ +#include "itkAnatomicalOrientation.h" +#ifndef ITK_FUTURE_LEGACY_REMOVE +# include "itkSpatialOrientationAdapter.h" +#endif + +namespace itk +{ + + +#ifndef ITK_FUTURE_LEGACY_REMOVE +AnatomicalOrientation::AnatomicalOrientation(LegacyOrientationType legacyOrientation) + : AnatomicalOrientation(SpatialOrientationAdapter().ToDirectionCosines(legacyOrientation)) +{ + assert(uint32_t(legacyOrientation) == uint32_t(m_Value)); +} +#endif + + +std::string +AnatomicalOrientation::GetAsPositiveStringEncoding() const +{ + + // a lambda function to convert a CoordinateEnum to a char + auto enumAsChar = [](CoordinateEnum coord) -> char { + switch (coord) + { + case CoordinateEnum::RightToLeft: + return 'L'; + case CoordinateEnum::LeftToRight: + return 'R'; + case CoordinateEnum::AnteriorToPosterior: + return 'P'; + case CoordinateEnum::PosteriorToAnterior: + return 'A'; + case CoordinateEnum::InferiorToSuperior: + return 'S'; + case CoordinateEnum::SuperiorToInferior: + return 'I'; + default: + return 'X'; + } + }; + + if (m_Value == PositiveEnum::INVALID) + { + return "INVALID"; + } + + return std::string({ enumAsChar(GetPrimaryTerm()), enumAsChar(GetSecondaryTerm()), enumAsChar(GetTertiaryTerm()) }); +} + + +std::string +AnatomicalOrientation::GetAsNegativeStringEncoding() const +{ + return ConvertStringEncoding(GetAsPositiveStringEncoding()); +} + + +AnatomicalOrientation +AnatomicalOrientation::CreateFromPositiveStringEncoding(std::string str) +{ + std::transform(str.begin(), str.end(), str.begin(), ::toupper); + + const std::map & stringToCode = GetStringToCode(); + auto iter = stringToCode.find(str); + if (iter == stringToCode.end()) + { + return AnatomicalOrientation(PositiveEnum::INVALID); + } + return AnatomicalOrientation(iter->second); +} + +AnatomicalOrientation +AnatomicalOrientation::CreateFromNegativeStringEncoding(std::string str) +{ + return AnatomicalOrientation::CreateFromPositiveStringEncoding(ConvertStringEncoding(str)); +} + + +std::string +AnatomicalOrientation::ConvertStringEncoding(std::string str) +{ + + auto flip = [](char c) -> char { + switch (::toupper(c)) + { + case 'R': + return 'L'; + case 'L': + return 'R'; + case 'A': + return 'P'; + case 'P': + return 'A'; + case 'S': + return 'I'; + case 'I': + return 'S'; + case 'X': + return 'X'; + default: + return c; + } + }; + + for (auto & c : str) + { + c = flip(c); + } + return str; +} + + +AnatomicalOrientation::CoordinateEnum +AnatomicalOrientation::GetCoordinateTerm(CoordinateMajornessTermsEnum cmt) const +{ + return static_cast(static_cast(m_Value) >> static_cast(cmt) & 0xff); +} + + +const std::map & +AnatomicalOrientation::GetCodeToString() +{ + auto createCodeToString = []() -> std::map { + std::map orientToString; + + for (auto code : { PositiveEnum::RIP, PositiveEnum::LIP, PositiveEnum::RSP, PositiveEnum::LSP, PositiveEnum::RIA, + PositiveEnum::LIA, PositiveEnum::RSA, PositiveEnum::LSA, PositiveEnum::IRP, PositiveEnum::ILP, + PositiveEnum::SRP, PositiveEnum::SLP, PositiveEnum::IRA, PositiveEnum::ILA, PositiveEnum::SRA, + PositiveEnum::SLA, PositiveEnum::RPI, PositiveEnum::LPI, PositiveEnum::RAI, PositiveEnum::LAI, + PositiveEnum::RPS, PositiveEnum::LPS, PositiveEnum::RAS, PositiveEnum::LAS, PositiveEnum::PRI, + PositiveEnum::PLI, PositiveEnum::ARI, PositiveEnum::ALI, PositiveEnum::PRS, PositiveEnum::PLS, + PositiveEnum::ARS, PositiveEnum::ALS, PositiveEnum::IPR, PositiveEnum::SPR, PositiveEnum::IAR, + PositiveEnum::SAR, PositiveEnum::IPL, PositiveEnum::SPL, PositiveEnum::IAL, PositiveEnum::SAL, + PositiveEnum::PIR, PositiveEnum::PSR, PositiveEnum::AIR, PositiveEnum::ASR, PositiveEnum::PIL, + PositiveEnum::PSL, PositiveEnum::AIL, PositiveEnum::ASL, PositiveEnum::INVALID }) + { + orientToString[code] = AnatomicalOrientation(code).GetAsPositiveStringEncoding(); + } + + return orientToString; + }; + static const std::map codeToString = createCodeToString(); + return codeToString; +} + +const std::map & +AnatomicalOrientation::GetStringToCode() +{ + + auto createStringToCode = []() -> std::map { + std::map stringToCode; + const std::map & codeToString = GetCodeToString(); + + for (const auto & kv : codeToString) + { + stringToCode[kv.second] = kv.first; + } + return stringToCode; + }; + + static const std::map stringToCode = createStringToCode(); + return stringToCode; +} + + +AnatomicalOrientation::PositiveEnum +AnatomicalOrientation::ConvertDirectionToPositiveEnum(const DirectionType & dir) +{ + // NOTE: This method was based off of itk::SpatialObjectAdaptor::FromDirectionCosines + // but it is DIFFERENT in the meaning of direction in terms of sign-ness. + CoordinateEnum terms[3] = { CoordinateEnum::UNKNOWN, CoordinateEnum::UNKNOWN, CoordinateEnum::UNKNOWN }; + + std::multimap> value_to_idx; + for (unsigned int c = 0; c < 3; ++c) + { + for (unsigned int r = 0; r < 3; ++r) + { + value_to_idx.emplace(std::abs(dir[c][r]), std::make_pair(c, r)); + } + } + + for (unsigned i = 0; i < 3; ++i) + { + + auto max_idx = value_to_idx.rbegin()->second; + const unsigned int max_c = max_idx.first; + const unsigned int max_r = max_idx.second; + + const int max_sgn = Math::sgn(dir[max_c][max_r]); + + for (auto it = value_to_idx.begin(); it != value_to_idx.end();) + { + if (it->second.first == max_c || it->second.second == max_r) + { + value_to_idx.erase(it++); + } + else + { + ++it; + } + } + + switch (max_c) + { + case 0: + { + // When the dominant axis sign is positive, assign the coordinate for the direction we are increasing towards. + // ITK is in LPS, so that is the positive direction + terms[max_r] = (max_sgn == 1) ? CoordinateEnum::RightToLeft : CoordinateEnum::LeftToRight; + break; + } + case 1: + { + terms[max_r] = (max_sgn == 1) ? CoordinateEnum::AnteriorToPosterior : CoordinateEnum::PosteriorToAnterior; + break; + } + case 2: + { + terms[max_r] = (max_sgn == 1) ? CoordinateEnum::InferiorToSuperior : CoordinateEnum::SuperiorToInferior; + break; + } + default: + itkGenericExceptionMacro("Unexpected Axis"); + } + } + + return AnatomicalOrientation(terms[0], terms[1], terms[2]); +} + + +typename AnatomicalOrientation::DirectionType +AnatomicalOrientation::ConvertPositiveEnumToDirection(PositiveEnum orientationEnum) +{ + const AnatomicalOrientation o(orientationEnum); + + CoordinateEnum terms[Dimension] = { o.GetPrimaryTerm(), o.GetSecondaryTerm(), o.GetTertiaryTerm() }; + DirectionType direction; + direction.Fill(0.0); + + for (unsigned int i = 0; i < Dimension; ++i) + { + const int sign = (static_cast(terms[i]) & 0x1) ? 1 : -1; + + switch (terms[i]) + { + case CoordinateEnum::LeftToRight: + case CoordinateEnum::RightToLeft: + direction[0][i] = -1 * sign; + break; + case CoordinateEnum::AnteriorToPosterior: + case CoordinateEnum::PosteriorToAnterior: + direction[1][i] = 1 * sign; + break; + case CoordinateEnum::InferiorToSuperior: + case CoordinateEnum::SuperiorToInferior: + direction[2][i] = -1 * sign; + break; + case CoordinateEnum::UNKNOWN: + break; + } + } + return direction; +} + +std::ostream & +operator<<(std::ostream & out, typename AnatomicalOrientation::CoordinateEnum value) +{ + switch (value) + { + case AnatomicalOrientation::CoordinateEnum::RightToLeft: + return out << "right-to-left"; + case AnatomicalOrientation::CoordinateEnum::LeftToRight: + return out << "left-to-right"; + case AnatomicalOrientation::CoordinateEnum::AnteriorToPosterior: + return out << "anterior-to-posterior"; + case AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior: + return out << "posterior-to-anterior"; + case AnatomicalOrientation::CoordinateEnum::InferiorToSuperior: + return out << "inferior-to-superior"; + case AnatomicalOrientation::CoordinateEnum::SuperiorToInferior: + return out << "superior-to-inferior"; + case AnatomicalOrientation::CoordinateEnum::UNKNOWN: + return out << "unknown"; + default: + return out << "invalid"; + } +} + +std::ostream & +operator<<(std::ostream & out, typename AnatomicalOrientation::PositiveEnum value) +{ + return (out << AnatomicalOrientation(value).GetAsPositiveStringEncoding()); +} + +std::ostream & +operator<<(std::ostream & out, typename AnatomicalOrientation::NegativeEnum value) +{ + return (out << AnatomicalOrientation(value).GetAsNegativeStringEncoding()); +} + +std::ostream & +operator<<(std::ostream & out, const AnatomicalOrientation & orientation) +{ + const auto terms = orientation.GetTerms(); + static_assert(std::tuple_size{} == 3); + return out << terms[0] << " " << terms[1] << " " << terms[2]; +} + +} // namespace itk diff --git a/Modules/Core/Common/test/CMakeLists.txt b/Modules/Core/Common/test/CMakeLists.txt index 461b2f96ed7..1bca0535242 100644 --- a/Modules/Core/Common/test/CMakeLists.txt +++ b/Modules/Core/Common/test/CMakeLists.txt @@ -1760,7 +1760,9 @@ set(ITKCommonGTests itkWeakPointerGTest.cxx itkCommonTypeTraitsGTest.cxx itkMetaDataDictionaryGTest.cxx - itkSpatialOrientationAdaptorGTest.cxx) + itkSpatialOrientationAdaptorGTest.cxx + itkAnatomicalOrientationGTest.cxx +) creategoogletestdriver(ITKCommon "${ITKCommon-Test_LIBRARIES}" "${ITKCommonGTests}") # If `-static` was passed to CMAKE_EXE_LINKER_FLAGS, compilation fails. No need to # test this case. diff --git a/Modules/Core/Common/test/itkAnatomicalOrientationGTest.cxx b/Modules/Core/Common/test/itkAnatomicalOrientationGTest.cxx new file mode 100644 index 00000000000..f09b5fcf0e8 --- /dev/null +++ b/Modules/Core/Common/test/itkAnatomicalOrientationGTest.cxx @@ -0,0 +1,269 @@ +/*========================================================================= + * + * Copyright NumFOCUS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *=========================================================================*/ + +#include + +#include "itkGTest.h" +#ifndef ITK_FUTURE_LEGACY_REMOVE +# define ITK_LEGACY_SILENT +#endif +#include "itkAnatomicalOrientation.h" +#include "itkImage.h" +#include + + +TEST(AnatomicalOrientation, ConstructionAndValues) +{ + using itk::AnatomicalOrientation; + using OE = AnatomicalOrientation::PositiveEnum; + using NOE = AnatomicalOrientation::NegativeEnum; + using CE = AnatomicalOrientation::CoordinateEnum; + using ImageType = itk::Image; + + ImageType::DirectionType d; + + AnatomicalOrientation do1(OE::LPS); + + EXPECT_EQ("LPS", do1.GetAsPositiveStringEncoding()); + EXPECT_EQ(CE::RightToLeft, do1.GetPrimaryTerm()); + EXPECT_EQ(CE::AnteriorToPosterior, do1.GetSecondaryTerm()); + EXPECT_EQ(CE::InferiorToSuperior, do1.GetTertiaryTerm()); + EXPECT_EQ(OE::LPS, do1.GetAsPositiveOrientation()); + EXPECT_EQ(NOE::RAI, do1.GetAsNegativeOrientation()); + + d.SetIdentity(); + EXPECT_EQ(d, do1.GetAsDirection()); + + + do1 = AnatomicalOrientation::CreateFromPositiveStringEncoding("RAS"); + + EXPECT_EQ("RAS", do1.GetAsPositiveStringEncoding()); + EXPECT_EQ(CE::LeftToRight, do1.GetPrimaryTerm()); + EXPECT_EQ(CE::PosteriorToAnterior, do1.GetSecondaryTerm()); + EXPECT_EQ(CE::InferiorToSuperior, do1.GetTertiaryTerm()); + EXPECT_EQ(OE::RAS, do1.GetAsPositiveOrientation()); + EXPECT_EQ(NOE::LPI, do1.GetAsNegativeOrientation()); + + d.Fill(0.0); + d(0, 0) = -1.0; + d(1, 1) = -1.0; + d(2, 2) = 1.0; + EXPECT_EQ(d, do1.GetAsDirection()); + + + do1 = AnatomicalOrientation::CreateFromPositiveStringEncoding("rai"); + + EXPECT_EQ("RAI", do1.GetAsPositiveStringEncoding()); + EXPECT_EQ(CE::LeftToRight, do1.GetPrimaryTerm()); + EXPECT_EQ(CE::PosteriorToAnterior, do1.GetSecondaryTerm()); + EXPECT_EQ(CE::SuperiorToInferior, do1.GetTertiaryTerm()); + EXPECT_EQ(OE::RAI, do1.GetAsPositiveOrientation()); + EXPECT_EQ(NOE::LPS, do1.GetAsNegativeOrientation()); + + + do1 = AnatomicalOrientation::CreateFromNegativeStringEncoding("LPI"); + + EXPECT_EQ("RAS", do1.GetAsPositiveStringEncoding()); + EXPECT_EQ("LPI", do1.GetAsNegativeStringEncoding()); + EXPECT_EQ(CE::LeftToRight, do1.GetPrimaryTerm()); + EXPECT_EQ(CE::PosteriorToAnterior, do1.GetSecondaryTerm()); + EXPECT_EQ(CE::InferiorToSuperior, do1.GetTertiaryTerm()); + EXPECT_EQ(OE::RAS, do1.GetAsPositiveOrientation()); + EXPECT_EQ(NOE::LPI, do1.GetAsNegativeOrientation()); + + do1 = AnatomicalOrientation(OE::PIR); + + EXPECT_EQ("PIR", do1.GetAsPositiveStringEncoding()); + EXPECT_EQ(CE::AnteriorToPosterior, do1.GetPrimaryTerm()); + EXPECT_EQ(CE::SuperiorToInferior, do1.GetSecondaryTerm()); + EXPECT_EQ(CE::LeftToRight, do1.GetTertiaryTerm()); + EXPECT_EQ(OE::PIR, do1.GetAsPositiveOrientation()); + EXPECT_EQ(NOE::ASL, do1.GetAsNegativeOrientation()); + + d.Fill(0.0); + d(1, 0) = 1.0; + d(2, 1) = -1.0; + d(0, 2) = -1.0; + EXPECT_EQ(d, do1.GetAsDirection()); + + AnatomicalOrientation do2(d); + + EXPECT_EQ("PIR", do2.GetAsPositiveStringEncoding()); + EXPECT_EQ(CE::AnteriorToPosterior, do2.GetPrimaryTerm()); + EXPECT_EQ(CE::SuperiorToInferior, do2.GetSecondaryTerm()); + EXPECT_EQ(CE::LeftToRight, do2.GetTertiaryTerm()); + EXPECT_EQ(OE::PIR, do2.GetAsPositiveOrientation()); + EXPECT_EQ(NOE::ASL, do2.GetAsNegativeOrientation()); + + EXPECT_EQ(d, do2.GetAsDirection()); + + AnatomicalOrientation do3 = AnatomicalOrientation::CreateFromPositiveStringEncoding("something invalid"); + EXPECT_EQ("INVALID", do3.GetAsPositiveStringEncoding()); + EXPECT_EQ(CE::UNKNOWN, do3.GetPrimaryTerm()); + EXPECT_EQ(CE::UNKNOWN, do3.GetSecondaryTerm()); + EXPECT_EQ(CE::UNKNOWN, do3.GetTertiaryTerm()); + EXPECT_EQ(OE::INVALID, do3.GetAsPositiveOrientation()); + EXPECT_EQ(NOE::INVALID, do3.GetAsNegativeOrientation()); +} + + +TEST(AnatomicalOrientation, ConvertDirectionToPositiveEnum) +{ + using itk::AnatomicalOrientation; + using OE = AnatomicalOrientation::PositiveEnum; + using ImageType = itk::Image; + ImageType::DirectionType d; + d.SetIdentity(); + + EXPECT_EQ(OE::LPS, AnatomicalOrientation(d)); + + d.Fill(0.0); + d(0, 0) = -1.0; + d(1, 1) = -1.0; + d(2, 2) = -1.0; + EXPECT_EQ(OE::RAI, AnatomicalOrientation(d)); + + d.Fill(0.0); + d(2, 0) = 1; + d(0, 1) = 1; + d(1, 2) = 1; + EXPECT_EQ(OE::SLP, AnatomicalOrientation(d)); + + d.Fill(0.0); + d(1, 0) = 1; + d(2, 1) = 1; + d(0, 2) = 1; + EXPECT_EQ(OE::PSL, AnatomicalOrientation(d)); + + d.Fill(0.0); + d(0, 0) = 1; + d(2, 1) = 1; + d(1, 2) = 1; + EXPECT_EQ(OE::LSP, AnatomicalOrientation(d)); + + d.Fill(0.0); + d(1, 0) = 1; + d(0, 1) = 1; + d(2, 2) = 1; + EXPECT_EQ(OE::PLS, AnatomicalOrientation(d)); + + d.Fill(0.0); + d(2, 0) = 1; + d(1, 1) = 1; + d(0, 2) = 1; + EXPECT_EQ(OE::SPL, AnatomicalOrientation(d)); + + const double data[] = { 0.5986634407395047, 0.22716302314740483, -0.768113953548866, + 0.5627936241740271, 0.563067040943212, 0.6051601804419384, + 0.5699696670095713, -0.794576911518317, 0.20924175102261847 }; + ImageType::DirectionType::InternalMatrixType m{ data }; + d.GetVnlMatrix() = m; + EXPECT_EQ(OE::PIR, AnatomicalOrientation(d)); +} + +TEST(AnatomicalOrientation, ConvertPositiveEnumToDirection) +{ + using itk::AnatomicalOrientation; + using ImageType = itk::Image; + using OE = AnatomicalOrientation::PositiveEnum; + + ImageType::DirectionType d; + d.SetIdentity(); + + EXPECT_EQ(d, AnatomicalOrientation(OE::LPS).GetAsDirection()); + + d.Fill(0.0); + d(0, 0) = -1.0; + d(1, 1) = -1.0; + d(2, 2) = -1.0; + EXPECT_EQ(d, AnatomicalOrientation(OE::RAI).GetAsDirection()); + + d.Fill(0.0); + d(2, 0) = 1; + d(0, 1) = 1; + d(1, 2) = 1; + EXPECT_EQ(d, AnatomicalOrientation(OE::SLP).GetAsDirection()); + + d.Fill(0.0); + d(1, 0) = 1; + d(2, 1) = 1; + d(0, 2) = 1; + EXPECT_EQ(d, AnatomicalOrientation(OE::PSL).GetAsDirection()); + + d.Fill(0.0); + d(0, 0) = 1; + d(2, 1) = 1; + d(1, 2) = 1; + EXPECT_EQ(d, AnatomicalOrientation(OE::LSP).GetAsDirection()); + + d.Fill(0.0); + d(1, 0) = 1; + d(0, 1) = 1; + d(2, 2) = 1; + EXPECT_EQ(d, AnatomicalOrientation(OE::PLS).GetAsDirection()); + + d.Fill(0.0); + d(2, 0) = 1; + d(1, 1) = 1; + d(0, 2) = 1; + EXPECT_EQ(d, AnatomicalOrientation(OE::SPL).GetAsDirection()); +} + +TEST(AntomicalOrientation, ToFromEnumInteroperability) +{ + + using OE = itk::AnatomicalOrientation::PositiveEnum; + using FromOE = itk::AnatomicalOrientation::NegativeEnum; + using CE = itk::AnatomicalOrientation::CoordinateEnum; + + static_assert(int(OE::RAI) == int(FromOE::LPS)); + static_assert(int(OE::LPS) == int(FromOE::RAI)); + static_assert(int(OE::RAS) == int(FromOE::LPI)); + static_assert(int(OE::LPI) == int(FromOE::RAS)); + static_assert(int(OE::PIR) == int(FromOE::ASL)); + static_assert(int(OE::ASL) == int(FromOE::PIR)); + + itk::AnatomicalOrientation itk_rai(FromOE::RAI); + + EXPECT_EQ(itk_rai, itk::AnatomicalOrientation(OE::LPS)); + EXPECT_EQ(itk_rai.GetAsPositiveOrientation(), OE::LPS); + EXPECT_EQ(itk_rai.GetAsPositiveStringEncoding(), "LPS"); + const std::array expected_terms = { { CE::RightToLeft, CE::AnteriorToPosterior, CE::InferiorToSuperior } }; + EXPECT_EQ(itk_rai.GetTerms(), expected_terms); +} + +#ifndef ITK_FUTURE_LEGACY_REMOVE +# include "itkSpatialOrientation.h" +TEST(AnatomicalOrientation, LegacyInteroperability) +{ + + using OE = itk::AnatomicalOrientation::PositiveEnum; + using SOE = itk::SpatialOrientationEnums::ValidCoordinateOrientations; + + // byte for byte compatibility, may assist with migration of bindings when types are not strictly enforced. + static_assert(int(SOE::ITK_COORDINATE_ORIENTATION_RAI) == int(OE::LPS)); + static_assert(int(SOE::ITK_COORDINATE_ORIENTATION_LPS) == int(OE::RAI)); + static_assert(int(SOE::ITK_COORDINATE_ORIENTATION_RSA) == int(OE::LIP)); + static_assert(int(SOE::ITK_COORDINATE_ORIENTATION_ASL) == int(OE::PIR)); + + itk::AnatomicalOrientation itk_rai(SOE::ITK_COORDINATE_ORIENTATION_RAI); + EXPECT_EQ(itk_rai, OE::LPS); + EXPECT_EQ(itk_rai.GetAsPositiveOrientation(), OE::LPS); + EXPECT_EQ(itk_rai.GetAsPositiveStringEncoding(), "LPS"); +} +#endif diff --git a/Modules/Core/Common/wrapping/itkAnatomicalOrientation.wrap b/Modules/Core/Common/wrapping/itkAnatomicalOrientation.wrap new file mode 100644 index 00000000000..9d81865c78e --- /dev/null +++ b/Modules/Core/Common/wrapping/itkAnatomicalOrientation.wrap @@ -0,0 +1 @@ +itk_wrap_simple_class("itk::AnatomicalOrientation") diff --git a/Modules/IO/GE/src/itkGE4ImageIO.cxx b/Modules/IO/GE/src/itkGE4ImageIO.cxx index 6fa3552585c..d979055dd8e 100644 --- a/Modules/IO/GE/src/itkGE4ImageIO.cxx +++ b/Modules/IO/GE/src/itkGE4ImageIO.cxx @@ -144,37 +144,27 @@ GE4ImageIO::ReadHeader(const char * FileNameToRead) if (strstr(tmpStr, "CORONAL") != nullptr) { - // hdr->imagePlane = - // itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ANALYZE_ORIENTATION_IRP_CORONAL; - // hdr->origin = itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ORIGIN_SRP; - // hdr->origin was SLA in the brains2 filter. - hdr->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RSP; + hdr->coordinateOrientation = AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::RightToLeft, + AnatomicalOrientation::CoordinateEnum::SuperiorToInferior, + AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior); } else if (strstr(tmpStr, "SAGITTAL") != nullptr) { - // hdr->imagePlane = - // itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ANALYZE_ORIENTATION_IRP_SAGITTAL; - // hdr->origin = itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ORIGIN_SRA; - // hdr->origin was SLP in the brains2 filter. - hdr->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_AIR; + hdr->coordinateOrientation = AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::AnteriorToPosterior, + AnatomicalOrientation::CoordinateEnum::InferiorToSuperior, + AnatomicalOrientation::CoordinateEnum::RightToLeft); } else if (strstr(tmpStr, "AXIAL") != nullptr) { - // hdr->imagePlane = - // itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ANALYZE_ORIENTATION_IRP_TRANSVERSE; - // hdr->origin = itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ORIGIN_SRA; // was SLP - hdr->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RAI; + hdr->coordinateOrientation = AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::RightToLeft, + AnatomicalOrientation::CoordinateEnum::AnteriorToPosterior, + AnatomicalOrientation::CoordinateEnum::InferiorToSuperior); } else { - // hdr->imagePlane = - // itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ANALYZE_ORIENTATION_IRP_CORONAL; - // hdr->origin = itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ORIGIN_SRP; // was SLA - hdr->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RSP; + hdr->coordinateOrientation = AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::RightToLeft, + AnatomicalOrientation::CoordinateEnum::SuperiorToInferior, + AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior); } /* Get the Scan Matrix from the IMAGE Header */ diff --git a/Modules/IO/GE/src/itkGE5ImageIO.cxx b/Modules/IO/GE/src/itkGE5ImageIO.cxx index cb062050499..33c128867cf 100644 --- a/Modules/IO/GE/src/itkGE5ImageIO.cxx +++ b/Modules/IO/GE/src/itkGE5ImageIO.cxx @@ -362,19 +362,27 @@ GE5ImageIO::ReadHeader(const char * FileNameToRead) { case GE_CORONAL: curImage->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RSP; + AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::RightToLeft, + AnatomicalOrientation::CoordinateEnum::SuperiorToInferior, + AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior); break; case GE_SAGITTAL: curImage->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_AIR; + AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::AnteriorToPosterior, + AnatomicalOrientation::CoordinateEnum::InferiorToSuperior, + AnatomicalOrientation::CoordinateEnum::RightToLeft); break; case GE_AXIAL: curImage->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RAI; + AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::RightToLeft, + AnatomicalOrientation::CoordinateEnum::AnteriorToPosterior, + AnatomicalOrientation::CoordinateEnum::InferiorToSuperior); break; default: curImage->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RSP; + AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::RightToLeft, + AnatomicalOrientation::CoordinateEnum::SuperiorToInferior, + AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior); break; } diff --git a/Modules/IO/GE/src/itkGEAdwImageIO.cxx b/Modules/IO/GE/src/itkGEAdwImageIO.cxx index 6f060293998..75cf01124b8 100644 --- a/Modules/IO/GE/src/itkGEAdwImageIO.cxx +++ b/Modules/IO/GE/src/itkGEAdwImageIO.cxx @@ -161,31 +161,24 @@ GEAdwImageIO::ReadHeader(const char * FileNameToRead) switch (tmpShort) { case GE_CORONAL: - // hdr->imagePlane = itk::IOCommon::ITK_ANALYZE_ORIENTATION_IRP_CORONAL; - // hdr->origin = itk::IOCommon::ITK_ORIGIN_SLA; - hdr->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RSP; + hdr->coordinateOrientation = AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::RightToLeft, + AnatomicalOrientation::CoordinateEnum::SuperiorToInferior, + AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior); break; case GE_SAGITTAL: - // hdr->imagePlane = - // itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ANALYZE_ORIENTATION_IRP_SAGITTAL; - // hdr->origin = itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ORIGIN_SLA; - hdr->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_AIR; + hdr->coordinateOrientation = AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::AnteriorToPosterior, + AnatomicalOrientation::CoordinateEnum::InferiorToSuperior, + AnatomicalOrientation::CoordinateEnum::RightToLeft); break; case GE_AXIAL: - // hdr->imagePlane = - // itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ANALYZE_ORIENTATION_IRP_TRANSVERSE; - // hdr->origin = itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ORIGIN_SLA; - hdr->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RAI; + hdr->coordinateOrientation = AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::RightToLeft, + AnatomicalOrientation::CoordinateEnum::AnteriorToPosterior, + AnatomicalOrientation::CoordinateEnum::InferiorToSuperior); break; default: - // hdr->imagePlane = - // itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ANALYZE_ORIENTATION_IRP_CORONAL; - // hdr->origin = itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ORIGIN_SLA; - hdr->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RSP; + hdr->coordinateOrientation = AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::RightToLeft, + AnatomicalOrientation::CoordinateEnum::SuperiorToInferior, + AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior); break; } this->GetFloatAt(f, GE_ADW_IM_LOC, &(hdr->sliceLocation)); diff --git a/Modules/IO/IPL/include/itkGEImageHeader.h b/Modules/IO/IPL/include/itkGEImageHeader.h index 37dd74cec3d..c586941c56d 100644 --- a/Modules/IO/IPL/include/itkGEImageHeader.h +++ b/Modules/IO/IPL/include/itkGEImageHeader.h @@ -30,6 +30,7 @@ #include "ITKIOIPLExport.h" #include "itkIOCommon.h" +#include "itkAnatomicalOrientation.h" enum GE_PANE_STRUCT { @@ -85,13 +86,15 @@ struct GEImageHeader short imageYsize; float imageXres; float imageYres; - itk::SpatialOrientationEnums::ValidCoordinateOrientations coordinateOrientation; - short numberOfSlices; - short offset; - char filename[itk::IOCommon::ITK_MAXPATHLEN + 1]; - char hospital[35]; - char modality[4]; - short imagesPerSlice; + + itk::AnatomicalOrientation::PositiveEnum coordinateOrientation; // uint32_t + + short numberOfSlices; + short offset; + char filename[itk::IOCommon::ITK_MAXPATHLEN + 1]; + char hospital[35]; + char modality[4]; + short imagesPerSlice; short turboFactor; // This is only relevant for the geADW image format, but // is put here for convenience }; diff --git a/Modules/IO/IPL/src/itkIPLCommonImageIO.cxx b/Modules/IO/IPL/src/itkIPLCommonImageIO.cxx index b0698c00e55..fdecc38f956 100644 --- a/Modules/IO/IPL/src/itkIPLCommonImageIO.cxx +++ b/Modules/IO/IPL/src/itkIPLCommonImageIO.cxx @@ -19,7 +19,7 @@ #include "itksys/SystemTools.hxx" #include "itkIPLCommonImageIO.h" #include "itkByteSwapper.h" -#include "itkSpatialOrientationAdapter.h" +#include "itkAnatomicalOrientation.h" #include "itkDirectory.h" #include "itkMetaDataObject.h" #include @@ -256,9 +256,8 @@ IPLCommonImageIO::ReadImageInformation() // // set direction cosines - using OrientAdapterType = SpatialOrientationAdapter; - SpatialOrientationAdapter::DirectionType dir = - OrientAdapterType().ToDirectionCosines(m_ImageHeader->coordinateOrientation); + AnatomicalOrientation::DirectionType dir = + AnatomicalOrientation(m_ImageHeader->coordinateOrientation).GetAsDirection(); std::vector dirx(3, 0), diry(3, 0), dirz(3, 0); dirx[0] = dir[0][0]; dirx[1] = dir[1][0]; diff --git a/Modules/IO/ImageBase/test/itkReadWriteImageWithDictionaryTest.cxx b/Modules/IO/ImageBase/test/itkReadWriteImageWithDictionaryTest.cxx index 725025709e3..98aa6330c42 100644 --- a/Modules/IO/ImageBase/test/itkReadWriteImageWithDictionaryTest.cxx +++ b/Modules/IO/ImageBase/test/itkReadWriteImageWithDictionaryTest.cxx @@ -19,7 +19,7 @@ #include "itkImageFileWriter.h" #include "itkIOCommon.h" #include "itkMetaDataObject.h" -#include "itkSpatialOrientationAdapter.h" +#include "itkAnatomicalOrientation.h" #include "itkTestingMacros.h" int @@ -45,8 +45,7 @@ itkReadWriteImageWithDictionaryTest(int argc, char * argv[]) inputImage->Allocate(); inputImage->FillBuffer(0); - inputImage->SetDirection(itk::SpatialOrientationAdapter().ToDirectionCosines( - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RIP)); + inputImage->SetDirection(itk::AnatomicalOrientation::CreateFromPositiveStringEncoding("LSA").GetAsDirection()); // Add some metadata in the dictionary itk::MetaDataDictionary & inputDictionary = inputImage->GetMetaDataDictionary(); diff --git a/Modules/IO/Meta/src/itkMetaImageIO.cxx b/Modules/IO/Meta/src/itkMetaImageIO.cxx index f6c2133cc0d..03caa8dc8be 100644 --- a/Modules/IO/Meta/src/itkMetaImageIO.cxx +++ b/Modules/IO/Meta/src/itkMetaImageIO.cxx @@ -17,7 +17,7 @@ *=========================================================================*/ #include "itkMetaImageIO.h" -#include "itkSpatialOrientationAdapter.h" +#include "itkAnatomicalOrientation.h" #include "itkIOCommon.h" #include "itksys/SystemTools.hxx" #include "itkMath.h" @@ -808,11 +808,8 @@ MetaImageIO::Write(const void * buffer) if (numberOfDimensions == 3) { - using SpatialOrientations = SpatialOrientationEnums::ValidCoordinateOrientations; - SpatialOrientations coordOrient = SpatialOrientations::ITK_COORDINATE_ORIENTATION_INVALID; - - std::vector dirx, diry, dirz; - SpatialOrientationAdapter::DirectionType dir; + std::vector dirx, diry, dirz; + AnatomicalOrientation::DirectionType dir; dirx = this->GetDirection(0); diry = this->GetDirection(1); dirz = this->GetDirection(2); @@ -822,238 +819,24 @@ MetaImageIO::Write(const void * buffer) dir[ii][1] = diry[ii]; dir[ii][2] = dirz[ii]; } - coordOrient = SpatialOrientationAdapter().FromDirectionCosines(dir); - - switch (coordOrient) - { - default: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RPI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RPS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RAI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RAS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RIA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RIP: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RSA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RSP: - { - m_MetaImage.AnatomicalOrientation(0, MET_ORIENTATION_RL); - break; - } - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LPI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LPS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LAI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LAS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LIA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LIP: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LSA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LSP: - { - m_MetaImage.AnatomicalOrientation(0, MET_ORIENTATION_LR); - break; - } - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ALI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ALS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ARI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ARS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_AIL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_AIR: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ASL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ASR: - { - m_MetaImage.AnatomicalOrientation(0, MET_ORIENTATION_AP); - break; - } - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PLI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PLS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PRI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PRS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PIL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PIR: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PSL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PSR: - { - m_MetaImage.AnatomicalOrientation(0, MET_ORIENTATION_PA); - break; - } - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_IPL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_IPR: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_IAL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_IAR: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ILA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ILP: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_IRA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_IRP: - { - m_MetaImage.AnatomicalOrientation(0, MET_ORIENTATION_IS); - break; - } - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SPL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SPR: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SAL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SAR: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SLA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SLP: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SRA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SRP: - { - m_MetaImage.AnatomicalOrientation(0, MET_ORIENTATION_SI); - break; - } - } - switch (coordOrient) - { - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PRI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PRS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ARI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ARS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_IRA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_IRP: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SRA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SRP: - { - m_MetaImage.AnatomicalOrientation(1, MET_ORIENTATION_RL); - break; - } - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PLI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PLS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ALI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ALS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ILA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ILP: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SLA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SLP: - { - m_MetaImage.AnatomicalOrientation(1, MET_ORIENTATION_LR); - break; - } - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LAI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LAS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RAI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RAS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_IAL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_IAR: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SAL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SAR: - { - m_MetaImage.AnatomicalOrientation(1, MET_ORIENTATION_AP); - break; - } - default: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LPI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LPS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RPI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RPS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_IPL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_IPR: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SPL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SPR: - { - m_MetaImage.AnatomicalOrientation(1, MET_ORIENTATION_PA); - break; - } - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PIL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PIR: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_AIL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_AIR: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LIA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LIP: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RIA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RIP: - { - m_MetaImage.AnatomicalOrientation(1, MET_ORIENTATION_IS); - break; - } - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PSL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PSR: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ASL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ASR: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LSA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LSP: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RSA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RSP: - { - m_MetaImage.AnatomicalOrientation(1, MET_ORIENTATION_SI); - break; - } - } - switch (coordOrient) - { - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PIR: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PSR: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_AIR: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ASR: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_IAR: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_IPR: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SAR: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SPR: - { - m_MetaImage.AnatomicalOrientation(2, MET_ORIENTATION_RL); - break; - } - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PIL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PSL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_AIL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ASL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_IAL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_IPL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SAL: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SPL: - { - m_MetaImage.AnatomicalOrientation(2, MET_ORIENTATION_LR); - break; - } - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LIA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LSA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RIA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RSA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ILA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_IRA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SLA: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SRA: - { - m_MetaImage.AnatomicalOrientation(2, MET_ORIENTATION_AP); - break; - } - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LIP: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LSP: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RIP: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RSP: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ILP: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_IRP: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SLP: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_SRP: - { - m_MetaImage.AnatomicalOrientation(2, MET_ORIENTATION_PA); - break; - } - default: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PLI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PRI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ALI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ARI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LAI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LPI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RAI: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RPI: - { - m_MetaImage.AnatomicalOrientation(2, MET_ORIENTATION_IS); - break; - } - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PLS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_PRS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ALS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_ARS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LAS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_LPS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RAS: - case SpatialOrientations::ITK_COORDINATE_ORIENTATION_RPS: - { - m_MetaImage.AnatomicalOrientation(2, MET_ORIENTATION_SI); - break; - } - } + AnatomicalOrientation coordOrient(dir); + + // Mapping from DICOM CoordinateEnum defined as the increasing direction to + // the MetaIO enum which has from/to orientation defined. + const std::map axisToMetOrientation{ + { AnatomicalOrientation::CoordinateEnum::RightToLeft, MET_ORIENTATION_RL }, + { AnatomicalOrientation::CoordinateEnum::LeftToRight, MET_ORIENTATION_LR }, + { AnatomicalOrientation::CoordinateEnum::AnteriorToPosterior, MET_ORIENTATION_AP }, + { AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior, MET_ORIENTATION_PA }, + { AnatomicalOrientation::CoordinateEnum::InferiorToSuperior, MET_ORIENTATION_IS }, + { AnatomicalOrientation::CoordinateEnum::SuperiorToInferior, MET_ORIENTATION_SI } + }; + + m_MetaImage.AnatomicalOrientation(0, axisToMetOrientation.at(coordOrient.GetPrimaryTerm())); + m_MetaImage.AnatomicalOrientation(1, axisToMetOrientation.at(coordOrient.GetSecondaryTerm())); + m_MetaImage.AnatomicalOrientation(2, axisToMetOrientation.at(coordOrient.GetTertiaryTerm())); } - // Propagage direction cosine information. + // Propagate direction cosine information. auto * transformMatrix = static_cast(malloc(numberOfDimensions * numberOfDimensions * sizeof(double))); if (transformMatrix) { diff --git a/Modules/IO/NIFTI/src/itkNiftiImageIO.cxx b/Modules/IO/NIFTI/src/itkNiftiImageIO.cxx index 7fde5622799..e5ecf351c6f 100644 --- a/Modules/IO/NIFTI/src/itkNiftiImageIO.cxx +++ b/Modules/IO/NIFTI/src/itkNiftiImageIO.cxx @@ -18,7 +18,7 @@ #include "itkNiftiImageIO.h" #include "itkIOCommon.h" #include "itkMetaDataObject.h" -#include "itkSpatialOrientationAdapter.h" +#include "itkAnatomicalOrientation.h" #include #include "itkNiftiImageIOConfigurePrivate.h" #include "itkMakeUniqueForOverwrite.h" @@ -1878,7 +1878,6 @@ IsAffine(const mat44 & nifti_mat) void NiftiImageIO::SetImageIOOrientationFromNIfTI(unsigned short dims, double spacingscale, double timingscale) { - typedef SpatialOrientationAdapter OrientAdapterType; // in the case of an Analyze75 file, use old analyze orient method. // but this could be a nifti file without qform and sform if (this->m_NiftiImage->qform_code == NIFTI_XFORM_UNKNOWN && this->m_NiftiImage->sform_code == NIFTI_XFORM_UNKNOWN) @@ -1897,33 +1896,47 @@ NiftiImageIO::SetImageIOOrientationFromNIfTI(unsigned short dims, double spacing this->GetLegacyAnalyze75Mode() != NiftiImageIOEnums::Analyze75Flavor::AnalyzeITK4 && this->GetLegacyAnalyze75Mode() != NiftiImageIOEnums::Analyze75Flavor::AnalyzeITK4Warning) { // only do this for Analyze file format - SpatialOrientationAdapter::OrientationType orient; + AnatomicalOrientation orient(AnatomicalOrientation::PositiveEnum::INVALID); switch (this->m_NiftiImage->analyze75_orient) { case a75_transverse_unflipped: - orient = SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RPI; + orient = AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::RightToLeft, + AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior, + AnatomicalOrientation::CoordinateEnum::InferiorToSuperior); break; case a75_sagittal_unflipped: - orient = SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_PIR; + orient = AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior, + AnatomicalOrientation::CoordinateEnum::InferiorToSuperior, + AnatomicalOrientation::CoordinateEnum::RightToLeft); break; case a75_coronal_unflipped: - orient = SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RIP; + orient = AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::RightToLeft, + AnatomicalOrientation::CoordinateEnum::InferiorToSuperior, + AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior); break; case a75_transverse_flipped: - orient = SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RAI; + orient = AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::RightToLeft, + AnatomicalOrientation::CoordinateEnum::AnteriorToPosterior, + AnatomicalOrientation::CoordinateEnum::InferiorToSuperior); break; case a75_sagittal_flipped: - orient = SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_PIL; + orient = AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior, + AnatomicalOrientation::CoordinateEnum::InferiorToSuperior, + AnatomicalOrientation::CoordinateEnum::LeftToRight); break; case a75_coronal_flipped: - orient = SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RSP; + orient = AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::RightToLeft, + AnatomicalOrientation::CoordinateEnum::SuperiorToInferior, + AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior); break; case a75_orient_unknown: - orient = SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RIP; + orient = AnatomicalOrientation(AnatomicalOrientation::CoordinateEnum::RightToLeft, + AnatomicalOrientation::CoordinateEnum::InferiorToSuperior, + AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior); break; } - const SpatialOrientationAdapter::DirectionType dir = OrientAdapterType().ToDirectionCosines(orient); - const int max_defined_orientation_dims = (dims > 3) ? 3 : dims; + const auto dir = orient.GetAsDirection(); + const int max_defined_orientation_dims = (dims > 3) ? 3 : dims; for (int d = 0; d < max_defined_orientation_dims; ++d) { std::vector direction(dims, 0.0); diff --git a/Modules/IO/NIFTI/test/itkNiftiImageIOTest.h b/Modules/IO/NIFTI/test/itkNiftiImageIOTest.h index 6bf97e9985f..c41dfa71511 100644 --- a/Modules/IO/NIFTI/test/itkNiftiImageIOTest.h +++ b/Modules/IO/NIFTI/test/itkNiftiImageIOTest.h @@ -30,7 +30,7 @@ #include "itkNiftiImageIO.h" #include "itkMetaDataObject.h" #include "itkIOCommon.h" -#include "itkSpatialOrientationAdapter.h" +#include "itkAnatomicalOrientation.h" #include "itkDiffusionTensor3D.h" #include "itkAffineTransform.h" #include "itkVector.h" @@ -228,8 +228,10 @@ template typename ImageType::DirectionType CORDirCosines() { - typename itk::SpatialOrientationAdapter::DirectionType CORdir = itk::SpatialOrientationAdapter().ToDirectionCosines( - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RIP); + auto CORdir = itk::AnatomicalOrientation(itk::AnatomicalOrientation::CoordinateEnum::RightToLeft, + itk::AnatomicalOrientation::CoordinateEnum::InferiorToSuperior, + itk::AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior) + .GetAsDirection(); typename ImageType::DirectionType dir; for (unsigned int i = 0; i < ImageType::ImageDimension; ++i) { diff --git a/Modules/IO/NIFTI/test/itkNiftiImageIOTest4.cxx b/Modules/IO/NIFTI/test/itkNiftiImageIOTest4.cxx index 64408d4e651..5ac8afc1550 100644 --- a/Modules/IO/NIFTI/test/itkNiftiImageIOTest4.cxx +++ b/Modules/IO/NIFTI/test/itkNiftiImageIOTest4.cxx @@ -71,7 +71,7 @@ itkNiftiImageIOTest4(int argc, char * argv[]) Test4ImageType::DirectionType dir; dir.SetIdentity(); -#if 1 + // arbitrarily rotate the unit vectors to pick random direction // cosines; vnl_random randgen(8775070); @@ -102,10 +102,6 @@ itkNiftiImageIOTest4(int argc, char * argv[]) } } -#else - dir = itk::SpatialOrientationAdapter().ToDirectionCosines( - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_PLI); -#endif test4Image->SetDirection(dir); std::string fname("directionsTest.nii.gz"); try diff --git a/Modules/IO/NIFTI/test/itkNiftiReadAnalyzeTest.cxx b/Modules/IO/NIFTI/test/itkNiftiReadAnalyzeTest.cxx index 5860d24ba6c..8310b3e354e 100644 --- a/Modules/IO/NIFTI/test/itkNiftiReadAnalyzeTest.cxx +++ b/Modules/IO/NIFTI/test/itkNiftiReadAnalyzeTest.cxx @@ -22,7 +22,7 @@ #include "itkImageFileReader.h" #include "itkImageRegionConstIterator.h" #include "itkMath.h" -#include "itkSpatialOrientationAdapter.h" +#include "itkAnatomicalOrientation.h" // debug #include @@ -120,59 +120,6 @@ const unsigned char LittleEndian_img[] = { 0x00, 0x00, 0xe0, 0x42, 0x00, 0x00, 0xe0, 0x42, 0x00, 0x00, 0xe0, 0x42, }; -// Map between axis string labels and spatial orientation -std::map codeToString = { - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RIP, "RIP" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_LIP, "LIP" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RSP, "RSP" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_LSP, "LSP" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RIA, "RIA" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_LIA, "LIA" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RSA, "RSA" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_LSA, "LSA" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_IRP, "IRP" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_ILP, "ILP" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_SRP, "SRP" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_SLP, "SLP" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_IRA, "IRA" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_ILA, "ILA" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_SRA, "SRA" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_SLA, "SLA" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RPI, "RPI" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_LPI, "LPI" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RAI, "RAI" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_LAI, "LAI" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RPS, "RPS" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_LPS, "LPS" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RAS, "RAS" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_LAS, "LAS" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_PRI, "PRI" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_PLI, "PLI" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_ARI, "ARI" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_ALI, "ALI" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_PRS, "PRS" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_PLS, "PLS" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_ARS, "ARS" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_ALS, "ALS" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_IPR, "IPR" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_SPR, "SPR" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_IAR, "IAR" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_SAR, "SAR" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_IPL, "IPL" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_SPL, "SPL" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_IAL, "IAL" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_SAL, "SAL" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_PIR, "PIR" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_PSR, "PSR" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_AIR, "AIR" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_ASR, "ASR" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_PIL, "PIL" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_PSL, "PSL" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_AIL, "AIL" }, - { itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_ASL, "ASL" } -}; - - /** WriteFile * Write out a char array as binary */ @@ -229,19 +176,19 @@ ReadImage(const std::string & fileName, int -itkNiftiAnalyzeContentsAndCoordinatesTest(char * argv[], - unsigned char hist_orient_code, - itk::SpatialOrientationEnums::ValidCoordinateOrientations expected_code, - itk::NiftiImageIOEnums::Analyze75Flavor analyze_mode, - bool flip_x = false) +itkNiftiAnalyzeContentsAndCoordinatesTest(char * argv[], + unsigned char hist_orient_code, + itk::AnatomicalOrientation expected_code, + itk::NiftiImageIOEnums::Analyze75Flavor analyze_mode, + bool flip_x = false) { std::string hdrName(argv[1]); hdrName += "/littleEndian_"; - hdrName += codeToString[expected_code]; + hdrName += expected_code.GetAsPositiveStringEncoding(); hdrName += ".hdr"; std::string imgName(argv[1]); imgName += "/littleEndian_"; - imgName += codeToString[expected_code]; + imgName += expected_code.GetAsPositiveStringEncoding(); imgName += ".img"; // hack the header to have proper orientation code @@ -301,14 +248,13 @@ itkNiftiAnalyzeContentsAndCoordinatesTest(char * } } - itk::SpatialOrientationEnums::ValidCoordinateOrientations orientation_code = - itk::SpatialOrientationAdapter().FromDirectionCosines(img->GetDirection()); + const itk::AnatomicalOrientation orientation_code(img->GetDirection()); // verify the correct orientation : if (orientation_code != expected_code) { std::cerr << "Analyze orientation " << static_cast(hist_orient_code) << std::endl; - std::cerr << "expected orientation " << codeToString[expected_code] << " but found " - << codeToString[orientation_code] << std::endl; + std::cerr << "expected orientation " << expected_code.GetAsPositiveStringEncoding() << " but found " + << orientation_code.GetAsPositiveStringEncoding() << std::endl; return EXIT_FAILURE; } @@ -318,7 +264,7 @@ itkNiftiAnalyzeContentsAndCoordinatesTest(char * << "negative x step:" << (flip_x ? "true" : "false") << std::endl << "Origin :" << img->GetOrigin() << std::endl << "Spacing :" << img->GetSpacing() << std::endl - << "Code :" << codeToString[orientation_code] << std::endl + << "Code :" << orientation_code.GetAsPositiveStringEncoding() << std::endl << "Direction:" << img->GetDirection() << std::endl; return EXIT_SUCCESS; @@ -343,95 +289,129 @@ itkNiftiReadAnalyzeTest(int argc, char * argv[]) return itkNiftiAnalyzeContentsAndCoordinatesTest( argv, 0, - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RPI, + itk::AnatomicalOrientation(itk::AnatomicalOrientation::CoordinateEnum::RightToLeft, + itk::AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior, + itk::AnatomicalOrientation::CoordinateEnum::InferiorToSuperior), itk::NiftiImageIOEnums::Analyze75Flavor::AnalyzeReject) != EXIT_FAILURE || itkNiftiAnalyzeContentsAndCoordinatesTest( argv, 0, - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RPI, + itk::AnatomicalOrientation(itk::AnatomicalOrientation::CoordinateEnum::RightToLeft, + itk::AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior, + itk::AnatomicalOrientation::CoordinateEnum::InferiorToSuperior), itk::NiftiImageIOEnums::Analyze75Flavor::AnalyzeSPM) == EXIT_FAILURE || itkNiftiAnalyzeContentsAndCoordinatesTest( argv, 1, - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RIP, + itk::AnatomicalOrientation(itk::AnatomicalOrientation::CoordinateEnum::RightToLeft, + itk::AnatomicalOrientation::CoordinateEnum::InferiorToSuperior, + itk::AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior), itk::NiftiImageIOEnums::Analyze75Flavor::AnalyzeSPM) == EXIT_FAILURE || itkNiftiAnalyzeContentsAndCoordinatesTest( argv, 2, - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_PIR, + itk::AnatomicalOrientation(itk::AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior, + itk::AnatomicalOrientation::CoordinateEnum::InferiorToSuperior, + itk::AnatomicalOrientation::CoordinateEnum::RightToLeft), itk::NiftiImageIOEnums::Analyze75Flavor::AnalyzeSPM) == EXIT_FAILURE || itkNiftiAnalyzeContentsAndCoordinatesTest( argv, 3, - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RAI, + itk::AnatomicalOrientation(itk::AnatomicalOrientation::CoordinateEnum::RightToLeft, + itk::AnatomicalOrientation::CoordinateEnum::AnteriorToPosterior, + itk::AnatomicalOrientation::CoordinateEnum::InferiorToSuperior), itk::NiftiImageIOEnums::Analyze75Flavor::AnalyzeSPM) == EXIT_FAILURE || itkNiftiAnalyzeContentsAndCoordinatesTest( argv, 4, - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RSP, + itk::AnatomicalOrientation(itk::AnatomicalOrientation::CoordinateEnum::RightToLeft, + itk::AnatomicalOrientation::CoordinateEnum::SuperiorToInferior, + itk::AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior), itk::NiftiImageIOEnums::Analyze75Flavor::AnalyzeSPM) == EXIT_FAILURE || itkNiftiAnalyzeContentsAndCoordinatesTest( argv, 5, - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_PIL, + itk::AnatomicalOrientation(itk::AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior, + itk::AnatomicalOrientation::CoordinateEnum::InferiorToSuperior, + itk::AnatomicalOrientation::CoordinateEnum::LeftToRight), itk::NiftiImageIOEnums::Analyze75Flavor::AnalyzeSPM) == EXIT_FAILURE || // ITK4 default behaviour: reader should ignore orientation code and always produce RAI , // there should be a warning on console itkNiftiAnalyzeContentsAndCoordinatesTest( argv, 0, - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RAI, + itk::AnatomicalOrientation(itk::AnatomicalOrientation::CoordinateEnum::RightToLeft, + itk::AnatomicalOrientation::CoordinateEnum::AnteriorToPosterior, + itk::AnatomicalOrientation::CoordinateEnum::InferiorToSuperior), itk::NiftiImageIOEnums::Analyze75Flavor::AnalyzeITK4Warning) == EXIT_FAILURE || // ITK4 reader should ignore orientation code and always produce RAI itkNiftiAnalyzeContentsAndCoordinatesTest( argv, 0, - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RAI, + itk::AnatomicalOrientation(itk::AnatomicalOrientation::CoordinateEnum::RightToLeft, + itk::AnatomicalOrientation::CoordinateEnum::AnteriorToPosterior, + itk::AnatomicalOrientation::CoordinateEnum::InferiorToSuperior), itk::NiftiImageIOEnums::Analyze75Flavor::AnalyzeITK4) == EXIT_FAILURE || itkNiftiAnalyzeContentsAndCoordinatesTest( argv, 1, - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RAI, + itk::AnatomicalOrientation(itk::AnatomicalOrientation::CoordinateEnum::RightToLeft, + itk::AnatomicalOrientation::CoordinateEnum::AnteriorToPosterior, + itk::AnatomicalOrientation::CoordinateEnum::InferiorToSuperior), itk::NiftiImageIOEnums::Analyze75Flavor::AnalyzeITK4) == EXIT_FAILURE || itkNiftiAnalyzeContentsAndCoordinatesTest( argv, 2, - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RAI, + itk::AnatomicalOrientation(itk::AnatomicalOrientation::CoordinateEnum::RightToLeft, + itk::AnatomicalOrientation::CoordinateEnum::AnteriorToPosterior, + itk::AnatomicalOrientation::CoordinateEnum::InferiorToSuperior), itk::NiftiImageIOEnums::Analyze75Flavor::AnalyzeITK4) == EXIT_FAILURE || itkNiftiAnalyzeContentsAndCoordinatesTest( argv, 3, - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RAI, + itk::AnatomicalOrientation(itk::AnatomicalOrientation::CoordinateEnum::RightToLeft, + itk::AnatomicalOrientation::CoordinateEnum::AnteriorToPosterior, + itk::AnatomicalOrientation::CoordinateEnum::InferiorToSuperior), itk::NiftiImageIOEnums::Analyze75Flavor::AnalyzeITK4) == EXIT_FAILURE || itkNiftiAnalyzeContentsAndCoordinatesTest( argv, 5, - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RAI, + itk::AnatomicalOrientation(itk::AnatomicalOrientation::CoordinateEnum::RightToLeft, + itk::AnatomicalOrientation::CoordinateEnum::AnteriorToPosterior, + itk::AnatomicalOrientation::CoordinateEnum::InferiorToSuperior), itk::NiftiImageIOEnums::Analyze75Flavor::AnalyzeITK4) == EXIT_FAILURE || itkNiftiAnalyzeContentsAndCoordinatesTest( argv, 5, - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RAI, + itk::AnatomicalOrientation(itk::AnatomicalOrientation::CoordinateEnum::RightToLeft, + itk::AnatomicalOrientation::CoordinateEnum::AnteriorToPosterior, + itk::AnatomicalOrientation::CoordinateEnum::InferiorToSuperior), itk::NiftiImageIOEnums::Analyze75Flavor::AnalyzeITK4) == EXIT_FAILURE || // flip X axis , SPM reader should respect this itkNiftiAnalyzeContentsAndCoordinatesTest( argv, 0, - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_LPI, + itk::AnatomicalOrientation(itk::AnatomicalOrientation::CoordinateEnum::LeftToRight, + itk::AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior, + itk::AnatomicalOrientation::CoordinateEnum::InferiorToSuperior), itk::NiftiImageIOEnums::Analyze75Flavor::AnalyzeSPM, true) == EXIT_FAILURE || // flip X axis , ITK4 reader should respect this itkNiftiAnalyzeContentsAndCoordinatesTest( argv, 0, - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_LAI, + itk::AnatomicalOrientation(itk::AnatomicalOrientation::CoordinateEnum::LeftToRight, + itk::AnatomicalOrientation::CoordinateEnum::AnteriorToPosterior, + itk::AnatomicalOrientation::CoordinateEnum::InferiorToSuperior), itk::NiftiImageIOEnums::Analyze75Flavor::AnalyzeITK4, true) == EXIT_FAILURE || // flip X axis , FSL reader should ignore this itkNiftiAnalyzeContentsAndCoordinatesTest( argv, 0, - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RPI, + itk::AnatomicalOrientation(itk::AnatomicalOrientation::CoordinateEnum::RightToLeft, + itk::AnatomicalOrientation::CoordinateEnum::PosteriorToAnterior, + itk::AnatomicalOrientation::CoordinateEnum::InferiorToSuperior), itk::NiftiImageIOEnums::Analyze75Flavor::AnalyzeFSL, true) == EXIT_FAILURE diff --git a/Modules/IO/PhilipsREC/src/itkPhilipsRECImageIO.cxx b/Modules/IO/PhilipsREC/src/itkPhilipsRECImageIO.cxx index 4e00f816bce..6ced3046896 100644 --- a/Modules/IO/PhilipsREC/src/itkPhilipsRECImageIO.cxx +++ b/Modules/IO/PhilipsREC/src/itkPhilipsRECImageIO.cxx @@ -29,7 +29,7 @@ #include "itkIOCommon.h" #include "itkByteSwapper.h" #include "itkMetaDataObject.h" -#include "itkSpatialOrientationAdapter.h" +#include "itkAnatomicalOrientation.h" #include "itksys/SystemTools.hxx" #include "itk_zlib.h" #include @@ -710,7 +710,7 @@ PhilipsRECImageIO::ReadImageInformation() AffineMatrix spacing; spacing.SetIdentity(); - SpatialOrientationEnums::ValidCoordinateOrientations coord_orient; + AnatomicalOrientation coord_orient(AnatomicalOrientation::FromEnum::RSA); switch (par.sliceorient) { @@ -744,7 +744,7 @@ PhilipsRECImageIO::ReadImageInformation() spacing[2][2] = par.vox[1]; } - SpatialOrientationAdapter::DirectionType dir = SpatialOrientationAdapter().ToDirectionCosines(coord_orient); + AnatomicalOrientation::DirectionType dir = coord_orient.GetAsDirection(); AffineMatrix direction; direction.SetIdentity(); diff --git a/Modules/IO/Siemens/src/itkSiemensVisionImageIO.cxx b/Modules/IO/Siemens/src/itkSiemensVisionImageIO.cxx index 5ce05187c89..1e6b52a1290 100644 --- a/Modules/IO/Siemens/src/itkSiemensVisionImageIO.cxx +++ b/Modules/IO/Siemens/src/itkSiemensVisionImageIO.cxx @@ -223,8 +223,7 @@ SiemensVisionImageIO::ReadHeader(const char * FileNameToRead) if (text_angle_len.empty() || itk::Math::abs(std::stod(text_angle_len)) <= 45.0) { // hdr->imagePlane = itk::IOCommon::ITK_ANALYZE_ORIENTATION_IRP_CORONAL; - hdr->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RSP; + hdr->coordinateOrientation = AnatomicalOrientation(itk::AnatomicalOrientation::NegativeEnum::RSP); } else { @@ -232,15 +231,13 @@ SiemensVisionImageIO::ReadHeader(const char * FileNameToRead) { // hdr->imagePlane = // itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ANALYZE_ORIENTATION_IRP_SAGITTAL; - hdr->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_AIR; + hdr->coordinateOrientation = AnatomicalOrientation(itk::AnatomicalOrientation::NegativeEnum::AIR); } else { // hdr->imagePlane = // itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ANALYZE_ORIENTATION_IRP_TRANSVERSE; - hdr->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RAI; + hdr->coordinateOrientation = AnatomicalOrientation(itk::AnatomicalOrientation::NegativeEnum::RAI); } } } @@ -250,8 +247,7 @@ SiemensVisionImageIO::ReadHeader(const char * FileNameToRead) { // hdr->imagePlane = // itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ANALYZE_ORIENTATION_IRP_SAGITTAL; - hdr->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_AIR; + hdr->coordinateOrientation = AnatomicalOrientation(itk::AnatomicalOrientation::NegativeEnum::AIR); } else { @@ -259,15 +255,13 @@ SiemensVisionImageIO::ReadHeader(const char * FileNameToRead) { // hdr->imagePlane = // itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ANALYZE_ORIENTATION_IRP_CORONAL; - hdr->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RSP; + hdr->coordinateOrientation = AnatomicalOrientation(itk::AnatomicalOrientation::NegativeEnum::RSP); } else { // hdr->imagePlane = // itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ANALYZE_ORIENTATION_IRP_TRANSVERSE; - hdr->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RAI; + hdr->coordinateOrientation = AnatomicalOrientation(itk::AnatomicalOrientation::NegativeEnum::RAI); } } } @@ -277,8 +271,7 @@ SiemensVisionImageIO::ReadHeader(const char * FileNameToRead) { // hdr->imagePlane = // itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ANALYZE_ORIENTATION_IRP_TRANSVERSE; - hdr->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RAI; + hdr->coordinateOrientation = AnatomicalOrientation(itk::AnatomicalOrientation::NegativeEnum::RAI); } else { @@ -286,15 +279,13 @@ SiemensVisionImageIO::ReadHeader(const char * FileNameToRead) { // hdr->imagePlane = // itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ANALYZE_ORIENTATION_IRP_CORONAL; - hdr->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RSP; + hdr->coordinateOrientation = AnatomicalOrientation(itk::AnatomicalOrientation::NegativeEnum::RSP); } else { // hdr->imagePlane = // itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_ANALYZE_ORIENTATION_IRP_SAGITTAL; - hdr->coordinateOrientation = - itk::SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_AIR; + hdr->coordinateOrientation = AnatomicalOrientation(itk::AnatomicalOrientation::NegativeEnum::AIR); } } }