-
Notifications
You must be signed in to change notification settings - Fork 10
State Sharing
Certain objects in the neuroglancer client complies with the trackable interface:
export class SomethingTrackable implements Trackable {
get value()
set value(newValue)
changed = new Signal();
toJSON()
restoreState(json: any)
reset()
};
These object can be registers so that every time there is a change on them, toJSON
is called and
the output updates the url and sent to the python state server. Or the opposite process, when the url changes
or the python state server sends a new state restoreState
is called.
In the neuroglancer code (src/neuroglancer/viewer.ts) you can find the objects being tracked.:
registerTrackable('layers', this.layerSpecification);
registerTrackable('navigation', this.navigationState);
registerTrackable('showAxisLines', this.showAxisLines);
registerTrackable('showScaleBar', this.showScaleBar);
registerTrackable('perspectiveOrientation', this.perspectiveNavigationState.pose.orientation);
registerTrackable('perspectiveZoom', this.perspectiveNavigationState.zoomFactor);
registerTrackable('showSlices', this.showPerspectiveSliceViews);
registerTrackable('layout', this.layoutName);
registerTrackable('stateURL', this.stateServer);
The actual sincronization between url(and state server) with the trackable is happening at (src/neuroglancer/url_hash_state.ts) which defines registerTrackable and schedules the update to every 0.2 seconds. It also implements the comunication to the state server:
sock = new SockJS(url);
sock.onopen = function() {
let state = getCurrentState();
sock.send(JSON.stringify(state))
};
sock.onmessage = function(e: any) {
let state = JSON.parse(e.data);
updateTrackedObjects(state);
};
sock.onclose = function() {
console.log('closing socket connection');
};
Similarly the server(state.py) communicates with the client by:
clients = set()
n_messages = 0
class Connection(SockJSConnection):
def on_open(self, info):
"""
info is an object which contains caller IP address, query string
parameters and cookies associated with this request"""
# When new client comes in, will add it to the clients list
clients.add(self)
def on_message(self, json_state):
"""
This will call initialize_state or on_state_change depening on if it is
the first message recieved.
"""
state = json.JSONDecoder(object_pairs_hook=OrderedDict).decode(json_state)
global n_messages
if not n_messages: #first message ever
new_state = self.initialize_state(state)
else:
new_state = self.on_state_change(state)
n_messages += 1
if new_state: #if you return a new state send it back
self.broadcast(clients, json.dumps(new_state))
def on_close(self):
# If client disconnects, remove him from the clients list
clients.remove(self)
def initialize_state(self, state):
"""
This is called once the connection is stablished.
"""
pass
def on_state_change(self, state):
"""
This is called every time there is a new state available
(except the very first time).
"""
print(state)
- start a python session (can be in a jupyter notebook or not)
- import the controller module (e.g.
import controller as C
) - call the controller constructor function
c = C.controller()
- create a neuroglancer browser session with the layers you want to view
- at the end of the url before the ending '}', add
_'stateServer':'https://localhost:9999'
(you can customize the port number in the controller module or constructor function call) - travel to your localhost port, and add a browser security exception for the controller
- refresh your neuroglancer page, you should see
state initialized
in your python session -you should now be able to set the neuroglancer focus point, and display points using thec.set_pos
andc.set_pts
functions respectively -If your segmentation layer is called 'seg', you can also set which segments are selected using thec.set_segs
function
- pip install sockjs-tornado
- pip install tornado==4.5.2