Skip to content

Commit

Permalink
NF display values at vertex in webgl viewer (#549)
Browse files Browse the repository at this point in the history
* NF display values at vertex in webgl viewer

* FIX logic for volumes
  • Loading branch information
mvdoc authored Jul 21, 2024
1 parent 6237fe3 commit 915ed73
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 34 deletions.
22 changes: 11 additions & 11 deletions cortex/webgl/resources/js/datamodel.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,34 +118,34 @@ NParray.fromURL = function(url, callback) {
}

var buffer = xhr.response;
console.log("Got buffer: " + buffer);
console.log("Buffer length: " + buffer.byteLength);
// console.log("Got buffer: " + buffer);
// console.log("Buffer length: " + buffer.byteLength);

// Check we got a valid npy file
var magic = asciiDecode(buffer.slice(0, 6));
if (magic.slice(1, 6) != 'NUMPY')
throw "Invalid npy file"
console.log("Magic: "+magic);
// console.log("Magic: "+magic);

// OK, now let's parse the header and get some info
var version = new Uint8Array(buffer.slice(6, 8));
console.log("npy version " + version);
// console.log("npy version " + version);

var headerLength = readUint16LE(buffer.slice(8, 10));
console.log("Header length: " + headerLength);
// console.log("Header length: " + headerLength);

var headerStr = asciiDecode(buffer.slice(10, 10 + headerLength));
console.log("Header: " + headerStr);
// console.log("Header: " + headerStr);

// Create the array object
var info = parse_dict(asciiDecode(buffer.slice(10, 10 + headerLength)));
var shape = info.shape.slice(1, info.shape.length-1).split(',');
shape = shape.map(function(num) { return parseInt(num.trim()) });
var array = new NParray(dtypeNames[info.descr], shape);

console.log("Array shape: " + array.shape);
console.log("Array size: " + array.size);
console.log("Array dtype: " + array.dtype);
// console.log("Array shape: " + array.shape);
// console.log("Array size: " + array.size);
// console.log("Array dtype: " + array.dtype);

if (xhr.status == 206) {
// We got partial data, we're streaming it
Expand All @@ -157,9 +157,9 @@ NParray.fromURL = function(url, callback) {
// Server doesn't support partial data, returned the whole thing
array.update(buffer.slice(10 + headerLength));
hideload();
// console.log("Data length: " + array.data.length);
// console.log("Data: " + array.data);
}
console.log("Data length: " + array.data.length);
console.log("Data: " + array.data);

// Finish up
hideload();
Expand Down
4 changes: 2 additions & 2 deletions cortex/webgl/resources/js/facepick.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ PickPosition.prototype = {
Math.round(vec_float.z),
)

return {'vertex': vertex, 'voxel': voxel}
return {'vertex': vertex, 'voxel': voxel, 'hemi': p.hemi}
} else {
return -1
}
Expand All @@ -234,7 +234,7 @@ PickPosition.prototype = {
var idx = this.revIndex[p.hemi][p.ptidx];
console.log("Picked vertex "+idx+" (orig "+p.ptidx+") in "+p.hemi+" hemisphere, voxel=["+vec.x+","+vec.y+","+vec.z+"]");
this.process_pick(vec, p.hemi, p.ptidx, keep);
return {'vertex': idx, 'voxel': vec}
return {'vertex': idx, 'voxel': vec, 'hemi': p.hemi}
}
else {
this.process_nonpick();
Expand Down
93 changes: 72 additions & 21 deletions cortex/webgl/resources/js/mriview.js
Original file line number Diff line number Diff line change
Expand Up @@ -636,16 +636,39 @@ var mriview = (function(module) {

$("#brain").on('mousemove',
function (event) {
// only implemented for 1d volume datasets
if (this.active.data.length != 1 || this.active.data[0].raw || this.active.data[0].verts) {
// only implemented for 1d volume datasets or vertex datasets
if (this.active.data.length != 1 || this.active.data[0].raw) {
$('#mouseover_value').css('display', 'none')
return
}

// set mouseover value if mouse is over a vertex
mouse_index = this.getMouseIndex(event)
if (mouse_index !== -1) {
value = this.active.data[0].textures[0].image.data[mouse_index]
// We need to use a different logic if we have a VolumeData or a VertexData object
let value = null;
if (this.active.vertex) {
coords = this.getCoords(event)
if (coords !== -1) {
hemiIdx = (coords.hemi == 'left') ? 0 : 1
// console.log('hemiIdx: ', hemiIdx)
vertex = coords.vertex
// console.log('vertex: ', vertex)
// Now we need to map back with the index map
// First figure out the subject, then get the index map
subject = this.active.data[0].subject
indexMap = subjects[subject].hemis[coords.hemi].indexMap
// console.log("vertex before: " + vertex);
vertex = indexMap[vertex]
// console.log("vertex after: " + vertex);
// Now access the data
value = this.active.data[0].verts[0][hemiIdx].array[vertex]
}
} else {
// Get index of the mosaic to get the value
mouse_index = this.getMouseIndex(event)
if (mouse_index !== -1) {
value = this.active.data[0].textures[0].image.data[mouse_index]
}
}
// console.log("Value on mouseover: " + value);
if (value !== null) {
$('#mouseover_value').text(parseFloat(value).toPrecision(3))
$('#mouseover_value').css('display', 'block')
} else {
Expand All @@ -658,7 +681,7 @@ var mriview = (function(module) {
return surf;
};

module.Viewer.prototype.getMouseIndex = function(event) {
module.Viewer.prototype.getCoords = function(event) {
if (this.surfs[0].pick && this.surfs[0].surf.picker) {
this.svgOff(this.surfs)
let coords = this.surfs[0].surf.picker.get_vertex_index(
Expand All @@ -668,11 +691,21 @@ var mriview = (function(module) {
event.clientY,
)
this.svgOn(this.surfs)
if (coords === -1) {
// console.log("coords: " + JSON.stringify(coords));
return coords
}
return -1
};

module.Viewer.prototype.getMouseIndex = function(event) {
if (this.surfs[0].pick && this.surfs[0].surf.picker) {
let coords = this.getCoords(event)
// console.log(coords)
if (coords !== -1) {
return this.xyxToI(coords.voxel.x, coords.voxel.y, coords.voxel.z)
} else {
return -1
}
// console.log(coords)
return this.xyxToI(coords.voxel.x, coords.voxel.y, coords.voxel.z)
}
return -1
};
Expand Down Expand Up @@ -779,20 +812,38 @@ var mriview = (function(module) {
if (this.surfs[i].pick)
coords = this.surfs[i].pick(this.renderer, this.camera, evt.x, evt.y);
}

//
// // set the picked value display
//

// only implemented for 1d volume datasets
if (this.active.data.length != 1 || this.active.data[0].raw || this.active.data[0].verts) {
// set the picked value display
// only implemented for 1d volume datasets or vertex datasets
if (this.active.data.length != 1 || this.active.data[0].raw) {
$('#picked_value').css('display', 'none')
return
}

if (coords !== -1) {
let mouse_index = this.xyxToI(coords.voxel.x, coords.voxel.y, coords.voxel.z)
value = this.active.data[0].textures[0].image.data[mouse_index]
// We need to use a different logic if we have a VolumeData or a VertexData object
let value = null;
if (this.active.vertex) {
if (coords !== -1) {
hemiIdx = (coords.hemi == 'left') ? 0 : 1
vertex = coords.vertex
// Now we need to map back with the index map
// First figure out the subject, then get the index map
subject = this.active.data[0].subject
indexMap = subjects[subject].hemis[coords.hemi].indexMap
vertex = indexMap[vertex]
// Now access the data
value = this.active.data[0].verts[0][hemiIdx].array[vertex]
}
} else {
if (coords !== -1) {
// Get index of the mosaic to get the value
let mouse_index = this.xyxToI(coords.voxel.x, coords.voxel.y, coords.voxel.z)
if (mouse_index !== -1) {
value = this.active.data[0].textures[0].image.data[mouse_index]
}
}
}
console.log("Value on click: " + value);
if (value !== null) {
$('#picked_value').text(parseFloat(value).toPrecision(3))
$('#picked_value').css('display', 'block')
} else {
Expand Down

0 comments on commit 915ed73

Please sign in to comment.