Skip to content

feat: Generate all thumbnails#125

Open
wayfarer3130 wants to merge 10 commits into
masterfrom
feat/generate-all-thumbnails
Open

feat: Generate all thumbnails#125
wayfarer3130 wants to merge 10 commits into
masterfrom
feat/generate-all-thumbnails

Conversation

@wayfarer3130
Copy link
Copy Markdown
Collaborator

Adds ability to generate thumbnails for selected queries from DICOMweb or file system.

@wayfarer3130 wayfarer3130 requested a review from jbocce May 8, 2026 20:47
Comment thread packages/create-dicomweb/bin/createdicomweb.mjs Outdated

_resolveBulkDataPath(studyUID, seriesUID, bulkDataURI, frameNumber) {
const frameSuffix = frameNumber ? `/${frameNumber}` : '';
if (/^https?:\/\//i.test(bulkDataURI)) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This test regex seems to be done a lot. Is it worth centralizing somewhere?

Copy link
Copy Markdown
Collaborator

@jbocce jbocce left a comment

Choose a reason for hiding this comment

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

Here are some requests from Claude. I think the first one is the most important to address.

  • HttpDicomWebReader._resolveBulkDataPath ignores instanceUID for instance-relative ./frames URIs (HttpDicomWebReader.mjs:55-65). The file reader distinguishes ./instances//frames (series-relative) from ./frames (instance-relative, needs instanceUID); the HTTP reader treats every ./-prefixed URI as series-relative. A server emitting BulkDataURI: "./frames" will resolve
    to studies//series//frames/ instead of studies//series//instances//frames/ — 404 or wrong frame. Match the file reader's rule.
  • Redundant double upload in studiesMain.mjs:31-34: uploadDeploy is awaited twice in a row. This appears pre-existing (also in master) and is not fixed by this PR — worth fixing while you're in the file.
  • thumbnailMain.mjs:831 HTTP-output guard fires after the more specific check: (outputDicomdir || dicomdir).startsWith('http') rejects an HTTP outputDicomdir, but the message "must be a file path" is misleading since s3:// is also accepted. Reword to "must be a local path or s3:// URI" and place it before the http-input check for clarity.
  • No Accept headers on QIDO/WADO-RS fetches (HttpDicomWebReader._fetch). DICOMweb-strict servers may return 406 or wrong representations. Set Accept: application/dicom+json for QIDO paths and multipart/related; type="application/octet-stream" (or the appropriate transfer-syntax variant) for bulk frames.
  • HTTP path has no retry / timeout / concurrency control. --all-thumbnails against a remote DICOMweb peer issues serial fetches with no backoff — slow on success, blocking on a single hang. Consider an AbortSignal with AbortSignal.timeout(...) per request, and Promise.all/p-limit for instance-level work.

@wayfarer3130 wayfarer3130 requested a review from rleisti May 13, 2026 13:40
@wayfarer3130
Copy link
Copy Markdown
Collaborator Author

@rleisti - I hvae this change to allow uploading the thumbnails in bulk to S3 or creating or re-creating them locally. It was for some OHIF test work, but I don't have a reviewer on the OHIF side who is familiar with this. Could you review the changes? I'd like to address the resolve bulkdata path as a separate issue, since the changes that were being directly suggested don't quite work without doing things in a different way.
I'm going to eventually follow the path of how OHIF does things, which is to add hidden data to bulkdata containing objects that have absolute paths plus the fetch function, but that is a bigger change than I'd like to include here.

Copy link
Copy Markdown
Collaborator

@rleisti rleisti left a comment

Choose a reason for hiding this comment

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

Added some initial comments: I have not gone through the entire review yet.

const shouldExclude = Array.from(excludePatterns).some(
pattern => entryRelativePath.indexOf(pattern) !== -1
);
const shouldInclude =
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

In studyMainSingle, options.include is set to ['thumbnail']. If collectFiles is called for the directory studies/<UID> then it seems this code would skip any sub-directories that not include the substring 'thumbnail' (like 'series'), cause it to skip series thumbnails.

await commonMain(this, 'root', uploadOptions, uploadDeploy.bind(null, studyDirectory));
console.log('Storing studyUID', studyUID);
await commonMain(this, 'root', options, uploadDeploy.bind(null, studyDirectory));
await commonMain(this, 'root', uploadOptions, uploadDeploy.bind(null, studyDirectory));
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

commonMain is being called twice with identical arguments: is this intended?

Comment thread packages/create-dicomweb/bin/createdicomweb.mjs Outdated
@wayfarer3130 wayfarer3130 requested a review from rleisti May 19, 2026 19:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants