Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add AnatomicalOrientation class #4804

Conversation

blowekamp
Copy link
Member

This PR is a WIP, and more details will be added here when ready for discussion and review.

See #4788 for this issue and discussion of these changes.

@github-actions github-actions bot added type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots area:Python wrapping Python bindings for a class type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct area:Core Issues affecting the Core module area:IO Issues affecting the IO module labels Aug 14, 2024
Copy link
Member

@dzenanz dzenanz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good so far!

@gdevenyi

This comment was marked as off-topic.

@blowekamp blowekamp force-pushed the add_anatomical_orientation branch from 2502620 to fb83a56 Compare August 15, 2024 12:44
@issakomi

This comment was marked as off-topic.

@gdevenyi

This comment was marked as off-topic.

@blowekamp
Copy link
Member Author

Please move this conversation about MINC to #147 or another place on topic.

@blowekamp blowekamp force-pushed the add_anatomical_orientation branch from fb83a56 to 4042eb3 Compare August 15, 2024 21:06
@blowekamp blowekamp force-pushed the add_anatomical_orientation branch from 4042eb3 to 3e2ef5b Compare August 16, 2024 18:35
@blowekamp
Copy link
Member Author

@dzenanz Almost there. There is currently both the ToEnum, and FromEnum. The class "AnatomicalOrientation" can be seen to hold the representation of the orientation, and provide conversion with the Enum's, direction matrix, and perhaps the preferred handling it as 3 components.

There is still the ToEnum string representation left over from the original DICOMOrientation class. That is AnatomicalOreination("LPS") construction and AnatomicalOrientation(OE::LPS).ToString() == "LPS". Anatomicalorientation::operator<< produce something like "left-to-right, anterior-to-posterior, inferior-to-superior" now, which is unambiguous. Perhaps the string character tripplets should just be removed? However the string representation is convent with a Python interface.

@dzenanz
Copy link
Member

dzenanz commented Aug 16, 2024

AnatomicalOreination("LPS") construction and AnatomicalOrientation(OE::LPS).ToString() == "LPS"

I would like to have this. This convenience did not exist within ITK proper before, so there is no need for some sort of backwards compatibility. I wonder whether we should have a method to convert "To" string from a "From" string and vice versa. E.g. if an application has "RAI" string as a "From" code, it can call something like AnatomicalOrientation::ConvertToFrom("RAI") and get "LPS". Such method would be symmetric, as the same operation would be needed to go from "From" to "To", and from "To" to "From" convention.

@blowekamp
Copy link
Member Author

So your suggestion is to keep the ambiguous "ToEnum" character representation, and just add a method to convert To/From character representations?

The concern here is really when AnatomicalOrientation("RIA") would be used, it is not clear if the string is being interpreted as a ToEnum or a FromEnum.

@dzenanz
Copy link
Member

dzenanz commented Aug 16, 2024

If you want, you can remove the string constructor. Is there another similarly convenient way to initialize it? Something like:

auto identityAO = AnatomicalOrientation::ToEnum("LPS");
AnatomicalOrientation ao(identityAO);

@dzenanz
Copy link
Member

dzenanz commented Aug 16, 2024

More generally,:

std::string toCode = "LPS";
auto aoEnum = AnatomicalOrientation::ToEnum(toCode);
AnatomicalOrientation ao(aoEnum);

@dzenanz
Copy link
Member

dzenanz commented Aug 21, 2024

What is the status of this PR? I would like it to be finished/merged before it becomes stale, as PR revival usually involves extra effort.

@blowekamp blowekamp force-pushed the add_anatomical_orientation branch from 3e2ef5b to 62a566b Compare September 3, 2024 16:05
@github-actions github-actions bot added the area:Filtering Issues affecting the Filtering module label Sep 3, 2024
@blowekamp
Copy link
Member Author

@dzenanz Shall we have the SpatialOrientation filter changes be in another PR?

@dzenanz
Copy link
Member

dzenanz commented Sep 3, 2024

I am fine with that. And that might even be better, to not hold up this PR.

@blowekamp blowekamp force-pushed the add_anatomical_orientation branch from 62a566b to 7192104 Compare September 3, 2024 18:00
@github-actions github-actions bot removed the area:Filtering Issues affecting the Filtering module label Sep 3, 2024
@blowekamp blowekamp force-pushed the add_anatomical_orientation branch from b642f96 to 58576c4 Compare October 21, 2024 18:30
@blowekamp blowekamp force-pushed the add_anatomical_orientation branch from 58576c4 to ded6b69 Compare October 21, 2024 19:17
@blowekamp blowekamp force-pushed the add_anatomical_orientation branch from ded6b69 to 1fb80ea Compare October 22, 2024 00:25
@blowekamp blowekamp requested review from N-Dekker and thewtex October 22, 2024 10:00
Copy link
Member

@thewtex thewtex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🍾

@blowekamp
Copy link
Member Author

I'm planning on merging this tomorrow unless there are further comments.

@N-Dekker
Copy link
Contributor

@blowekamp Shall I still have a look before the merge?

@blowekamp
Copy link
Member Author

@blowekamp Shall I still have a look before the merge?

yes please.

Comment on lines +185 to +199
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<double, std::pair<unsigned, unsigned>> 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));
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ConvertDirectionToPositiveEnum is hard for me to understand. I hope the other reviewers do understand it better than I do 😃

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The math or the general input and output of the method?

Copy link
Contributor

@N-Dekker N-Dekker Oct 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you are creating this multi-map, in order to find the direction matrix element that has the highest absolute value, right? (Just for my understanding -- this is not a change request.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that appears to be what is going on. As the comment says it was mostly a copy of the existing working method in itk::SpatialObjectAdaptor::FromDirectionCosines

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, thanks, and the math itself? How does it work? Is it a known approach?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a tested algorithm that worked for all the test cases I put it through. It explicitly does what a "smarter" and incorrect algorithm did previously:
8801247

@blowekamp blowekamp merged commit 283ad56 into InsightSoftwareConsortium:master Oct 23, 2024
13 checks passed
@dzenanz
Copy link
Member

dzenanz commented Oct 23, 2024

🎆 🎊 🥳

@N-Dekker
Copy link
Contributor

@blowekamp There appear some compile errors at the CI (master branch), if you know how to fix them, please do 😃 At https://open.cdash.org/viewBuildError.php?buildid=9981860


/Users/builder/externalModules/IO/PhilipsREC/src/itkPhilipsRECImageIO.cxx:713:61: error: no member named 'FromEnum' in 'itk::AnatomicalOrientation'
  AnatomicalOrientation coord_orient(AnatomicalOrientation::FromEnum::RSA);
                                     ~~~~~~~~~~~~~~~~~~~~~~~^
[CTest: warning matched] /Users/builder/externalModules/IO/PhilipsREC/src/itkPhilipsRECImageIO.cxx:713:37: warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]
  AnatomicalOrientation coord_orient(AnatomicalOrientation::FromEnum::RSA);
                                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[CTest: warning matched] /Users/builder/externalModules/IO/PhilipsREC/src/itkPhilipsRECImageIO.cxx:713:38: note: add a pair of parentheses to declare a variable
  AnatomicalOrientation coord_orient(AnatomicalOrientation::FromEnum::RSA);
                                     ^
      
 

@blowekamp
Copy link
Member Author

Follow up: #4899

@jhlegarreta
Copy link
Member

jhlegarreta commented Oct 27, 2024

Seems like there's a warning in the ITK.Windows.Python Azure build introduced by this PR:

D:\a\1\s-build\Wrapping\Modules\ITKCommon\itkAnatomicalOrientationPython.cpp(3971):
 warning C4996: 'itk::AnatomicalOrientation::AnatomicalOrientation':
 Use the AnatomicalOrientation::FromEnum type instead.

e.g.
https://dev.azure.com/itkrobotwindowpython/ITK.Windows.Python/_build/results?buildId=4113&view=logs&j=2d2b3007-3c5c-5840-9bb0-2b1ea49925f3&t=77aad734-2057-5694-9ae2-ee1f5f26eae8&l=4288

Visible in the dashboard as well:
https://open.cdash.org/viewBuildError.php?type=1&buildid=9988068

Not sure how the below block could be handled better to avoid the warning:
https://github.com/InsightSoftwareConsortium/ITK/pull/4804/files#diff-0271cfd0418afac76ae9a99eb3c59923eac04cdfc032bbf51c3bc59c88ca1c81R441-R443

@blowekamp
Copy link
Member Author

Not sure how the below block could be handled better to avoid the warning: https://github.com/InsightSoftwareConsortium/ITK/pull/4804/files#diff-0271cfd0418afac76ae9a99eb3c59923eac04cdfc032bbf51c3bc59c88ca1c81R441-R443

Neither am I. Is the build/wrapping defining ITK_LEGACY_SILENT when compiling?

@N-Dekker
Copy link
Contributor

@blowekamp Please note that the warning still uses the term FromEnum. Didn't you replace that by Positive/Negative Enum?

@blowekamp
Copy link
Member Author

Please note that the warning still uses the term FromEnum. Didn't you replace that by Positive/Negative Enum?

Yes, good catch the text in the warning should be updated as you recommend. But the issue is that the warning should not be occurring.

@blowekamp
Copy link
Member Author

Perhaps the bigger problem on the nightly build:

/Users/builder/external[Modules/IO/PhilipsREC/src/itkPhilipsRECImageIO.cxx:721](https://github.com/InsightSoftwareConsortium/ITK/blob/0883d0c3b7967b9319ad9ac3a3d15fae576e382c/Modules/IO/PhilipsREC/src/itkPhilipsRECImageIO.cxx#L721):20: error: no viable overloaded '='
      coord_orient = SpatialOrientationEnums::ValidCoordinateOrientations::ITK_COORDINATE_ORIENTATION_RAI;
      ~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[CTest: warning matched] /Users/builder/external[Modules/Core/Common/include/itkAnatomicalOrientation.h:53](https://github.com/InsightSoftwareConsortium/ITK/blob/0883d0c3b7967b9319ad9ac3a3d15fae576e382c/Modules/Core/Common/include/itkAnatomicalOrientation.h#L53):24: note: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'itk::SpatialOrientationEnums::ValidCoordinateOrientations' to 'const itk::AnatomicalOrientation' for 1st argument
class ITKCommon_EXPORT AnatomicalOrientation
                       ^

@seanm may be compiling with LEGACY_REMOVE enabled so this conversion function is removed.

@dzenanz
Copy link
Member

dzenanz commented Oct 28, 2024

Most of Ryzenator's and Corista's builds have ITK_LEGACY_REMOVE:BOOL=ON.

@blowekamp
Copy link
Member Author

Most of Ryzenator's and Corista's builds have ITK_LEGACY_REMOVE:BOOL=ON.

But they don't have PhilipsREC module enabled?

@dzenanz
Copy link
Member

dzenanz commented Oct 28, 2024

But they don't have PhilipsREC module enabled?

Ah, that is a non-default module, which I indeed did not turn on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:Core Issues affecting the Core module area:IO Issues affecting the IO module area:Python wrapping Python bindings for a class type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants