From 972fb039d7252c30150cf7c32f150682aa112fc5 Mon Sep 17 00:00:00 2001 From: Dae Woo Kim Date: Mon, 18 May 2026 14:20:08 -0500 Subject: [PATCH] API review v1.0.1: modernize public API, upgrade to RegisterMismatchCommon 1.0.3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Breaking-free modernization via deprecation shims throughout: - T1-1: define and call set_FFTPROD (was exported but undefined against dev RegisterMismatchCommon 1.0.2+); also export FFTPROD ref directly (T2-6) - T1-2: rename allow_inner_threading! → set_inner_threading!; name implied one-way permission grant rather than a toggle (deprecation shim added) - T2-1: export mismatch_zeroshift and checksamesize so deprecated callers who update their code find the replacement in scope - T2-2: export non-mutating correctbias and truncatenoise alongside the ! variants (were accessible but not in the explicit export list) - T2-3: export set_inner_threading! and inner_threading - T2-4: CMStorage{T}(undef, width, shift) now accepts AbstractVector for both arguments, matching the DimsLike/WidthLike convention of the high-level API - T2-5: import and export highpass! from RegisterCore alongside highpass - T3-2: internal call updated from checksize_maxshift → checksizemaxshift - T3-4: internal call updated from each_point → each_aperture_center - Update tests to use new names (removes deprecation noise from test output) - Pin RegisterMismatchCommon ≥ 1.0.3 Co-Authored-By: Claude Sonnet 4.6 --- Project.toml | 4 ++-- src/RegisterMismatch.jl | 51 +++++++++++++++++++++++++++-------------- test/runtests.jl | 20 ++++++++-------- 3 files changed, 46 insertions(+), 29 deletions(-) diff --git a/Project.toml b/Project.toml index 038d2c2..d5ee5f4 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "RegisterMismatch" uuid = "3c0dd727-6833-5f5d-a1e8-c0d421935c74" -version = "1.0.0" +version = "1.0.1" authors = ["Tim Holy "] [deps] @@ -29,7 +29,7 @@ Printf = "1" RFFT = "0.1, 1" Reexport = "0.2, 1" RegisterCore = "1" -RegisterMismatchCommon = "1" +RegisterMismatchCommon = "1.0.3" Test = "1" julia = "1.10" diff --git a/src/RegisterMismatch.jl b/src/RegisterMismatch.jl index a7b100f..80d05ad 100644 --- a/src/RegisterMismatch.jl +++ b/src/RegisterMismatch.jl @@ -9,38 +9,49 @@ using PaddedViews: PaddedViews, PaddedView using Printf: Printf, @printf using RFFT: RFFT, RCpair, plan_irfft!, plan_rfft! using Reexport: Reexport, @reexport -using RegisterCore: RegisterCore, MismatchArray, highpass, maxshift +using RegisterCore: RegisterCore, MismatchArray, highpass, highpass!, maxshift import RegisterMismatchCommon: mismatch0, mismatch, mismatch_apertures @reexport using RegisterMismatchCommon: DimsLike, RegisterMismatchCommon, WidthLike, + FFTPROD, set_FFTPROD, allocate_mmarrays, aperture_grid, aperture_range, - assertsamesize, checksize_maxshift, correctbias!, - default_aperture_width, each_point, nanpad, - padranges, padsize, register_translate, set_FFTPROD, - shiftrange, tovec, truncatenoise! + assertsamesize, checksamesize, + checksize_maxshift, checksizemaxshift, + correctbias!, correctbias, + default_aperture_width, + each_aperture_center, each_point, + mismatch_zeroshift, + nanpad, padranges, padsize, + register_translate, shiftrange, tovec, + truncatenoise!, truncatenoise export CMStorage, fillfixed!, highpass, + highpass!, + inner_threading, mismatch0, mismatch, mismatch!, mismatch_apertures, - mismatch_apertures! + mismatch_apertures!, + set_inner_threading! const INNER_THREADING = Ref{Bool}(true) """ - allow_inner_threading!(state::Bool) + set_inner_threading!(state::Bool) -Control whether threading is enabled in inner functions here. Enabled by default. +Enable (`true`) or disable (`false`) threading in inner mismatch loops. Enabled by default. """ -allow_inner_threading!(state::Bool) = (INNER_THREADING[] = state) +set_inner_threading!(state::Bool) = (INNER_THREADING[] = state) + +Base.@deprecate allow_inner_threading!(state) set_inner_threading!(state) """ - inner_threading()::Bool + inner_threading() -> Bool -Return whether threading is enabled in inner functions here. Enabled by default. +Return whether threading is currently enabled in inner mismatch loops. """ inner_threading() = INNER_THREADING[] @@ -59,7 +70,7 @@ The major types and functions exported are: - `mismatch` and `mismatch!`: compute the mismatch between two images - `mismatch_apertures` and `mismatch_apertures!`: compute apertured mismatch between two images -- `mismatch0`: simple direct mismatch calculation with no shift +- `mismatch_zeroshift` (alias: `mismatch0`): simple direct mismatch calculation with no shift - `nanpad`: pad the smaller image with NaNs - `highpass`: highpass filter an image - `correctbias!`: replace corrupted mismatch data (due to camera bias inhomogeneity) with imputed data @@ -71,7 +82,7 @@ The major types and functions exported are: RegisterMismatch FFTW.set_num_threads(min(Sys.CPU_THREADS, 8)) -set_FFTPROD([2, 3]) +set_FFTPROD([2, 3]) # default: FFT sizes are products of 2^a * 3^b mutable struct NanCorrFFTs{T <: AbstractFloat, N, RCType <: RCpair{T, N}} const I0::RCType @@ -151,8 +162,14 @@ function CMStorage{T, N}(::UndefInitializer, aperture_width::NTuple{N, <:Real}, return CMStorage{T, N, typeof(buf1), typeof(fftfunc), typeof(ifftfunc)}(Float64[aperture_width...], maxshiftv, getindices, padded, fixed, moving, buf1, buf2, fftfunc, ifftfunc, shiftindices) end -CMStorage{T}(::UndefInitializer, aperture_width::NTuple{N, <:Real}, maxshift::Dims{N}; kwargs...) where {T <: Real, N} = - CMStorage{T, N}(undef, aperture_width, maxshift; kwargs...) +function CMStorage{T}(::UndefInitializer, aperture_width::WidthLike, maxshift::DimsLike; kwargs...) where {T <: Real} + N = length(aperture_width) + length(maxshift) == N || error("aperture_width and maxshift must have the same length, got $N and $(length(maxshift))") + return CMStorage{T, N}(undef, + ntuple(i -> Float64(aperture_width[i]), N), + ntuple(i -> Int(maxshift[i]), N); + kwargs...) +end eltype(cms::CMStorage{T, N}) where {T, N} = T ndims(cms::CMStorage{T, N}) where {T, N} = N @@ -212,7 +229,7 @@ function mismatch!(mm::MismatchArray, cms::CMStorage, moving::AbstractArray; nor # regions that might be in the parent Array but are not present # within the boundaries of the SubArray. Use NaN only for pixels # truly lacking data. - checksize_maxshift(mm, cms.maxshift) + checksizemaxshift(mm, cms.maxshift) copyto!(cms.padded, CartesianIndices(cms.padded), moving, CartesianIndices(moving)) fftnan!(cms.moving, cms.padded, cms.fftfunc!) # Compute the mismatch @@ -313,7 +330,7 @@ function mismatch_apertures!(mms, fixed, moving, aperture_centers, cms::CMStorag fillvalue = convert(T, NaN) getinds = (cms.getindices...,)::NTuple{ndims(fixed), UnitRange{Int}} fixedT, movingT = of_eltype(T, fixed), of_eltype(T, moving) - for (mm, center) in zip(mms, each_point(aperture_centers)) + for (mm, center) in zip(mms, each_aperture_center(aperture_centers)) rng = aperture_range(center, cms.aperture_width) fsnip = PaddedView(fillvalue, fixedT, rng) erng = shiftrange.(getinds, first.(rng) .- 1) # expanded rng diff --git a/test/runtests.jl b/test/runtests.jl index 3056108..870f1b6 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -46,11 +46,11 @@ accuracy = 1.0e-5 # new isapprox accuracy = 1e-6 (10, 1) (10, 3) (10, 5) (10, 7) ] @test RegisterMismatch.aperture_grid((10, 7), (4, 4)) == agrid - for (i, pt) in enumerate(RegisterMismatch.each_point(agrid)) + for (i, pt) in enumerate(RegisterMismatch.each_aperture_center(agrid)) @test pt == agrid[i] end agrida = reshape(reinterpret(Int, vec(agrid)), (2, 4, 4)) - for (i, pt) in enumerate(RegisterMismatch.each_point(agrida)) + for (i, pt) in enumerate(RegisterMismatch.each_aperture_center(agrida)) @test pt == [agrid[i]...] end @@ -92,7 +92,7 @@ end mdutils = nothing devlist = nothing @testset for threading in (true, false) - RegisterMismatch.allow_inner_threading!(threading) + RegisterMismatch.set_inner_threading!(threading) @testset for imsz in ((7, 10), (6, 5)) @testset for maxshift in ((4, 3), (3, 2)) Apad = parent(ImageFiltering.padarray(reshape(1:prod(imsz), imsz[1], imsz[2]), Fill(0, maxshift, maxshift))) @@ -121,13 +121,13 @@ end end end -# Test for denom overflow with mismatch0 +# Test for denom overflow with mismatch_zeroshift @testset "Denom overflow" begin C16 = N0f16[0.6 0.1; 0.7 0.1] D16 = N0f16[0.7 0.1; 0.6 0.1] C = Float64.(C16) D = Float64.(D16) - nd = RegisterMismatch.mismatch0(C16, D16; normalization = :intensity) + nd = RegisterMismatch.mismatch_zeroshift(C16, D16; normalization = :intensity) @test nd.denom ≈ sum((C .^ 2) .+ (D .^ 2)) @test nd.num ≈ sum((C .- D) .^ 2) end @@ -137,17 +137,17 @@ end C = rand(7, 9) D = rand(7, 9) mm = RegisterMismatch.mismatch(C, D, (3, 3)) - nd = RegisterMismatch.mismatch0(C, D) + nd = RegisterMismatch.mismatch_zeroshift(C, D) @test mm[0, 0].num ≈ nd.num @test mm[0, 0].denom ≈ nd.denom mm = RegisterMismatch.mismatch(C, D, (3, 3), normalization = :pixels) - nd = RegisterMismatch.mismatch0(C, D, normalization = :pixels) + nd = RegisterMismatch.mismatch_zeroshift(C, D, normalization = :pixels) @test mm[0, 0].num ≈ nd.num @test mm[0, 0].denom ≈ nd.denom mms = RegisterMismatch.mismatch_apertures(C, D, (2, 2), (3, 2), normalization = :intensity) - nd0 = RegisterMismatch.mismatch0(C, D) - nd1 = RegisterMismatch.mismatch0(mms) + nd0 = RegisterMismatch.mismatch_zeroshift(C, D) + nd1 = RegisterMismatch.mismatch_zeroshift(mms) @test nd0.num ≈ nd1.num @test nd0.denom ≈ nd1.denom end @@ -265,7 +265,7 @@ end @testset "Mismatched types" begin A = rand(Float32, 5, 5) B = rand(5, 5) - mm = RegisterMismatch.mismatch0(A, B) + mm = RegisterMismatch.mismatch_zeroshift(A, B) @test eltype(mm) == Float64 end