Skip to content

Commit c0b10eb

Browse files
Merge pull request #1477 from KrisThielemans/PoissonLLHessianFix
Hessian times input for PoissonLL...ProjData: throw error if result would be incorrect
2 parents 3f6c0c9 + 2992bc5 commit c0b10eb

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

documentation/release_6.2.htm

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,13 @@ <h3>Bug fixes</h3>
121121
handled. Also, downsampling of <code>BlocksOnCylindrical</code> scanners in scatter simulation was inaccurate.<br>
122122
<a href=https://github.com/UCL/STIR/pull/1466>PR #1466</a>
123123
</li>
124+
<li>
125+
The "Hessian times input" calculations of the Poisson log-likelihood for projection data
126+
were incorrect when the forward projection of the "input" contains negatives.
127+
We now detect this and throw an error if it occurs. A proper fix
128+
will have to be for later.<br>
129+
See <a href="https://github.com/UCL/STIR/issues/1461">Issue #1461</a>
130+
</li>
124131
</ul>
125132

126133
<h3>Build system</h3>

src/recon_buildblock/PoissonLogLikelihoodWithLinearModelForMeanAndProjData.cxx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -977,12 +977,15 @@ PoissonLogLikelihoodWithLinearModelForMeanAndProjData<
977977
this->get_num_subsets());
978978

979979
info("Forward projecting input image.", 2);
980+
volatile bool any_negatives = false;
980981
#ifdef STIR_OPENMP
981982
# pragma omp parallel for schedule(dynamic)
982983
#endif
983984
// note: older versions of openmp need an int as loop
984985
for (int i = 0; i < static_cast<int>(vg_idx_to_process.size()); ++i)
985986
{
987+
if (any_negatives)
988+
continue; // early exit as we'll throw error outside of the parallel for
986989
const auto viewgram_idx = vg_idx_to_process[i];
987990
{
988991
#ifdef STIR_OPENMP
@@ -1011,6 +1014,11 @@ PoissonLogLikelihoodWithLinearModelForMeanAndProjData<
10111014
{
10121015
tmp_viewgrams = this->get_proj_data().get_empty_related_viewgrams(viewgram_idx, symmetries_sptr);
10131016
this->get_projector_pair().get_forward_projector_sptr()->forward_project(tmp_viewgrams);
1017+
if (tmp_viewgrams.find_min() < 0)
1018+
{
1019+
any_negatives = true;
1020+
continue; // throw error outside of parallel for
1021+
}
10141022
}
10151023

10161024
// now divide by the data term
@@ -1024,6 +1032,11 @@ PoissonLogLikelihoodWithLinearModelForMeanAndProjData<
10241032

10251033
} // end of loop over view/segments
10261034

1035+
if (any_negatives)
1036+
error("PoissonLL add_multiplication_with_approximate_sub_Hessian: forward projection of input contains negatives. The "
1037+
"result would be incorrect, so we abort.\n"
1038+
"See https://github.com/UCL/STIR/issues/1461");
1039+
10271040
shared_ptr<TargetT> tmp(output.get_empty_copy());
10281041
this->get_projector_pair().get_back_projector_sptr()->get_output(*tmp);
10291042
// output += tmp;
@@ -1098,11 +1111,15 @@ PoissonLogLikelihoodWithLinearModelForMeanAndProjData<TargetT>::actual_accumulat
10981111

10991112
// Forward project input image
11001113
info("Forward projecting input image.", 2);
1114+
volatile bool any_negatives = false;
11011115
#ifdef STIR_OPENMP
11021116
# pragma omp parallel for schedule(dynamic)
11031117
#endif
11041118
for (int i = 0; i < static_cast<int>(vg_idx_to_process.size()); ++i)
11051119
{ // Loop over each of the viewgrams in input_viewgrams_vec, forward projecting input into them
1120+
if (any_negatives)
1121+
continue; // early exit as we'll throw error outside of the parallel for
1122+
11061123
const auto viewgram_idx = vg_idx_to_process[i];
11071124
{
11081125
#ifdef STIR_OPENMP
@@ -1118,7 +1135,16 @@ PoissonLogLikelihoodWithLinearModelForMeanAndProjData<TargetT>::actual_accumulat
11181135
}
11191136
input_viewgrams_vec[i] = this->get_proj_data().get_empty_related_viewgrams(viewgram_idx, symmetries_sptr);
11201137
this->get_projector_pair().get_forward_projector_sptr()->forward_project(input_viewgrams_vec[i]);
1138+
if (input_viewgrams_vec[i].find_min() < 0)
1139+
{
1140+
any_negatives = true;
1141+
continue; // throw error outside of parallel for
1142+
}
11211143
}
1144+
if (any_negatives)
1145+
error("PoissonLL accumulate_sub_Hessian_times_input: forward projection of input contains negatives. The "
1146+
"result would be incorrect, so we abort.\n"
1147+
"See https://github.com/UCL/STIR/issues/1461");
11221148

11231149
info("Forward projecting current image estimate and back projecting to output.", 2);
11241150
this->get_projector_pair().get_forward_projector_sptr()->set_input(current_image_estimate);

0 commit comments

Comments
 (0)