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

ACR Slice Position Functionality #299

Merged
merged 12 commits into from
Jan 24, 2023
Merged

Conversation

YassineAzma
Copy link
Collaborator

  • Adds an ACR slice position script and associated unit tests that calculates the bar length difference (which is twice the slice position displacement) of slices 1 and 11 of the ACR phantom. This is done within the new HazenTask framework. The methodology is as follows:
    • Calculates the centroid of the object following morphological operations and a centre-of-mass calculation.
      • This step also produces a binary mask.
    • Uses line profiles and peak-finding operations to identify features in the phantom corresponding to the two wedges at the top of the phantom.
    • Draws interpolated line profiles (for subpixel measurement) through these wedges.
    • Uses circular shifting of these line profiles to find the pixel offset that produces the minimum difference between the two line profile.
    • Uses this pixel offset to calculate the bar length difference.

These results are visualised in the report, as shown below:
image
image

Adds algorithm to calculate slice position displacements. Rotation detection (and correction) pending!
Adds unit tests for the ACR slice position HazenTask. No coverage for the find_n_peaks static method as it will be later placed in a separate module along with an improved centroid detection function.
Make the find_n_peaks method static until an ACR-specific module is created with commonly reused functions.
Corrects wording used in docstring.
@YassineAzma YassineAzma added the enhancement New feature or request label Jan 3, 2023
@YassineAzma YassineAzma added this to the ACR Phantom milestone Jan 3, 2023
@YassineAzma YassineAzma self-assigned this Jan 3, 2023
@github-actions
Copy link

github-actions bot commented Jan 3, 2023

Coverage

Coverage Report
FileStmtsMissCoverMissing
hazenlib
   HazenTask.py25484%18, 32–34
   __init__.py1554472%141, 145, 155, 160, 197, 204–209, 220, 223–230, 250–252, 270–272, 291–293, 302, 307, 313, 363, 374, 380–386, 396–398, 406–407, 411
   exceptions.py21481%17–21
   relaxometry.py3179072%238–256, 631, 690–692, 746, 794–816, 834–849, 1174–1177, 1186–1189, 1201–1214, 1217–1222, 1233–1263
   shapes.py20955%13, 16, 24–29, 32
   snr_map.py111595%408, 413–415, 444
   tools.py84890%43–50, 92, 101, 117
hazenlib/tasks
   acr_geometric_accuracy.py1455562%38–72, 176–192, 206–230
   acr_ghosting.py1164264%33–53, 91–93, 123–125, 161–194
   acr_slice_position.py1575366%53–74, 152, 215–260
   acr_snr.py1375858%34–71, 96, 165–175, 208–221, 254–267
   acr_uniformity.py893264%34–54, 121–138
   ghosting.py1505166%18–32, 47, 109–110, 114, 124–125, 151–153, 170–172, 218–256
   relaxometry.py7271%10–11
   slice_position.py1182281%31, 40–41, 103–104, 130, 210, 217–234
   slice_width.py3565285%34–37, 107, 166–186, 451, 456–457, 463, 468, 530–531, 780–821
   snr.py1636660%62–67, 161–179, 194–203, 221–231, 258–268, 273–283, 314–327, 332–340, 369–382
   snr_map.py770%1–11
   spatial_resolution.py2464482%36–39, 62, 147, 206, 332–368
   uniformity.py781976%42–45, 91–92, 99, 133–147
TOTAL251866774% 

Tests Skipped Failures Errors Time
200 0 💤 0 ❌ 0 🔥 2m 32s ⏱️

@YassineAzma
Copy link
Collaborator Author

Note that there is a function outside of the class, find_n_peaks, which will be later refactored into a library of ACR specific functions, in the same vein as tools.py.

@YassineAzma YassineAzma changed the base branch from main to release/1.1.1 January 24, 2023 09:33
@Lucrezia-Cester
Copy link
Contributor

Lucrezia-Cester commented Jan 24, 2023

Hi @YassineRMH,

I am having trouble checking this from the images, but you are basically calculating difference in length of the two wedges right? Such as shown in picture below

If that is the case, could this be incorporated as a "short summary" of the algorithm in the docstring?

Screenshot 2023-01-24 at 11 31 17

@YassineAzma
Copy link
Collaborator Author

YassineAzma commented Jan 24, 2023

Hi @YassineRMH,

I am having trouble checking this from the images, but you are basically calculating difference in legth of the two wedges right? Such as shown in picture below

Screenshot 2023-01-24 at 11 31 17

Pretty much. Measurement of wedge lengths didn't perform so well in low SNR datasets, and this method allows sub-pixel measurement via interpolation (similar to how it would be done in a DICOM viewer). I'll add axis labels to the plots with the x units being relative pixel position in mm. Would that make it easier to understand?

Add x-label to plots.
@Lucrezia-Cester
Copy link
Contributor

@YassineRMH But the final number for slice position is the difference in length of the wedges right?

@YassineAzma
Copy link
Collaborator Author

YassineAzma commented Jan 24, 2023

@YassineRMH But the final number for slice position is the difference in length of the wedges right?

Yes, but I calculate it by finding the minimum difference in the subtraction of the right line profile through the wedge (subject to various shifts) and the left profile through the wedge.

Here's the updated docstring:

This script calculates the bar length difference in accordance with the ACR Guidance. Line profiles are drawn 
vertically through the left and right wedges. Circular shifts are applied to the right wedge's line profile and 
subtracted from the static left wedge line profile. The shift used to produce the minimum difference between the 
circularly shifted right line profile and the static left one are used to determine the bar length difference, 
which is twice the slice position displacement. The results are also visualised. 

Trimmed down the docstring and attempted to make it clearer.
@Lucrezia-Cester
Copy link
Contributor

Hi @YassineRMH, could you please expand on this sentence as I cannot quite understand it "Circular shifts are applied to the right wedge's line profile and
subtracted from the static left wedge line profile."

I will then merge this PR.

@YassineAzma
Copy link
Collaborator Author

Hi @YassineRMH, could you please expand on this sentence as I cannot quite understand it "Circular shifts are applied to the right wedge's line profile and subtracted from the static left wedge line profile."

I will then merge this PR.

How about this:

This script calculates the bar length difference in accordance with the ACR Guidance. Line profiles are drawn
vertically through the left and right wedges. The right wedge's line profile is shifted and wrapped round before being subtracted from the left wedge's line profile, e.g.:

Right line profile: [1, 2, 3, 4, 5]
Right line profile wrapped round by 1: [2, 3, 4, 5, 1]

This wrapping process, from hereon referred to as circular shifting, is then used for subtractions.

The shift used to produce the minimum difference between the circularly shifted right line profile and the static left one are used to determine the bar length difference, which is twice the slice position displacement. The results are also visualised.

If this is acceptable, I'll commit it. Let me know where it does not make sense.

@Lucrezia-Cester
Copy link
Contributor

@YassineRMH thank you @YassineRMH, please commit this and I'll merge

Updated docstring.
@Lucrezia-Cester Lucrezia-Cester merged commit 576c07c into release/1.1.1 Jan 24, 2023
@YassineAzma YassineAzma deleted the acr_slice_position branch January 25, 2023 14:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants