-
Notifications
You must be signed in to change notification settings - Fork 59
Scripting
CATMAID is written in javascript on the client side. The whole of CATMAID is available at your fingertips if only you knew what to type into the javascript console.
In Google Chrome, push shift+control+j (shift+command+j in MacOSX) or go to the menu "Tools - Javascript Console".
Every widget is an object, and the prototype of that object has an instances array. For example, open a Selection Table by clicking on its icon that looks like this: ['S']
... and then open the Javascript Console, and type:
var tables = SelectionTable.prototype.getInstances();
The tables array should contain one single entry:
var st = tables[0];
The SkeletonSource is an Object that provides an interface for adding and getting skeletons. All widgets that can list and deliver skeletons extend SkeletonSource.
Each skeleton is represented by a SkeletonModel object, which is a simple object holding fields for the ID and its selected state, with separate fields for the visibility of presynaptic sites, postsynaptic sites, meta information like "uncertain end", low-confidence edges etc., for skeleton text tags, and for the skeleton as a whole.
Well-implemented widgets return copies of the SkeletonModel internally representing each skeleton in that widget. To alter the model, you'll have to append it back to the widget. Here is how:
Following from the SelectionTable example, now manually add skeletons to it by selecting them in the canvas (click on an existing skeleton node) and then pushing the "Append" button of the Selection Table widget. Then we can get the SkeletonModel instances representing each Skeleton, in this case just one:
var models = st.getSkeletonModels();
Here, models is an Object with skeleton ID as keys and SkeletonModel instances as values. To change the visibility of all the skeletons we will change the selected field of each, along with all other fields, via the method setVisible:
Object.keys(models).forEach(function(skeleton_id) {
models[skeleton_id].setVisible(false);
};
To update the SelectionTable, the modified models must be appended back, which won't duplicate them: will simply read the new values of the updated ones and append new ones if any:
st.append(models);
Now the checkbox of the listed neurons in the Selection Table should have been unticked.
Assuming you have a list of neurons in a Selection widget, and at least a subset of them is selected (their checkboxes are ticked):
// Assuming it is the first one opened:
var st = SelectionTable.prototype.getInstances()[0];
// List of skeleton IDs
var skids = st.getSelectedSkeletons();
// Pick one skeleton at random: var skid = skids[Math.floor(Math.random() * skids.length)];
// Select the skeleton in the canvas TracingTool.goToNearestInNeuronOrSkeleton("skeleton", skid);
If the Selection Table is linked to a 3D Viewer (as is the default when the 3D Viewer is open), then this will hide all neurons except the one selected at random:
var selectAtRandom = function() {
var st = SelectionTable.prototype.getInstances()[0];
var models = st.getSkeletonModels();
var skids = Object.keys(models);
var skid = skids[Math.floor(Math.random() * skids.length)];
console.log("Picking: ", skid);
TracingTool.goToNearestInNeuronOrSkeleton("skeleton", skid);
// Leave selected only skid
Object.keys(models).forEach(function(id) {
models[id].setVisible(id == skid);
});
st.append(models);
};
selectAtRandom();
Given the annotation as text, we obtain first its ID from the local cache (which is loaded on startup), and then request from the server the list of neurons along with their associated skeleton IDs:
var selectAtRandom = function(annotation) {
if (!annotation) return alert("What annotation?");
var annot = annotations.annotation_ids[annotation];
if (!annot) return alert("Invalid annotation");
var request = function(url, post, callback) {
requestQueue.register(
django_url + project.id + url, "POST", post,
function(status, text) {
if (200 !== status) return;
var json = $.parseJSON(text);
if (json.error) return alert(json.error);
callback(json);
});
};
request(
"/neuron/query-by-annotations",
{neuron_query_by_annotation: [annot]},
function(json) {
var skids = json.entities.map(function(e) {
return e.skeleton_ids[0];
});
var skid = skids[Math.floor(Math.random() * skids.length)];
console.log("Picking: ", skid);
TracingTool.goToNearestInNeuronOrSkeleton("skeleton", skid);
});
};