Skip to content

Commit c68d4ea

Browse files
fedorovclaude
andcommitted
ENH: add obliquity_degrees column to detect gantry tilt and oblique acquisitions
Add a numeric column reporting the angle (in degrees) between the slice normal and the nearest cardinal axis. 0° = pure axial/sagittal/coronal, higher values indicate oblique acquisition or gantry tilt. ~27k series (9%) in IDC have non-trivial obliquity. This information was previously invisible in the boolean checks since the projection-based approach correctly handles oblique geometry — a tilted series passes all regularity checks. The new column lets users identify tilted series that may need special handling (e.g., reformatting to true axial). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 3a6ecbd commit c68d4ea

1 file changed

Lines changed: 21 additions & 1 deletion

File tree

scripts/sql/volume_geometry_index.sql

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,22 @@ geometryChecks AS (
289289
# (see CTE 3 above). MAX ignores NULLs, so the last slice (which has
290290
# NULL slice_interval from LEAD) is automatically excluded.
291291
MAX(ABS(slice_interval - expected_spacing))
292-
< relativeSliceTolerance * ABS(ANY_VALUE(expected_spacing)) AS uniform_slice_spacing
292+
< relativeSliceTolerance * ABS(ANY_VALUE(expected_spacing)) AS uniform_slice_spacing,
293+
294+
# obliquity_degrees: the angle (in degrees) between the slice normal
295+
# and the nearest cardinal axis (X, Y, or Z in patient coordinates).
296+
# 0° means pure axial, sagittal, or coronal. Values > 0° indicate
297+
# oblique acquisition or gantry tilt (e.g., ~15° for tilted head CT).
298+
# Computed as ACOS of the largest absolute component of the normalized
299+
# slice normal vector — the largest component corresponds to the
300+
# nearest cardinal axis.
301+
ROUND(ACOS(
302+
GREATEST(
303+
ABS(ANY_VALUE(cp.x)),
304+
ABS(ANY_VALUE(cp.y)),
305+
ABS(ANY_VALUE(cp.z))
306+
) / ANY_VALUE(crossProductMagnitude)
307+
) * 180 / ACOS(-1), 2) AS obliquity_degrees
293308

294309
FROM sliceProjection
295310
GROUP BY
@@ -333,6 +348,11 @@ SELECT
333348
# (within relativeSliceTolerance, a relative fraction of expected spacing)
334349
uniform_slice_spacing,
335350
# description:
351+
# angle in degrees between the slice normal and the nearest cardinal axis
352+
# (X, Y, or Z in patient coordinates); 0 means pure axial, sagittal, or coronal;
353+
# values above 0 indicate oblique acquisition or gantry tilt
354+
obliquity_degrees,
355+
# description:
336356
# TRUE if all individual checks pass, indicating the series forms a regularly-spaced
337357
# rectilinear 3D volume that can be loaded directly into a 3D array without resampling
338358
single_orientation AND orthogonal_orientation AND unique_slice_positions

0 commit comments

Comments
 (0)