Skip to content

Commit 5133512

Browse files
Merge pull request #262 from allen-cell-animated/feature/rename-package
* rename npm package to `@aics/vole-core` * revise/update README * remove react example * rebuild docs (such as they are) to pick up new names
2 parents f1b507f + 050bd30 commit 5133512

18 files changed

+3371
-5650
lines changed

.eslintrc.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
2-
"extends": ["eslint:recommended", "plugin:react/recommended", "plugin:@typescript-eslint/recommended", "prettier"],
2+
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
33
"env": {
44
"browser": true,
55
"es6": true,
66
"mocha": true
77
},
8-
"plugins": ["@typescript-eslint", "react"],
8+
"plugins": ["@typescript-eslint"],
99
"rules": {
1010
"@typescript-eslint/ban-types": ["warn"],
1111
"@typescript-eslint/naming-convention": [

DEV.md

+7-18
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,12 @@
99
- supports ome.tif, .tif, and .czi provided they are self contained z stacks.
1010
- note: the files will be placed in a temporary "cache" folder which should be periodically cleaned out.
1111

12-
## Deugging React setup
13-
This will make a simple react app with the volume viewer installed.
14-
- make sure node.js is installed
15-
- make sure aicsimage python lib is installed
16-
- `npm install`
17-
- `npm run build`
18-
- `npm run react-example`
19-
- Open localhost:9030/volumeviewer/
20-
- supports ome.tif, .tif, and .czi provided they are self contained z stacks.
21-
- note: the files will be placed in a temporary "cache" folder which should be periodically cleaned out.
22-
23-
2412
## Publishing
25-
* Requires that you are listed as a maintainer for this npm module
2613

27-
- Commit and push changes
28-
- Login: `npm login`
29-
- Make sure you can run build successfully: `npm run build`
30-
- Update version: `npm version patch`
31-
- Publish: `npm publish`
14+
- Requires that you are listed as a maintainer for this npm module
15+
16+
* Commit and push changes
17+
* Login: `npm login`
18+
* Make sure you can run build successfully: `npm run build`
19+
* Update version: `npm version patch`
20+
* Publish: `npm publish`

README.md

+43-111
Original file line numberDiff line numberDiff line change
@@ -1,135 +1,67 @@
1-
# AICS Volume Viewer
1+
# Vol-E core
22

3-
This is a WebGL canvas-based volume viewer. It can display multichannel volume data of 8-bit intensity values.
4-
Volume data is provided to the core 3d viewer in two parts. The first part is via a json object containing dimensions and other metadata. The second part is the volume data itself.
3+
This is a WebGL canvas-based volume viewer. It can display multichannel volume data with high channel counts, and is optimized for OME-Zarr files. With OME-Zarr, the viewer can prefetch and cache Zarr chunks in browser memory for optimized performance.
54

6-
The volume-viewer package exposes two key modules:
5+
The Vol-E core package exposes several key modules:
76

8-
- `View3d` is the viewing component that contains a canvas and supports zoom/pan/rotate interaction with the volume.
9-
- `Volume` is the class that holds the volume data. After initialization, this is generally a read-only holder for raw data.
7+
- `View3d` is the viewing component that contains a canvas and supports zoom/pan/rotate interaction with the volume via `VolumeDrawable`.
8+
- `Volume` is the class that holds the volume dimensions and a collection of `Channel`s that contain the volume pixel data. After initialization, this is generally a read-only holder for raw data.
9+
- `VolumeLoaderContext` is an interface that lets you initialize asynchronous data loading of different formats via its `createLoader` method.
10+
- `IVolumeLoader` is an interface for requesting volume dimensions and data.
11+
- `LoadSpec` is a small bundle of information to guide the IVolumeLoader on exactly what to load.
1012

11-
It also provides the following two utility modules:
13+
There are several ways to deliver volume data to the viewer:
1214

13-
- `VolumeLoader` is a convenience class for downloading and unpacking texture atlases from .png files (up to 3 channels per png) into a Volume.
14-
- `VolumeMaker` is a convenience module for creating simple test volume data
15-
16-
There are two ways to deliver volume data to the viewer:
17-
18-
- raw Uint8Arrays of 3d volume data (one Uint8Array per channel). ( `Volume.setChannelDataFromVolume` )
19-
- texture atlases (png files or Uint8Arrays containing volume slices tiled across a 2d image) ( `Volume.setChannelDataFromAtlas` )
15+
- Load OME-Zarr from publicly accessible web links. Authentication is not explicitly supported in Vol-E.
16+
- Load raw TypedArrays of 3d volume data ( see `RawArrayLoader` and `Volume.setChannelDataFromVolume` ).
17+
- (legacy) Load texture atlases as .png files or Uint8Arrays containing volume slices tiled across a 2d image ( see `JsonImageInfoLoader` and `Volume.setChannelDataFromAtlas` ).
2018

2119
# Example
2220

23-
See public/index.ts for a working example. (`npm install; npm run dev` will run that code) The basic code to get the volume viewer up and running is as follows:
21+
See [`public/index.ts`](./public/index.ts) for a working example. (`npm install; npm run dev` will run that code)
2422

25-
```javascript
26-
import { View3d, Volume, VolumeLoader, VolumeMaker } from "volume-viewer";
23+
The basic code to get the viewer up and running is as follows:
2724

25+
```javascript
2826
// find a div that will hold the viewer
29-
const el = document.getElementById("volume-viewer");
27+
const el = document.getElementById("vol-e");
28+
29+
// create the loaderContext
30+
const loaderContext = new VolumeLoaderContext(CACHE_MAX_SIZE, CONCURRENCY_LIMIT, PREFETCH_CONCURRENCY_LIMIT);
3031

3132
// create the viewer. it will try to fill the parent element.
3233
const view3D = new View3d(el);
34+
view3D.loaderContext = loaderContext;
3335

34-
// create a volume image with dimensions passed in via jsondata
35-
// this json format is documented in Volume.ts as ImageInfo
36-
const aimg = new Volume(jsondata);
36+
// ensure the loader worker is ready
37+
await loaderContext.onOpen();
38+
// get the actual loader. In most cases this will create a WorkerLoader that uses a OmeZarrLoader internally.
39+
const loader = await loaderContext.createLoader(path);
3740

41+
const loadSpec = new LoadSpec();
42+
// give the loader a callback to call when it receives channel data asynchronously
43+
const volume = await loader.createVolume(loadSpec, (v: Volume, channelIndex: number) => {
44+
const currentVol = v;
45+
46+
// currently, this must be called when channel data arrives (here in this callback)
47+
view3D.onVolumeData(currentVol, [channelIndex]);
48+
49+
view3D.setVolumeChannelEnabled(currentVol, channelIndex, true);
50+
51+
// these calls tell the viewer that things are out of date
52+
view3D.updateActiveChannels(currentVol);
53+
view3D.updateLuts(currentVol);
54+
view3D.redraw();
55+
});
3856
// tell the viewer about the image
39-
view3D.addVolume(aimg);
40-
41-
// load volume data into the image. volumeData here is an array of Uint8Arrays.
42-
// each element in volumeData is a flattened 3d volume stored in xyz order in a Uint8Array.
43-
// Intensities must have been be scaled to fit in uint8.
44-
for (let i = 0; i < volumeData.length; ++i) {
45-
aimg.setChannelDataFromVolume(i, volumeData[i], [0, 255]);
46-
// optional: initialize with a lookup table suitable for visualizing noisy biological data
47-
const hmin = aimg.getHistogram(i).findBinOfPercentile(0.5);
48-
const hmax = aimg.getHistogram(i).findBinOfPercentile(0.983);
49-
const lut = new Lut().createFromMinMax(hmin, hmax);
50-
aimg.setLut(i, lut);
51-
}
52-
53-
// enable only the first 3 channels
54-
for (var ch = 0; ch < aimg.num_channels; ++ch) {
55-
view3D.setVolumeChannelEnabled(aimg, ch, ch < 3);
56-
}
57-
58-
// set some viewing parameters
59-
view3D.updateDensity(aimg, 0.05);
60-
view3D.updateExposure(0.75);
61-
// tell the viewer to update because new data has been added.
62-
view3D.updateActiveChannels(aimg);
63-
view3D.updateLuts(aimg);
57+
view3D.addVolume(volume);
58+
// start requesting volume data
59+
loader.loadVolumeData(volume);
6460
```
6561

6662
# React example
6763

68-
- in `VolumeViewer.jsx`
69-
70-
```JavaScript
71-
import * as React from "react";
72-
73-
import { View3d, Volume, VolumeLoader, VolumeMaker } from 'volume-viewer';
74-
75-
76-
const url = 'https://s3-us-west-2.amazonaws.com/bisque.allencell.org/v1.4.0/Cell-Viewer_Thumbnails/AICS-11/';
77-
const volumeToLoad = 'AICS-11_3136_atlas.json';
78-
export class VolumeViewer extends React.Component {
79-
constructor(props) {
80-
super(props);
81-
this.volumeViewer = React.createRef();
82-
}
83-
84-
componentDidMount() {
85-
const ref = this.volumeViewer;
86-
if (!ref.current) {
87-
return;
88-
}
89-
const el = ref.current;
90-
this.view3D = new View3d(el);
91-
// to download a volume encoded as a json plus tiled png images:
92-
// this format is documented in Volume.ts as ImageInfo
93-
return fetch(`${url}/${volumeToLoad}`)
94-
.then((response) => {
95-
return response.json();
96-
})
97-
.then(jsondata => {
98-
// when json file is received, create Volume object
99-
const aimg = new Volume(jsondata);
100-
// tell the 3d view about it.
101-
this.view3D.addVolume(aimg);
102-
103-
jsondata.images = jsondata.images.map(img => ({ ...img, name: `${url$}${img.name}` }));
104-
// download the volume data itself in the form of tiled png files
105-
VolumeLoader.loadVolumeAtlasData(aimg, jsondata.images, (url, channelIndex) => {
106-
// initialize each channel as it arrives and tell the view to update.
107-
const hmin = aimg.getHistogram(channelIndex).findBinOfPercentile(0.5);
108-
const hmax = aimg.getHistogram(channelIndex).findBinOfPercentile(0.983);
109-
const lut = new Lut().createFromMinMax(hmin, hmax);
110-
aimg.setLut(i, lut);
111-
112-
this.view3D.setVolumeChannelEnabled(aimg, channelIndex, channelIndex < 3);
113-
this.view3D.updateActiveChannels(aimg);
114-
115-
this.view3D.updateLuts(aimg);
116-
});
117-
// set some initial viewing parameters
118-
this.view3D.setCameraMode('3D');
119-
this.view3D.updateDensity(aimg, 0.05);
120-
this.view3D.updateExposure(0.75);
121-
});
122-
}
123-
124-
render() {
125-
return (
126-
<div
127-
style={{height: 1000, width: '100%'}}
128-
ref={this.volumeViewer}
129-
/>
130-
)
131-
}
132-
```
64+
See [vole-app](https://github.com/allen-cell-animated/website-3d-cell-viewer) for a complete application that wraps View3D in a React component.
13365

13466
# Acknowledgements
13567

0 commit comments

Comments
 (0)