Skip to content

Commit

Permalink
support pass parameters to cellpose
Browse files Browse the repository at this point in the history
  • Loading branch information
Nanguage committed Dec 19, 2023
1 parent 41e2365 commit e656e15
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 22 deletions.
6 changes: 5 additions & 1 deletion src/components/AdvanceSetting.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div>
<div class="advance-setting-container">
<div class="server-setting">
<h3>Settings for server</h3>
<label class="field-label">Server URL</label>
Expand Down Expand Up @@ -61,6 +61,10 @@
</template>

<style scoped>
.advance-setting-container {
padding-left: 20px;
padding-bottom: 20px;
}
.field-label {
display: block;
margin-bottom: 5px;
Expand Down
48 changes: 48 additions & 0 deletions src/components/ModelParameters.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<template>
<div v-if="parameters && (parameters.length > 0)">
<HideContainer :summary="'Model parameters'">
<OverlayContainer :open="overlay">
<div class="model-params-container">
<div v-for="(paramGroup, index) in parameters" :key="index">
<h3>{{ paramGroup.name }}</h3>
<div v-for="(param, index2) in paramGroup.parameters" :key="index">
<label class="field-label">{{ param.name }}</label>
<InputNumber showButtons v-if="param.type === 'number'" v-model="parameterValues[param.name]" />
<Dropdown :options="param.enum" v-else-if="param.enum" v-model="parameterValues[param.name]" />
<InputText v-else="param.type === 'string'" v-model="parameterValues[param.name]" />
</div>
</div>
</div>
</OverlayContainer>
</HideContainer>
</div>
</template>

<style scoped>
.field-label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
.model-params-container {
padding-left: 20px;
padding-bottom: 20px;
}
</style>

<script>
import HideContainer from './HideContainer.vue';
import OverlayContainer from './OverlayContainer.vue';
export default {
props: {
parameters: Array,
parameterValues: Object,
overlay: Boolean,
},
components: {
HideContainer,
OverlayContainer
},
}
</script>
6 changes: 5 additions & 1 deletion src/components/ModelSelect.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div>
<Dropdown v-model="currentModel" :options="modelList" option-label="name">
<Dropdown :disabled="!open" v-model="currentModel" :options="modelList" option-label="name">
<template #value="slotProps">
<div v-if="slotProps.value">
<div>
Expand All @@ -25,6 +25,10 @@
<script>
export default {
props: {
open: {
type: Boolean,
default: false
},
additionalModels: {
type: Array,
default: () => []
Expand Down
57 changes: 44 additions & 13 deletions src/components/RunPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<div class="model-selection">
<div class="model-selection-line">
<div class="model-selection-label">Model</div>
<ModelSelect @model-selected="handleModelChange" :additional-models="additionalModels" />
<ModelSelect :open="this.modelSelectEnable" @model-selected="handleModelChange" :additional-models="additionalModels" />
</div>
<div class="model-selection-tips">ℹ️ Please visit <a href="https://bioimage.io/#/" target="_blank">bioimage.io</a> to view detailed information about the model.</div>
</div>
Expand All @@ -28,6 +28,11 @@
Show reference output
</Button>
</div>
<ModelParameters
:parameters="this.additionalParameters"
:parameterValues="this.additionalParameterValues"
:overlay="waiting"
/>
<HideContainer :summary="'Advanced settings'">
<OverlayContainer :open="waiting">
<AdvanceSetting
Expand Down Expand Up @@ -106,6 +111,7 @@ import OverlayContainer from "./OverlayContainer.vue";
import AdvanceSetting from "./AdvanceSetting.vue";
import LoadingAnimation from "./LoadingAnimation.vue";
import ModelSelect from "./ModelSelect.vue";
import ModelParameters from "./ModelParameters.vue";
import { ModelRunner } from "../modelRun";
import { ImagejJsController } from "../viewerControl";
Expand All @@ -129,11 +135,13 @@ export default {
buttonEnabledRun: false,
buttonEnabledInput: false,
buttonEnabledOutput: false,
modelSelectEnable: false,
tileSizes: { x: 0, y: 0, z: 0 },
tileOverlaps: { x: 0, y: 0, z: 0 },
runner: null,
serverUrl: "https://hypha.bioimage.io",
serverUrl: "https://ai.imjoy.io",
additionalModels: [],
additionalParameterValues: {}
}),
computed: {
infoColor() {
Expand All @@ -151,29 +159,37 @@ export default {
return this.runner.modelTritonConfig;
},
inputMinShape() {
if (!this.runner) {
if (!this?.runner?.rdf) {
return {};
}
return this.runner.getInputMinShape();
},
inputMaxShape() {
if (!this.runner) {
if (!this?.runner?.rdf) {
return {};
}
return this.runner.getInputMaxShape();
},
inputSpec() {
if (!this.runner) {
if (!this?.runner?.rdf) {
return {};
}
return this.runner.rdf.inputs[0];
},
outputSpec() {
if (!this.runner) {
if (!this?.runner?.rdf) {
return {};
}
return this.runner.rdf.outputs[0];
},
additionalParameters() {
if (!this?.runner?.rdf) {
return [];
}
const params = this?.runner?.rdf?.additional_parameters || [];
console.log("Additional parameters: ", params);
return params
},
},
watch: {
tileSizes: {
Expand All @@ -193,7 +209,17 @@ export default {
console.log(oldObj, newObj);
},
deep: true
}
},
additionalParameters() {
const initValues = {};
for (const paramGroup of this.additionalParameters) {
for (const param of paramGroup.parameters) {
initValues[param.name] = param.default;
}
}
console.log("Init additional parameters", initValues)
this.additionalParameterValues = initValues;
},
},
mounted() {
this.init();
Expand Down Expand Up @@ -221,11 +247,11 @@ export default {
this.turnButtons(true);
},
async initModel(modelId, runner=undefined) {
this.setInfoPanel(`Initializing model ${modelId}...`, true);
this.turnButtons(false);
if (runner === undefined) {
runner = this.runner;
}
this.setInfoPanel(`Initializing model ${modelId}...`, true);
this.turnButtons(false);
try {
await runner.loadModel(modelId);
} catch (e) {
Expand All @@ -239,10 +265,11 @@ export default {
this.setInfoPanel("");
},
turnButtons(on) {
if (!this.runner.rdf) {
if (!this?.runner?.rdf) {
this.buttonEnabledRun = false;
this.buttonEnabledInput = false;
this.buttonEnabledOutput = false;
this.modelSelectEnable = false;
} else {
this.buttonEnabledRun = on;
this.buttonEnabledInput = on && (
Expand All @@ -251,10 +278,13 @@ export default {
this.buttonEnabledOutput = on && (
rdfHas(this.runner.rdf, "test_outputs") ||
rdfHas(this.runner.rdf, "sample_outputs"));
this.modelSelectEnable = on;
}
},
handleModelChange(model) {
this.initModel(model.id);
if (this?.runner?.rdf) {
this.initModel(model.id);
}
},
async handleServerUrlChange(url) {
this.serverUrl = url;
Expand Down Expand Up @@ -327,9 +357,10 @@ export default {
this.outputSpec,
this.tileSizes,
this.tileOverlaps,
this.additionalParameterValues,
(msg) => {
this.setInfoPanel(msg, true);
}
},
);
if (this.runner.isImg2Img()) {
const imgsForShow = processForShow(outTensor, this.outputSpec.axes);
Expand Down Expand Up @@ -413,6 +444,6 @@ export default {
this.setInfoPanel("");
}
},
components: { HideContainer, OverlayContainer, AdvanceSetting, LoadingAnimation, ModelSelect }
components: { HideContainer, OverlayContainer, AdvanceSetting, LoadingAnimation, ModelSelect, ModelParameters }
};
</script>
43 changes: 36 additions & 7 deletions src/modelRun.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,10 @@ class TritonExecutor {
return ret;
}

async runCellpose(array, diameter = 30) {
async runCellpose(array, additionalParameters = {}) {
console.log("Running cellpose with parameters: ", additionalParameters);
const ret = await this.triton.execute({
inputs: [array, { diameter: diameter }],
inputs: [array, additionalParameters],
model_name: "cellpose-python",
decode_json: true,
_rkwargs: true,
Expand Down Expand Up @@ -228,18 +229,41 @@ export class ModelRunner {
sample_inputs: [
"https://zenodo.org/api/records/6647674/files/sample_input_0.tif/content",
],
additional_parameters: [
{
name: "Cellpose Parameters",
parameters: [
{
name: "diameter",
type: "number",
default: 30,
description: "Diameter of the nuclei in pixels.",
},
{
name: "model_type",
type: "string",
default: "nuclei",
description: "Type of cells to segment.",
enum: ["nuclei", "cyto"],
},
],
},
],
};
return rdf;
}

async submitTensor(tensor) {
async submitTensor(tensor, additionalParameters = undefined) {
const reverseEnd = this.inputEndianness === "<";
const data_type = this.rdf.inputs[0].data_type;
const reshapedImg = tfjsToImJoy(tensor, reverseEnd, data_type);
const modelId = this.modelId;
let outImg;
if (modelId === "cellpose-python") {
const resp = await this.tritonExecutor.runCellpose(reshapedImg);
const resp = await this.tritonExecutor.runCellpose(
reshapedImg,
additionalParameters
);
outImg = resp.mask;
} else {
const resp = await this.tritonExecutor.execute(modelId, [reshapedImg]);
Expand All @@ -251,11 +275,11 @@ export class ModelRunner {
return outImg;
}

async runOneTensor(tensor, padder) {
async runOneTensor(tensor, padder, additionalParameters = undefined) {
console.log("Input tile shape: " + tensor.shape);
const [paddedTensor, padArr] = padder.pad(tensor);
console.log("Padded tile shape: " + paddedTensor.shape);
let outImg = await this.submitTensor(paddedTensor);
let outImg = await this.submitTensor(paddedTensor, additionalParameters);
console.log("Output tile shape: " + outImg._rshape);
const outTensor = imjoyToTfjs(outImg);
const isImg2Img =
Expand All @@ -275,6 +299,7 @@ export class ModelRunner {
outputSpec,
tileSizes,
tileOverlaps,
additionalParameters = undefined,
reportFunc = undefined
) {
if (!reportFunc) {
Expand Down Expand Up @@ -308,7 +333,11 @@ export class ModelRunner {
const tile = inTiles[i];
console.log(tile);
tile.slice(tensor);
const outTensor = await this.runOneTensor(tile.data, padder);
const outTensor = await this.runOneTensor(
tile.data,
padder,
additionalParameters
);
const outTile = new ImgTile(tile.starts, tile.ends, tile.indexes);
outTile.data = outTensor;
outTiles.push(outTile);
Expand Down

0 comments on commit e656e15

Please sign in to comment.