Code Monkey home page Code Monkey logo

camicroscope's Introduction

camicroscope: a web-based image viewer optimized for large bio-medical image data viewing

caMicroscope is a web-based biomedical image and data viewer, with a strong emphasis on cancer pathology WSI (Whole Slide Imaging). This guide has sections for different kinds of use of the platform. The User Guide covers the basics on how to use caMicroscope viewer. nanoBorb covers nanoBorb, the version of caMicroscope designed as a standalone application for individual users without a server. Hosted Setup covers how to set up caMicroscope for multiple users on a server. Developer Guide covers the broad strokes on how to add new functionality to caMicroscope.

View Slides Measure Features Annotate Areas of Interest Alternate Annotation Method Automatic Object Detection Test Classification Models

User Guide

Selecting an Image

Depending on what is providing the image metadata, a different login process may be necessary. For public instances, no log in is necessary, and you can proceed to view slides. Use of other tools, such as annotations may or may not require login in this case. For slim instances, login should be done through a redirect directly. For pathDB instances, login should be done on the login link on the main page. At this point, select a collection, if applicable, and proceed to open or "view" the image of your choice.

Viewing an Image

Once an image is open, you can pan around the image by either clicking and dragging (when no conflicting tool, such as the pen, is open), or by moving the red bounding box in the viewport in the bottom right. Zooming can be accomplished through the scroll wheel, pinch events on a touch screen, by using the zoom slider or its associated buttons, or by clicking on the zoom number and inputting a different number.

Using Tools

The toolbar is in the top-left of the main content window. Use the toolbar buttons to manipulate the slide. To close any toolbar button, click the same button again or a new button.

Tool Name Function
Annotations Opens the Annotation panel, where you can select which annotation set to view, name that annotation set, add optional notes about the annotation set, save the annotation set, and reset the panel to its original state.
Layer Manager Opens the Layers Manager panel, where you can select which layers to view.
Home Return to the data table so that you can open another slide.
Draw Draw thin lines, thick lines, or polygons on the image. Annotations can also be computer aided using the Smart-pen tool. Draw them, stretch them, remove them. To maintain the integrity of measurements, avoid drawing shapes that overlap or intersect one another.
Preset Labels Use a preset annotation type immediately to quickly annotate a slide consistently.
Magnifier The Magnifier works like a magnifying glass and allows you to see the slide at normal magnification (1.0), low magnification (0.5), or high magnification (2.0). Click a magnification level and place the bounding box on the area of the slide you want to magnify.
Measurement Drag this tool on the slide to learn the measurement in micrometers.
Share View Opens a window with a URL to the current presentation state of the slide including the magnification level, layers that are currently open, and your position on the image.
Side by Side Viewer Shows the Layer Manager panel, the left and right layers, and inset window. For the right and left layer, select which layer you want to view.
Heatmap For a slide with heatmap data, opens the choices of heatmaps available, as well as ways of displaying the heatmaps. The gradient shows all of the values on the selected spectrum for the field you selected. Contains a heatmap edit pen function.
Labeling Use this tool to draw a circle or rectangle around a tumor region, measure an area on the slide, download labels, and submit a bug report. The Labeling tool has its own toolbar with tools in the following order from left to right: return to the previous slide, place a square on the slide, place a circle on the slide, measure an area, download labels, and submit a bug report. Click the left arrow at the far right of the toolbar to hide it, then click the right arrow to show it.
Segment This tool allows you to display, count, and export nuclear segmentations on the image. Clicking this tool opens the following custom toolbar.
Model Show results from a pre-trained tensorflow compatible model on a ROI of the slide.
Download Slide Download the slide image to your system
Mark Reviewed Use to signify the completion of review of a slide.
Bug Report Report a bug or give feedback.
Slide Capture Click to take a screenshot of the slide and annotations on it.
Tutorial Click to view a guided tour of the viewer tools.

Toolbar Shortcuts

Tool Shortcut
Annotation Ctrl + a
Magnifier Ctrl + m
Measurement Ctrl + r
Side-by-Side Ctrl + s
Close all tools ESC

Hosted Setup

The full distribution repository for hosted caMicroscope is here. run with docker-compose -f caMicroscope.yml up

this will build all services and run in the foreground. Use docker-compose -f caMicroscope.yml build to rebuild the services.

Once everything is up, go to <the host this is running on>:4010/ to see the landing page.

Other Resources

Developer Guide

We are collecting feedback to write this section in more detail. Please add your suggestions here.

caMicroscope is open source software. Any involvement and contribution with the caMicroscope project is greatly appreciated. Feel free to get directly involved in any of the repositories in the caMicroscope organization. New developers may find the notes in CONTRIBUTING helpful to start contributing to caMicroscope.

It is highly recommended to make any changes off of the develop branch of a repository, and, when ready, create a PR to the develop branch of the source repository. Before sending the PR, make sure that there are no linting errors by running npm install and then npm run lint to see the errors and npm run lint-fix to automatically fix the errors in the repository folder.

Source code organization ie the file structure of caMicroscope can be found in file structure

Fast Local Changes

When using the hosted setup, you can have the distribution host the changes from your local. Follow these steps :

  • Clone this repository, the Caracal repository and the distribution in the same parent directory
  • Set the build to build your local changes instead of the hosted git versions by editing the ca-back container section of your develop.yml. Replace the build context section with the path to your caracal checkout ("../Caracal"), and add - ../caMicroscope:/src/camicroscope to the volumes.
  • Remove this line from 'Dockerfile' in Caracal repository :
RUN git clone https://github.com/${fork:-camicroscope}/camicroscope.git --branch=${viewer:-master}
  • In Distro repository, enter the following commands :
docker-compose -f develop.yml build
docker-compose -f develop.yml up

camicroscope's People

Contributors

abdulrashidreshamwala avatar ajasniew avatar akazer2 avatar akhil-rana avatar akhilesh-max avatar akhileshadithya avatar amritansh22 avatar birm avatar bridge2014 avatar cgdogan avatar cjchirag7 avatar dependabot[bot] avatar gbengaoluwadahunsi avatar hemansh31 avatar insiyaa avatar jasoxlee avatar jbalsamo avatar lastlegion avatar leoarc avatar lincolnnus avatar lochipi avatar mgautam98 avatar nanli-emory avatar pranavbudhwant avatar r7rohan avatar sohamsshah avatar tdiprima avatar vedant1202 avatar vikasgola avatar vunh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

camicroscope's Issues

Separate Magnifier

GOAL: A way to see high detail in a region without changing the main view.

Possible Implementation: Open a separate window or div and keep its x and y position matched with the crosshair/pointer position.

Debug docker hub automated build fail

s/w Ashish, looks like build is failing due to some artifacts residing in ViewerDockerContainer/html/. According to the Dockerfile, camicroscope is being pulled in from the camicroscope repository. Same thing with Security.

Doing simple test โ€“ removing camicroscope from html dir to trigger auto-build, and see if the removal of the directory fixes the error.

Example error.

Related to #96.

Consider adding a watermark (back)

previously:

        // add small watermark
        viewer.addHandler('update-viewport', function() {
             viewer.drawer.context.fillText('caMicroscope', document.documentElement.clientWidth-100, document.documentElement.clientHeight-20)
        });

It sometimes acted really strangely (maybe only in safari??)

Refactor Dynamic services UI code

Currently there are some hardcoded assumptions about the order, also there are a few unnecessary callback that can be refactored out.

Relative path issue

Enough of the codebase looks for absolute paths, so rev proxy deployments fail.

Save Zoom Mode Preference

As a proof of concept for indexedDB and configuration persistence, save whether or not to disable the scroll wheel as zoom.

Algorithm Usability Improvements

(In addition to the ux fixes)

  • Save presets for algorithms for session
  • Show a low quality representative preview at start quickly (to help with tuning before running)

missing apis

Three files use getProperties.php, but the file is missing. If that section of code is ever called, it will fail:

geoJSONHandler_Lymph.js
geoJSONHandler.js
geoJSONHandler_sc.js

Noted: a api/Data/getPropertiesClone.php was created, but I'm having a hard time tracking down the deletion of aforementioned getProperties.php.

Note: In the context of this code, "getProperties" seems to be a misnomer and should be renamed appropriately. This file is actually used for deletion purposes.

Related: #95

Saving and loading from state

We have the ability to store and load view state(i.e. zoom and pan position). The viewer gives a sharable link that can be used to launch camicroscope from this old state.

We need to document the types of state we want to support, example:
viewport, algorithms etc. so that external agents can push this state information too.

Support filenames with strange characters

I noticed that when ingesting images with strange filenames, such as:
EX10-0218-4-CK818-[Boon's]-AV.svs
EX10-0218DV-1-[NBF]-CK8
18-AV.svs
the QUIP viewer wouldn't display the images. If I first renamed the files to something more standard, then QUIP would work just fine.

Spyglass does not show annotations

  1. When an algorithm is selected, spyglass should show those annotations. Or, we need to be able to explain why not.
  2. (Related to spyglass) Figure out why camic_state.get_url_state() is undefined at StateSchema.js (line 23), and what is it used for?

QUIP 2 Issue - Delete Markup Button

Someone tried to delete a markup, and the normal shortcut wouldn't work. On QUIP1, the shortcut is (CTRL + Left Click ) on the annotation, but on QUIP2, that doesn't work.

User specific heatmaps and markups

Once user is logged in the session variable $_SESSION["email"] has the email address of the user and can be used to identify it.
It is available across all PHP files in camicroscope and can be used to add user information to POST requests.

Harmonize attribute names

We need to be consistent in our naming of common attributes such as patient/subject, specimen, and image/case.
ID, case-id, case_id, imageID etc., are all names that point to the same thing - a UID for the image. Lets clean this up in the upcoming 1.0 release

Image uploader changes ndpi file extension to dpi.

When a Hamamatsu file with extension ndpi is uploaded using the Image Uploader, the resulting file has a dpi extension. The file is then not recognized by the server as an openslide compatible format.

I am running sbubmi/quip_*:1.0 images.

UI Improvements/Fixes

General

  • Universal Design Document/Spec for caMic and related apps
  • Header Redesign

Image Loader

  • โ€œProblem with Uploadingโ€ should probably be bigger or have border/box
  • change 100% color on progress bar

Feature Scape

  • Move where scatter plots are and/or show/hide the matrix on click.
  • On hover, show mini plot if possible, else correlation coefficient.
  • On click, show modal plot with correlation coefficient.

caMicroscope

  • Image analysis button seems to change opacity of a non-visible div
  • Make workflow on โ€œwork order panelโ€ more apparent.
  • Contextual (in place) menus/commands for annotation

caMic Lymphocyte

  • Having two home buttons makes no sense
  • Blue plus and minus icons canโ€™t be seen well
  • There should be a way to exit draw thin line from the menu
  • Zoom on scroll doesnโ€™t seem to work, also canโ€™t zoom out
  • Plus and minus should be functionally replaced with an opacity slider, not two head buttons

Instructions for Composite

The composite tools don't seem to make any sense to me. In most interactions, I get "select one and only one algorithm" regardless of if I've done so or not.

Use templates properly

Our sliders should be templated. Here is an example of code that should have been templated. During our refactoring, we should be able to push the template into Mongo, and then populate the form from a separate file that relies on that template.

panel.html(function () {
return "<div id='panelHeader'><h4 id='workOrderTitle'> Work Order </h4><a href='#' id='cancelOrderTitle'><div id='cancelWorkOrder'> <img src='images/ic_close_white_24px.svg' /> </div></a></div><div id='panelBody'><form id='workOrderForm' action='#'></form></div>";
});
var schema = {
"range1": {
"type": "number",
"title": "Threshold Gain",
//"description": "Threshold gain for calling something in the image as nucleus. Run as default value 1.0",
"default": r,
"minimum": 0.5,
"exclusiveMinimum": false,
"maximum": 1.5
},
"result1": {
"type": "number",
"maxLength": 3,
"notitle": true,
"required": true,
"placeholder": r,
"readonly": false
},
"range2": {
"type": "number",
"title": "Expected Roundness/Smoothness",
//"description": "Threshold gain for calling something in the image as nucleus. Run as default value 1.0",
"default": w,
"minimum": 0.0,
"exclusiveMinimum": false,
"maximum": 10.0
},
"result2": {
"type": "number",
"maxLength": 3,
"notitle": true,
"required": true,
"placeholder": w,
"readonly": false
},
"range3": {
"type": "number",
"title": "Size Lower Threshold",
//"description": "Threshold gain for calling something in the image as nucleus. Run as default value 1.0",
"default": l,
"minimum": 1.0,
"exclusiveMinimum": false,
"maximum": 30.0
},
"result3": {
"type": "number",
"maxLength": 3,
"notitle": true,
"required": true,
"placeholder": l,
"readonly": false
},
"range4": {
"type": "number",
"title": "Size Upper Threshold",
"default": u,
"minimum": 1.0,
"maximum": 500.0
},
"result4": {
"type": "number",
"maxLength": 3,
"notitle": true,
"required": true,
"placeholder": u,
"readonly": false
},
"range5": {
"type": "number",
"title": "Kernel Size",
"default": k,
"minimum": 1.0,
"maximum": 30.0
},
"result5": {
"type": "number",
"maxLength": 3,
"notitle": true,
"required": true,
"placeholder": k,
"readonly": false
},
"radios6": {
"type": "integer",
"title": "Choose declumping method",
"enum": [0, 1, 2],
default: pj
}
};
// console.log('Schema: ' + JSON.stringify(schema, null, 4));
var formSchema = {
'schema': schema,
'form': [{
'type': 'fieldset',
//'legend': 'Parameters',
'expendable': true,
'items': [
{
"key": "range1",
"type": "range",
"step": 0.1,
"onChange": function (evt) {
var valueRange1 = jQuery(evt.target).val();
r = valueRange1;
jQuery('[id*="-result1"]').val(r);
/*
if(valueRange1) {
document.getElementById("jsonform-0-elt-result1").value = valueRange1;
}
document.getElementById("jsonform-0-elt-result1").value = valueRange1;
*/
},
"otherField": {"key": "result1", "inline": true}
},
"result1",
{
"key": "range2",
"type": "range",
"step": 0.1,
"onChange": function (evt) {
var valueRange2 = jQuery(evt.target).val();
w = valueRange2;
jQuery('[id*="-result2"]').val(w);
/*
if(valueRange2) {
document.getElementById("jsonform-0-elt-result2").value = valueRange2;
}
*/
}
},
"result2",
{
"key": "range3",
"type": "range",
"step": 0.1,
"onChange": function (evt) {
var valueRange3 = jQuery(evt.target).val();
l = valueRange3;
jQuery('[id*="-result3"]').val(l);
/*
if(valueRange3) {
document.getElementById("jsonform-0-elt-result3").value = valueRange3;
} */
}
},
"result3",
{
"key": "range4",
"type": "range",
"step": 0.1,
"onChange": function (evt) {
var valueRange4 = jQuery(evt.target).val();
u = valueRange4;
jQuery('[id*="-result4"]').val(u);
/*
if(valueRange4) {
document.getElementById("jsonform-0-elt-result4").value = valueRange4;
} */
}
},
"result4",
{
"key": "range5",
"type": "range",
"step": 0.1,
"onChange": function (evt) {
var valueRange5 = jQuery(evt.target).val();
k = valueRange5;
console.log("valueRange5:", k);
jQuery('[id*="-result5"]').val(k);
/*
if(valueRange5) {
document.getElementById("jsonform-0-elt-result5").value = valueRange5;
}
*/
}
},
"result5",
{
"key": "radios6",
"type": "radios",
"titleMap": {
0: "--- No Declumping",
1: "--- Mean Shift Declumping",
2: "--- Watershed Declumping"
},
"onChange": function (e) {
// console.log(e);
var radio_value = jQuery(e.target).val();
// console.log("radio_value is : "+radio_value);
//pj=parseInt(radio_value);
pj = radio_value;
// console.log("pj is : "+pj);
}
}
]
}],
"params": {
"fieldHtmlClass": "input-small"
}
};

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.