Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate TIFF access into vitessce-image-viewer and Improve Metadata Caching #31

Merged
merged 8 commits into from
Feb 4, 2020

Conversation

ilan-gold
Copy link
Collaborator

This looks to finish the work for #15 and #30. Once this is merged (or rather while it's under review), I will begin working on integrating pyramidal tiff into vitessce and vitessce-data. Since the tiff pyramid is a fairly "standard" format in my eyes, I will thus look to make this the default in vitessce and hold off on zarr.

@ilan-gold ilan-gold requested a review from mccalluc February 3, 2020 21:46
Comment on lines +1 to +97
import {BaseTileLayer} from '@deck.gl/layers';
import {Texture2D} from '@luma.gl/webgl'
import GL from '@luma.gl/constants';
import { COORDINATE_SYSTEM } from 'deck.gl';
import { XRLayer } from '../xr-layer';
import {tileToBoundingBox} from './tiling-utils';
import {getTileIndices} from './tiling-utils';
import { loadZarr, loadTiff } from './data-utils';

const defaultProps = Object.assign({}, BaseTileLayer.defaultProps, {
id: `microscopy-tile-layer`,
pickable: false,
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
maxZoom: 0,
onViewportLoad: false,
renderSubLayers: (props) => {
const {
bbox: {
west, south, east, north,
},
} = props.tile;
const { sliderValues, data, colorValues } = props;
const xrl = new XRLayer(props, {
id: `XR-Layer-${west}-${south}-${east}-${north}`,
pickable: false,
coordinateSystem: COORDINATE_SYSTEM.CARTESIAN,
rgbData: data,
sliderValues,
colorValues,
bounds: [west, south, east, north],
visible: true,
});
return xrl;
},
});

export class MicroscopyViewerLayerBase extends BaseTileLayer {

constructor(props) {
const minZoom = Math.floor(-1 * Math.log2(Math.max(props.imageHeight, props.imageWidth)));
const {sliderValues, colorValues} = props
var orderedSliderValues = []
var orderedColorValues = []
Object.keys(sliderValues).sort().forEach(function(key) {
orderedSliderValues.push(sliderValues[key]);
})
Object.keys(colorValues).sort().forEach(function(key) {
orderedColorValues.push(colorValues[key]);
})
var diff = 6 - orderedSliderValues.length
for (var i = 0; i < diff; i++) {
orderedSliderValues.push(65535);
}
var diff = 6 - orderedColorValues.length
for (var j = 0; j < diff; j++) {
orderedColorValues.push([0,0,0]);
}
orderedColorValues = orderedColorValues.map(color => color.map(ch => ch / 255))
const getZarr = ({ x, y, z }) => {
return loadZarr({
x, y, z: -1 * z, ...props,
});
}
const getTiff = ({ x, y, z }) => {
return loadTiff({
x, y, z: -1 * z, ...props,
});
}
const getTileData = (props.useZarr && getZarr) ||
(props.useTiff && getTiff) ||
props.getTileData
const overrideValuesProps = Object.assign(
{}, props, {
sliderValues: orderedSliderValues,
colorValues: orderedColorValues,
minZoom,
getTileData,
getTileIndices: (viewport, maxZoom, minZoom) => {
return getTileIndices({
viewport, maxZoom, minZoom, ...props,
});
},
tileToBoundingBox: (x, y, z) => {
return tileToBoundingBox({
x, y, z, ...props,
});
},
}
)
const layerProps = Object.assign({}, defaultProps, overrideValuesProps)
super(layerProps)
}

}

MicroscopyViewerLayerBase.layerName = 'MicroscopyViewerLayerBase';
MicroscopyViewerLayerBase.defaultProps = defaultProps;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Copy and pasted into a new file :)

@ilan-gold ilan-gold changed the title Integrate GeoTIFF access into vitessce-image-viewer and Improve Metadata Caching Integrate TIFF access into vitessce-image-viewer and Improve Metadata Caching Feb 3, 2020
Copy link
Contributor

@mccalluc mccalluc left a comment

Choose a reason for hiding this comment

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

Could turn on linting in Travis? Whatever rules we have on Vitessce are fine. Whatever the linting would complain about, I'd like to complain about, and it's easier for the computer to do the complaining. :)

Copy link
Contributor

@mccalluc mccalluc left a comment

Choose a reason for hiding this comment

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

The last few comments have all just been linting issues. Please get it turned on, and then I'll give it another look. Thanks!

@@ -44,7 +45,7 @@ This component can be used with an already existing `DeckGL` setup.

##### `getTileData` (Function) **POTENIAL FUTURE BREAKING CHANGES WITH NEW FEATURES**

`getTileData` given x, y, z indices of the tile, returns the tile data or a Promise that resolves to the tile data. Alternatively, pass in `useZarr` as true to use `zarr` and our funcionality. Soon, there will be a `useGeoTIFF` as well. Look
`getTileData` given x, y, z indices of the tile, returns the tile data or a Promise that resolves to the tile data. Alternatively, pass in `useZarr` as true to use `zarr` and our functionality. Otherwise, you can use `useTiff` to make range requests directly against a pyramid/tiled tiff. Look
Copy link
Contributor

Choose a reason for hiding this comment

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

I think useZarr is out, for now? Update docs if so.

channel_0: "https://vitessce-vanderbilt-data.storage.googleapis.com/test-data/vanderbilt-data/tiff-pyramid/vanderbilt_test_0.ome.tiff",
channel_1: "https://vitessce-vanderbilt-data.storage.googleapis.com/test-data/vanderbilt-data/tiff-pyramid/vanderbilt_test_1.ome.tiff",
channel_2: "https://vitessce-vanderbilt-data.storage.googleapis.com/test-data/vanderbilt-data/tiff-pyramid/vanderbilt_test_2.ome.tiff",
channel_3: "https://vitessce-vanderbilt-data.storage.googleapis.com/test-data/vanderbilt-data/tiff-pyramid/vanderbilt_test_3.ome.tiff",
Copy link
Contributor

Choose a reason for hiding this comment

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

  • How do you generate the data that goes on the google service? We need the scripts documented, like in vitessce-data.
  • Make a variable for the repeated string?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Getting to this data task today. Will do for repeated string.

@@ -0,0 +1,46 @@
import {fromUrl, Pool, getDecoder } from 'geotiff/dist/geotiff.bundle.min.js';
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it something about their packaging that forces us to reference it this way?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes. People seem to have trouble with it

async function loadTile({image, channel, x, y, pool}) {
var tile = await image.getTileOrStrip(x,y, 0, pool)
var dataObj = {}
const bits8 = image.fileDirectory.BitsPerSample[0]===8
Copy link
Contributor

Choose a reason for hiding this comment

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

Here it's clear, but I'd prefer to give booleans is* names... like is8bit.

dataObj[channel] = (bits8 && new Uint8Array(tile.data)) ||
(bits16 && new Uint16Array(tile.data)) ||
(bits32 && new Uint32Array(tile.data))
return dataObj
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's use semicolons... I know they're not really necessary in JS, but consistency is good.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Will run prettier/eslint later


export function loadTiff({connections, x, y, z, pool}){
const configListPromises = Object.keys(connections).map((channel) => {
var image = connections[channel][z]
Copy link
Contributor

Choose a reason for hiding this comment

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

let's not use var.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Will run prettier/eslint later

return Promise.all(configListPromises).then((dataList) => {
const orderedList = []
const dataObj = Object.assign({}, ...dataList)
Object.keys(dataObj).sort().forEach(function(key) {
Copy link
Contributor

Choose a reason for hiding this comment

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

arrow syntax.

@ilan-gold ilan-gold force-pushed the ilan-gold/geotiff_addition branch from adee215 to 80a60a6 Compare February 4, 2020 19:19
@ilan-gold ilan-gold merged commit f901168 into master Feb 4, 2020
@ilan-gold ilan-gold deleted the ilan-gold/geotiff_addition branch February 4, 2020 19:33
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.

2 participants