diff --git a/documentation/release_6.3.htm b/documentation/release_6.3.htm
index bdcc5dce7..b15a601cd 100644
--- a/documentation/release_6.3.htm
+++ b/documentation/release_6.3.htm
@@ -48,6 +48,10 @@
New functionality
stir_timings has now an extra option to parse a par-file for a projector-pair.
+
+ Added the ability to set a forward projector for mask projection in the ScatterEstimation
class.
+ PR #1530
+
Duration in sinogram interfile/exam_info obtained from lm_to_projdata has the correct value if we unlist all the events. This is not true for ROOT files
PR #1519
diff --git a/src/include/stir/scatter/ScatterEstimation.h b/src/include/stir/scatter/ScatterEstimation.h
index e3ed9a722..84d91e745 100644
--- a/src/include/stir/scatter/ScatterEstimation.h
+++ b/src/include/stir/scatter/ScatterEstimation.h
@@ -39,6 +39,7 @@
#include "stir/stir_math.h"
#include "stir/FilePath.h"
+#include "stir/recon_buildblock/ForwardProjectorByBin.h"
START_NAMESPACE_STIR
@@ -171,6 +172,11 @@ class ScatterEstimation : public ParsingObject
void set_recompute_mask_image(bool arg);
void set_recompute_mask_projdata(bool arg);
+ //! Sets the forward projector for the scatter estimation
+ void set_forward_projector_for_mask_sptr(const shared_ptr projector_sptr);
+ //! Get the forward projector used for the scatter estimation mask calculation
+ shared_ptr get_forward_projector_for_mask_sptr() const;
+
inline void set_scatter_simulation_method_sptr(const shared_ptr);
inline void set_num_iterations(int);
@@ -276,6 +282,8 @@ class ScatterEstimation : public ParsingObject
//! The file name for the attenuation coefficients.
//! If they are to be recalculated they will be stored here, if set.
std::string atten_coeff_filename;
+ //! ForwardProjector
+ shared_ptr forward_projector_for_mask_sptr;
//! \details the set of parameters to obtain a mask from the attenuation image
/*! The attenuation image will be thresholded to find a plausible mask for where there
diff --git a/src/scatter_buildblock/ScatterEstimation.cxx b/src/scatter_buildblock/ScatterEstimation.cxx
index efe3e2d9b..54cf56167 100644
--- a/src/scatter_buildblock/ScatterEstimation.cxx
+++ b/src/scatter_buildblock/ScatterEstimation.cxx
@@ -112,6 +112,10 @@ ScatterEstimation::initialise_keymap()
this->parser.add_key("mask projdata filename", &this->mask_projdata_filename);
this->parser.add_key("tail fitting parameter filename", &this->tail_mask_par_filename);
// END MASK
+
+ // Forward projector for mask projection
+ this->parser.add_parsing_key("forward projector for mask type", &this->forward_projector_for_mask_sptr);
+
this->parser.add_key("background projdata filename", &this->back_projdata_filename);
this->parser.add_parsing_key("Normalisation type", &this->norm_3d_sptr);
this->parser.add_key("attenuation correction factors filename", &this->atten_coeff_filename);
@@ -451,6 +455,18 @@ ScatterEstimation::set_recompute_mask_projdata(bool arg)
this->recompute_mask_projdata = arg;
}
+void
+ScatterEstimation::set_forward_projector_for_mask_sptr(const shared_ptr projector_sptr)
+{
+ this->forward_projector_for_mask_sptr = projector_sptr;
+}
+
+shared_ptr
+ScatterEstimation::get_forward_projector_for_mask_sptr() const
+{
+ return forward_projector_for_mask_sptr;
+}
+
bool
ScatterEstimation::already_setup() const
{
@@ -1237,30 +1253,32 @@ ScatterEstimation::project_mask_image()
}
}
- shared_ptr forw_projector_sptr;
- shared_ptr PM(new ProjMatrixByBinUsingRayTracing());
- forw_projector_sptr.reset(new ForwardProjectorByBinUsingProjMatrixByBin(PM));
+ if (!this->forward_projector_for_mask_sptr)
+ {
+ shared_ptr PM(new ProjMatrixByBinUsingRayTracing());
+ forward_projector_for_mask_sptr.reset(new ForwardProjectorByBinUsingProjMatrixByBin(PM));
+ }
info(boost::format("ScatterEstimation: Forward projector used for the calculation of "
"the tail mask: %1%")
- % forw_projector_sptr->parameter_info());
+ % forward_projector_for_mask_sptr->parameter_info());
shared_ptr mask_projdata;
if (run_in_2d_projdata)
{
- forw_projector_sptr->set_up(this->input_projdata_2d_sptr->get_proj_data_info_sptr(), this->mask_image_sptr);
+ forward_projector_for_mask_sptr->set_up(this->input_projdata_2d_sptr->get_proj_data_info_sptr(), this->mask_image_sptr);
mask_projdata.reset(new ProjDataInMemory(this->input_projdata_2d_sptr->get_exam_info_sptr(),
this->input_projdata_2d_sptr->get_proj_data_info_sptr()));
}
else
{
- forw_projector_sptr->set_up(this->input_projdata_sptr->get_proj_data_info_sptr(), this->mask_image_sptr);
+ forward_projector_for_mask_sptr->set_up(this->input_projdata_sptr->get_proj_data_info_sptr(), this->mask_image_sptr);
mask_projdata.reset(new ProjDataInMemory(this->input_projdata_sptr->get_exam_info_sptr(),
this->input_projdata_sptr->get_proj_data_info_sptr()));
}
- forw_projector_sptr->forward_project(*mask_projdata, *this->mask_image_sptr);
+ forward_projector_for_mask_sptr->forward_project(*mask_projdata, *this->mask_image_sptr);
// add 1 to be able to use create_tail_mask_from_ACFs (which expects ACFs,
// so complains if the threshold is too low)