Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
be94cb8
Merge branch 'release_4' into my_master
robbietuk Oct 10, 2020
40f6b61
Modify LL computation to be KL
robbietuk Sep 28, 2020
3adec82
Logcosh fixes
robbietuk Nov 26, 2020
266a62e
Add Logcosh to users guide
robbietuk Nov 26, 2020
5237ef1
Add method stir.ToPriorWithParabolicSurrogate() to python.
robbietuk Oct 15, 2020
0ff2b26
Merge branch 'LogcoshAmendments' into ZeljkoCustomBranch
robbietuk Nov 26, 2020
d18af14
Merge branch 'KL_computation' into ZeljkoCustomBranch
robbietuk Nov 26, 2020
3b3cab1
Revert Logcosh registered_name to Logcosh and update docs [ci skip]
robbietuk Nov 26, 2020
f47455e
Merge branch 'LogcoshAmendments' into ZeljkoCustomBranch
robbietuk Nov 26, 2020
e484441
Merge branch 'master' into ZeljkoCustomBranch
robbietuk Dec 9, 2020
53ea1d1
Merge remote-tracking branch 'origin/master' into ZeljkoCustomBranch
robbietuk Dec 10, 2020
e93d3a0
parabolic_surrogate_curvature_times_input methods for QP and Logcosh
robbietuk Dec 10, 2020
69694ef
Remove redundant computation
robbietuk Dec 10, 2020
a1347dc
Merge pull request #11 from robbietuk/PriorParabolicTimesImage
Dec 14, 2020
ca36386
Merge remote-tracking branch 'UCL/master' into ZeljkoCustomBranch
robbietuk Feb 2, 2021
30ddb4e
Merge remote-tracking branch 'UCL/master' into ZeljkoCustomBranch
robbietuk Feb 15, 2021
8d317ce
Merge branch 'master' into ZeljkoCustomBranch
robbietuk Feb 15, 2021
14136a3
Merge remote-tracking branch 'UCL/master' into ZeljkoCustomBranch
robbietuk Mar 9, 2021
b188f01
Merge remote-tracking branch 'UCL/master' into ZeljkoCustomBranch
robbietuk Mar 15, 2021
58b8a25
Merge remote-tracking branch 'UCL/master' into ZeljkoCustomBranch
robbietuk Mar 16, 2021
8586c70
Merge branch 'master' into ZeljkoCustomBranch
robbietuk Apr 9, 2021
f848d0d
Merge branch 'master' into ZeljkoCustomBranch
robbietuk Apr 16, 2021
b3a0152
Merge branch 'master' into ZeljkoCustomBranch
robbietuk May 6, 2021
0413b5c
Merge remote-tracking branch 'UCL/master' into ZeljkoCustomBranch
robbietuk May 17, 2021
48b044d
Merge branch 'master' into ZeljkoCustomBranch
robbietuk May 20, 2021
e73c7eb
Merge branch 'master' into ZeljkoCustomBranch
robbietuk May 26, 2021
5c502d8
Merge branch 'master' into ZeljkoCustomBranch
robbietuk Jul 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions src/buildblock/recon_array_functions.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -374,12 +374,15 @@ void accumulate_loglikelihood(Viewgram<float>& projection_data,
// std::cerr << "Zero at " << r << ", " << b <<'\n';
const float new_estimate =
max(estimated_projections[r][b],
projection_data[r][b]/max_quotient);
if (projection_data[r][b]<=small_value)
sub_result += - double(new_estimate);
else
sub_result += projection_data[r][b]*log(double(new_estimate)) - double(new_estimate);
}
projection_data[r][b]/max_quotient);

if (projection_data[r][b] > 0.0)
{
sub_result += - (projection_data[r][b] * log(projection_data[r][b] / double(new_estimate)) + double(new_estimate) - projection_data[r][b]);
} else {
sub_result += - (double(new_estimate));
}
}
result += sub_result;
}

Expand Down
5 changes: 5 additions & 0 deletions src/include/stir/recon_buildblock/LogcoshPrior.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ class LogcoshPrior: public
const BasicCoordinate<3,int>& coords,
const DiscretisedDensity<3,elemT> &current_image_estimate);

//! compute the parabolic surrogate curvature for the prior of the current image estimate and multiply by input image
void parabolic_surrogate_curvature_times_input(DiscretisedDensity<3,elemT>& output,
const DiscretisedDensity<3,elemT> &current_image_estimate,
const DiscretisedDensity<3,elemT> &input_image);

//! Compute the multiplication of the hessian of the prior multiplied by the input.
virtual Succeeded accumulate_Hessian_times_input(DiscretisedDensity<3,elemT>& output,
const DiscretisedDensity<3,elemT>& current_estimate,
Expand Down
14 changes: 13 additions & 1 deletion src/include/stir/recon_buildblock/PriorWithParabolicSurrogate.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,19 @@ class PriorWithParabolicSurrogate:
parabolic_surrogate_curvature(TargetT& parabolic_surrogate_curvature,
const TargetT &current_estimate) = 0;

//! A function that allows skipping some computations if the curvature is independent of the \c current_estimate
//! This will calculate the parabolic surrogate curvature of the current image estimate multiplied by the input image
/*!
Function is comparable to that of accumulate_Hessian_times_input() but instead of the Hessian, we use the parabolic
surrogate curvature.
For each voxel (f_{j}) of the image, this method computes
\beta \sum_{i\in J} d_{i,j} f_{i}
where J is the neighbourhood about voxel j and d_{i,j} is the surrogate function between j and i.
*/
virtual void parabolic_surrogate_curvature_times_input(TargetT& output,
const TargetT& current_image_estimate,
const TargetT& input_image) = 0;

//! A function that allows skipping some computations if the curvature is independent of the \c current_estimate
/*! Defaults to return \c true, but can be overloaded by the derived class.
*/
virtual bool
Expand Down
8 changes: 7 additions & 1 deletion src/include/stir/recon_buildblock/QuadraticPrior.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,13 @@ class QuadraticPrior: public
const BasicCoordinate<3,int>& coords,
const DiscretisedDensity<3,elemT> &current_image_estimate);

//! Call accumulate_Hessian_times_input
//! compute the parabolic surrogate curvature for the prior of the current image estimate and multiply by input image
void parabolic_surrogate_curvature_times_input(DiscretisedDensity<3,elemT>& output,
const DiscretisedDensity<3,elemT> &current_image_estimate,
const DiscretisedDensity<3,elemT> &input_image);


//! Call accumulate_Hessian_times_input
virtual Succeeded
add_multiplication_with_approximate_Hessian(DiscretisedDensity<3,elemT>& output,
const DiscretisedDensity<3,elemT>& input) const;
Expand Down
74 changes: 74 additions & 0 deletions src/recon_buildblock/LogcoshPrior.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ accumulate_Hessian_times_input(DiscretisedDensity<3,elemT>& output,
// the only difference is that parabolic_surrogate_curvature uses input==1

assert( output.has_same_characteristics(input));
output.fill(0.f);
if (this->penalisation_factor==0)
{
return Succeeded::yes;
Expand Down Expand Up @@ -577,6 +578,79 @@ accumulate_Hessian_times_input(DiscretisedDensity<3,elemT>& output,
return Succeeded::yes;
}

template <typename elemT>
void
LogcoshPrior<elemT>::
parabolic_surrogate_curvature_times_input(DiscretisedDensity<3,elemT>& output,
const DiscretisedDensity<3,elemT> &current_image_estimate,
const DiscretisedDensity<3,elemT> &input_image)
{
assert( output.has_same_characteristics(input));
assert( output.has_same_characteristics(current_image_estimate));
output.fill(0.f);
if (this->penalisation_factor==0)
{
return;
}

DiscretisedDensityOnCartesianGrid<3,elemT>& output_cast =
dynamic_cast<DiscretisedDensityOnCartesianGrid<3,elemT> &>(output);

if (weights.get_length() ==0)
{
compute_weights(weights, output_cast.get_grid_spacing(), this->only_2D);
}

const bool do_kappa = !is_null_ptr(kappa_ptr);

if (do_kappa && !kappa_ptr->has_same_characteristics(input_image))
error("LogcoshPrior: kappa image has not the same index range as the reconstructed image\n");

const int min_z = output.get_min_index();
const int max_z = output.get_max_index();
for (int z=min_z; z<=max_z; z++)
{
const int min_dz = max(weights.get_min_index(), min_z-z);
const int max_dz = min(weights.get_max_index(), max_z-z);

const int min_y = output[z].get_min_index();
const int max_y = output[z].get_max_index();

for (int y=min_y;y<= max_y;y++)
{
const int min_dy = max(weights[0].get_min_index(), min_y-y);
const int max_dy = min(weights[0].get_max_index(), max_y-y);

const int min_x = output[z][y].get_min_index();
const int max_x = output[z][y].get_max_index();

for (int x=min_x;x<= max_x;x++)
{
const int min_dx = max(weights[0][0].get_min_index(), min_x-x);
const int max_dx = min(weights[0][0].get_max_index(), max_x-x);

elemT result = 0;
for (int dz=min_dz;dz<=max_dz;++dz)
for (int dy=min_dy;dy<=max_dy;++dy)
for (int dx=min_dx;dx<=max_dx;++dx)
{
elemT voxel_diff= current_image_estimate[z][y][x] - current_image_estimate[z+dz][y+dy][x+dx];
elemT current = weights[dz][dy][dx] *
surrogate(voxel_diff, this->scalar) * input_image[z+dz][y+dy][x+dx];

if (do_kappa)
current *= (*kappa_ptr)[z][y][x] * (*kappa_ptr)[z+dz][y+dy][x+dx];

result += current;
}

output[z][y][x] += result * this->penalisation_factor;
}
}
}
return;
}

# ifdef _MSC_VER
// prevent warning message on reinstantiation,
// note that we get a linking error if we don't have the explicit instantiation below
Expand Down
72 changes: 72 additions & 0 deletions src/recon_buildblock/QuadraticPrior.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,78 @@ accumulate_Hessian_times_input(DiscretisedDensity<3,elemT>& output,
return Succeeded::yes;
}

template <typename elemT>
void
QuadraticPrior<elemT>::
parabolic_surrogate_curvature_times_input(DiscretisedDensity<3,elemT>& output,
const DiscretisedDensity<3,elemT> &current_image_estimate,
const DiscretisedDensity<3,elemT> &input_image)
{
assert( output.has_same_characteristics(input));
assert( output.has_same_characteristics(current_image_estimate));
output.fill(0.f);
if (this->penalisation_factor==0)
{
return;
}

DiscretisedDensityOnCartesianGrid<3,elemT>& output_cast =
dynamic_cast<DiscretisedDensityOnCartesianGrid<3,elemT> &>(output);

if (weights.get_length() ==0)
{
compute_weights(weights, output_cast.get_grid_spacing(), this->only_2D);
}

const bool do_kappa = !is_null_ptr(kappa_ptr);

if (do_kappa && !kappa_ptr->has_same_characteristics(input_image))
error("LogcoshPrior: kappa image has not the same index range as the reconstructed image\n");

const int min_z = output.get_min_index();
const int max_z = output.get_max_index();
for (int z=min_z; z<=max_z; z++)
{
const int min_dz = max(weights.get_min_index(), min_z-z);
const int max_dz = min(weights.get_max_index(), max_z-z);

const int min_y = output[z].get_min_index();
const int max_y = output[z].get_max_index();

for (int y=min_y;y<= max_y;y++)
{
const int min_dy = max(weights[0].get_min_index(), min_y-y);
const int max_dy = min(weights[0].get_max_index(), max_y-y);

const int min_x = output[z][y].get_min_index();
const int max_x = output[z][y].get_max_index();

for (int x=min_x;x<= max_x;x++)
{
const int min_dx = max(weights[0][0].get_min_index(), min_x-x);
const int max_dx = min(weights[0][0].get_max_index(), max_x-x);

elemT result = 0;
for (int dz=min_dz;dz<=max_dz;++dz)
for (int dy=min_dy;dy<=max_dy;++dy)
for (int dx=min_dx;dx<=max_dx;++dx)
{
// The parabolic surrogate curvature of the QP is 1
elemT current = weights[dz][dy][dx] * input_image[z+dz][y+dy][x+dx];

if (do_kappa)
current *= (*kappa_ptr)[z][y][x] * (*kappa_ptr)[z+dz][y+dy][x+dx];

result += current;
}

output[z][y][x] += result * this->penalisation_factor;
}
}
}
}


# ifdef _MSC_VER
// prevent warning message on reinstantiation,
// note that we get a linking error if we don't have the explicit instantiation below
Expand Down
7 changes: 7 additions & 0 deletions src/swig/stir.i
Original file line number Diff line number Diff line change
Expand Up @@ -1657,6 +1657,13 @@ stir::RegisteredParsingObject< stir::LogcoshPrior<elemT>,
stir::PriorWithParabolicSurrogate<TargetT > >;
%template (LogcoshPrior3DFloat) stir::LogcoshPrior<elemT>;

// Allows for access to parabolic surrogate type prior methods ( THIS IS A TEMPORARY FIX )
%inline %{template <class T> stir::PriorWithParabolicSurrogate<T> * ToPriorWithParabolicSurrogate(stir::GeneralisedPrior<T> *b) {
return dynamic_cast<stir::PriorWithParabolicSurrogate<T>*>(b);
}
%}
%template(ToPriorWithParabolicSurrogate) ToPriorWithParabolicSurrogate<TargetT >;

%template (Reconstruction3DFloat) stir::Reconstruction<TargetT >;
//%template () stir::Reconstruction<TargetT >;
%template (IterativeReconstruction3DFloat) stir::IterativeReconstruction<TargetT >;
Expand Down