Skip to content

Commit a87a2c7

Browse files
committed
Merge remote-tracking branch 'upstream/main' into ingest-RANSAC
# Conflicts: # pyproject.toml
2 parents 19a42c0 + 0792cce commit a87a2c7

155 files changed

Lines changed: 11889 additions & 308 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ Modules/ThirdParty/Expat/src/expat/lib/xmlparse.c hooks-max-size=320000
5959
Documentation/docs/releases/* hooks-max-size=300000
6060
Documentation/Art/* hooks-max-size=300000
6161
pixi.lock hooks-max-size=1000000
62+
Testing/Data/content-links.manifest hooks-max-size=1000000
6263

6364
# VNL-specific .gitattributes should go into Modules/ThirdParty/VNL/.gitattributes
6465
# GDCM-specific .gitattributes should go into Modules/ThirdParty/GDCM/src/gdcm/.gitattributes

CMake/ITKExternalData.cmake

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,22 @@ if(NOT ITK_FORBID_DOWNLOADS)
5151
ExternalData_URL_TEMPLATES
5252
# Data published on GitHub Pages
5353
"https://insightsoftwareconsortium.github.io/ITKTestingData/%(algo)/%(hash)"
54-
# Data published on Girder
55-
"https://data.kitware.com:443/api/v1/file/hashsum/%(algo)/%(hash)/download"
56-
# Data published by developers using git-gerrit-push.
57-
"https://itk.org/files/ExternalData/%(algo)/%(hash)"
5854
# Local IPFS gateway
5955
"http://127.0.0.1:8080/ipfs/%(hash)"
6056
# Protocol Labs gateway
6157
"https://ipfs.io/ipfs/%(hash)"
58+
# Filebase gateway
59+
"https://ipfs.filebase.io/ipfs/%(hash)"
6260
# Gateway for data pinned on pinata
6361
"https://gateway.pinata.cloud/ipfs/%(hash)"
6462
# Cloudflare gateway
6563
"https://cloudflare-ipfs.com/ipfs/%(hash)"
6664
# Additional gateway (modern but has redirect)
6765
"https://dweb.link/ipfs/%(hash)"
66+
# Data published on Girder
67+
"https://data.kitware.com:443/api/v1/file/hashsum/%(algo)/%(hash)/download"
68+
# Data published by developers using git-gerrit-push.
69+
"https://itk.org/files/ExternalData/%(algo)/%(hash)"
6870
)
6971
endif()
7072

-72.1 KB
Binary file not shown.

Documentation/docs/contributing/data.md

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ generation) also applies to any other data contained in a text file that a
1111
test may require, if any.
1212

1313
If you just want to browse and download the ITK testing images, browse the
14-
[ITKData Datalad repository].
14+
[ITKTestingData repository]. Historical snapshots are also archived in
15+
the [ITKData DataLad repository].
1516

1617
Setup
1718
-----
@@ -43,7 +44,33 @@ associated with these files.
4344
Generate the *.cid* content link from your test data file, *MyTest.png* in
4445
this example, with the [content-link-upload] web app. This app will
4546
upload the data to IPFS and provide a *.cid* CMake ExternalData content link file
46-
to download.
47+
to download. This is the easiest and recommended way to upload new test data.
48+
49+
For command-line uploads, run the Python helper at
50+
`Utilities/Maintenance/ExternalDataUpload/upload.py` from the
51+
`external-data-upload` pixi environment:
52+
53+
```bash
54+
pixi run -e external-data-upload python \
55+
Utilities/Maintenance/ExternalDataUpload/upload.py \
56+
Modules/.../test/Baseline/MyTest.png
57+
```
58+
59+
The helper packs the file into a CARv1 with `npx ipfs-car` (defaults
60+
match the unixfs-v1-2025 / IPIP-0499 profile so CIDs are reproducible),
61+
uploads the CAR to your [Filebase] IPFS bucket via Filebase's S3-compatible
62+
REST API, verifies the CID Filebase reports back matches what was computed
63+
locally, and replaces the original file with `MyTest.png.cid` containing
64+
that CID. The CID and source-tree path are also recorded in
65+
`Testing/Data/content-links.manifest`. A local IPFS daemon is **not**
66+
required.
67+
68+
First-time CLI users must complete the one-time pixi + Filebase setup
69+
documented in
70+
[`Utilities/Maintenance/ExternalDataUpload/README.md`] before the helper
71+
will succeed. Contributors who prefer not to run any local tooling can
72+
instead use the [content-link-upload] web app, which returns a `.cid`
73+
file directly.
4774

4875
For more details, see the description and procedures in [Upload Binary Data].
4976

@@ -142,5 +169,8 @@ the [InterPlanetary File System (IPFS)].
142169
[CMake ExternalData: Using Large Files with Distributed Version Control]: https://blog.kitware.com/cmake-externaldata-using-large-files-with-distributed-version-control/
143170
[content-link-upload]: https://content-link-upload.itk.org
144171
[InterPlanetary File System (IPFS)]: https://ipfs.tech/
145-
[ITKData Datalad repository]: https://gin.g-node.org/InsightSoftwareConsortium/ITKData/src/main
172+
[ITKData DataLad repository]: https://gin.g-node.org/InsightSoftwareConsortium/ITKData/src/main
173+
[ITKTestingData repository]: https://github.com/InsightSoftwareConsortium/ITKTestingData
146174
[Upload Binary Data]: upload_binary_data.md
175+
[`Utilities/Maintenance/ExternalDataUpload/README.md`]: https://github.com/InsightSoftwareConsortium/ITK/blob/main/Utilities/Maintenance/ExternalDataUpload/README.md
176+
[Filebase]: https://filebase.com/

Documentation/docs/contributing/upload_binary_data.md

Lines changed: 126 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -33,35 +33,47 @@ adopting Web3, we gain:
3333
- **Scalability**
3434
- **Sustainability**
3535

36-
Contributors to the ITK upload their data through a simple web app
37-
that utilizes an easy-to-use, permissionless, free service, [web3.storage].
38-
39-
Data used in the ITK Git repository is periodically tracked in a
40-
dedicated DataLad repository, the [ITKData DataLad repository].
41-
and stored across redundant locations so it can be retrieved from any of
42-
the following:
43-
44-
- Local [IPFS](https://ipfs.io/) nodes
45-
- Peer [IPFS](https://ipfs.io/) nodes
46-
- [web3.storage](https://web3.storage/)
47-
- [pinata.cloud](https://pinata.cloud)
48-
- Kitware's IPFS Server
49-
- [ITKTestingData](https://github.com/InsightSoftwareConsortium/ITKTestingData) GitHub Pages CDN
36+
Contributors upload their data by running a small Python helper that packs
37+
the file into a [CARv1] using `npx ipfs-car`, uploads the CAR to a [Filebase]
38+
IPFS bucket through Filebase's S3-compatible REST API, records the resulting
39+
CID in a manifest, and (optionally) mirrors the bytes into the [ITKTestingData]
40+
GitHub Pages repository. A local [Kubo] daemon, IPFS Desktop, or any
41+
`ipfs pin remote` PSA service is **not** required. See
42+
[`Utilities/Maintenance/ExternalDataUpload/README.md`] for the one-time
43+
developer setup and full workflow.
44+
45+
[CARv1]: https://ipld.io/specs/transport/car/carv1/
46+
47+
Data referenced from the ITK Git repository is stored across redundant
48+
locations so it can be retrieved from any of the following at build time:
49+
50+
- [Filebase] IPFS gateway (where uploads land)
51+
- [ITKTestingData] GitHub Pages mirror
52+
- Public IPFS HTTP gateways (`ipfs.io`, `dweb.link`, `cloudflare-ipfs.com`,
53+
`gateway.pinata.cloud`)
54+
- Local [Kubo] gateway (typically `127.0.0.1:8080`) when present
5055
- Kitware's Apache HTTP Server
51-
- Local testing data cache
56+
- Local `ExternalData_OBJECT_STORES` cache
5257
- Archive tarballs from GitHub Releases
58+
- Historical [ITKData DataLad repository] snapshots (older content links)
5359

5460
![ITK testing data figure](./itk-testing-data.png)
5561

56-
*Testing data workflow. Testing or example data is uploaded to IPFS via the content-link-upload.itk.org web app.
57-
This pins the data on multiple servers across the globe.
58-
At release time, the data is also pinned on multiple servers in the USA and France and community pinners.
59-
At release time, the data is also stored in the DataLad Git repository, served on an Apache HTTP server, and the GitHub Pages CDN.
60-
At test time an ITK build can pull the data from a local cache, archive tarball, the Apache HTTP server, GitHub Pages CDN, or multiple IPFS HTTP gateways.*
61-
62-
See also our [Data](data.md) guide for more information. If you just
63-
want to browse and download the ITK testing images, see the
64-
[ITKData DataLad repository].
62+
*Testing data workflow. New content is added with the
63+
`Utilities/Maintenance/ExternalDataUpload/upload.py` helper, which packs
64+
the file into a CAR with `npx ipfs-car` (defaults match the
65+
unixfs-v1-2025 / IPIP-0499 profile so CIDs are reproducible) and uploads
66+
the CAR to a [Filebase] IPFS bucket via boto3 against Filebase's
67+
S3-compatible API. The CID Filebase reports back from `head_object` is
68+
verified against the locally computed CID, written as a `.cid` content
69+
link in the ITK source tree, and recorded in
70+
`Testing/Data/content-links.manifest`. Files ≤ 50 MB can additionally be
71+
mirrored into [ITKTestingData] for GitHub Pages CDN delivery. At test
72+
time an ITK build can fetch the data from a local cache, archive tarball,
73+
the Apache HTTP server, the GitHub Pages mirror, or any of several public
74+
IPFS HTTP gateways.*
75+
76+
See also our [Data](data.md) guide for more information.
6577

6678
Adding images as input to ITK sources
6779
-------------------------------------
@@ -89,107 +101,136 @@ need to be followed:
89101
Upload new testing data
90102
-----------------------
91103

92-
### Prerequisites
104+
### One-time setup
93105

94-
[web3.storage] is a decentralized IPFS storage
95-
provider where any ITK community member can upload binary data files.
96-
There are two primary methods available to upload data files:
106+
The upload workflow needs:
97107

98-
A. The CMake ExternalData Web3 upload browser interface.
99-
B. The <span class="title-ref">w3</span> command line executable that
100-
comes with the [@web3-storage/w3cli] Node.js NPM package.
108+
- The `external-data-upload` pixi environment installed
109+
(`pixi install -e external-data-upload`). It provides Python 3, [boto3],
110+
and Node.js (which makes `npx ipfs-car` available without a separate
111+
global install).
112+
- A [Filebase] IPFS bucket and an S3 access key for that bucket. Filebase's
113+
free tier is sufficient — the upload uses the S3 import-as-CAR path,
114+
not the legacy IPFS Pinning Service API.
115+
- The credentials exported as environment variables before running the
116+
helper:
101117

102-
Once files have been uploaded, they will be publicly
103-
available and accessible since data is content addressed on the IPFS
104-
peer-to-peer network.
118+
```bash
119+
export FILEBASE_ACCESS_KEY=...
120+
export FILEBASE_SECRET_KEY=...
121+
export FILEBASE_BUCKET=itk-data
122+
```
105123

106-
In addition to these two methods, documented in detail below, another
107-
possibility includes pinning the data on IPFS with [other pinning services]
108-
and creating the content link file manually. The content link file is simply a
109-
plan text file with a `.cid` extension whose contents are the CID file.
110-
However, the documented two methods are recommended due to their simplicity
111-
and in order to keep CID values consistent.
124+
The full step-by-step setup is documented in
125+
[`Utilities/Maintenance/ExternalDataUpload/README.md`]. Complete that
126+
one-time setup before proceeding.
112127

113-
At release time, the release manager uploads and archives repository data
114-
references in other storage locations for additional redundancy.
128+
[boto3]: https://boto3.amazonaws.com/
115129

116-
### Option A) Upload Via the Web Interface
130+
### Upload a file
117131

118-
Use the [Content Link Upload]
119-
tool ([Alt Link]) to
120-
upload your data to the [IPFS] and download the
121-
corresponding CMake content link file.
132+
From the ITK source tree, run the upload helper with the path to the file
133+
you want to upload:
122134

123-
![[CMake ExternalData Web3
124-
Content Link Upload](https://content-link-upload.itk.org/)](./content-link-upload.png)
135+
```bash
136+
pixi run -e external-data-upload python \
137+
Utilities/Maintenance/ExternalDataUpload/upload.py \
138+
Modules/.../test/Baseline/MyTest.png
139+
```
125140

126-
### Option B) Upload Via CMake and Node.js CLI
141+
The helper will:
127142

128-
Install the <span class="title-ref">w3</span> CLI with the
129-
[@web3-storage/w3cli] [Node.js] package:
143+
1. Pack the file into a CARv1 with `npx ipfs-car pack --no-wrap`
144+
ipfs-car v1+ defaults to 1 MiB chunks, 1024 children per node, raw
145+
leaves, CIDv1, which is the unixfs-v1-2025 profile, so the CID is
146+
reproducible across implementations.
147+
2. PUT the CAR to your Filebase IPFS bucket with
148+
`x-amz-meta-import: car` so Filebase imports it server-side, then
149+
read the imported CID back via `head_object` and verify it matches
150+
the locally computed CID.
151+
3. Replace `MyTest.png` in the source tree with `MyTest.png.cid` — a
152+
one-line text file containing the CID.
153+
4. Append the CID and source-tree path to
154+
`Testing/Data/content-links.manifest`.
155+
5. Print the `git rm` / `git add` commands needed to stage the change.
130156

131-
```bash
132-
npm install -g @web3-storage/w3cli
133-
```
157+
### Mirror to ITKTestingData (optional but recommended)
134158

135-
Login in with your credentials.
159+
Pass `--testing-data-repo <path>` to additionally copy the file into a
160+
local clone of [ITKTestingData] at `CID/<cid>`:
136161

137162
```bash
138-
w3 login
163+
pixi run -e external-data-upload python \
164+
Utilities/Maintenance/ExternalDataUpload/upload.py \
165+
--testing-data-repo ~/src/ITKTestingData \
166+
Modules/.../test/Baseline/MyTest.png
139167
```
140168

141-
Create an <span class="title-ref">w3externaldata</span> bash/zsh
142-
function:
169+
This populates the GitHub Pages mirror gateway
170+
(`https://insightsoftwareconsortium.github.io/ITKTestingData/CID/<cid>`)
171+
already listed in [`CMake/ITKExternalData.cmake`]. Commit and push in
172+
the `ITKTestingData` repo to publish. Files larger than **50 MB** are
173+
skipped for the mirror step only (GitHub rejects pushes containing
174+
files over 50 MB per file) — the Filebase upload still proceeds for
175+
those files.
143176

144-
```bash
145-
function w3externaldata() { w3 put $1 --no-wrap | tail -n 1 | awk -F "/ipfs/" '{print $2}' | tee $1.cid }
146-
```
177+
### Alternative: upload via the web app
178+
179+
Contributors who prefer not to run any local tooling can upload a file
180+
through the [Content Link Upload] web app ([Alt Link]). The app pins the
181+
file and returns the corresponding `.cid` content link to download. The
182+
resulting CID is usable anywhere the helper-produced CID would be — but
183+
the manifest entry and the optional [ITKTestingData] mirror must then be
184+
added by hand. The helper above is preferred when available because it
185+
also updates `Testing/Data/content-links.manifest` in one step.
147186

148-
Call the function with the file to be uploaded. This command will
149-
generate the <span class="title-ref">\<filename\>.cid</span> content
150-
link:
187+
### Normalize existing content links
188+
189+
Older `.md5` / `.sha256` / `.sha512` content links can be converted to
190+
`.cid`, and existing `.cid` links can be regenerated under the
191+
unixfs-v1-2025 profile, with:
151192

152193
```bash
153-
w3externaldata <filename>
154-
1 file (0.3MB)
155-
⁂ Stored 1 file
156-
bafkreifpfhcc3gc7zo2ds3ktyyl5qrycwisyaolegp47cl27i4swxpa2ey
194+
pixi run -e external-data-upload python \
195+
Utilities/Maintenance/ExternalDataUpload/normalize.py <path-or-file>
157196
```
158197

159-
### Add the content link to the source tree
198+
See [`Utilities/Maintenance/ExternalDataUpload/README.md`] for the full
199+
set of options (`--dry-run`, `--hash-only`, `--cid-only`,
200+
`--testing-data-repo`, `--bucket`).
160201

161-
Add the file to the repository in the directory referenced by the
162-
*CMakeLists.txt* script. Move the content link file to the **source tree** at
163-
the location where the actual file is desired in the build tree.
202+
### Add the content link to the source tree
164203

165-
Stage the new file to your commit:
204+
The upload helper prints the exact commands to stage:
166205

167206
```bash
168-
git add -- path/to/file.cid
207+
git rm path/to/MyTest.png
208+
git add path/to/MyTest.png.cid
209+
git add Testing/Data/content-links.manifest
210+
git commit
169211
```
170212

171-
Next time CMake configuration runs, it will find the new content link. During
172-
the next project build, the data file corresponding to the content link will
173-
be downloaded into the build tree.
213+
Next time CMake configuration runs, it will find the new content link.
214+
During the next project build, the data file corresponding to the
215+
content link will be downloaded into the build tree from the first
216+
reachable gateway in [`CMake/ITKExternalData.cmake`].
174217

175218
[Alt Link]: https://content-link-upload.itk.eth.limo
176219
[Analyze format]: http://www.grahamwideman.com/gw/brain/analyze/formatdoc.htm
177220
[Content Identifier (CID)]: https://docs.ipfs.tech/concepts/content-addressing/
178221
[Content Link Upload]: https://content-link-upload.itk.org
179222
[CONTRIBUTING.md]: ../CONTRIBUTING.md
180223
[CMake]: https://cmake.org/
224+
[`CMake/ITKExternalData.cmake`]: https://github.com/InsightSoftwareConsortium/ITK/blob/main/CMake/ITKExternalData.cmake
225+
[Filebase]: https://filebase.com/
181226
[Git]: https://git-scm.com/
182227
[IPFS]: https://ipfs.io/
183-
[ITKData Datalad repository]: https://gin.g-node.org/InsightSoftwareConsortium/ITKData/src/main
184228
[ITK community]: https://discourse.itk.org/
185229
[ITK Sphinx Examples]: https://itk.org/ITKExamples/index.html
186230
[ITK Software Guide]: https://itk.org/ItkSoftwareGuide.pdf
231+
[ITKData DataLad repository]: https://gin.g-node.org/InsightSoftwareConsortium/ITKData/src/main
187232
[ITKTestingData]: https://github.com/InsightSoftwareConsortium/ITKTestingData
188-
[MD5 hash]: https://en.wikipedia.org/wiki/MD5
233+
[Kubo]: https://github.com/ipfs/kubo
189234
[multiformats]: https://multiformats.io/
190-
[Node.js]: https://nodejs.org/
191-
[other pinning services]: https://docs.ipfs.tech/how-to/work-with-pinning-services/
192-
[SHA512 hash]: https://en.wikipedia.org/wiki/SHA-2
193235
[solution to this problem]: https://blog.kitware.com/cmake-externaldata-using-large-files-with-distributed-version-control/
194-
[web3.storage]: https://web3.storage/
195-
[@web3-storage/w3cli]: https://www.npmjs.com/package/@web3-storage/w3cli
236+
[`Utilities/Maintenance/ExternalDataUpload/README.md`]: https://github.com/InsightSoftwareConsortium/ITK/blob/main/Utilities/Maintenance/ExternalDataUpload/README.md
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
bafkreifmtmpjuppizngftzcnt3ilufa66dajy3i6xogn3jfirveqw63cwu

Modules/Filtering/AnisotropicDiffusionLBR/test/Baseline/Cos3D_cCED.vtk.md5

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
bafkreif4yuyueovggfvnjj3qrnct54nrm52pfconktlvavzq7kt64jo3ji

Modules/Filtering/AnisotropicDiffusionLBR/test/Baseline/FingerPrint_I_20.png.md5

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
bafkreicjpqxemmg3lgvigudscqqaiy3mjrgm3tm3ep7ngskw3is3fix2qi

0 commit comments

Comments
 (0)