Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion web/src/utils/externalServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ const EXTERNAL_SERVICES: ExternalService[] = [
endpoint: "https://ome.github.io/ome-ngff-validator/?source=$asset_url$",
},

{
name: "Neurosift",
regex: /\.nii(\.gz)?$/,
maxsize: Infinity,
endpoint:
"https://neurosift.app/dandiset/$dandiset_id$?tab=$asset_path$",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you explain why the path is needed for Neurosift? Typically, the API yields file contents through the asset_url value.

(I bring this up because I'm always wary when we expand this "API", especially since we're always seeming to do so in an ad hoc way.)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

IIRC it is because neurosift indexes entire dandisets via lindi and refer to them by original path...

@magland is that correct or we could refer also by an asset id?

Copy link
Copy Markdown
Member Author

@kabilar kabilar Feb 11, 2026

Choose a reason for hiding this comment

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

I wasn't able to construct a Neurosift URL with the DANDI asset_url so that the .nii.gz is displayed. Perhaps I am doing something wrong, or in fact Neurosift does just need the path for visualization in NiiVue.

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.

@yarikoptic neurosift/lindi only indexes public nwb files, and does not use the path.

In this case, it's BIDS... right? So the path is used to refer to the .nii.gz file, correct?

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.

Yes, in this case, it needs the path, not the asset url.

},

{
name: "Neurosift",
regex: /\.nwb$/,
Expand Down Expand Up @@ -90,6 +98,7 @@ interface ServiceUrlData {
assetDandiUrl: string,
assetDandiMetadataUrl: string,
assetS3Url: string,
assetPath: string,
}

function serviceURL(endpoint: ExternalServiceEndpoint, data: ServiceUrlData): string | null {
Expand All @@ -112,7 +121,8 @@ function serviceURL(endpoint: ExternalServiceEndpoint, data: ServiceUrlData): st
.replaceAll('$asset_url$', data.assetUrl)
.replaceAll('$asset_dandi_url$', data.assetDandiUrl)
.replaceAll('$asset_dandi_metadata_url$', data.assetDandiMetadataUrl)
.replaceAll('$asset_s3_url$', data.assetS3Url);
.replaceAll('$asset_s3_url$', data.assetS3Url)
.replaceAll('$asset_path$', data.assetPath);
}

export function getExternalServices(path: AssetPath, info: {dandisetId: string, dandisetVersion: string}) {
Expand All @@ -136,6 +146,7 @@ export function getExternalServices(path: AssetPath, info: {dandisetId: string,
const assetDandiUrl = `${assetDandiMetadataUrl}download/`;
const assetS3Url = trimEnd((path.asset as AssetFile).url, '/');
const assetId = path.asset?.asset_id;
const assetPath = path.path;

if (!assetId) {
// This should never happen
Expand All @@ -158,6 +169,7 @@ export function getExternalServices(path: AssetPath, info: {dandisetId: string,
assetDandiUrl,
assetDandiMetadataUrl,
assetS3Url,
assetPath,
});
return url ? [{ name: service.name, url }] : [];
});
Expand Down