@niivue/niivue 0.38.10 → 0.40.0

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 CHANGED
@@ -26,9 +26,10 @@ The command `npm run demo` will minify the project and locally host all of the [
26
26
  # Projects and People using NiiVue
27
27
 
28
28
  - Analysis of Functional NeuroImages (AFNI) [Scientific and Statistical Computing Core](https://afni.nimh.nih.gov/) (National Institutes of Health)
29
+ - [ChRIS Research Integration System (ChRIS) from Boston Children's Hospital](https://chrisproject.org/) uses [NiiVue](https://app.chrisproject.org/niivue).
29
30
  - [Center for the Study of Aphasia Recovery](https://cstar.sc.edu/) (University of South Carolina)
30
31
  - FMRIB's Software Library (FSL) [Wellcome Centre for Integrative Neuroimaging](https://www.win.ox.ac.uk/) (University of Oxford)
31
- - FreeSurfer [Laboratories for Computational Neuroimaging](https://lcn.martinos.org/) (Massachusetts General Hospital)
32
+ - FreeSurfer [Laboratories for Computational Neuroimaging](https://lcn.martinos.org/) (Massachusetts General Hospital) uses NiiVue for [FreeBrowse](https://github.com/freesurfer/freebrowse)
32
33
  - [OpenNeuro.org](https://openneuro.org) uses NiiVue to visualize datasets
33
34
  - [BrainLife.io](https://brainlife.io/about/) integrates NiiVue into [ezbids](https://brainlife.io/ezbids/)
34
35
  - [nilearn](https://nilearn.github.io/stable/index.html) is extending [ipyniivue](https://github.com/niivue/ipyniivue)
@@ -50,5 +51,5 @@ NiiVue supports many popular brain imaging formats:
50
51
  - Voxel-based formats: [NIfTI](https://brainder.org/2012/09/23/the-nifti-file-format/), [NRRD](http://teem.sourceforge.net/nrrd/format.html), [MRtrix MIF](https://mrtrix.readthedocs.io/en/latest/getting_started/image_data.html#mrtrix-image-formats), [AFNI HEAD/BRIK](https://afni.nimh.nih.gov/pub/dist/doc/program_help/README.attributes.html), [MGH/MGZ](https://surfer.nmr.mgh.harvard.edu/fswiki/FsTutorial/MghFormat), [ITK MHD](https://itk.org/Wiki/ITK/MetaIO/Documentation#Reading_a_Brick-of-Bytes_.28an_N-Dimensional_volume_in_a_single_file.29), [ECAT7](https://github.com/openneuropet/PET2BIDS/tree/28aae3fab22309047d36d867c624cd629c921ca6/ecat_validation/ecat_info).
51
52
  - Mesh-based formats: [GIfTI](https://www.nitrc.org/projects/gifti/), [ASC](http://www.grahamwideman.com/gw/brain/fs/surfacefileformats.htm), [BYU/GEO/G](http://www.grahamwideman.com/gw/brain/fs/surfacefileformats.htm), [BrainSuite DFS](http://brainsuite.org/formats/dfs/), [ICO/TRI](http://www.grahamwideman.com/gw/brain/fs/surfacefileformats.htm), [PLY](<https://en.wikipedia.org/wiki/PLY_(file_format)>), [BrainNet NV](https://www.nitrc.org/projects/bnv/), [BrainVoyager SRF](https://support.brainvoyager.com/brainvoyager/automation-development/84-file-formats/344-users-guide-2-3-the-format-of-srf-files), [FreeSurfer](http://www.grahamwideman.com/gw/brain/fs/surfacefileformats.htm), [MZ3](https://github.com/neurolabusc/surf-ice/tree/master/mz3), [OFF](<https://en.wikipedia.org/wiki/OFF_(file_format)>), [Wavefront OBJ](https://brainder.org/tag/obj/), [STL](https://medium.com/3d-printing-stories/why-stl-format-is-bad-fea9ecf5e45), [Legacy VTK](https://vtk.org/wp-content/uploads/2015/04/file-formats.pdf), [X3D](https://3dprint.nih.gov/).
52
53
  - Mesh overlay formats: [GIfTI](https://www.nitrc.org/projects/gifti/), [CIfTI-2](https://balsa.wustl.edu/about/fileTypes), [MZ3](https://github.com/neurolabusc/surf-ice/tree/master/mz3), [SMP](https://support.brainvoyager.com/brainvoyager/automation-development/84-file-formats/40-the-format-of-smp-files), STC, FreeSurfer (CURV/ANNOT)
53
- - Tractography formats: [TCK](https://mrtrix.readthedocs.io/en/latest/getting_started/image_data.html#tracks-file-format-tck), [TRK](http://trackvis.org/docs/?subsect=fileformat), [TRX](https://github.com/frheault/tractography_file_format), VTK, AFNI .niml.tract
54
+ - Tractography formats: [TCK](https://mrtrix.readthedocs.io/en/latest/getting_started/image_data.html#tracks-file-format-tck), [TRK](http://trackvis.org/docs/?subsect=fileformat), [TRX](https://github.com/frheault/tractography_file_format), [TSF](https://mrtrix.readthedocs.io/en/dev/getting_started/image_data.html#track-scalar-file-format-tsf), [TT](https://dsi-studio.labsolver.org/doc/cli_data.html), VTK, AFNI .niml.tract
54
55
  - DICOM: [DICOM](https://dicom.nema.org/medical/dicom/current/output/chtml/part10/chapter_7.html) and [DICOM Manifests](docs/development-notes/dicom-manifests.md)
@@ -248,8 +248,13 @@ type LegacyConnectome = Partial<ConnectomeOptions> & {
248
248
  type ValuesArray = Array<{
249
249
  id: string;
250
250
  vals: number[];
251
+ global_min?: number;
252
+ global_max?: number;
253
+ cal_min?: number;
254
+ cal_max?: number;
251
255
  }>;
252
- type AnyNumberArray = number[] | Float64Array | Float32Array | Uint32Array | Uint16Array | Uint8Array | Int32Array | Int16Array | Int8Array;
256
+ type TypedNumberArray = Float64Array | Float32Array | Uint32Array | Uint16Array | Uint8Array | Int32Array | Int16Array | Int8Array;
257
+ type AnyNumberArray = number[] | TypedNumberArray;
253
258
  type DefaultMeshType = {
254
259
  positions: Float32Array;
255
260
  indices: Int32Array;
@@ -260,6 +265,10 @@ type TRACT = {
260
265
  offsetPt0: number[];
261
266
  dps: ValuesArray;
262
267
  };
268
+ type TT = {
269
+ pts: number[];
270
+ offsetPt0: number[];
271
+ };
263
272
  type TRX = {
264
273
  pts: number[];
265
274
  offsetPt0: number[];
@@ -269,14 +278,14 @@ type TRX = {
269
278
  header: unknown;
270
279
  };
271
280
  type TRK = {
272
- pts: number[];
273
- offsetPt0: number[];
281
+ pts: Float32Array;
282
+ offsetPt0: Uint32Array;
274
283
  dps: ValuesArray;
275
284
  dpv: ValuesArray;
276
285
  };
277
286
  type TCK = {
278
- pts: number[];
279
- offsetPt0: number[];
287
+ pts: Float32Array;
288
+ offsetPt0: Uint32Array;
280
289
  };
281
290
  type VTK = DefaultMeshType | {
282
291
  pts: Float32Array;
@@ -386,14 +395,15 @@ declare class NVMesh {
386
395
  opacity: number;
387
396
  visible: boolean;
388
397
  meshShaderIndex: number;
389
- offsetPt0: number[] | null;
398
+ offsetPt0: number[] | Uint32Array | null;
390
399
  colormapInvert: boolean;
391
400
  fiberGroupColormap: ColorMap | null;
392
401
  indexBuffer: WebGLBuffer;
393
402
  vertexBuffer: WebGLBuffer;
394
403
  vao: WebGLVertexArrayObject;
395
- pts: number[];
396
- tris?: number[];
404
+ vaoFiber: WebGLVertexArrayObject;
405
+ pts: number[] | Float32Array;
406
+ tris?: number[] | Uint32Array;
397
407
  layers: NVMeshLayer[];
398
408
  type: MeshType;
399
409
  data_type?: string;
@@ -403,6 +413,9 @@ declare class NVMesh {
403
413
  fiberDither: number;
404
414
  fiberColor: string;
405
415
  fiberDecimationStride: number;
416
+ fiberSides: number;
417
+ fiberRadius: number;
418
+ f32PerVertex: number;
406
419
  fiberMask?: unknown[];
407
420
  colormap?: ColorMap | LegacyConnectome | string | null;
408
421
  dpg?: ValuesArray | null;
@@ -440,14 +453,16 @@ declare class NVMesh {
440
453
  * @param colorbarVisible - does this mesh display a colorbar
441
454
  * @param anatomicalStructurePrimary - region for mesh. Default is an empty string
442
455
  */
443
- constructor(pts: number[], tris: number[], name: string | undefined, rgba255: number[] | undefined, opacity: number | undefined, visible: boolean | undefined, gl: WebGL2RenderingContext, connectome?: LegacyConnectome | string | null, dpg?: ValuesArray | null, dps?: ValuesArray | null, dpv?: ValuesArray | null, colorbarVisible?: boolean, anatomicalStructurePrimary?: string);
456
+ constructor(pts: number[] | Float32Array, tris: number[] | Uint32Array, name: string | undefined, rgba255: number[] | undefined, opacity: number | undefined, visible: boolean | undefined, gl: WebGL2RenderingContext, connectome?: LegacyConnectome | string | null, dpg?: ValuesArray | null, dps?: ValuesArray | null, dpv?: ValuesArray | null, colorbarVisible?: boolean, anatomicalStructurePrimary?: string);
457
+ linesToCylinders(gl: WebGL2RenderingContext, posClrF32: Float32Array, indices: number[]): void;
444
458
  updateFibers(gl: WebGL2RenderingContext): void;
445
459
  updateConnectome(gl: WebGL2RenderingContext): void;
460
+ indexNearestXYZmm(Xmm: number, Ymm: number, Zmm: number): number[];
446
461
  updateMesh(gl: WebGL2RenderingContext): void;
447
462
  reverseFaces(gl: WebGL2RenderingContext): void;
448
463
  setLayerProperty(id: number, key: keyof NVMeshLayer, val: number | string | boolean, gl: WebGL2RenderingContext): void;
449
464
  setProperty(key: keyof this, val: unknown, gl: WebGL2RenderingContext): void;
450
- generatePosNormClr(pts: number[], tris: number[], rgba255: number[]): Float32Array;
465
+ generatePosNormClr(pts: number[] | Float32Array, tris: number[] | Uint32Array, rgba255: number[]): Float32Array;
451
466
  static loadConnectomeFromFreeSurfer(json: {
452
467
  points?: Point[];
453
468
  data_type: string;
@@ -495,6 +510,8 @@ declare class NVMesh {
495
510
  static readTxtVTK(buffer: ArrayBuffer): VTK;
496
511
  static readTRK(buffer: ArrayBuffer): TRK;
497
512
  static readTCK(buffer: ArrayBuffer): TCK;
513
+ static readTSF(buffer: ArrayBuffer): Float32Array;
514
+ static readTT(buffer: ArrayBuffer): TT;
498
515
  static readTRX(buffer: ArrayBuffer): TRX;
499
516
  static readTRACT(buffer: ArrayBuffer): TRACT;
500
517
  }
@@ -739,14 +756,14 @@ declare class NVImage {
739
756
  intensityRaw2Scaled(raw: number): number;
740
757
  intensityScaled2Raw(scaled: number): number;
741
758
  saveToUint8Array(fnm: string, drawing8?: Uint8Array | null): Uint8Array;
742
- saveToDisk(fnm: string, drawing8?: Uint8Array | null): Uint8Array;
759
+ saveToDisk(fnm?: string, drawing8?: Uint8Array | null): Uint8Array;
743
760
  static fetchDicomData(url: string, headers?: Record<string, string>): Promise<ArrayBuffer[]>;
744
761
  static fetchPartial(url: string, bytesToLoad: number, headers?: Record<string, string>): Promise<Response>;
745
762
  /**
746
763
  * factory function to load and return a new NVImage instance from a given URL
747
764
  * @returns NVImage instance
748
765
  */
749
- static loadFromUrl({ url, urlImgData, headers, name, colormap, opacity, cal_min, cal_max, trustCalMinMax, percentileFrac, ignoreZeroVoxels, visible, useQFormNotSForm, colormapNegative, frame4D, isManifest, limitFrames4D, imageType }?: Partial<Omit<ImageFromUrlOptions, 'url'>> & {
766
+ static loadFromUrl({ url, urlImgData, headers, name, colormap, opacity, cal_min, cal_max, trustCalMinMax, percentileFrac, ignoreZeroVoxels, visible, useQFormNotSForm, colormapNegative, frame4D, isManifest, limitFrames4D, imageType, colorbarVisible }?: Partial<Omit<ImageFromUrlOptions, 'url'>> & {
750
767
  url?: string | Uint8Array | ArrayBuffer;
751
768
  }): Promise<NVImage>;
752
769
  static readFileAsync(file: File, bytesToLoad?: number): Promise<ArrayBuffer>;
@@ -808,6 +825,10 @@ declare class NVImage {
808
825
  * Converts NVImage to NIfTI compliant byte array
809
826
  */
810
827
  toUint8Array(drawingBytes?: Uint8Array | null): Uint8Array;
828
+ convertVox2Frac(vox: vec3): vec3;
829
+ convertFrac2Vox(frac: vec3): vec3;
830
+ convertFrac2MM(frac: vec3, isForceSliceMM?: boolean): vec4;
831
+ convertMM2Frac(mm: vec3 | vec4, isForceSliceMM?: boolean): vec3;
811
832
  }
812
833
 
813
834
  type FreeSurferConnectome = {
@@ -906,13 +927,16 @@ type NVConfigOptions = {
906
927
  isRadiologicalConvention: boolean;
907
928
  meshThicknessOn2D: number | string;
908
929
  dragMode: DRAG_MODE;
930
+ yoke3Dto2DZoom: boolean;
909
931
  isDepthPickMesh: boolean;
910
932
  isCornerOrientationText: boolean;
911
933
  sagittalNoseLeft: boolean;
912
934
  isSliceMM: boolean;
935
+ isV1SliceShader: boolean;
913
936
  isHighResolutionCapable: boolean;
914
937
  logLevel: 'debug' | 'info' | 'warn' | 'error' | 'fatal' | 'silent';
915
938
  loadingText: string;
939
+ isForceMouseClickToVoxelCenters: boolean;
916
940
  dragAndDropEnabled: boolean;
917
941
  drawingEnabled: boolean;
918
942
  penValue: number;
@@ -1311,6 +1335,16 @@ declare class NVUtilities {
1311
1335
  * @returns filled number array
1312
1336
  */
1313
1337
  static range(start: number, stop: number, step: number): number[];
1338
+ /**
1339
+ * convert spherical AZIMUTH, ELEVATION to Cartesian
1340
+ * @param azimuth - azimuth number
1341
+ * @param elevation - elevation number
1342
+ * @returns the converted [x, y, z] coordinates
1343
+ * @example
1344
+ * xyz = NVUtilities.sph2cartDeg(42, 42)
1345
+ */
1346
+ static sph2cartDeg(azimuth: number, elevation: number): number[];
1347
+ static vox2mm(XYZ: number[], mtx: mat4): vec3;
1314
1348
  }
1315
1349
 
1316
1350
  /**
@@ -1318,11 +1352,13 @@ declare class NVUtilities {
1318
1352
  */
1319
1353
  declare class NVMeshLoaders {
1320
1354
  static readTRACT(buffer: ArrayBuffer): TRACT;
1355
+ static readTT(buffer: ArrayBuffer): TT;
1321
1356
  static readTRX(buffer: ArrayBuffer): TRX;
1357
+ static readTSF(buffer: ArrayBuffer, n_vert?: number): Float32Array;
1322
1358
  static readTCK(buffer: ArrayBuffer): TCK;
1323
1359
  static readTRK(buffer: ArrayBuffer): TRK;
1324
1360
  static readTxtVTK(buffer: ArrayBuffer): VTK;
1325
- static readLayer(name: string, buffer: ArrayBuffer, nvmesh: NVMesh, opacity?: number, colormap?: string, colormapNegative?: string, useNegativeCmap?: boolean, cal_min?: number | null, cal_max?: number | null, isOutlineBorder?: boolean): void;
1361
+ static readLayer(name: string | undefined, buffer: ArrayBuffer, nvmesh: NVMesh, opacity?: number, colormap?: string, colormapNegative?: string, useNegativeCmap?: boolean, cal_min?: number | null, cal_max?: number | null, isOutlineBorder?: boolean): void;
1326
1362
  static readSMP(buffer: ArrayBuffer, n_vert: number): Float32Array;
1327
1363
  static readSTC(buffer: ArrayBuffer, n_vert: number): Float32Array;
1328
1364
  static readCURV(buffer: ArrayBuffer, n_vert: number): Float32Array;
@@ -1460,12 +1496,15 @@ type NiiVueOptions = {
1460
1496
  isCornerOrientationText?: boolean;
1461
1497
  sagittalNoseLeft?: boolean;
1462
1498
  isSliceMM?: boolean;
1499
+ isV1SliceShader?: boolean;
1463
1500
  isHighResolutionCapable?: boolean;
1501
+ isForceMouseClickToVoxelCenters?: boolean;
1464
1502
  drawingEnabled?: boolean;
1465
1503
  penValue?: number;
1466
1504
  floodFillNeighbors?: number;
1467
1505
  maxDrawUndoBitmaps?: number;
1468
1506
  thumbnail?: string;
1507
+ meshXRay?: number;
1469
1508
  };
1470
1509
  type UIData = {
1471
1510
  mousedown: boolean;
@@ -1493,6 +1532,11 @@ type UIData = {
1493
1532
  loading$: Subject<unknown>;
1494
1533
  dpr?: number;
1495
1534
  };
1535
+ type SaveImageOptions = {
1536
+ filename: string;
1537
+ isSaveDrawing: boolean;
1538
+ volumeByIndex: number;
1539
+ };
1496
1540
  /**
1497
1541
  * Niivue can be attached to a canvas. An instance of Niivue contains methods for
1498
1542
  * loading and rendering NIFTI image data in a WebGL 2.0 context.
@@ -1523,6 +1567,7 @@ declare class Niivue {
1523
1567
  overlayTexture: WebGLTexture | null;
1524
1568
  overlayTextureID: WebGLTexture | null;
1525
1569
  sliceMMShader?: Shader;
1570
+ sliceV1Shader?: Shader;
1526
1571
  orientCubeShader?: Shader;
1527
1572
  orientCubeShaderVAO: WebGLVertexArrayObject | null;
1528
1573
  rectShader?: Shader;
@@ -1809,13 +1854,16 @@ declare class Niivue {
1809
1854
  isRadiologicalConvention: boolean;
1810
1855
  meshThicknessOn2D: string | number;
1811
1856
  dragMode: DRAG_MODE;
1857
+ yoke3Dto2DZoom: boolean;
1812
1858
  isDepthPickMesh: boolean;
1813
1859
  isCornerOrientationText: boolean;
1814
1860
  sagittalNoseLeft: boolean;
1815
1861
  isSliceMM: boolean;
1862
+ isV1SliceShader: boolean;
1816
1863
  isHighResolutionCapable: boolean;
1817
1864
  logLevel: "debug" | "info" | "warn" | "error" | "fatal" | "silent";
1818
1865
  loadingText: string;
1866
+ isForceMouseClickToVoxelCenters: boolean;
1819
1867
  dragAndDropEnabled: boolean;
1820
1868
  drawingEnabled: boolean;
1821
1869
  penValue: number;
@@ -2183,10 +2231,10 @@ declare class Niivue {
2183
2231
  * @param isSaveDrawing - determines whether drawing or background image is saved
2184
2232
  * @param volumeByIndex - determines layer to save (0 for background)
2185
2233
  * @param volumeByIndex - determines layer to save (0 for background)
2186
- * @example niivue.saveImage('test.nii', true);
2234
+ * @example niivue.saveImage(\{ filename: "myimage.nii.gz", isSaveDrawing: true \});
2187
2235
  * @see {@link https://niivue.github.io/niivue/features/draw.ui.html|live demo usage}
2188
2236
  */
2189
- saveImage(fnm: string, isSaveDrawing?: boolean, volumeByIndex?: number): Uint8Array | boolean;
2237
+ saveImage(options?: SaveImageOptions): Uint8Array | boolean;
2190
2238
  getMeshIndexByID(id: string | number): number;
2191
2239
  /**
2192
2240
  * change property of mesh, tractogram or connectome
@@ -2336,7 +2384,7 @@ declare class Niivue {
2336
2384
  * niivue.setCrosshairColor([0, 1, 0, 0.5]) // set crosshair to transparent green
2337
2385
  * @see {@link https://niivue.github.io/niivue/features/colormaps.html|live demo usage}
2338
2386
  */
2339
- setCrosshairColor(color: number[]): Promise<void>;
2387
+ setCrosshairColor(color: number[]): void;
2340
2388
  /**
2341
2389
  * set thickness of crosshair
2342
2390
  * @example niivue.crosshairWidth(2)
@@ -2786,7 +2834,7 @@ declare class Niivue {
2786
2834
  mouseClick(x: number, y: number, posChange?: number, isDelta?: boolean): void;
2787
2835
  drawRuler(): void;
2788
2836
  drawRuler10cm(startXYendXY: number[]): void;
2789
- screenXY2mm(x: number, y: number, forceSlice?: number): vec3;
2837
+ screenXY2mm(x: number, y: number, forceSlice?: number): vec4;
2790
2838
  dragForPanZoom(startXYendXY: number[]): void;
2791
2839
  dragForCenterButton(startXYendXY: number[]): void;
2792
2840
  dragForSlicer3D(startXYendXY: number[]): void;