Skip to content

Commit

Permalink
Merge pull request #92 from thejohnhoffer/gating-john
Browse files Browse the repository at this point in the history
Move outline to glsl
  • Loading branch information
kruegert authored May 1, 2022
2 parents b44fe4f + 0cbe6b9 commit 97a1134
Show file tree
Hide file tree
Showing 14 changed files with 1,571 additions and 936 deletions.
6 changes: 5 additions & 1 deletion minerva_analysis/client/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
data/
data/
.editorconfig
.eslintignore
.eslintrc.json
tsconfig.json
18 changes: 3 additions & 15 deletions minerva_analysis/client/dist/vendor_bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion minerva_analysis/client/src/css/viewer.css
Original file line number Diff line number Diff line change
Expand Up @@ -193,4 +193,4 @@
#gating_controls_panel input {
height: 11px;
margin: 1px 10px 0 5px;
}
}
37 changes: 23 additions & 14 deletions minerva_analysis/client/src/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ d3.json(`/config?t=${Date.now()}`).then(function (config) {
async function init(conf) {

config = conf;
//maximum selections
config.maxSelections = 4;
config.extraZoomLevels = 3;
//channel information
for (let idx = 0; idx < config["imageData"].length; idx++) {
imageChannels[config["imageData"][idx].fullname] = idx;
Expand All @@ -57,24 +60,25 @@ async function init(conf) {
dataLayer = new DataLayer(config, imageChannels);
await dataLayer.init();

//init color scheme
colorScheme = new ColorScheme(dataLayer);
await colorScheme.init();

//init channel panel
channelList = new ChannelList(config, dataLayer, eventHandler);
await channelList.init();

//create image viewer
seaDragonViewer = new ImageViewer(config, dataLayer, channelList, eventHandler, colorScheme);

//init gating panel
csv_gatingList = new CSVGatingList(config, dataLayer, eventHandler);
await csv_gatingList.init();

//init color scheme
colorScheme = new ColorScheme(dataLayer);
await colorScheme.init();

//init image viewer
seaDragonViewer = new ImageViewer(config, dataLayer, eventHandler, colorScheme);
seaDragonViewer.init();
seaDragonViewer.init(csv_gatingList);
}


//EVENT HANDLING

/**
Expand All @@ -88,7 +92,6 @@ const actionColorTransferChange = (d) => {
// d3.select('body').style('cursor', 'progress');
seaDragonViewer.updateChannelColors(d.name, d.color, d.type);
// d3.select('body').style('cursor', 'default');
seaDragonViewer.csvGatingOverlay.draw();
}
eventHandler.bind(ChannelList.events.COLOR_TRANSFER_CHANGE, actionColorTransferChange);

Expand All @@ -112,7 +115,8 @@ const actionChannelsToRenderChange = (d) => {
d.name = dataLayer.getFullChannelName(d.name);

//send to image viewer
seaDragonViewer.updateActiveChannels(d.name, d.selections, d.status);
const action = ["remove", "add"][+d.status];
seaDragonViewer.updateActiveChannels(d.name, action);

d3.select('body').style('cursor', 'default');
}
Expand Down Expand Up @@ -140,19 +144,21 @@ eventHandler.bind(ImageViewer.events.imageClickedMultiSel, actionImageClickedMul
* @param {package object} d The selected/deselected channels
*/
const channelSelect = async (sels) => {
// pause new rendering until data loads
const resume = seaDragonViewer.sleep();
let channelCells = await dataLayer.getChannelCellIds(sels);
dataLayer.addAllToCurrentSelection(channelCells);
updateSeaDragonSelection(false);
updateSeaDragonSelection();
resume();
}
eventHandler.bind(ChannelList.events.CHANNEL_SELECT, channelSelect);

/**
* Listens to and updates based on selection changes (specific for seadragon)
* @param {boolean} d Whether to repaint
*/
function updateSeaDragonSelection(repaint = true) {
seaDragonViewer.updateSelection(dataLayer.getCurrentSelection(), repaint);
seaDragonViewer.csvGatingOverlay.evaluate();
function updateSeaDragonSelection() {
seaDragonViewer.updateSelection(dataLayer.getCurrentSelection());
}

/**
Expand All @@ -168,6 +174,8 @@ const gatingBrushEnd = async (packet) => {
this.config[datasource].featureData[0].xCoordinate,
this.config[datasource].featureData[0].yCoordinate
];
// pause new rendering until data loads
const resume = seaDragonViewer.sleep();
// Toggle these methods with centroids on/off ui
if (csv_gatingList.eval_mode === 'and') {
// AND
Expand All @@ -180,6 +188,7 @@ const gatingBrushEnd = async (packet) => {
dataLayer.addAllToCurrentSelection(gatedCells);
// Update view
updateSeaDragonSelection();
resume();
}
eventHandler.bind(CSVGatingList.events.GATING_BRUSH_END, gatingBrushEnd);

Expand Down Expand Up @@ -207,4 +216,4 @@ const add_scalebar = () => {
seaDragonViewer.addScaleBar();
seaDragonViewer.forceRepaint();
}
eventHandler.bind(ImageViewer.events.addScaleBar, add_scalebar);
eventHandler.bind(ImageViewer.events.addScaleBar, add_scalebar);
2 changes: 0 additions & 2 deletions minerva_analysis/client/src/js/vendor.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import 'viawebgl'
import * as viaWebGL from 'viawebgl';
import {ViewerManager} from './views/viewerManager';
import Dropzone from 'dropzone';
import {CsvGatingOverlay} from './views/CsvGatingOverlay';

window.convert = convert;
window.$ = $;
Expand All @@ -32,7 +31,6 @@ window.Sortable = Sortable;
window.Mark = Mark;
window.OpenSeadragon = viaWebGL.OpenSeadragon;
window.Dropzone = Dropzone;
window.CsvGatingOverlay = CsvGatingOverlay;
window.viaWebGL = viaWebGL;
window.ViewerManager = ViewerManager;

4 changes: 2 additions & 2 deletions minerva_analysis/client/src/js/views/channelList.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ class ChannelList {
*/
constructor(config, dataLayer, eventHandler) {
this.config = config;
this.maxSelections = config.maxSelections;
this.eventHandler = eventHandler;
this.dataLayer = dataLayer;
this.selections = [];
this.maxSelections = 4;
this.ranges = {};
this.sliders = new Map();
var that = this;
Expand Down Expand Up @@ -713,4 +713,4 @@ ChannelList.events = {
CHANNELS_CHANGE: "CHANNELS_CHANGE",
CHANNEL_SELECT: "CHANNEL_SELECT",
RESET_LISTS: "RESET_LISTS"
};
};
2 changes: 1 addition & 1 deletion minerva_analysis/client/src/js/views/channelMatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -316,4 +316,4 @@ function swapNodes(n1, n2) {
}
p1.insertBefore(n2, p1.children[i1]);
p2.insertBefore(n1, p2.children[i2]);
}
}
54 changes: 29 additions & 25 deletions minerva_analysis/client/src/js/views/csvGatingList.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ class CSVGatingList {
*/
constructor(config, dataLayer, eventHandler) {
this.config = config;
this.waiting = Promise.resolve(true);
this.maxSelections = config.maxSelections;
this.eventHandler = eventHandler;
this.dataLayer = dataLayer;
this.selections = {};
this.maxSelections = 4;
this.ranges = {};
this.hasGatingGMM = {};
this.gatingIDs = {};
Expand All @@ -40,18 +41,11 @@ class CSVGatingList {
* @param name - the channel to set and display as selected
*/
selectChannel(name) {
// For overlay (and query incrementor)
// seaDragonViewer.csvGatingOverlay.run_balancer++;

if (!(name in this.hasGatingGMM)) {
let channelTrace = this.getAndDrawGatingGMM(name);
}

// Add
this.selections[this.dataLayer.getFullChannelName(name)] = this.sliders.get(name).value();

// Trigger
this.eventHandler.trigger(CSVGatingList.events.GATING_BRUSH_END, this.selections);
this.awaitGatingGMM(name).then(() => {
const fullName = this.dataLayer.getFullChannelName(name);
this.selections[fullName] = this.sliders.get(name).value();
this.eventHandler.trigger(CSVGatingList.events.GATING_BRUSH_END, this.selections);
});
}

/**
Expand Down Expand Up @@ -169,7 +163,11 @@ class CSVGatingList {
autoBtn.classList.add('auto-btn');
autoBtn.setAttribute('id', "auto-btn_" + channelID);
autoBtn.textContent = "auto";
autoBtn.addEventListener("click", async function() { await self.autoGate(fullName) });
autoBtn.addEventListener("click", async () => {
const shortName = self.dataLayer.getShortChannelName(fullName);
await self.awaitGatingGMM(shortName);
self.autoGate(shortName);
});

autoCol.appendChild(autoBtn);
autoBtn.addEventListener("click", e => e.stopPropagation());
Expand Down Expand Up @@ -303,22 +301,20 @@ class CSVGatingList {
* @function autoGate - applies thresholds based on Gaussian Mixture Model
* @param name - the name of the channel to apply it to
*/
async autoGate(name) {
autoGate(shortName) {
const self = this;
let shortName = self.dataLayer.getShortChannelName(name);

let gate = this.hasGatingGMM[shortName]['gate']
let gate = this.hasGatingGMM[shortName].gate;
if (!this.dataLayer.isTransformed()) {
gate = parseInt(gate)
} else {
gate = gate.toFixed(7);
}
// For interaction
self.selections[name][0] = gate;
let gate_end = self.selections[name][1]
self.selections[shortName][0] = gate;
let gate_end = self.selections[shortName][1]
self.sliders.get(shortName).value([gate, gate_end]);
// For records
this.gating_channels[name] = [gate, gate_end];
this.gating_channels[shortName] = [gate, gate_end];

this.eventHandler.trigger(CSVGatingList.events.GATING_BRUSH_END, self.selections);
}
Expand Down Expand Up @@ -506,6 +502,7 @@ class CSVGatingList {
// Toggle outlined / filled cell selections
gating_controls_outlines.addEventListener('change', e => {
seaDragonViewer.viewerManagerVMain.sel_outlines = e.target.checked;
this.eventHandler.trigger(CSVGatingList.events.GATING_BRUSH_END, this.selections);
})

// Toggle outlined / filled cell selections
Expand All @@ -521,8 +518,7 @@ class CSVGatingList {
this.eval_mode = 'and';
}

// Update overlay centroid (will also trigger event)
seaDragonViewer.csvGatingOverlay.control(e.target.checked);
this.eventHandler.trigger(CSVGatingList.events.GATING_BRUSH_END, this.selections);
})

}
Expand Down Expand Up @@ -741,6 +737,14 @@ class CSVGatingList {
this.drawGatingGMM(name);
}

awaitGatingGMM(name) {
if (!(name in this.hasGatingGMM)) {
const waiting = this.getAndDrawGatingGMM(name)
this.waiting = Promise.all([this.waiting, waiting]);
}
return this.waiting;
}

drawGatingGMM(name){
let fullname = this.dataLayer.getFullChannelName(name);
let channelID = this.gatingIDs[name];
Expand Down Expand Up @@ -849,7 +853,7 @@ window.addEventListener("resize", function () {
csv_gatingList.addSlider(name, document.getElementById("csv_gating_list").getBoundingClientRect().width,
sliderRange, slider.value());
if (csv_gatingList.hasGatingGMM[name]) {
let channelTrace = csv_gatingList.drawGatingGMM(name);
csv_gatingList.drawGatingGMM(name);
}
});
}
Expand Down Expand Up @@ -878,4 +882,4 @@ CSVGatingList
GATING_COLOR_TRANSFER_CHANGE_MOVE: "GATING_TRANSFER_CHANGE_MOVE",
GATING_COLOR_TRANSFER_CHANGE: "GATING_TRANSFER_CHANGE",
GATING_CHANNELS_CHANGE: "GATING_CHANNELS_CHANGE"
};
};
Loading

0 comments on commit 97a1134

Please sign in to comment.