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

Scatter simulation #44

Merged
merged 195 commits into from
Apr 21, 2020
Merged

Conversation

NikEfth
Copy link
Collaborator

@NikEfth NikEfth commented Sep 12, 2016

So, this is the PR for the scatter simulation.

New classes ScatterSimulation and SingleScatterSimulation which have taken over the old ScatterEstimation. This is their "minimal" implementation having only the functionality that the older class used to have. I removed, for the time being, the subsampling stuff, in order to first see why/where there is the mistake. Once this has been sorted I will start adding more things bit-by-bit.

Please don't review the new ScatterEstimation class, yet. I will create a branch, from this one, on which I will work on the ScatterEstimation and let you know when it will be ready for reviewing.

In addition, there are some minor changes in other places, like clone functions in ExamInfo.
In my laptop all tests succeeded and Travis is doing good, so far.

ATB,
Nikos

Transfer code from the other branches.
Files which were deleted when merged with UCL/master
New clone functions added in ExamInfo.
@KrisThielemans
Copy link
Collaborator

Hi
Most of these are small. some are pedantic...

Some of these functions should probably have PET in their name (Maybe only the ScatterSimulation bits?)

  • Not sure about authors of these files (and corresponding copyright). Probably need to include Harry, maybe Pablo and Nikos Dikaios. Depends on what you copied from where.
  • Copyright (C) 2013 - 2016 University College London, use a comma unless changes made 2014, 2015 as well :-;

ScatterEstimationByBin

  • Best to rename to avoid name clash with old class. Drop ByBin?
  • Why do we need reconstruct_iterative and reconstruct_analytic (with such differrent calling sequence)?
  • get_image_from_file doxygen says it’s set_image_from_file. Also some doxygen below that for functions which don’t exist, which will confuse it.
  • post_processing() I think we should move most of its functionality to setup(). post_processing is only called after parsing, so wouldn’t be appropriate within python/Matlab.
  • ProjDataInfoCylindricalNoArcCorr * proj_data_info_2d_ptr; No raw pointers as class members.
    ExamInfo::clone() . no need for the static cast (just return new ExamInfo(*this))
  • There are multiplicative_data_3d and normalisation_data_3d (what’s the difference?) and norm_projdata_3d_sptr. The latter one should normally not be a class member as it’s presumably used to create normalisation_data_3d
  • mask_atten_image_filename etc. Why the “atten” in the variable name?
  • variable multimulti2d is a strange name :-;

ScatterSimulation

  • doxygen containis typo SignelScatterSimulation (important for linking). Also needs to be prefixed by stir:: to get the link to work.
  • Lots of inline functions. I think we should move it to .cxx. Inline is good for small functions called often, but otherwise slow down the compiler (and mean more recompilations if you change their implementation). (could leave the Compton ones inline if you prefer)
  • set_activity_image_sptr return Succeeded, set_activity_image doesn’t (calls error). Best to let both do the same,and I’m these days in favour of the latter. (i.e. let the user catch exceptions)
  • get_output_proj_data(shared_ptr& arg), change to shared_ptr get_output_proj_data() const;
  • set_attenuation_threshold(const float& arg) etc. ok to use references but it’s quite non-standard and actually slower for such small entities (as you’ll be passing pointers around)
  • post_processing creates a ProjDataInMemory for input_projdata_2d_sptr if data is 2D, just copy pointer?
  • reconstruction_template_par_filename usage. I see you had to do some explicit KeyParser stuff here after all. Maybe that means we had to have it elsewhere after all? I guess same for ScatterSimulation
  • Zoom factors currently still hard-wired
  • reconstruct_iterative. Cannot have paths like "./extras/recon_". They will likely fail on Windows. Shouldn’t the writing be left to the reconstruction object? (i.e. set its output filename)
  • apply_mask_in_place. This seems far too complicated. It was done like that in the script as we didn’t have a masking facility there. If the mask is binary, shouldn’t we just multiply?

other

  • scatter_detection_modelling.cxx, scatter_estimate_for_one_scatter_point.cxx, single_scatter_integrals.cxx, upsample_and_fit_scatter_estimate.cxx sadly have a load of white space differences. Not sure what to do about this, but I’d prefer to revert those…
  • single_scatter_estimate.cxx . has white space diffs, but we probably should rename single_scatter_estimate etc?

- [x] Choose set_up by dynamic_cast rather than name.
- [x] post_processing() I think we should move most of its functionality
to setup(). post_processing is only called after parsing, so wouldn’t be
appropriate within python/Matlab.
- [x] reconstruction_template_par_filename usage. I see you had to do
some explicit KeyParser stuff here after all. Maybe that means we had to
have it elsewhere after all? I guess same for ScatterSimulation
SingleScatterSimulation

ScatterEstimationByBin:
- [x] post_processing() I think we should move most of its functionality
to setup(). post_processing is only called after parsing, so wouldn’t be
appropriate within python/Matlab.
- [x] ProjDataInfoCylindricalNoArcCorr * proj_data_info_2d_ptr; No raw
pointers as class members. ExamInfo::clone() . no need for the static
cast (just return new ExamInfo(*this))
- [x] Choose set_up by dynamic_cast rather than name.

ScatterSimulation:
- [x] Lots of inline functions. I think we should move it to .cxx.
Inline is good for small functions called often, but otherwise slow down
the compiler (and mean more recompilations if you change their
implementation). (could leave the Compton ones inline if you prefer)
- [x] set_activity_image_sptr return Succeeded, set_activity_image
doesn’t (calls error). Best to let both do the same,and I’m these days
in favour of the latter. (i.e. let the user catch exceptions)
- [x] set_attenuation_threshold(const float& arg) etc. ok to use
references but it’s quite non-standard and actually slower for such
small entities (as you’ll be passing pointers around)
- [x] post_processing creates a ProjDataInMemory for
input_projdata_2d_sptr if data is 2D, just copy pointer?
	— I presume that this comment is for ScatterEstimationaByBin. Well not quite. If it is 2D then I cannot upsample. So (better) through an error?
- [x] reconstruction_template_par_filename usage. I see you had to do
some explicit KeyParser stuff here after all. Maybe that means we had to
have it elsewhere after all? I guess same for ScatterSimulation
	- Most of this code is now in the post_processing().
Next steps are to run the estimation process.
What is left to be tested is the return to 3D.

- [x] There are multiplicative_data_3d and normalisation_data_3d (what’s
the difference?) and norm_projdata_3d_sptr. The latter one should
normally not be a class member as it’s presumably used to create
normalisation_data_3d
the results are disappointing.
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.

hi. most comments are tiny. I think there is one bug (in attenuation coefficients).

there's still a few files with mostly white-space diffs. I'd prefer that you revert those such that I can see what actually changed (unless you're 100% sure that you current editor settings are the final ones that we're going to use, and you email me a diff ignoring white-space...)

thanks!

In addition to the comments in the github side:

- [x] mask_atten_image_filename etc. Why the “atten” in the variable
name?
- [x] variable multimulti2d is a strange name :-;
- [x] get_output_proj_data(shared_ptr& arg), change to shared_ptr
get_output_proj_data() const;
- [x] Zoom factors currently still hard-wired
- [x] Every member initialised in post_proccessing must have a set
function
- [x] Use only BinNormalisation throught out the code.
Copy link
Collaborator Author

@NikEfth NikEfth left a comment

Choose a reason for hiding this comment

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

Needs some clean up but most comments have been implemented.

this->multiplicative_data_2d_sptr.reset(
new ChainedBinNormalisation(attenuation_correction, normalisation_coeffs));

iterative_object->get_objective_function_sptr()->set_normalisation_sptr(multiplicative_data_2d_sptr);
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 cannot fully understand the comment.

int len_x = this->atten_image_sptr.get()[0][min_z][min_y].get_length();

if (len_y != len_x)
error(boost::format("The voxels in the x (%1%) and y (%2%)"
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 have to check this more. I think I saw it somewhere

I had some mistakes mainly in the normalisations.
I think the estimation it working now.
fitting to the input_data than (input_data - randoms).

In addition, I removed some obsolete variables.
minor amendments and addition of the code to sabsample the scanner
Use boost::filesystem to create the path and filenames in debug mode. 
Now, paths are cross-platform

more minor aesthetic corrections
In estimation the appending to boost path was corrected in more places.
The run_scatter_test was a bit weird as in the simultion sets the zoomed image both in for the scatter points and as the original attenuation image. I am not sure wether this is bug or a feature to speed up the process. I left it as is for now.
@KrisThielemans
Copy link
Collaborator

hi nikos, I haven't checked why you need boost filesystem and boost system, but I'm somewhat reluctant to use this. We'd introduce a dependency on compiled libraries for boost, and that's creating us a ton of problems for SIRF sadly (you would think it'd be simple but it isn't).

could you tell me what you're using this for? We likely have equivalents in utilities.h.

We were using the environment variable RANDOM before, but this
is a system variable that returns a random number. This caused
failurs on OSX.
@KrisThielemans
Copy link
Collaborator

Success! https://travis-ci.org/github/UCL/STIR/builds/674304290.

The problem was that the test-script was using the env variable RANDOM. This turns out to be used to let you get a random number... (try echo $RANDOM a few times). Looks like you can overwrite it in Linux, but not OSX. Oh well.

Code was fine all along. I've also (re)checked that results of the scatter-simulation are identical to what we have in master.

I'll extend the tests a bit, possibly do a bit more renaming, and then it should be ready.

However, while checking everything, I discovered a problem when using the zooming of the attenuation image. I'll file a separate issue for that as it's also in master. Not sure yet if I'll fix this in this PR or not.

@KrisThielemans
Copy link
Collaborator

KrisThielemans commented Apr 16, 2020

A few more thing to finish

  • fix (potential) axial shift in scatter simulations #495
  • remove used of static variables such as max_single_scatter_cos_angle that actually depend on energy etc (as unsafe when the Scatter Simulation is run for different energy windows)
  • rename some classes to include the PET name (as wouldn't work for SPECT etc)
  • add a simple test for ScatterEstimation

- Currently only check in Debug mode to avoid impact on computation time.
- move computation of shift_detector_coordinates_to_origin to set_up
 (from process_data)
see UCL#495

- in downsample_density_image*, adjust zoom_z to avoid problems with UCL#495,
  also allow specifying default zoom_z (-1) if new_size_z is given
- add functions to check consistency in z-location (currently still disabled)

Also add get_*image() functions to avoid using shared_ptr too much
we had some static variables, and forget to clear the cached
detection_points_vector
These are tests for a symmetric object, checking if the result is symmetric.

Also enabled the consistency check mentioned in UCL#495. This means that
run_scatter_tests/sh will now fail.
This is now done by default in ScatterSimulation. Removing this avoids problems with UCL#495.

- changed recon_test_pack and PET_simulation script/par-file
- changed scatter-output file in recon_test_pack to take the new zooming into account.
Difference with respect to the previous version is about 4%.
(Note that the previous version was incorrect due to UCL#495)
- some clarifications in sample scatter_simulation.par
- removed obsolete file
Use scatter_estimate(Bin) as opposed to in terms of 2 detectors such that it
will apply for SPECT at some point.
original values did not reflect this was PET specific. Also used
more standard-form keywords for the simulate_scatter .par file.

Also fixed some issues in example files and STIR-UsersGuide
This was not necessary earlier-on as SingleScatterSimulation::process_data()
was calling set_up(), but no longer...
- use standard keywords for reconstruction and scatter simulation
- allow specifying these in the parameter file itself (as opposed to requiring a separate file)
3 Travis jobs gave errors of 0.124% while our threshold was 0.1%.
@KrisThielemans
Copy link
Collaborator

Current results (not changed since a while now) on the NEMA data from examples/Siemens-mMR/process_NEMA_data.sh
(500s, OSEM 14 subsets, 42 subiterations, 8mm Gaussian post-filter)

image

Good, but some non-uniformity still visible. We don't have the bed attenuation currently though.

@KrisThielemans
Copy link
Collaborator

I'm going to stop with this. There's still improvements to be made, but time has run out. It's working ok as far as I can see, and tests succeeded.

I'll make an issue with extra things to do.

@KrisThielemans KrisThielemans merged commit d510555 into UCL:release_4.0.0 Apr 21, 2020
KrisThielemans added a commit to KrisThielemans/STIR-1 that referenced this pull request Sep 17, 2023
…3_05_07

Merge master to tof 2023 05 07 + Siemens support
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.

4 participants