Analysis of commit 846ffc9
Assignee: @copilot
Summary
Two duplication patterns were found in fidnii/src/utils/coordinates.ts:
normalizedToWorld / worldToNormalized share ~18 identical lines of axis-index setup and error-handling code.
clampPixelCoord / roundPixelCoord / floorPixelCoord / ceilPixelCoord all apply a single Math.* function element-wise to a [number, number, number] triple — 4 structurally identical functions totalling ~37 lines.
Duplication Details
Pattern 1 — Shared Axis-Index Setup in normalizedToWorld / worldToNormalized
- Severity: Medium
- Occurrences: 2
- Locations:
fidnii/src/utils/coordinates.ts lines 131–163 (normalizedToWorld)
fidnii/src/utils/coordinates.ts lines 173–207 (worldToNormalized)
- Duplicated block (~18 lines, identical in both functions):
const shape = ngffImage.data.shape
const dims = ngffImage.dims
const yIdx = dims.indexOf("y")
const xIdx = dims.indexOf("x")
if (yIdx === -1 || xIdx === -1) {
const missingAxes = [xIdx === -1 ? "x" : null, yIdx === -1 ? "y" : null]
.filter((axis): axis is string => axis !== null)
.join(", ")
throw new Error(
`NgffImage is missing required spatial dimension(s): \$\{missingAxes}`,
)
}
const zIdx = dims.indexOf("z")
const dimZ = zIdx !== -1 ? shape[zIdx] : 1
const dimY = shape[yIdx]
const dimX = shape[xIdx]
Refactoring suggestion: Extract to a private helper, e.g.:
function getSpatialDims(ngffImage: NgffImage): {
dimX: number; dimY: number; dimZ: number
} { ... }
Both normalizedToWorld and worldToNormalized call this helper and use the returned values.
Pattern 2 — Four Identical Element-Wise Pixel-Coordinate Mappers
- Severity: Low-Medium
- Occurrences: 4
- Locations:
fidnii/src/utils/coordinates.ts lines 216–225 (clampPixelCoord)
fidnii/src/utils/coordinates.ts lines 233–241 (roundPixelCoord)
fidnii/src/utils/coordinates.ts lines 249–257 (floorPixelCoord)
fidnii/src/utils/coordinates.ts lines 265–273 (ceilPixelCoord)
- Structural template (same for every function except the
Math.* call):
export function (name)PixelCoord(
pixelCoord: [number, number, number],
// (clampPixelCoord also takes `shape` as a second param)
): [number, number, number] {
return [
Math.(op)(pixelCoord[0], ...),
Math.(op)(pixelCoord[1], ...),
Math.(op)(pixelCoord[2], ...),
]
}
Refactoring suggestion: Extract a generic helper:
function mapPixelCoord(
pixelCoord: [number, number, number],
fn: (v: number, i: number) => number,
): [number, number, number] {
return [fn(pixelCoord[0], 0), fn(pixelCoord[1], 1), fn(pixelCoord[2], 2)]
}
Then each public function becomes a one-liner wrapper.
Impact Analysis
- Maintainability: Both patterns require parallel edits whenever the logic changes — for Pattern 1, any update to the axis-validation error message or default-z handling must be copied to both functions.
- Bug Risk: Inconsistent fixes are likely; a bug fix applied to one function may be missed in the other.
- Code Bloat: ~55 lines can be reduced to ~20 after refactoring.
Implementation Checklist
Analysis Metadata
- Analyzed Files:
fidnii/src/utils/coordinates.ts (primary), fidnii/src/OMEZarrNVImage.ts, fidnii/src/ClipPlanes.ts, fidnii/src/utils/orientation.ts
- Detection Method: Serena semantic code analysis + pattern search
- Commit:
846ffc9ba09295d0427772a86fddb822b9d7d307
- Analysis Date: 2026-04-16
Generated by Duplicate Code Detector
To install this agentic workflow, run
gh aw add github/gh-aw/.github/workflows/duplicate-code-detector.md@33cd6c7f1fee588654ef19def2e6a4174be66197
Analysis of commit 846ffc9
Assignee:
@copilotSummary
Two duplication patterns were found in
fidnii/src/utils/coordinates.ts:normalizedToWorld/worldToNormalizedshare ~18 identical lines of axis-index setup and error-handling code.clampPixelCoord/roundPixelCoord/floorPixelCoord/ceilPixelCoordall apply a singleMath.*function element-wise to a[number, number, number]triple — 4 structurally identical functions totalling ~37 lines.Duplication Details
Pattern 1 — Shared Axis-Index Setup in
normalizedToWorld/worldToNormalizedfidnii/src/utils/coordinates.tslines 131–163 (normalizedToWorld)fidnii/src/utils/coordinates.tslines 173–207 (worldToNormalized)Refactoring suggestion: Extract to a private helper, e.g.:
Both
normalizedToWorldandworldToNormalizedcall this helper and use the returned values.Pattern 2 — Four Identical Element-Wise Pixel-Coordinate Mappers
fidnii/src/utils/coordinates.tslines 216–225 (clampPixelCoord)fidnii/src/utils/coordinates.tslines 233–241 (roundPixelCoord)fidnii/src/utils/coordinates.tslines 249–257 (floorPixelCoord)fidnii/src/utils/coordinates.tslines 265–273 (ceilPixelCoord)Math.*call):Refactoring suggestion: Extract a generic helper:
Then each public function becomes a one-liner wrapper.
Impact Analysis
Implementation Checklist
getSpatialDimshelper fornormalizedToWorld/worldToNormalizedmapPixelCoordhelper (or inlineArray.frommap) for the four element-wise functionsbun run checkto confirm linting passesAnalysis Metadata
fidnii/src/utils/coordinates.ts(primary),fidnii/src/OMEZarrNVImage.ts,fidnii/src/ClipPlanes.ts,fidnii/src/utils/orientation.ts846ffc9ba09295d0427772a86fddb822b9d7d307