Skip to content

Commit

Permalink
supporting cave properties in annotation shader
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisj committed Aug 7, 2023
1 parent 65a0757 commit 760bbfc
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 67 deletions.
80 changes: 26 additions & 54 deletions src/neuroglancer/datasource/cave/backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,14 @@ import { AnnotationSubsetGeometryChunk } from "src/neuroglancer/annotation/backe
import { WithParameters } from "src/neuroglancer/chunk_manager/backend";
import { WithSharedCredentialsProviderCounterpart } from "src/neuroglancer/credentials_provider/shared_counterpart";
import { CancellationToken } from "src/neuroglancer/util/cancellation";
import { responseJson } from "src/neuroglancer/util/http_request";
import { responseArrayBuffer, responseJson } from "src/neuroglancer/util/http_request";
import { SpecialProtocolCredentials } from "src/neuroglancer/util/special_protocol_request";
import { registerSharedObject } from "src/neuroglancer/worker_rpc";
import { AnnotationSourceParameters, AnnotationSpatialIndexSourceParameters, API_STRING } from "./base";
import {cancellableFetchSpecialOk} from 'neuroglancer/util/special_protocol_request';

import {vec3} from 'neuroglancer/util/geom';
import { Annotation, AnnotationBase, AnnotationSerializer, AnnotationType, Line, Point, makeAnnotationPropertySerializers } from "src/neuroglancer/annotation";
import {Uint64} from "src/neuroglancer/util/uint64";


const annotationPropertySerializers =
makeAnnotationPropertySerializers(/*rank=*/ 3, /*propertySpecs=*/[]);

import {Annotation, AnnotationBase, AnnotationSerializer, AnnotationType, Line, Point, makeAnnotationPropertySerializers} from "src/neuroglancer/annotation";
import {Uint64} from "neuroglancer/util/uint64";


function parseCaveAnnototations(segmentId: Uint64, annotationsJson: any[], parameters: AnnotationSourceParameters) {
Expand All @@ -34,7 +28,7 @@ function parseCaveAnnototations(segmentId: Uint64, annotationsJson: any[], param
type: AnnotationType.POINT,
id: `${segmentId}_${x.id}`,
description: `size: ${x.size}`,
properties: [], // [x.size]
properties: parameters.properties.map(p => x[p.identifier]),
};
if (points.length > 1) {
return {
Expand All @@ -57,38 +51,33 @@ function parseCaveAnnototations(segmentId: Uint64, annotationsJson: any[], param

@registerSharedObject() //
export class CaveAnnotationSpatialIndexSourceBackend extends (WithParameters(WithSharedCredentialsProviderCounterpart<SpecialProtocolCredentials>()(AnnotationGeometryChunkSourceBackend), AnnotationSpatialIndexSourceParameters)) {
// private minishardIndexSource =
// getMinishardIndexDataSource(this.chunkManager, this.credentialsProvider, this.parameters);
parent: CaveAnnotationSourceBackend;
async download(chunk: AnnotationGeometryChunk, cancellationToken: CancellationToken) {
console.log("SPATIAL DOWNLOAD!");
cancellationToken;
console.log('chunk', chunk);
const {parent} = this;
console.log('parent', parent);

const {parent} = this;
const {parameters} = parent; // we probably don't need separate spatial index for now

this.parent.parameters.timestamp;



const url = `${parameters.url}/${API_STRING}/datastack/${parameters.datastack}/query?return_pyarrow=false&split_positions=false&count=false&allow_missing_lookups=false`;
const {datastack, table, timestamp, rank, properties} = parameters;
const binaryFormat = false;
const url = `${parameters.url}/${API_STRING}/datastack/${datastack}/query?return_pyarrow=${binaryFormat}&split_positions=false&count=false&allow_missing_lookups=false`;
const payload = `{
"timestamp": "${parameters.timestamp}",
"timestamp": "${timestamp}",
"limit": 10000,
"table": "${parameters.table}"
"table": "${table}"
}`;
const response = await cancellableFetchSpecialOk(this.credentialsProvider, url, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: payload,
}, responseJson, cancellationToken);
}, binaryFormat ? responseArrayBuffer : responseJson, cancellationToken);
if (response !== undefined) {
if (binaryFormat) {
console.log("got arraybuffer!", response.byteLength);
return;
}
console.log("got annotations!", response.length);
const annotations = parseCaveAnnototations(Uint64.ZERO, response, parameters);
// this.annotationCache[chunk.objectId.toJSON()] = annotations;
const serializer = new AnnotationSerializer(annotationPropertySerializers);
const propertySerializers = makeAnnotationPropertySerializers(rank, properties);
const serializer = new AnnotationSerializer(propertySerializers);
for (const annotation of annotations) {
// this.annotationCache.set(annotation.id, annotation);
serializer.add(annotation);
Expand All @@ -108,31 +97,26 @@ export class CaveAnnotationSourceBackend extends (WithParameters(WithSharedCrede
chunk: AnnotationSubsetGeometryChunk, relationshipIndex: number,
cancellationToken: CancellationToken) {
const {parameters} = this;
const url = `${parameters.url}/${API_STRING}/datastack/${parameters.datastack}/query?return_pyarrow=false&split_positions=false&count=false&allow_missing_lookups=false`;
const {datastack, table, relationships, timestamp, rank, properties} = parameters;
const url = `${parameters.url}/${API_STRING}/datastack/${datastack}/query?return_pyarrow=false&split_positions=false&count=false&allow_missing_lookups=false`;
const payload = `{
"timestamp": "${parameters.timestamp}",
"timestamp": "${timestamp}",
"filter_in_dict": {
"${parameters.table}":{
"${parameters.relationships[relationshipIndex]}_root_id": [${chunk.objectId.toJSON()}]
"${table}":{
"${relationships[relationshipIndex]}_root_id": [${chunk.objectId.toJSON()}]
}
},
"table": "${parameters.table}"
}`; // TODO (hardcooding _root_id)
// parameters; for spatial
// const payload = `{
// "timestamp": "${parameters.timestamp}",
// "limit": 10000,
// "table": "${parameters.table}"
// }`;
"table": "${table}"
}`; // TODO (hardcoding `_root_id`)
const response = await cancellableFetchSpecialOk(this.credentialsProvider, url, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: payload,
}, responseJson, cancellationToken);
if (response !== undefined) {
const annotations = parseCaveAnnototations(chunk.objectId, response, this.parameters);
// this.annotationCache[chunk.objectId.toJSON()] = annotations;
const serializer = new AnnotationSerializer(annotationPropertySerializers);
const propertySerializers = makeAnnotationPropertySerializers(rank, properties);
const serializer = new AnnotationSerializer(propertySerializers);
for (const annotation of annotations) {
this.annotationCache.set(annotation.id, annotation);
serializer.add(annotation);
Expand All @@ -145,19 +129,7 @@ export class CaveAnnotationSourceBackend extends (WithParameters(WithSharedCrede
cancellationToken;
const {parameters} = this;
console.log('downloadMetadata', chunk.key, chunk.annotation, parameters);

if (!chunk.key) return;
chunk.annotation = this.annotationCache.get(chunk.key) || null;



// this.annotationCache[chunk.ob]

// if (response === undefined) {
// chunk.annotation = null;
// } else {
// chunk.annotation = parseSingleAnnotation(
// response, this.parameters, this.annotationPropertySerializer, chunk.key!);
// }
}
}
46 changes: 33 additions & 13 deletions src/neuroglancer/datasource/cave/frontend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { cancellableFetchSpecialOk, parseSpecialUrl, SpecialProtocolCredentials,
import { CompleteUrlOptions, ConvertLegacyUrlOptions, DataSource, DataSourceProvider, GetDataSourceOptions, NormalizeUrlOptions, RedirectError } from "..";
import { parseMultiscaleVolumeInfo, parseProviderUrl } from "neuroglancer/datasource/precomputed/frontend";
import { AnnotationSourceParameters, AnnotationSpatialIndexSourceParameters, API_STRING, API_STRING_V2 } from "neuroglancer/datasource/cave/base";
import { AnnotationType, parseAnnotationPropertySpecs } from "neuroglancer/annotation";
import { AnnotationPropertySpec, AnnotationType, parseAnnotationPropertySpecs } from "neuroglancer/annotation";
import {SliceViewSingleResolutionSource} from "src/neuroglancer/sliceview/frontend";
import {AnnotationGeometryChunkSpecification} from "src/neuroglancer/annotation/base";
import * as matrix from 'neuroglancer/util/matrix';
Expand Down Expand Up @@ -66,8 +66,8 @@ class AnnotationMetadata {
// type: verifyObjectProperty(
// metadata, 'annotation_type', typeObj => verifyEnumString(typeObj, AnnotationType)),
rank,
relationships: tableMetadata.properties,
properties: verifyObjectProperty(metadata, 'properties', parseAnnotationPropertySpecs),
relationships: tableMetadata.relationships,
properties: tableMetadata.shaderProperties,
};
/*
verifyObjectProperty(
Expand Down Expand Up @@ -239,10 +239,16 @@ interface TableMetadata {
voxel_resolution_x: number,
voxel_resolution_y: number,
voxel_resolution_z: number,
properties: string[],
relationships: string[],
shaderProperties: AnnotationPropertySpec[],
}

const schemaFormatToPropertyType: {[key: string]: string} = {
'float': 'float32',
}

const BOUND_SPATIAL_POINT = 'BoundSpatialPoint';
const SPATIAL_POINT = 'SpatialPoint';

async function getTableMetadata(credentialsProvider: SpecialProtocolCredentialsProvider, url: string, datastack: string, version: number, table: string): Promise<TableMetadata> {
const metadataURL = `${url}/${API_STRING_V2}/datastack/${datastack}/version/${version}/table/${table}/metadata`;
Expand Down Expand Up @@ -272,20 +278,33 @@ async function getTableMetadata(credentialsProvider: SpecialProtocolCredentialsP
const definitionName = refToName(ref);
const definitions = verifyObjectProperty(schema, 'definitions', verifyObject);
const definition = verifyObjectProperty(definitions, definitionName, verifyObject);
const properties = verifyObjectProperty(definition, 'properties', x => {
const res = [];
const [relationships, shaderProperties] = verifyObjectProperty(definition, 'properties', x => {
const relationships: string[] = [];
const shaderProps: unknown[] = [];
const result = verifyObjectAsMap(x, verifyObject);
for (const [name, obj] of result) {
console.log('name', name);
verifyObject(obj);
const ref = verifyOptionalObjectProperty(obj, '$ref', verifyString);
if (!ref) continue;
const refName = refToName(ref);
const order = verifyOptionalObjectProperty(obj, 'order', verifyNonnegativeInt) || 0;
if (refName === BOUND_SPATIAL_POINT) { // TODO, maybe we want to support SpatialPoint?
res[order] = name;
if (ref) {
const refName = refToName(ref);
const order = verifyOptionalObjectProperty(obj, 'order', verifyNonnegativeInt) || 0;
if (refName === BOUND_SPATIAL_POINT) { // TODO, maybe we want to support SpatialPoint?
relationships[order] = name;
} else if (refName === SPATIAL_POINT) {
// TODO
}
}
const format = obj['format'];
const type = schemaFormatToPropertyType[format];
if (type) {
shaderProps.push({
id: name,
type,
});
}
}
return res.filter(x => x !== undefined);
return [relationships.filter(x => x !== undefined), parseAnnotationPropertySpecs(shaderProps)];
});

// TODO, maybe use flat_segmentation_source to automatically link up the segmentation?
Expand All @@ -295,7 +314,8 @@ async function getTableMetadata(credentialsProvider: SpecialProtocolCredentialsP
voxel_resolution_x,
voxel_resolution_y,
voxel_resolution_z,
properties,
relationships,
shaderProperties,
}
}

Expand Down

0 comments on commit 760bbfc

Please sign in to comment.