@niivue/nv-ext-niimath 1.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -0
- package/package.json +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# @niivue/nv-ext-niimath
|
|
2
|
+
|
|
3
|
+
Browser-side niimath pipelines for [NiiVue](https://github.com/niivue), wrapping the [`@niivue/niimath`](https://www.npmjs.com/package/@niivue/niimath) WebAssembly build of Chris Rorden's [`niimath`](https://github.com/rordenlab/niimath). All processing runs in a Web Worker; no data leaves the browser.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @niivue/nv-ext-niimath
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Requires `@niivue/niivue` as a peer dependency.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import NiiVueGPU from '@niivue/niivue'
|
|
17
|
+
import { Niimath, runNiimathPipeline } from '@niivue/nv-ext-niimath'
|
|
18
|
+
|
|
19
|
+
const nv = new NiiVueGPU()
|
|
20
|
+
await nv.attachTo('gl1')
|
|
21
|
+
|
|
22
|
+
// One Niimath instance per page — its worker is expensive to spin up.
|
|
23
|
+
const niimath = new Niimath()
|
|
24
|
+
await niimath.init()
|
|
25
|
+
|
|
26
|
+
const input = document.querySelector<HTMLInputElement>('#nifti')!
|
|
27
|
+
input.addEventListener('change', async () => {
|
|
28
|
+
const file = input.files?.[0]
|
|
29
|
+
if (!file) return
|
|
30
|
+
const result = await runNiimathPipeline(niimath, file, [
|
|
31
|
+
{ method: 's', args: [3] }, // -s 3 (Gaussian smoothing, sigma 3 mm)
|
|
32
|
+
{ method: 'thr', args: [0.5] }, // -thr 0.5
|
|
33
|
+
{ method: 'bin', args: [] }, // -bin
|
|
34
|
+
])
|
|
35
|
+
await nv.loadVolumes([
|
|
36
|
+
{ url: new File([result], 'processed.nii.gz'), name: 'processed.nii.gz' },
|
|
37
|
+
])
|
|
38
|
+
})
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## API
|
|
42
|
+
|
|
43
|
+
### `runNiimathPipeline(niimath, file, steps, outName?): Promise<Blob>`
|
|
44
|
+
|
|
45
|
+
Walks `steps` and dispatches each to the matching method on the niimath
|
|
46
|
+
chain. Returns the final NIfTI result as a `Blob`. The caller owns the
|
|
47
|
+
`Niimath` lifetime; this function never terminates the worker so it can
|
|
48
|
+
be reused across many pipelines.
|
|
49
|
+
|
|
50
|
+
**Serial only.** The underlying worker has a single `onmessage` handler
|
|
51
|
+
that gets reassigned on every `run()`, so two overlapping calls against
|
|
52
|
+
the same `Niimath` instance will steal each other's responses. Either
|
|
53
|
+
await the previous call (typical UI pattern: disable Run while a job is
|
|
54
|
+
in flight) or instantiate a separate `Niimath` per concurrent stream.
|
|
55
|
+
|
|
56
|
+
`outName` defaults to `'output.nii.gz'`. The WASM build of niimath
|
|
57
|
+
gzip-compresses its output, so a `.nii` filename produces a file the
|
|
58
|
+
worker then can't read back (surfaces as a generic
|
|
59
|
+
`Uncaught [object Object]` error). Override only if you have a reason.
|
|
60
|
+
|
|
61
|
+
### `NiimathStep`
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
interface NiimathStep {
|
|
65
|
+
method: string // niimath flag without '-' (e.g. 's', 'thr')
|
|
66
|
+
args: (string | number)[] // positional parameters; strings auto-parsed
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Re-exports
|
|
71
|
+
|
|
72
|
+
- `Niimath` — the underlying `@niivue/niimath` class for full control.
|
|
73
|
+
- `ImageProcessorMethods`, `Operators`, `OperatorDefinition` — types from
|
|
74
|
+
`@niivue/niimath` for callers building UIs against the operator catalog.
|
|
75
|
+
|
|
76
|
+
## Why a wrapper?
|
|
77
|
+
|
|
78
|
+
`@niivue/niimath` already exposes a clean method-chain API (`.s(3).thr(0.5).bin().run()`). This wrapper exists so that UIs whose pipelines come from user input (drag-reorderable steps, dropdown selections, etc.) can build a `NiimathStep[]` array and hand it off, rather than having to build the chain via dynamic-method dispatch themselves.
|
|
79
|
+
|
|
80
|
+
## Try it locally
|
|
81
|
+
|
|
82
|
+
A full example app lives at [`apps/demo-ext-niimath`](https://github.com/niivue/mono/tree/main/apps/demo-ext-niimath) (UI: sample-volume picker, drag-reorderable pipeline, generated-command preview, history). To run it from a clone of the monorepo:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
bun install # From monorepo root
|
|
86
|
+
bunx nx dev demo-ext-niimath # Start dev server (port 8089)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Part of the [NiiVue](https://github.com/niivue) ecosystem
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@niivue/nv-ext-niimath",
|
|
3
|
+
"version": "1.0.0-rc.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Browser-side niimath pipeline runner for NiiVue, wrapping the @niivue/niimath WebAssembly build",
|
|
6
|
+
"main": "./dist/nv-ext-niimath.js",
|
|
7
|
+
"module": "./dist/nv-ext-niimath.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/nv-ext-niimath.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"@niivue/niivue": "1.0.0-rc.5"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@niivue/niimath": "^1.2.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@niivue/niivue": "1.0.0-rc.5",
|
|
26
|
+
"typescript": "~5.8.3",
|
|
27
|
+
"vite": "^6.3.2",
|
|
28
|
+
"vite-plugin-dts": "^4.5.4"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "bunx --bun vite build",
|
|
32
|
+
"typecheck": "bunx tsc --noEmit"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
}
|
|
37
|
+
}
|