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

Safer C++ DataContainer data type handling updated #1210

Open
wants to merge 27 commits into
base: master
Choose a base branch
from

Conversation

evgueni-ovtchinnikov
Copy link
Contributor

Changes in this pull request

This PR takes over from PR #1195, which was left unattended for a long time, resulting in weird conflicts with master.

Testing performed

All tests run by ctest succeeded.

Related issues

Fixes #1193.

Checklist before requesting a review

  • I have performed a self-review of my code
  • I have added docstrings/doxygen in line with the guidance in the developer guide
  • I have implemented unit tests that cover any new or modified functionality
  • The code builds and runs on my machine
  • CHANGES.md has been updated with any functionality change

Contribution Notes

Please read and adhere to the contribution guidelines.

Please tick the following:

  • The content of this Pull Request (the Contribution) is intentionally submitted for inclusion in SIRF (the Work) under the terms and conditions of the Apache-2.0 License.

if (this != &to_copy) {
if (static_cast<void*>(this) != static_cast<const void*>(&to_copy)) {
// Try to cast to NiftiImageData.
const NiftiImageData<dataType> * const nii_ptr = dynamic_cast<const NiftiImageData<dataType> * const >(&to_copy);
Copy link
Member

Choose a reason for hiding this comment

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

Are the following lines supposed to work also if dataType != float?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no idea, this is Richard's stuff, and it looks like he wanted to cover for lots of data types - from bool to long double (see NiftiImageData.h)

at any rate, I doubt we would ever need any dataType other than float

to remind you: dataType cannot be complex - complex images are treated as pairs of real ones

Copy link
Member

Choose a reason for hiding this comment

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

Checking copy_nifti_image it contains

memcpy(output_image_sptr->data, image_to_copy_sptr->data, mem);

therefore, it needs to have the same data-types, see these lines are correct.

Note that it can be simplified to

auto nii_ptr = dynamic_cast<const NiftiImageData<dataType> * const >(&to_copy)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

therefore, it needs to have the same data-types

so far as I can see, this is to be taken care of by nifti_copy_nim_info

Note that it can be simplified

thanks, adopted

else {
this->_nifti_image = NiftiImageData<float>::create_from_geom_info(*to_copy.get_geom_info_sptr());
// Always float
this->set_up_data(NIFTI_TYPE_FLOAT32);
Copy link
Member

Choose a reason for hiding this comment

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

this looks incorrect to me. *this should always have dataType, otherwise templating this makes no sense. So we need to set-up with the corresponding NIFTI.... (Easiest to do by having a helper class with template specialisations for supported dataTypes).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe this is only needed if we decide to use nifti data types other than DT_FLOAT32.

@@ -102,7 +139,11 @@ NiftiImageData<dataType>& NiftiImageData<dataType>::operator=(const ImageData& t
// Always float
this->set_up_data(NIFTI_TYPE_FLOAT32);
Copy link
Member

Choose a reason for hiding this comment

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

as above

auto &it_src = to_copy.begin();
auto &it_dst = this->begin();
for (; it_src != to_copy.end(); ++it_src, ++it_dst)
*it_dst = (*it_src).complex_float().real();
Copy link
Member

Choose a reason for hiding this comment

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

this is truncating complex to float. 2 remarks:

  • This would be amazingly confusing if dataType is complex. I know you're saying this can currently not happen, but do we guarantee it anywhere?
  • If dataType is float or double, then this in my opinion shouldn't be in an assignment operator.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, dataType cannot be complex - see 12 data types dealt with by change_datatype.

As the destination can only store float data while the source has complex_float_t data, some kind of truncation (either abs or real) is unavoidable I am afraid.

src/Registration/cReg/NiftiImageData.cpp Outdated Show resolved Hide resolved
@KrisThielemans KrisThielemans added this to the v4.0 milestone Nov 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Longer term solutions to DataContainer data type issue needed.
2 participants