|
1117 | 1117 | max.forEach((n, i) => maxNum[i] = Number(n));
|
1118 | 1118 |
|
1119 | 1119 | let min = new Array(maxNum.length).fill(0);
|
1120 |
| - return new CATMAID.BlockCoordBounds(min, maxNum); |
| 1120 | + let x = new CATMAID.BlockCoordBounds(min, maxNum) |
| 1121 | + return x; |
1121 | 1122 | }
|
1122 | 1123 |
|
1123 | 1124 | blockSize(zoomLevel) {
|
|
1127 | 1128 | 1
|
1128 | 1129 | ];
|
1129 | 1130 | let bs = this.datasetAttributes.get_block_size(zoomLevel);
|
1130 |
| - return CATMAID.tools.permute(bs, this.sliceDims); |
| 1131 | + let x = CATMAID.tools.permute(bs, this.sliceDims); |
| 1132 | + return x; |
1131 | 1133 | }
|
1132 | 1134 |
|
1133 | 1135 | voxelOffset(zoomLevel) {
|
|
1364 | 1366 | if (block) {
|
1365 | 1367 | let n = 1;
|
1366 | 1368 | let stride = block.size.map(s => { let rn = n; n *= s; return rn; });
|
| 1369 | + let dd = new nj.NdArray(nj.ndarray(block.data, block.size, stride)) |
| 1370 | + .transpose(...this.sliceDims); |
1367 | 1371 | return {
|
1368 | 1372 | etag: block.etag,
|
1369 |
| - block: new nj.NdArray(nj.ndarray(block.data, block.size, stride)) |
1370 |
| - .transpose(...this.sliceDims), |
| 1373 | + block: dd, |
1371 | 1374 | gridPosition: block.gridPosition,
|
1372 | 1375 | };
|
1373 | 1376 | } else {
|
|
1384 | 1387 | /**
|
1385 | 1388 | * Image block source type for OME Zarr datasets.
|
1386 | 1389 | * See https://ngff.openmicroscopy.org/latest/
|
1387 |
| - * See https://guido.io/zarr.js/ |
| 1390 | + * See https://zarrita.dev/packages/zarrita.html |
1388 | 1391 | *
|
1389 | 1392 | * Source type: 15
|
1390 | 1393 | */
|
|
1404 | 1407 | }
|
1405 | 1408 |
|
1406 | 1409 | if (!supportsDynamicImport() || typeof BigInt === 'undefined') {
|
1407 |
| - // TODO: should fail gracefully here instead. |
1408 | 1410 | throw new CATMAID.Error(
|
1409 | 1411 | 'Your browser does not support features required for OME-Zarr mirrors');
|
1410 | 1412 | }
|
1411 | 1413 |
|
1412 | 1414 | this.datasetURL = this.baseURL;
|
1413 |
| - // XXX: get dims from data, collecting x,y,z in axes field |
1414 |
| - this.sliceDims = [1, 2, 3]; |
1415 |
| - this.reciprocalSliceDims = Array.from(Array(this.sliceDims.length).keys()) |
1416 |
| - .sort((a, b) => this.sliceDims[a] - this.sliceDims[b]); |
1417 |
| - console.log('this.sliceDims',this.sliceDims) |
1418 |
| - console.log('this.reciprocalSliceDims',this.reciprocalSliceDims) |
1419 | 1415 |
|
1420 | 1416 | this.promiseReady = OMEZarrBlockSource.loadZarrita()
|
1421 | 1417 | .then(() => this.loadRoot())
|
|
1466 | 1462 | 'Only OME-Zarr version 0.5 is supported');
|
1467 | 1463 | }
|
1468 | 1464 |
|
| 1465 | + // extract slice dims based on spatial axes names |
| 1466 | + const targetNames = ["x", "y", "z"]; |
| 1467 | + this.sliceDims = this.rootData.attributes.ome.multiscales[0].axes.reduce((acc, item, index) => { |
| 1468 | + if (targetNames.includes(item.name)) { |
| 1469 | + acc.push(index); |
| 1470 | + } |
| 1471 | + return acc; |
| 1472 | + }, []); |
| 1473 | + |
| 1474 | + this.reciprocalSliceDims = Array.from(Array(this.sliceDims.length).keys()) |
| 1475 | + .sort((a, b) => this.sliceDims[a] - this.sliceDims[b]); |
| 1476 | + |
1469 | 1477 | let datasets = this.rootData.attributes.ome.multiscales[0].datasets;
|
1470 | 1478 | this.datasetAttributes = [];
|
1471 | 1479 | this.stores = {};
|
|
1489 | 1497 | allPathsPromise.push(request(index, url))
|
1490 | 1498 | }
|
1491 | 1499 |
|
1492 |
| - // get the results for each scale level and populate datasetAttributes and create stores |
| 1500 | + // get the resulting array specs for each scale level |
| 1501 | + // and populate datasetAttributes and create stores |
1493 | 1502 | return Promise.all(allPathsPromise).then(result => {
|
1494 | 1503 | for (let index = 0; index < result.length; index++) {
|
1495 | 1504 | let storePath = `${this.datasetURL}/${datasets[index].path}`
|
|
1507 | 1516 | this.tileHeight,
|
1508 | 1517 | 1
|
1509 | 1518 | ];
|
1510 |
| - // XXX: is chunk_shape correct as block_size |
1511 |
| - let bs = this.datasetAttributes[zoomLevel].ds.chunk_grid.configuration.chunk_shape; |
1512 |
| - // console.log('blockSize', zoomLevel, bs, 'permute', CATMAID.tools.permute(bs, this.sliceDims)); |
| 1519 | + let bs = this.datasetAttributes[zoomLevel].ds.codecs[0].configuration.chunk_shape; |
1513 | 1520 | return CATMAID.tools.permute(bs, this.sliceDims);
|
1514 | 1521 | }
|
1515 | 1522 |
|
1516 | 1523 | blockCoordBounds(zoomLevel) {
|
1517 | 1524 | if (!this.ready) return;
|
1518 |
| - // XXX What should it return? |
1519 |
| - console.log('blockCoordBounds', zoomLevel) |
1520 |
| - return new CATMAID.BlockCoordBounds([0,0,0], [100,100,100]); |
| 1525 | + // volume shape divided by chunk_shape at zoom level |
| 1526 | + let dimension = this.datasetAttributes[zoomLevel].ds.shape; |
| 1527 | + let block_size = this.datasetAttributes[zoomLevel].ds.codecs[0].configuration.chunk_shape; |
| 1528 | + let max = dimension.map((d, i) => { |
| 1529 | + return d / block_size[i]; |
| 1530 | + }) |
| 1531 | + let maxNum = new Array(max.length); |
| 1532 | + max.forEach((n, i) => maxNum[i] = Number(n)); |
| 1533 | + let min = [0,0,0]; // new Array(maxNum.length).fill(0); |
| 1534 | + return new CATMAID.BlockCoordBounds(min, maxNum); |
1521 | 1535 | }
|
1522 | 1536 |
|
1523 | 1537 | dataType () {
|
|
1528 | 1542 | }
|
1529 | 1543 | }
|
1530 | 1544 |
|
1531 |
| - |
1532 | 1545 | readBlock(zoomLevel, ...sourceCoord) {
|
1533 | 1546 | return this.promiseReady.then(() => {
|
1534 |
| - let path = this.datasetPath(zoomLevel); |
1535 |
| - let dataAttrs = this.datasetAttributes[zoomLevel]; |
1536 |
| - let blockCoord = CATMAID.tools.permute(sourceCoord, this.reciprocalSliceDims); |
1537 |
| - // console.log('readBlock', zoomLevel, sourceCoord, path, dataAttrs, 'blockCoord', blockCoord); |
1538 |
| - |
1539 |
| - let arr = new nj.NdArray(nj.uint8(nj.random([32,32,32]).multiply(255).tolist()) ); |
1540 |
| - // XXX: why is it not showing random data in the stack viewer? |
1541 |
| - console.log('arr', arr) |
1542 |
| - |
1543 |
| - // XXX: load array data |
1544 |
| - const arr2 = Window.Zarrita.open.v3(this.stores[zoomLevel], { kind: "array" }).then(arr => { |
1545 |
| - console.log('opened arr', arr2); |
1546 |
| - //const view = Window.Zarrita.get(arr, [null, null, 0]).then(view => {console.log('view', arr); return view}); |
1547 |
| - return arr |
| 1547 | + let blockCoord = CATMAID.tools.permute(sourceCoord, this.reciprocalSliceDims); |
| 1548 | + return Window.Zarrita.open.v3(this.stores[zoomLevel], { kind: "array" }).then(arr => { |
| 1549 | + const viewChunk2 = arr.getChunk(blockCoord).then(view => { |
| 1550 | + let d1 = new nj.NdArray(nj.ndarray(view.data, view.shape, view.stride)) |
| 1551 | + let view2 = d1.transpose(...this.sliceDims); |
| 1552 | + return view2; |
| 1553 | + }); |
| 1554 | + return {block: viewChunk2, etag: undefined}; |
1548 | 1555 | });
|
1549 |
| - |
1550 |
| - return {block: arr.transpose(...this.sliceDims), etag: undefined}; |
1551 | 1556 | });
|
1552 | 1557 | }
|
1553 | 1558 |
|
1554 | 1559 | datasetPath(zoomLevel) {
|
1555 |
| - return `${this.datasetURL}/${this.datasetAttributes[zoomLevel].root.path.path}`; |
| 1560 | + return `${this.datasetURL}/${this.datasetAttributes[zoomLevel].root.path}`; |
1556 | 1561 | }
|
1557 | 1562 |
|
1558 | 1563 | numScaleLevels() {
|
|
0 commit comments