Skip to content

ENH: Ingest AnisotropicDiffusionLBR into Modules/Filtering#6093

Open
hjmjohnson wants to merge 175 commits intoInsightSoftwareConsortium:mainfrom
hjmjohnson:ingest-AnisotropicDiffusionLBR
Open

ENH: Ingest AnisotropicDiffusionLBR into Modules/Filtering#6093
hjmjohnson wants to merge 175 commits intoInsightSoftwareConsortium:mainfrom
hjmjohnson:ingest-AnisotropicDiffusionLBR

Conversation

@hjmjohnson
Copy link
Copy Markdown
Member

Moves AnisotropicDiffusionLBR from a configure-time remote fetch into the ITK source tree at Modules/Filtering/AnisotropicDiffusionLBR/. Full upstream git history and blame preserved. Relates to #6060.

Approach

Per reviewer consensus on #6061 and #6085: remote modules go directly into their appropriate group — no intermediate staging directory.

The upstream repo (ITKAnisotropicDiffusionLBR) is grafted via git merge --allow-unrelated-histories --no-ff of a filter-repo'd clone that rewrites paths under Modules/Filtering/AnisotropicDiffusionLBR/. The merge commit is byte-identical to the upstream tree (just path-prefixed); all artifact removal happens in a separate STYLE commit.

Commit structure (5 commits)
  1. COMP: Bump AnisotropicDiffusionLBR to upstream/main tip — updates GIT_TAG to upstream HEAD (203260b9)
  2. ENH: Ingest ITKAnisotropicDiffusionLBR into Modules/Filtering — merge commit, byte-identical to upstream tree
  3. STYLE: Remove non-ITK artifacts from ingested AnisotropicDiffusionLBR — removes .github/, pyproject.toml, CTestConfig.cmake, .clang-format, .gitattributes, LICENSE (Apache-2.0 duplicate)
  4. COMP: Remove AnisotropicDiffusionLBR.remote.cmake; now in-tree — deletes the remote fetch declaration
  5. COMP: Fix pre-commit hook failures for AnisotropicDiffusionLBR — gersemi, trailing whitespace, EOF fixes
Verification
  • 136 upstream commits preserved across the merge boundary
  • 12 distinct authors surface in git log (Matt McCormick, Bradley Lowekamp, Dženan Zukić, Hans Johnson, Jon Haitz Legarreta, Tom Birdsong, etc.)
  • git blame walks through the merge boundary to original authors (2015+)
  • Configure: clean
  • Build: no errors, no warnings
  • Tests: 6/6 pass
  • Pre-commit: all hooks pass
AI disclosure

Ingestion tooling (ingest-remote-module.sh) and commit structure developed with Claude Code assistance. All commits reviewed and verified locally.

thewtex added 30 commits May 27, 2015 21:33
Initial import from http://hdl.handle.net/10380/3505
http://insight-journal.org/browse/publication/953

Add missing LICENSE file.

Test data is uploaded to midas3.kitware.com and content links are added
instead.
This is a requirement to add the file to ITK as a Remote Module.
Also fix trailing whitespace, indentation, some comments.
This causes issues when building outside the ITK source tree.
This is not found in Windows.  itk::TimeProbe is a cross-platform replacement.
 This was used for debug code, so that was removed.
Uses std::cout instead of std::cerr.
This is for:

  c:\jenkins\workspace\itkgerritwindows\itk-src\modules\remote\anisotropicdiffusionlbr\include\itkLinearAnisotropicDiffusionLBRImageFilter.h(110)
  : warning C4348:
  'itk::LinearAnisotropicDiffusionLBRImageFilter::GetDiffusion' : redefinition
  of default parameter : parameter 1
This is for:

  c:\jenkins\workspace\itkgerritwindows\itk-src\modules\remote\anisotropicdiffusionlbr\include\itkStructureTensorImageFilter.h(95)
  : warning C4348:
  'itk::StructureTensorImageFilter,itk::Image>::IntermediateFilter' :
  redefinition of default parameter : parameter 1

on MSVC.
hjmjohnson and others added 10 commits November 11, 2025 21:03
Previous: 753f2498af4dbd4a864fe6378da72e92654b7f80
Updated:  203260b929acda68a1f64b1267b0d89e825904ec
Grafts the ITKAnisotropicDiffusionLBR remote module into the ITK source tree at
Modules/Filtering/AnisotropicDiffusionLBR/, replacing the configure-time
fetch declared in Modules/Remote/AnisotropicDiffusionLBR.remote.cmake.

Upstream:         https://github.com/InsightSoftwareConsortium/ITKAnisotropicDiffusionLBR.git
Upstream SHA:     203260b929acda68a1f64b1267b0d89e825904ec
Upstream branch:  main
Ingest date:      2026-04-20
Compliance level: 2
License:          Apache-2.0

Full upstream commit history preserved via
git merge --allow-unrelated-histories --no-ff.
git blame and git log --follow walk across the merge boundary.
Removes standalone-repo scaffolding that has no role in the ITK
monorepo. No edits to ingested source files; structural cleanup only.
Module is now at Modules/Filtering/AnisotropicDiffusionLBR/.
The configure-time fetch is no longer needed.
@github-actions github-actions bot added type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots type:Enhancement Improvement of existing methods or implementation area:Python wrapping Python bindings for a class type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct area:Filtering Issues affecting the Filtering module area:Remotes Issues affecting the Remote module type:Data Changes to testing data labels Apr 20, 2026
Add -DModule_AnisotropicDiffusionLBR:BOOL=ON to the configure-ci pixi
task so CI builds and tests this in-tree module. The module retains
EXCLUDE_FROM_DEFAULT for end-user opt-in.
@hjmjohnson hjmjohnson force-pushed the ingest-AnisotropicDiffusionLBR branch from f942a33 to d6c65ba Compare April 20, 2026 23:20
@hjmjohnson hjmjohnson requested a review from thewtex April 20, 2026 23:21
@hjmjohnson
Copy link
Copy Markdown
Member Author

@thewtex — this PR demonstrates the process for ingesting remote modules directly into their appropriate group, per your feedback on #6061 and #6085. One PR per module, full upstream history preserved via git merge --allow-unrelated-histories. Module stays EXCLUDE_FROM_DEFAULT; CI opts in explicitly via configure-ci.

If this looks right, I'll proceed with the remaining ~30 Tier-A modules using the same pattern.

Overall ingestion plan

Approach (per reviewer consensus on #6061, #6085):

  • Each remote module goes directly into its existing group (Modules/Filtering/, Modules/IO/, etc.)
  • One PR per module
  • Full upstream git history preserved — git blame walks across the merge boundary
  • Upstream repo archived on GitHub after merge

Commit structure per module (7 commits):

  1. COMP: Bump <Name> to upstream/<branch> tip — sync to latest upstream SHA
  2. ENH: Ingest ITK<Name> into Modules/<Group> — merge commit, byte-identical to upstream tree (just path-prefixed)
  3. STYLE: Remove non-ITK artifacts from ingested <Name>.github/, pyproject.toml, CTestConfig.cmake, .clang-format, .gitattributes, redundant LICENSE
  4. COMP: Remove <Name>.remote.cmake; now in-tree — delete the remote fetch declaration
  5. COMP: Fix pre-commit hook failures for <Name> — gersemi, trailing whitespace, EOF newlines
  6. STYLE: Add missing trailing newlines to .md5 data files — ghostflow compliance
  7. ENH: Enable <Name> in CI via configure-ci — add -DModule_<Name>:BOOL=ON to pixi configure-ci

What stays independent (not ingested):
RTK, CudaCommon, Cleaver, SCIFIO, Shape, TractographyTRX, WebAssemblyInterface, SphinxExamples, TubeTK, Ultrasound, and modules with external library deps (TotalVariation, IOOMEZarrNGFF, IOOpenSlide, VkFFTBackend, MeshToPolyData, IOTransformDCMTK).

Proposed wave order:

Wave Modules Group
1 AnisotropicDiffusionLBR, FastBilateral, LabelErodeDilate, GenericLabelInterpolator, SplitComponents, PolarTransform, MultipleImageIterator, HigherOrderAccurateGradient, ParabolicMorphology, MorphologicalContourInterpolation, SmoothingRecursiveYvvGaussianFilter, Cuberille, MeshNoise, SubdivisionQuadEdgeMeshFilter Filtering
1 IOMeshSTL, IOMeshMZ3, IOFDF IO
2 BoneEnhancement, BoneMorphometry, TextureFeatures, IsotropicWavelets, Montage, Thickness3D, Strain, PhaseSymmetry, SimpleITKFilters Filtering
2 IOScanco, MGHIO IO
2 GrowCut Segmentation
2 RANSAC, VariationalRegistration Registration
Ingestion script (ingest-remote-module.sh)
# Usage:
./ingest-remote-module.sh <ModuleName> <DestGroup> [OPTIONS]

# Examples:
./ingest-remote-module.sh AnisotropicDiffusionLBR Filtering
./ingest-remote-module.sh IOMeshSTL IO
./ingest-remote-module.sh GrowCut Segmentation --dry-run

# Options:
#   --dry-run          Preview without executing
#   --skip-bump        Don't update GIT_TAG to upstream tip
#   --skip-precommit   Don't run pre-commit fixes
#   --upstream-url     Override GIT_REPOSITORY from .remote.cmake
#   --upstream-branch  Override upstream branch (default: auto-detect)
#   --itk-source       Override ITK source root detection

What it automates:

  1. Parses Modules/Remote/<Name>.remote.cmake for upstream URL and SHA
  2. Bumps GIT_TAG to the current upstream tip (if out of date)
  3. Clones upstream, runs git filter-repo --to-subdirectory-filter to rewrite paths
  4. Merges into ITK with --allow-unrelated-histories --no-ff (byte-identical to upstream)
  5. Removes non-ITK artifacts (CI configs, packaging scaffolding) in a separate STYLE commit
  6. Deletes the .remote.cmake file
  7. Runs pre-commit hooks to convergence
  8. Adds -DModule_<Name>:BOOL=ON to configure-ci in pyproject.toml

Prerequisites: git-filter-repo (pip install git-filter-repo), pixi, clean working tree.

What it does NOT do: push, open PRs, or modify source code. All improvements (clang-tidy, CMake modernization, test renames) are deferred to follow-up PRs.

@hjmjohnson hjmjohnson requested review from blowekamp and dzenanz April 21, 2026 10:48
@hjmjohnson hjmjohnson marked this pull request as ready for review April 21, 2026 10:49
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 21, 2026

Greptile Summary

This PR ingests AnisotropicDiffusionLBR from its remote fetch location into Modules/Filtering/AnisotropicDiffusionLBR/, preserving the full upstream git history via a filter-repo-rewritten merge commit. The remote .cmake file is deleted, pyproject.toml is updated to enable the module in CI, and upstream-only artifacts (.github/, pyproject.toml, CI configs) are stripped in a separate STYLE commit.

  • P1: itkStructureTensorImageFilter.h has using Superclass = ImageToImageFilter<TImage, TImage> but the class inherits from ImageToImageFilter<TImage, TTensorImage> — these are distinct template instantiations and the alias misrepresents the base class.

Confidence Score: 4/5

Safe to merge after addressing the Superclass typedef bug in itkStructureTensorImageFilter.h

One P1 finding: the Superclass alias in itkStructureTensorImageFilter resolves to the wrong template instantiation (TImage vs TTensorImage), which is a latent type-correctness defect even though the current build passes. The P2 on itk-module.cmake I/O deps is cosmetic. The ingestion mechanics, history preservation, and CI configuration are all correct.

Modules/Filtering/AnisotropicDiffusionLBR/include/itkStructureTensorImageFilter.h (wrong Superclass alias)

Important Files Changed

Filename Overview
Modules/Filtering/AnisotropicDiffusionLBR/include/itkStructureTensorImageFilter.h Incorrect Superclass typedef — aliases ImageToImageFilter<TImage, TImage> instead of the actual base ImageToImageFilter<TImage, TTensorImage>
Modules/Filtering/AnisotropicDiffusionLBR/itk-module.cmake ITKIOSpatialObjects and ITKMetaIO listed in module DEPENDS but no public headers require them; likely should be in TEST_DEPENDS or removed
Modules/Filtering/AnisotropicDiffusionLBR/CMakeLists.txt Standard in-tree module build file; version hardcoded to 5.1.0 with a comment noting it should track ITK
Modules/Remote/AnisotropicDiffusionLBR.remote.cmake Remote fetch declaration correctly removed now that the module is in-tree
Modules/Filtering/AnisotropicDiffusionLBR/include/itkAnisotropicDiffusionLBRImageFilter.h Base non-linear anisotropic diffusion filter; clean ITK-style header with correct type aliases
Modules/Filtering/AnisotropicDiffusionLBR/include/itkCoherenceEnhancingDiffusionImageFilter.h CED/EED subclass; clean header with properly overridden EigenValuesTransform
Modules/Filtering/AnisotropicDiffusionLBR/include/itkLinearAnisotropicDiffusionLBRImageFilter.h Linear diffusion core filter with LBR stencil arithmetic; correct ITK conventions
Modules/Filtering/AnisotropicDiffusionLBR/test/CMakeLists.txt 15 test cases across 2D/3D images with proper DATA{} references and baseline comparisons
pyproject.toml Adds -DModule_AnisotropicDiffusionLBR:BOOL=ON to CI configure, correctly enabling the now in-tree module
Modules/Filtering/AnisotropicDiffusionLBR/wrapping/CMakeLists.txt Wrapping configured with WRAPPING_SUBMODULE_ORDER ensuring base class wraps before subclass; auto-discovers itkCoherenceEnhancingDiffusionImageFilter.wrap

Class Diagram

%%{init: {'theme': 'neutral'}}%%
classDiagram
    class ImageToImageFilter~TImage,TOutput~ {
        +GenerateData()
    }
    class LinearAnisotropicDiffusionLBRImageFilter~TImage,TScalar~ {
        +SetInputImage()
        +SetInputTensor()
        +SetMaxDiffusionTime()
        +GenerateData()
    }
    class AnisotropicDiffusionLBRImageFilter~TImage,TScalar~ {
        +EigenValuesTransform()
        +ComputeDiffusionTensors()
        +GenerateData()
    }
    class CoherenceEnhancingDiffusionImageFilter~TImage,TScalar~ {
        +EigenValuesTransform()
        -g_CED()
        -g_EED()
    }
    class StructureTensorImageFilter~TImage,TTensorImage~ {
        +GenerateData()
    }

    ImageToImageFilter <|-- LinearAnisotropicDiffusionLBRImageFilter
    ImageToImageFilter <|-- AnisotropicDiffusionLBRImageFilter
    ImageToImageFilter <|-- StructureTensorImageFilter
    AnisotropicDiffusionLBRImageFilter <|-- CoherenceEnhancingDiffusionImageFilter
    AnisotropicDiffusionLBRImageFilter o-- LinearAnisotropicDiffusionLBRImageFilter : uses
    AnisotropicDiffusionLBRImageFilter o-- StructureTensorImageFilter : uses
Loading

Reviews (1): Last reviewed commit: "ENH: Enable AnisotropicDiffusionLBR in C..." | Re-trigger Greptile

ITK_DISALLOW_COPY_AND_MOVE(StructureTensorImageFilter);

using Self = StructureTensorImageFilter;
using Superclass = ImageToImageFilter<TImage, TImage>;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Incorrect Superclass type alias

Superclass is aliased to ImageToImageFilter<TImage, TImage>, but the class actually inherits from ImageToImageFilter<TImage, TTensorImage>. These are two different template instantiations: TImageTTensorImage (the default TTensorImage is Image<SymmetricSecondRankTensor<...>, N>, not TImage). Any downstream code that resolves StructureTensorImageFilter::Superclass::OutputImageType will get the wrong type.

Suggested change
using Superclass = ImageToImageFilter<TImage, TImage>;
using Superclass = ImageToImageFilter<TImage, TTensorImage>;

Comment on lines +10 to +11
ITKCommon
ITKIOImageBase
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Questionable module-level I/O dependencies

ITKIOSpatialObjects and ITKMetaIO appear in module DEPENDS, but none of the public headers include anything from these modules (no SpatialObject or MetaIO headers are pulled in). I/O used only in tests should live under TEST_DEPENDS, not DEPENDS, to avoid forcing downstream consumers to link against unused I/O libraries. If these are genuinely unused, they can be removed outright; if they are needed for test I/O (e.g. .vtk files), ITKIOVTK would be the correct dependency and it should go in TEST_DEPENDS.

@blowekamp
Copy link
Copy Markdown
Member

I don't think merging the full history is a good idea to all remote repositories. The remote repos have not had the same rigor as the main repo, larger file ( such as those used for papers may have been included, or perhaps some copyright material). There could also have been a long initial development period too. If this is done with most remotes then I think the ITK git history may become to bloated.

There may be some git history filter that could be run to reduce it to the files that are important ( main cxx,h file ) but I am unsure.

Also it appear the remote CMake code is still here.

@hjmjohnson
Copy link
Copy Markdown
Member Author

There may be some git history filter that could be run to reduce it to the files that are important ( main cxx,h file ) but I am unsure.

@blowekamp We could
-"squash" to 1 commit, (retain last-modified attribution, with reference to the original archived repo for deeper dives into attribution).

  • or could have a history filter that removes large files,
  • or removes all transient files that are not retained in the origin/main sandbox.
  • or a combination of the above.

Could you help me define a set of characteristics that are most important to retain?

My desired characteristics:

  1. retain last-modified attribution ... That's about it. The return on investment diminishes significantly after that. We have a complete history, it's just not as easy to find (but a vanishingly small number of people will need that).

@blowekamp
Copy link
Copy Markdown
Member

For these particular file I see a comment "Created by Jean-Marie Mirebeau on 28/02/2014." but it does not look like he is a git author. I think this is a special case that may need to be created.

Perhaps we can just squash the commits and use primary author and co-author?

I think it will be important to remove extra files in this process. I don't think the paper and related material should be in ITK. This repo has an "Old" directory that I expect is not needed. There is an "example" directory with what appears to be a full content PNG file, which should be removed. I think an "example" directory with executables is reasonable on a per module basis, but I'm not aware of the current support in modules.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:Filtering Issues affecting the Filtering module area:Python wrapping Python bindings for a class area:Remotes Issues affecting the Remote module type:Data Changes to testing data type:Enhancement Improvement of existing methods or implementation type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants