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

Spelunker rebase stop layer #622

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@ jobs:
strategy:
matrix:
node-version:
- "16.x"
- "20.x"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- uses: actions/cache@v3
- uses: actions/cache@v4
with:
path: "**/node_modules"
key: ${{ runner.os }}-${{ matrix.node-version }}-node_modules-${{ hashFiles('**/package-lock.json') }}
Expand All @@ -50,7 +50,7 @@ jobs:
run: echo ${{ env.BUILD_INFO }} >> src/version.json
shell: bash
- name: Build client bundles
run: node ./config/esbuild-cli.js --config=min --no-typecheck --define STATE_SERVERS=$(cat config/state_servers.json | tr -d " \t\n\r") --define NEUROGLANCER_BUILD_INFO='${{ env.BUILD_INFO }}' --define CUSTOM_BINDINGS=$(cat config/custom-keybinds.json | tr -d " \t\n\r")
run: npm run build -- --no-typecheck --no-lint
- run: cp -r ./dist/min appengine/frontend/static/
- name: start deployment
uses: bobheadxi/deployments@v1
Expand All @@ -61,12 +61,12 @@ jobs:
env: ${{ env.BRANCH_NAME }}
desc: Setting up staging deployment for ${{ env.BRANCH_NAME }}
- id: "auth"
uses: "google-github-actions/auth@v1"
uses: "google-github-actions/auth@v2"
with:
workload_identity_provider: "projects/483670036293/locations/global/workloadIdentityPools/neuroglancer-github/providers/github"
service_account: "[email protected]"
- id: deploy
uses: google-github-actions/deploy-appengine@main
uses: google-github-actions/deploy-appengine@v2
with:
version: ${{ env.GITHUB_SHA }}
deliverables: appengine/frontend/app.yaml
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build_preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm install
Expand Down
7 changes: 4 additions & 3 deletions src/credentials_provider/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@
/**
* @file Generic facility for providing authentication/authorization credentials.
*/

import { type OAuth2Credentials } from "#src/credentials_provider/oauth2.js";
import type { CancellationToken } from "#src/util/cancellation.js";
import { MultipleConsumerCancellationTokenSource } from "#src/util/cancellation.js";
import type { Owned } from "#src/util/disposable.js";
import { RefCounted } from "#src/util/disposable.js";
import { type HttpError } from "#src/util/http_request.js";
import { StringMemoize } from "#src/util/memoize.js";
import { HttpError } from "#src/util/http_request";
import { OAuth2Credentials } from "#src/credentials_provider/oauth2";



/**
* Wraps an arbitrary JSON credentials object with a generation number.
Expand Down
90 changes: 64 additions & 26 deletions src/datasource/graphene/frontend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,32 @@
*/

import "#src/datasource/graphene/graphene.css";
import { debounce } from "lodash-es";
import {
AnnotationDisplayState,
AnnotationLayerState,
} from "#src/annotation/annotation_layer_state.js";
import type {
AnnotationReference,
Annotation,
AnnotationSource,
AnnotationType,
Line,
Point,
import { type MultiscaleAnnotationSource } from "#src/annotation/frontend_source.js";
import {
type AnnotationReference,
type Annotation,
type AnnotationSource, AnnotationType,
type Line,
type Point,
LocalAnnotationSource,
makeDataBoundsBoundingBoxAnnotationSet,
} from "#src/annotation/index.js";
import { LayerChunkProgressInfo } from "#src/chunk_manager/base.js";
import type { ChunkManager, WithParameters } from "#src/chunk_manager/frontend.js";
import { type ChunkManager, WithParameters } from "#src/chunk_manager/frontend.js";
import { makeIdentityTransform } from "#src/coordinate_transform.js";
import { WithCredentialsProvider } from "#src/credentials_provider/chunk_source_frontend.js";
import type { CredentialsManager } from "#src/credentials_provider/index.js";

import type {
ChunkedGraphChunkSource as ChunkedGraphChunkSourceInterface,
ChunkedGraphChunkSpecification,
MultiscaleMeshMetadata,
} from "#src/datasource/graphene/base.js";
import { MultiscaleAnnotationSource } from "#src/annotation/frontend_source";
import {
CHUNKED_GRAPH_LAYER_RPC_ID,
CHUNKED_GRAPH_RENDER_LAYER_UPDATE_SOURCES_RPC_ID,
Expand Down Expand Up @@ -78,6 +81,7 @@ import type {
import type { LoadedDataSubsource } from "#src/layer/layer_data_source.js";
import { LoadedLayerDataSource } from "#src/layer/layer_data_source.js";
import { SegmentationUserLayer } from "#src/layer/segmentation/index.js";
import * as json_keys from "#src/layer/segmentation/json_keys.js";
import { MeshSource } from "#src/mesh/frontend.js";
import type { DisplayDimensionRenderInfo } from "#src/navigation_state.js";
import type {
Expand Down Expand Up @@ -143,27 +147,32 @@ import {
MergedAnnotationStates,
PlaceLineTool,
} from "#src/ui/annotations.js";
import { getDefaultAnnotationListBindings } from "#src/ui/default_input_event_bindings";
import { getDefaultAnnotationListBindings } from "#src/ui/default_input_event_bindings.js";
import {
LayerTool,
makeToolActivationStatusMessageWithHeader,
makeToolButton,
registerLegacyTool,
registerTool,
ToolActivation
type ToolActivation
} from "#src/ui/tool.js";
import type { Uint64Set } from "#src/uint64_set.js";
import { Uint64Set } from "#src/uint64_set.js";
import {
type CancellationToken,
CancellationTokenSource,
} from "#src/util/cancellation.js";
import { packColor } from "#src/util/color.js";
import type { Owned, RefCounted } from "#src/util/disposable.js";
import { ValueOrError, makeValueOrError, valueOrThrow } from "#src/util/error.js";
import { type Owned, RefCounted } from "#src/util/disposable.js";
import { removeChildren } from "#src/util/dom.js";
import { type ValueOrError, makeValueOrError, valueOrThrow } from "#src/util/error.js";
import { EventActionMap } from "#src/util/event_action_map.js";
import { mat4, vec3, vec4 } from "#src/util/geom.js";
import {
HttpError,
isNotFoundError,
responseJson,
} from "#src/util/http_request.js";
import { removeChildren } from "#src/util/dom";

import {
parseArray,
parseFixedLengthArray,
Expand All @@ -184,13 +193,13 @@ import {
verifyString,
verifyStringArray
} from "#src/util/json.js";
import { MouseEventBinder } from "#src/util/mouse_bindings.js";
import { getObjectId } from "#src/util/object_id.js";
import { NullarySignal } from "#src/util/signal.js";
import type {
SpecialProtocolCredentials,
SpecialProtocolCredentialsProvider,
} from "#src/util/special_protocol_request.js";
import { MouseEventBinder } from "#src/util/mouse_bindings";
import {
cancellableFetchSpecialOk,
parseSpecialUrl,
Expand All @@ -200,11 +209,11 @@ import { Uint64 } from "#src/util/uint64.js";
import { makeDeleteButton } from "#src/widget/delete_button.js";
import type { DependentViewContext } from "#src/widget/dependent_view_widget.js";
import { makeIcon } from "#src/widget/icon.js";
import {
CancellationToken,
CancellationTokenSource,
} from "#src/util/cancellation";
import { debounce } from "lodash";

import type { LayerControlDefinition } from "#src/widget/layer_control.js";
import { addLayerControlToOptionsTab } from "#src/widget/layer_control.js";
import { rangeLayerControl } from "#src/widget/layer_control_range.js";


function vec4FromVec3(vec: vec3, alpha = 0) {
const res = vec4.clone([...vec]);
Expand Down Expand Up @@ -1626,7 +1635,7 @@ class GraphConnection extends SegmentationGraphSourceConnection {
);
const segmentConst = segmentId.clone();
if (added && isBaseSegment) {
this.graph.getRoot(segmentConst).then((rootId) => {
this.graph.getRoot(segmentConst, this.layer.displayState.stopLayer.value).then((rootId) => {
if (segmentsState.visibleSegments.has(segmentConst)) {
segmentsState.visibleSegments.add(rootId);
}
Expand Down Expand Up @@ -1952,11 +1961,14 @@ class GrapheneGraphServerInterface {
private credentialsProvider: SpecialProtocolCredentialsProvider,
) { }

async getRoot(segment: Uint64, timestamp = "") {
async getRoot(segment: Uint64, timestamp = "", stop_layer: number | undefined = undefined) {
const timestampEpoch = new Date(timestamp).valueOf() / 1000;

const url = `${this.url}/node/${String(segment)}/root?int64_as_str=1${Number.isNaN(timestampEpoch) ? "" : `&timestamp=${timestampEpoch}`
let url = `${this.url}/node/${String(segment)}/root?int64_as_str=1${Number.isNaN(timestampEpoch) ? "" : `&timestamp=${timestampEpoch}`
}`;
if (stop_layer !== undefined) {
url += "&stop_layer=" + stop_layer;
}

const promise = cancellableFetchSpecialOk(
this.credentialsProvider,
Expand Down Expand Up @@ -2125,6 +2137,17 @@ class GrapheneGraphServerInterface {
}
}

export const LAYER_CONTROLS: LayerControlDefinition<SegmentationUserLayer>[] = [
{
label: "Stop Layer", // Adjust the label as needed
toolJson: json_keys.STOP_LAYER,
// ... other properties (toolJson, isValid, title) based on your requirements
...rangeLayerControl((layer) => ({
value: layer.displayState.stopLayer,
options: { min: 0.0, max: 10, step: 1.0 }
})), // Integrate your getter function
}]

class GrapheneGraphSource extends SegmentationGraphSource {
private connections = new Set<GraphConnection>();
public graphServer: GrapheneGraphServerInterface;
Expand Down Expand Up @@ -2188,8 +2211,14 @@ class GrapheneGraphSource extends SegmentationGraphSource {
}
}

getRoot(segment: Uint64) {
return this.graphServer.getRoot(segment);

getRoot(segment: Uint64, stop_layer: number) {
if (stop_layer > 0) {
return this.graphServer.getRoot(segment, "", stop_layer);
}
else {
return this.graphServer.getRoot(segment);
}
}

async findPath(
Expand Down Expand Up @@ -2276,7 +2305,15 @@ class GrapheneGraphSource extends SegmentationGraphSource {
title: "Find Path",
}),
);
for (const control of LAYER_CONTROLS) {
toolbox.appendChild(
addLayerControlToOptionsTab(tab, layer, tab.visibility, control),
);
}


parent.appendChild(toolbox);

parent.appendChild(
context.registerDisposer(
new MulticutAnnotationLayerView(layer, layer.annotationDisplayState),
Expand Down Expand Up @@ -2310,6 +2347,7 @@ class GrapheneGraphSource extends SegmentationGraphSource {
}
}


class ChunkedGraphChunkSource
extends SliceViewChunkSource
implements ChunkedGraphChunkSourceInterface {
Expand Down
5 changes: 3 additions & 2 deletions src/datasource/middleauth/credentials_provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,16 @@ import {
CredentialsProvider,
makeCredentialsGetter,
} from "#src/credentials_provider/index.js";
import { type OAuth2Credentials } from "#src/credentials_provider/oauth2.js";
import { StatusMessage } from "#src/status.js";
import { type HttpError } from "#src/util/http_request.js";
import {
verifyObject,
verifyObjectProperty,
verifyString,
verifyStringArray,
} from "#src/util/json.js";
import { HttpError } from "#src/util/http_request";
import { OAuth2Credentials } from "#src/credentials_provider/oauth2";


export type MiddleAuthToken = {
tokenType: string;
Expand Down
10 changes: 8 additions & 2 deletions src/layer/segmentation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ import { DisplayOptionsTab } from "#src/ui/segmentation_display_options_tab.js";
import { Uint64Map } from "#src/uint64_map.js";
import { Uint64OrderedSet } from "#src/uint64_ordered_set.js";
import { Uint64Set } from "#src/uint64_set.js";
import { gatherUpdate } from "#src/util/array.js";
import {
packColor,
parseRGBColorSpecification,
Expand All @@ -122,14 +123,14 @@ import {
verifyFiniteNonNegativeFloat,
verifyObjectAsMap,
verifyOptionalObjectProperty,
verifyPositiveInt,
verifyString,
} from "#src/util/json.js";
import { Signal } from "#src/util/signal.js";
import { Uint64 } from "#src/util/uint64.js";
import { makeWatchableShaderError } from "#src/webgl/dynamic_shader.js";
import type { DependentViewContext } from "#src/widget/dependent_view_widget.js";
import { registerLayerShaderControlsTool } from "#src/widget/shader_controls.js";
import { gatherUpdate } from "#src/util/array";

export const SKELETON_RENDERING_SHADER_CONTROL_TOOL_ID =
"skeletonShaderControl";
Expand Down Expand Up @@ -485,6 +486,7 @@ class SegmentationUserLayerDisplayState implements SegmentationDisplayState {
);
objectAlpha = trackableAlphaValue(1.0);
ignoreNullVisibleSet = new TrackableBoolean(true, true);
stopLayer = new TrackableValue<number>(0, verifyPositiveInt);
skeletonRenderingOptions = new SkeletonRenderingOptions();
shaderError = makeWatchableShaderError();
renderScaleHistogram = new RenderScaleHistogram();
Expand Down Expand Up @@ -595,7 +597,11 @@ export class SegmentationUserLayer extends Base {
};

displayState = new SegmentationUserLayerDisplayState(this);

stopLayer = new TrackableValue<number>(
0,
verifyFiniteNonNegativeFloat,
0,
);
anchorSegment = new TrackableValue<Uint64 | undefined>(undefined, (x) =>
x === undefined ? undefined : Uint64.parseString(x),
);
Expand Down
1 change: 1 addition & 0 deletions src/layer/segmentation/json_keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const IGNORE_NULL_VISIBLE_SET_JSON_KEY = "ignoreNullVisibleSet";
export const MESH_JSON_KEY = "mesh";
export const SKELETONS_JSON_KEY = "skeletons";
export const SEGMENTS_JSON_KEY = "segments";
export const STOP_LAYER = 'stop_layer';
export const EQUIVALENCES_JSON_KEY = "equivalences";
export const COLOR_SEED_JSON_KEY = "colorSeed";
export const SEGMENT_STATED_COLORS_JSON_KEY = "segmentColors";
Expand Down
6 changes: 3 additions & 3 deletions src/segmentation_display_state/frontend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,16 @@ import {
} from "#src/util/color.js";
import { RefCounted } from "#src/util/disposable.js";
import { measureElementClone } from "#src/util/dom.js";
import type { vec3 } from "#src/util/geom.js";
import { kOneVec, vec4 } from "#src/util/geom.js";
import { vec3, kOneVec, vec4 } from "#src/util/geom.js";
import { NullarySignal } from "#src/util/signal.js";
import { Uint64 } from "#src/util/uint64.js";
import { withSharedVisibility } from "#src/visibility_priority/frontend.js";
import { ColorWidget } from "#src/widget/color.js";
import { makeCopyButton } from "#src/widget/copy_button.js";
import { makeEyeButton } from "#src/widget/eye_button.js";
import { makeFilterButton } from "#src/widget/filter_button.js";
import { makeStarButton } from "#src/widget/star_button.js";
import { ColorWidget } from "#src/widget/color";


export class Uint64MapEntry {
constructor(
Expand Down
Loading
Loading