|
29 | 29 | # is computed from the full span (first-to-last slice position divided by |
30 | 30 | # N-1), and each adjacent pair is compared against it — an approach that |
31 | 31 | # minimizes floating-point accumulation errors (see 3D Slicer reference |
32 | | -# below). |
| 32 | +# below). The slice spacing tolerance is relative (a fraction of expected |
| 33 | +# spacing) rather than absolute, so it scales correctly for both human |
| 34 | +# imaging (~1-5mm spacing) and preclinical/small-animal imaging (~0.1mm). |
33 | 35 | # |
34 | 36 | # Similarly, projecting IPP onto the row and column directions gives |
35 | 37 | # in-plane coordinates that should be constant across all slices if the |
|
71 | 73 | # `bigquery-public-data.idc_current.dicom_all` with e.g. `bigquery-public-data.idc_v18.dicom_all` |
72 | 74 |
|
73 | 75 | # Configurable parameters |
74 | | -DECLARE sliceIntervalTolerance FLOAT64 DEFAULT 0.2; # max allowed variation in slice spacing (mm); |
75 | | - # matches kSliceTolerance in dcm2niix |
76 | | - # (https://github.com/rordenlab/dcm2niix/blob/f6d7a001/console/nii_dicom_batch.cpp#L64) |
| 76 | +DECLARE relativeSliceTolerance FLOAT64 DEFAULT 0.02; # max allowed variation in slice spacing as a fraction |
| 77 | + # of expected spacing (2%); relative tolerance scales |
| 78 | + # correctly for both human imaging (~1-5mm spacing) |
| 79 | + # and preclinical/small-animal imaging (~0.1mm spacing) |
77 | 80 | DECLARE inPlaneTolerance FLOAT64 DEFAULT 0.1; # max in-plane position jitter (mm) |
78 | 81 | DECLARE orientationTolerance FLOAT64 DEFAULT 0.01; # cross-product magnitude deviation from 1.0 |
79 | 82 |
|
@@ -275,11 +278,15 @@ geometryChecks AS ( |
275 | 278 | MAX(inPlaneCol) - MIN(inPlaneCol) < inPlaneTolerance AS consistent_in_plane_col, |
276 | 279 |
|
277 | 280 | # uniform_slice_spacing: TRUE if every adjacent slice interval is |
278 | | - # within sliceIntervalTolerance of the expected uniform spacing. |
| 281 | + # within relativeSliceTolerance of the expected uniform spacing. |
| 282 | + # The tolerance is relative (a fraction of expected_spacing) so it |
| 283 | + # scales correctly for both human imaging (~1-5mm spacing) and |
| 284 | + # preclinical/small-animal imaging (~0.1mm spacing). |
279 | 285 | # The expected spacing is derived from the full first-to-last span |
280 | 286 | # (see CTE 3 above). MAX ignores NULLs, so the last slice (which has |
281 | 287 | # NULL slice_interval from LEAD) is automatically excluded. |
282 | | - MAX(ABS(slice_interval - expected_spacing)) < sliceIntervalTolerance AS uniform_slice_spacing |
| 288 | + MAX(ABS(slice_interval - expected_spacing)) |
| 289 | + < relativeSliceTolerance * ABS(ANY_VALUE(expected_spacing)) AS uniform_slice_spacing |
283 | 290 |
|
284 | 291 | FROM sliceProjection |
285 | 292 | GROUP BY |
@@ -320,7 +327,7 @@ SELECT |
320 | 327 | consistent_image_dimensions, |
321 | 328 | # description: |
322 | 329 | # TRUE if the spacing between consecutive slices is constant |
323 | | - # (within sliceIntervalTolerance) |
| 330 | + # (within relativeSliceTolerance, a relative fraction of expected spacing) |
324 | 331 | uniform_slice_spacing, |
325 | 332 | # description: |
326 | 333 | # TRUE if all individual checks pass, indicating the series forms a regularly-spaced |
|
0 commit comments