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

remove presmoothingforward & postsmoothingback projectors #607

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

rijobro
Copy link
Collaborator

@rijobro rijobro commented Jun 25, 2020

Suggestion fix for #606. So far, I've only implemented copies for ...MatrixByBin projectors, but would have to be implemented for all projectors. Could easily be extended to projector pairs.

@rijobro rijobro marked this pull request as draft June 25, 2020 11:52
Copy link
Collaborator

@KrisThielemans KrisThielemans left a comment

Choose a reason for hiding this comment

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

Do we really need to implement most of these copy constructors? Isn't the default one ok in most cases?

It's seems surprising to let create_shared_clone() return a unique_ptr.... What was our terminology for the other hierarchy (I can't find it anymore...).

Otherwise looks good. I guess we need to still add a few others.

@@ -55,6 +55,12 @@ BackProjectorByBin::BackProjectorByBin()
set_defaults();
}

BackProjectorByBin::BackProjectorByBin(const BackProjectorByBin& to_copy)
: _already_set_up(false), _density_sptr(nullptr), _post_data_processor_sptr(nullptr)
Copy link
Collaborator

Choose a reason for hiding this comment

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

why set these to null etc? I can agree you'd want to force people to call set_up again (although I'm not sure it's strictly necessary), but I find it dangerous to remove any _post_data_processor_sptr. If there was one, it won't be a clone anymore!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I thought it best to set them as null so as not to create a shallow copy (since they don't have their own create_shared_clone methods). What if you think you're modifying the data processors parameters for the clone, when in actual fact, you're modifying the parameters of both the clone and the original?

Copy link
Collaborator

Choose a reason for hiding this comment

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

That sounds dangerous indeed. However, the question is if it can happen. We've put in a lot of effort to avoid it in the other stuff.

However, as far as I remember, _density_sptr is only set by BackProjector::set_up() which would create a new sptr. (not modify an existing one). Indeed, I don't think there's a way to modify to modify the shared object. Similarly, as long as we don't have a shared_ptr<DataProcessor> get_post_data_processor_sptr() or DataProcessor& get_post_data_processor(), I cannot see how it would be unsafe to reuse it.

It's possibly a bit confusing that set_post_data_processor would override anything that was already there. We replace that then with add (and use ChainedDataProcessor) and add a remove_post_data_processor like I believe you do in SIRF transformations. However, I don't think that's really necessary for now.

So, if we don't do that work, the question is what is more surprising: a clone which doesn't do the same (the current situation), or a clone where a subsequent set_post_data_processor would override whatever was there. I certainly think the former is less desirable.

Copy link
Collaborator

Choose a reason for hiding this comment

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

the unique_ptr was functionality that I copied from SIRF's clone methods for DataContainer. Would you rather it were shared_ptr? I thought unique_ptr would let the user know that the copy wasn't stored elsewhere.

That's true, but it's weird to have a create_shared return a unique. It should then be called create_unique_clone. I'm fine with calling it the latter. (It's certainly better than implying that its properties are shared)

Copy link
Collaborator

Choose a reason for hiding this comment

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

2nd thoughts. Are they in fact unique?

For instance, the projmatrix presumably still is shared (I would certainly suggest that it is, as otherwise you're going to run out of memory very quickly). Can anyone call its various set functions? Obviously, the original owner could. This is an example where sharing is actually necessary, albeit it dangerous. oh well

This is

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's confusing, I tried to make them as independent as possible (e.g., no sharing of data processors), but they do share the projmatrix (for memory).

My feeling is that we can do what we want in terms of which objects are copied shallowly and deeply, provided we document it well. I already put in the doxygen that the projmatrix would only be shallow copied. I can also do a shallow copy of the data processor if you'd like, and document that, too.

We could name the method create_clone, which is less specific on unique versus shared. This seems appropriate, since we're doing a mix of the two.

What do you think?

@@ -56,6 +56,12 @@ ForwardProjectorByBin::ForwardProjectorByBin()
set_defaults();
}

ForwardProjectorByBin::ForwardProjectorByBin(const ForwardProjectorByBin &to_copy)
: _already_set_up(false), _density_sptr(nullptr), _pre_data_processor_sptr(nullptr)
Copy link
Collaborator

Choose a reason for hiding this comment

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

see comment for BackProjectorByBin

src/recon_test/test_projector_clone.cxx Outdated Show resolved Hide resolved
@rijobro
Copy link
Collaborator Author

rijobro commented Jun 28, 2020

the unique_ptr was functionality that I copied from SIRF's clone methods for DataContainer. Would you rather it were shared_ptr? I thought unique_ptr would let the user know that the copy wasn't stored elsewhere.

@rijobro
Copy link
Collaborator Author

rijobro commented Jun 28, 2020

Do we really need to implement most of these copy constructors? Isn't the default one ok in most cases?

If we use the default, then we'll create a shallow copy of any shared pointers, which seems dangerous to me. Ideally, both DataProcessor and DiscretisedDensity would have their own create_shared_clone methods which I would have used in the base-level projectors.

I guess we need to still add a few others.

It looks like, currently, this functionality would only be used in #580 and then #240 once I get that up to date again. Could we do it on a case-by-case basis?

@KrisThielemans
Copy link
Collaborator

Do we really need to implement most of these copy constructors? Isn't the default one ok in most cases?

If we use the default, then we'll create a shallow copy of any shared pointers, which seems dangerous to me. Ideally, both DataProcessor and DiscretisedDensity would have their own create_shared_clone methods which I would have used in the base-level projectors.

discussed above. I don't think that's necessary here.

Obviously, the aim of having shared_ptr is to share some stuff (as long as it's safe). Otherwise we should have unique_ptr all over the place.

Co-authored-by: Kris Thielemans <KrisThielemans@users.noreply.github.com>
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.

None yet

2 participants