Skip to content

Commit

Permalink
ENH: Use ToEnum and FromEnum for clear anatomical orientations
Browse files Browse the repository at this point in the history
Use the To/From in the enum type names of single letter
representations, to indicate if the acronym represents the anatomical
direction where the axis increasing "to" or coming "from".
  • Loading branch information
blowekamp committed Aug 15, 2024
1 parent 7eef0fa commit 4042eb3
Show file tree
Hide file tree
Showing 5 changed files with 344 additions and 112 deletions.
198 changes: 181 additions & 17 deletions Modules/Core/Common/include/itkAnatomicalOrientation.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ class ITKCommon_EXPORT AnatomicalOrientation
LeftToRight = 3,
PosteriorToAnterior = 4, ///< front - 0b0100
AnteriorToPosterior = 5, ///< back
InferiorToSuperior = 8, ///< above - 0b1000
SuperiorToInferior = 9, ///< bottom
InferiorToSuperior = 8, ///< head - 0b1000
SuperiorToInferior = 9, ///< foot
};

private:
Expand All @@ -91,7 +91,7 @@ class ITKCommon_EXPORT AnatomicalOrientation
#define ITK_ORIENTATION_ENUM(P, S, T) m_OrientationValue<P, S, T>


enum class ToOrientationEnum : uint32_t
enum class ToEnum : uint32_t

{
INVALID = 0,
Expand Down Expand Up @@ -246,6 +246,162 @@ class ITKCommon_EXPORT AnatomicalOrientation
CoordinateEnum::RightToLeft)
};

enum class FromEnum : uint32_t

{
INVALID = 0,
RIP = ITK_ORIENTATION_ENUM(CoordinateEnum::RightToLeft,
CoordinateEnum::InferiorToSuperior,
CoordinateEnum::PosteriorToAnterior),
LIP = ITK_ORIENTATION_ENUM(CoordinateEnum::LeftToRight,
CoordinateEnum::InferiorToSuperior,
CoordinateEnum::PosteriorToAnterior),
RSP = ITK_ORIENTATION_ENUM(CoordinateEnum::RightToLeft,
CoordinateEnum::SuperiorToInferior,
CoordinateEnum::PosteriorToAnterior),
LSP = ITK_ORIENTATION_ENUM(CoordinateEnum::LeftToRight,
CoordinateEnum::SuperiorToInferior,
CoordinateEnum::PosteriorToAnterior),
RIA = ITK_ORIENTATION_ENUM(CoordinateEnum::RightToLeft,
CoordinateEnum::InferiorToSuperior,
CoordinateEnum::AnteriorToPosterior),
LIA = ITK_ORIENTATION_ENUM(CoordinateEnum::LeftToRight,
CoordinateEnum::InferiorToSuperior,
CoordinateEnum::AnteriorToPosterior),
RSA = ITK_ORIENTATION_ENUM(CoordinateEnum::RightToLeft,
CoordinateEnum::SuperiorToInferior,
CoordinateEnum::AnteriorToPosterior),
LSA = ITK_ORIENTATION_ENUM(CoordinateEnum::LeftToRight,
CoordinateEnum::SuperiorToInferior,
CoordinateEnum::AnteriorToPosterior),

IRP = ITK_ORIENTATION_ENUM(CoordinateEnum::InferiorToSuperior,
CoordinateEnum::RightToLeft,
CoordinateEnum::PosteriorToAnterior),
ILP = ITK_ORIENTATION_ENUM(CoordinateEnum::InferiorToSuperior,
CoordinateEnum::LeftToRight,
CoordinateEnum::PosteriorToAnterior),
SRP = ITK_ORIENTATION_ENUM(CoordinateEnum::SuperiorToInferior,
CoordinateEnum::RightToLeft,
CoordinateEnum::PosteriorToAnterior),
SLP = ITK_ORIENTATION_ENUM(CoordinateEnum::SuperiorToInferior,
CoordinateEnum::LeftToRight,
CoordinateEnum::PosteriorToAnterior),
IRA = ITK_ORIENTATION_ENUM(CoordinateEnum::InferiorToSuperior,
CoordinateEnum::RightToLeft,
CoordinateEnum::AnteriorToPosterior),
ILA = ITK_ORIENTATION_ENUM(CoordinateEnum::InferiorToSuperior,
CoordinateEnum::LeftToRight,
CoordinateEnum::AnteriorToPosterior),
SRA = ITK_ORIENTATION_ENUM(CoordinateEnum::SuperiorToInferior,
CoordinateEnum::RightToLeft,
CoordinateEnum::AnteriorToPosterior),
SLA = ITK_ORIENTATION_ENUM(CoordinateEnum::SuperiorToInferior,
CoordinateEnum::LeftToRight,
CoordinateEnum::AnteriorToPosterior),

RPI = ITK_ORIENTATION_ENUM(CoordinateEnum::RightToLeft,
CoordinateEnum::PosteriorToAnterior,
CoordinateEnum::InferiorToSuperior),
LPI = ITK_ORIENTATION_ENUM(CoordinateEnum::LeftToRight,
CoordinateEnum::PosteriorToAnterior,
CoordinateEnum::InferiorToSuperior),
RAI = ITK_ORIENTATION_ENUM(CoordinateEnum::RightToLeft,
CoordinateEnum::AnteriorToPosterior,
CoordinateEnum::InferiorToSuperior),
LAI = ITK_ORIENTATION_ENUM(CoordinateEnum::LeftToRight,
CoordinateEnum::AnteriorToPosterior,
CoordinateEnum::InferiorToSuperior),
RPS = ITK_ORIENTATION_ENUM(CoordinateEnum::RightToLeft,
CoordinateEnum::PosteriorToAnterior,
CoordinateEnum::SuperiorToInferior),
LPS = ITK_ORIENTATION_ENUM(CoordinateEnum::LeftToRight,
CoordinateEnum::PosteriorToAnterior,
CoordinateEnum::SuperiorToInferior),
RAS = ITK_ORIENTATION_ENUM(CoordinateEnum::RightToLeft,
CoordinateEnum::AnteriorToPosterior,
CoordinateEnum::SuperiorToInferior),
LAS = ITK_ORIENTATION_ENUM(CoordinateEnum::LeftToRight,
CoordinateEnum::AnteriorToPosterior,
CoordinateEnum::SuperiorToInferior),

PRI = ITK_ORIENTATION_ENUM(CoordinateEnum::PosteriorToAnterior,
CoordinateEnum::RightToLeft,
CoordinateEnum::InferiorToSuperior),
PLI = ITK_ORIENTATION_ENUM(CoordinateEnum::PosteriorToAnterior,
CoordinateEnum::LeftToRight,
CoordinateEnum::InferiorToSuperior),
ARI = ITK_ORIENTATION_ENUM(CoordinateEnum::AnteriorToPosterior,
CoordinateEnum::RightToLeft,
CoordinateEnum::InferiorToSuperior),
ALI = ITK_ORIENTATION_ENUM(CoordinateEnum::AnteriorToPosterior,
CoordinateEnum::LeftToRight,
CoordinateEnum::InferiorToSuperior),
PRS = ITK_ORIENTATION_ENUM(CoordinateEnum::PosteriorToAnterior,
CoordinateEnum::RightToLeft,
CoordinateEnum::SuperiorToInferior),
PLS = ITK_ORIENTATION_ENUM(CoordinateEnum::PosteriorToAnterior,
CoordinateEnum::LeftToRight,
CoordinateEnum::SuperiorToInferior),
ARS = ITK_ORIENTATION_ENUM(CoordinateEnum::AnteriorToPosterior,
CoordinateEnum::RightToLeft,
CoordinateEnum::SuperiorToInferior),
ALS = ITK_ORIENTATION_ENUM(CoordinateEnum::AnteriorToPosterior,
CoordinateEnum::LeftToRight,
CoordinateEnum::SuperiorToInferior),

IPR = ITK_ORIENTATION_ENUM(CoordinateEnum::InferiorToSuperior,
CoordinateEnum::PosteriorToAnterior,
CoordinateEnum::RightToLeft),
SPR = ITK_ORIENTATION_ENUM(CoordinateEnum::SuperiorToInferior,
CoordinateEnum::PosteriorToAnterior,
CoordinateEnum::RightToLeft),
IAR = ITK_ORIENTATION_ENUM(CoordinateEnum::InferiorToSuperior,
CoordinateEnum::AnteriorToPosterior,
CoordinateEnum::RightToLeft),
SAR = ITK_ORIENTATION_ENUM(CoordinateEnum::SuperiorToInferior,
CoordinateEnum::AnteriorToPosterior,
CoordinateEnum::RightToLeft),
IPL = ITK_ORIENTATION_ENUM(CoordinateEnum::InferiorToSuperior,
CoordinateEnum::PosteriorToAnterior,
CoordinateEnum::LeftToRight),
SPL = ITK_ORIENTATION_ENUM(CoordinateEnum::SuperiorToInferior,
CoordinateEnum::PosteriorToAnterior,
CoordinateEnum::LeftToRight),
IAL = ITK_ORIENTATION_ENUM(CoordinateEnum::InferiorToSuperior,
CoordinateEnum::AnteriorToPosterior,
CoordinateEnum::LeftToRight),
SAL = ITK_ORIENTATION_ENUM(CoordinateEnum::SuperiorToInferior,
CoordinateEnum::AnteriorToPosterior,
CoordinateEnum::LeftToRight),

PIR = ITK_ORIENTATION_ENUM(CoordinateEnum::PosteriorToAnterior,
CoordinateEnum::InferiorToSuperior,
CoordinateEnum::RightToLeft),
PSR = ITK_ORIENTATION_ENUM(CoordinateEnum::PosteriorToAnterior,
CoordinateEnum::SuperiorToInferior,
CoordinateEnum::RightToLeft),
AIR = ITK_ORIENTATION_ENUM(CoordinateEnum::AnteriorToPosterior,
CoordinateEnum::InferiorToSuperior,
CoordinateEnum::RightToLeft),
ASR = ITK_ORIENTATION_ENUM(CoordinateEnum::AnteriorToPosterior,
CoordinateEnum::SuperiorToInferior,
CoordinateEnum::RightToLeft),
PIL = ITK_ORIENTATION_ENUM(CoordinateEnum::PosteriorToAnterior,
CoordinateEnum::InferiorToSuperior,
CoordinateEnum::LeftToRight),
PSL = ITK_ORIENTATION_ENUM(CoordinateEnum::PosteriorToAnterior,
CoordinateEnum::SuperiorToInferior,
CoordinateEnum::LeftToRight),
AIL = ITK_ORIENTATION_ENUM(CoordinateEnum::AnteriorToPosterior,
CoordinateEnum::InferiorToSuperior,
CoordinateEnum::LeftToRight),
ASL = ITK_ORIENTATION_ENUM(CoordinateEnum::AnteriorToPosterior,
CoordinateEnum::SuperiorToInferior,
CoordinateEnum::LeftToRight)

};

#undef ITK_ORIENTATION_ENUM


Expand All @@ -255,7 +411,7 @@ class ITKCommon_EXPORT AnatomicalOrientation
*/
AnatomicalOrientation(CoordinateEnum primary, CoordinateEnum secondary, CoordinateEnum tertiary);

AnatomicalOrientation(ToOrientationEnum orientation)
AnatomicalOrientation(ToEnum orientation)
: m_Value(orientation)
{}

Expand All @@ -268,15 +424,17 @@ class ITKCommon_EXPORT AnatomicalOrientation
AnatomicalOrientation(LegacyOrientationType legacyOrientation);
#endif

AnatomicalOrientation(FromEnum orientation);

explicit AnatomicalOrientation(const DirectionType & d)
: m_Value(DirectionCosinesToOrientation(d))
{}

explicit AnatomicalOrientation(std::string str);

operator ToOrientationEnum() const { return m_Value; }
operator ToEnum() const { return m_Value; }

const std::string &
std::string
GetAsString() const;

DirectionType
Expand All @@ -285,7 +443,7 @@ class ITKCommon_EXPORT AnatomicalOrientation
return OrientationToDirectionCosines(m_Value);
}

ToOrientationEnum
ToEnum
GetAsOrientation() const
{
return m_Value;
Expand All @@ -309,6 +467,11 @@ class ITKCommon_EXPORT AnatomicalOrientation
return GetCoordinateTerm(CoordinateMajornessTermsEnum::TertiaryMinor);
}

std::array<CoordinateEnum, 3>
GetTerms() const
{
return { GetPrimaryTerm(), GetSecondaryTerm(), GetTertiaryTerm() };
}

static bool
SameOrientationAxes(CoordinateEnum a, CoordinateEnum b)
Expand All @@ -318,42 +481,43 @@ class ITKCommon_EXPORT AnatomicalOrientation
}

/** \brief Return the closest orientation for a direction cosine matrix. */
static ToOrientationEnum
static ToEnum
DirectionCosinesToOrientation(const DirectionType & dir);

/** \brief Return the direction cosine matrix for a orientation. */
static DirectionType OrientationToDirectionCosines(ToOrientationEnum);
static DirectionType OrientationToDirectionCosines(ToEnum);


friend ITKCommon_EXPORT std::ostream &
operator<<(std::ostream & out, ToOrientationEnum value);
operator<<(std::ostream & out, ToEnum value);


private:
// Private methods to create the maps, these will only be called once.
static std::map<ToOrientationEnum, std::string>
static std::map<ToEnum, std::string>
CreateCodeToString();
static std::map<std::string, ToOrientationEnum>
CreateStringToCode();

/** \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<ToOrientationEnum, std::string> &
static const std::map<ToEnum, std::string> &
GetCodeToString();

/** \brief Return the global instance of the map from string to orientation enum.
*/
static const std::map<std::string, ToOrientationEnum> &
static const std::map<std::string, ToEnum> &
GetStringToCode();

ToOrientationEnum m_Value;
ToEnum m_Value;
};


ITKCommon_EXPORT std::ostream &
operator<<(std::ostream & out, typename AnatomicalOrientation::ToOrientationEnum value);
operator<<(std::ostream & out, typename AnatomicalOrientation::CoordinateEnum value);

ITKCommon_EXPORT std::ostream &
operator<<(std::ostream & out, typename AnatomicalOrientation::ToEnum value);

ITKCommon_EXPORT std::ostream &
operator<<(std::ostream & out, const AnatomicalOrientation & orientation);
Expand Down
Loading

0 comments on commit 4042eb3

Please sign in to comment.