Skip to content

Displaced detector#877

Open
axel-grc wants to merge 2 commits into
RTKConsortium:mainfrom
axel-grc:DisplacedDetector
Open

Displaced detector#877
axel-grc wants to merge 2 commits into
RTKConsortium:mainfrom
axel-grc:DisplacedDetector

Conversation

@axel-grc
Copy link
Copy Markdown
Collaborator

@axel-grc axel-grc commented Dec 19, 2025

Fix #480
Closes #509

@axel-grc axel-grc requested a review from SimonRit December 19, 2025 09:48
@axel-grc axel-grc changed the title ENH: Add exception handling for parallel geometry in DisplacedDetector filters Displaced detector Dec 19, 2025
Copy link
Copy Markdown
Collaborator

@SimonRit SimonRit left a comment

Choose a reason for hiding this comment

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

I suggest "solving" the problem by an error message instead of copy pasting code. You can check in the test that an error message is thrown, I know there is an ITK macro for this.

Comment on lines +119 to +125
/** Returns true when offsets were explicitly provided */
bool
GetOffsetsSet() const
{
return m_OffsetsSet;
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please use ITK's GetMacro for booleans

Comment on lines +116 to +152
// If the user manually set offsets, apply the same corner-based logic as the base class
typename Superclass::InputImageType::PointType corner;
inputPtr->TransformIndexToPhysicalPoint(inputPtr->GetLargestPossibleRegion().GetIndex(), corner);
double inferiorCorner = corner[0];
double superiorCorner = inferiorCorner;
if (inputPtr->GetSpacing()[0] < 0.)
inferiorCorner += inputPtr->GetSpacing()[0] * (outputLargestPossibleRegion.GetSize(0) - 1);
else
superiorCorner += inputPtr->GetSpacing()[0] * (outputLargestPossibleRegion.GetSize(0) - 1);

inferiorCorner += this->GetMaximumOffset();
superiorCorner += this->GetMinimumOffset();

if (inferiorCorner > 0. || superiorCorner < 0.)
{
itkGenericExceptionMacro(<< "Cannot account for detector displacement larger than 50% of panel size."
<< " Corner inf=" << inferiorCorner << " and corner sup=" << superiorCorner);
}
else if ((itk::Math::abs(inferiorCorner + superiorCorner) <
0.1 * itk::Math::abs(superiorCorner - inferiorCorner)) ||
!this->m_PadOnTruncatedSide)
{
// nothing to do, keep region
}
else if (superiorCorner + inferiorCorner > 0.)
{
this->SetInPlace(false);
typename itk::Index<3>::IndexValueType index =
outputLargestPossibleRegion.GetIndex()[0] - outputLargestPossibleRegion.GetSize()[0];
outputLargestPossibleRegion.SetIndex(0, index);
outputLargestPossibleRegion.SetSize(0, outputLargestPossibleRegion.GetSize()[0] * 2);
}
else
{
this->SetInPlace(false);
outputLargestPossibleRegion.SetSize(0, outputLargestPossibleRegion.GetSize()[0] * 2);
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't think we should do the same as in the base class. I suggest to throw an error message instead of copy pasting code, that's will be simpler.

Comment on lines +99 to +122
{
constexpr double minOffset = -16.;
constexpr double maxOffset = 12.;

std::cout << "\n\n****** Case 4: manual offsets ******" << std::endl;

using OffsetDDFType = rtk::DisplacedDetectorForOffsetFieldOfViewImageFilter<OutputImageType>;
auto cudaddf = OffsetDDFType::New();
cudaddf->SetInput(slp->GetOutput());
cudaddf->SetGeometry(geometry);
cudaddf->SetOffsets(minOffset, maxOffset);
cudaddf->InPlaceOff();
TRY_AND_EXIT_ON_ITK_EXCEPTION(cudaddf->Update());

using CPUDDFType = rtk::DisplacedDetectorImageFilter<OutputImageType>;
auto cpuddf = CPUDDFType::New();
cpuddf->SetInput(slp->GetOutput());
cpuddf->SetGeometry(geometry);
cpuddf->SetOffsets(minOffset, maxOffset);
cpuddf->InPlaceOff();
TRY_AND_EXIT_ON_ITK_EXCEPTION(cpuddf->Update());

CheckImageQuality<OutputImageType>(cudaddf->GetOutput(), cpuddf->GetOutput(), 1.e-6, 100, 1.);
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The problem of this test is that it is not an offset FOV. In this case, DisplacedDetectorImageFilter can be used.

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.

DisplacedDetectorForOffsetFieldOfViewImageFilter discards manually set offset rtkfdk app returns NaN values for parallel geometry

2 participants