From ab1f761a3a24cf81672fd761e449d6e30b8d81f4 Mon Sep 17 00:00:00 2001 From: Mark Winter <mwinter@drexel.edu> Date: Tue, 28 Sep 2021 16:32:55 -0400 Subject: [PATCH] Split the online documentation into sections for API, usage, and example plugin --- docs/{methods.md => api.md} | 176 +----------------------------------- docs/plugin_example.md | 5 + docs/usage.md | 171 +++++++++++++++++++++++++++++++++++ readme.md | 4 +- 4 files changed, 181 insertions(+), 175 deletions(-) rename docs/{methods.md => api.md} (58%) create mode 100644 docs/plugin_example.md create mode 100644 docs/usage.md diff --git a/docs/methods.md b/docs/api.md similarity index 58% rename from docs/methods.md rename to docs/api.md index c8b279d..7f7ef05 100644 --- a/docs/methods.md +++ b/docs/api.md @@ -1,4 +1,4 @@ -# LEVERSC: Cross-Platform Scriptable Multichannel 3-D Visualization for Fluorescence Microscopy Images (Online Methods) +# LEVERSC: Cross-Platform Scriptable Multichannel 3-D Visualization for Fluorescence Microscopy Images (API Documentation) # Architecture The LEVERSC visualization tool is a [node.js](https://nodejs.org) application for visualization of multichannel 3-D volumetric data using webgl. @@ -8,179 +8,7 @@ Currently LEVERSC has plugins for ImageJ, Python and MATLAB. Additional plugins This architecture is very flexible and supports fast, cross-platform communication between any image processing environment that supports HTTP POST/GET requests. A detailed API breakdown follows, as well as example usage from Python and MATLAB. -# Usage Example -## Scripted Movie Rendering (in MATLAB) -In this section we will discuss in detail the usage of the script application programming interface ([API](#api)) for rendering high-quality presentation movies. -The full script ([```sampleVolumeMovie.m```](../src/MATLAB/sampleVolumeMovie.m)) is available in the ```src/MATLAB``` directory of the LEVERSC repository. - -### Movie setup -We begin by loading some image data, in this case from the sample .LEVER file distributed along with the LEVERSC repository. -```matlab -%% Load image (in this case from a LEVER file) -strDB='../../sampleImages/lscSampleImage.LEVER'; -[im,CONSTANTS]=leversc.loadImage(strDB); -``` - -A leversc class object must be initialized, here we initialize the leversc class with image data and metadata (metadata fields such as ```PixelPhysicalSize``` are important for correct data visualization). -```matlab -% Initialize leversc class with image and metadata -lsc=leversc(im,CONSTANTS); -``` - -A reproducible movie render should set the rendering parameters consistently at the beginning of rendering to properly visualize the data. -In this case we used the LEVERSC tool interface to interactively identify good visualization values, then used the ```/renderParams``` API call to read the current settings. -The image below shows the LEVERSC interface for selecting visualization (rendering) parameters: - - - - -The selected rendering parameters were hard-coded into our rendering script. -```matlab -%% Set up pre-selected render properties -lsc.renderParams(1).alpha = 1; -lsc.renderParams(1).dark = 0; -lsc.renderParams(1).medium = 0.78; -lsc.renderParams(1).bright = 0.96; -lsc.renderParams(1).color = [1;1;1]; -``` - -We disable the display of most UI elements -```matlab -%% Disable most UI elements -lsc.uiParams.sidebar='none'; -lsc.uiParams.clockButton='none'; -lsc.uiParams.webToolbar='none'; -``` - -We reset the view parameters to defaults for the start of the movie: -```matlab -%% Reset view parameters (also set background to black) -lsc.viewParams.clipMode = 0; -lsc.viewParams.worldRot = reshape([1,0,0,0; 0,1,0,0; 0,0,1,0; 0,0,0,1], 16,1); -lsc.viewParams.zoom = 0; -lsc.viewParams.bgColor = [0,0,0]; -``` - -The first step in this movie is to apply a quick animated zoom to fill the display with the actual data in the volume, capturing frames for each zoom level. -Since our movie will run at 10 frames per second (fps) we interpolate our zoom over 10 frames (a 1 second zoom): -```matlab -%% Quick zoom from 0 to 0.4 (1 sec = 10 frames) -zlevels = linspace(0,0.4, 10); -for i=1:length(zlevels) - lsc.viewParams.zoom=zlevels(i); - - imCap = get_rendered_frame(lsc); - if ( bPreview ) - imagesc(imCap); - axis image; - drawnow(); - else - writeVideo(vidWrite,imCap); - end -end -``` - -Next we apply a 5 second (50 frame) rotation of 180 degrees about the y-axis: -```matlab -%% Rotate halfway around in 5sec -angles = linspace(0,180,50); -for i=2:length(angles) - ry=[cosd(angles(i)), 0, sind(angles(i)),0; - 0,1,0,0; - -sind(angles(i)),0,cosd(angles(i)),0; - 0,0,0,1]; - - worldRot=ry; - lsc.viewParams.worldRot=worldRot(:); - - imCap = get_rendered_frame(lsc); - if ( bPreview ) - imagesc(imCap); - axis image; - drawnow(); - else - writeVideo(vidWrite,imCap); - end -end -``` - -Next we move the sampling plane to the edge of the volume and turn on planar clipping. -Then we animate moving the plane to just a little back from the volume center. -The plane animation is 2 seconds (20 frames) long: -```matlab -%% Put sample plane at the back of the volume and set to planar clipping mode, -%% then animate plane movement into just back from center -planeZs = linspace(85,50, 20); -lsc.viewParams.planeCenter(3) = planeZs(1); -lsc.viewParams.clipMode = 1; % Plane-clipping mode -for i=1:length(planeZs) - lsc.viewParams.planeCenter(3) = planeZs(i); - - imCap = get_rendered_frame(lsc); - if ( bPreview ) - imagesc(imCap); - axis image; - drawnow(); - else - writeVideo(vidWrite,imCap); - end -end -``` - -We apply another 180 degree rotation to rotate the volume the rest of the way back to the starting view. -This time we show matrix multiplication for the world rotation matrix by a delta rotation matrix: -```matlab -%% Rotate the rest of the way around with plane clipping on (5sec) -% This time we use a "delta" rotation matrix to show how matrix -% products can be used -frameRots = 50; -angleDelta = 180 / frameRots; -deltaRY = [cosd(angleDelta), 0, sind(angleDelta),0; - 0,1,0,0; - -sind(angleDelta),0,cosd(angleDelta),0; - 0,0,0,1]; -worldRot = reshape(lsc.viewParams.worldRot, 4,4); -for i=1:frameRots - worldRot = deltaRY * worldRot; - lsc.viewParams.worldRot = worldRot(:); - - imCap = get_rendered_frame(lsc); - if ( bPreview ) - imagesc(imCap); - axis image; - drawnow(); - else - writeVideo(vidWrite,imCap); - end -end -``` - -As a final animation, we change the plane clipping mode to slice sampling, and animate moving out of the volume towards the camera: -```matlab -%% Change to slice clipping mode and pull plane back toward camera -startZ = lsc.viewParams.planeCenter(3); -planeZs = linspace(startZ,1,20); -lsc.viewParams.clipMode = 2; % Slice-clipping mode -for i=1:length(planeZs) - lsc.viewParams.planeCenter(3) = planeZs(i); - - imCap = get_rendered_frame(lsc); - if ( bPreview ) - imagesc(imCap); - axis image; - drawnow(); - else - writeVideo(vidWrite,imCap); - end -end -``` -If run with the ```bPreview``` flag set to false, this will generate ```lscSampleMovie.mp4```. -**NOTE:** The LEVERSC window size will determine the resolution of the video produced, so it is important to set the window size appropriately before running the video script. - -Using the example shown here, as well as the full ```viewParams``` and ```renderParams``` API calls, complex camera and movie effects can be built through interpolation of multiple parameters at each frame. - - -# API +# Application Programming Interface (API) ## Ports LEVERSC *Figure* windows are represented by port bindings, beginning at port 3001 for figure 1 and port 3002 for figure 2, etc. diff --git a/docs/plugin_example.md b/docs/plugin_example.md new file mode 100644 index 0000000..9921c0f --- /dev/null +++ b/docs/plugin_example.md @@ -0,0 +1,5 @@ +# LEVERSC: Cross-Platform Scriptable Multichannel 3-D Visualization for Fluorescence Microscopy Images + +# Developing a LEVERSC Plugin +This section provides a concrete example of implementing a very basic Python module to send multichannel 3-D NumPy array data to the LEVERSC tool via the HTTP request API. Though this is an introductory example, very similar code is implemented in the [LEVERSC Python interface](../src/Python/leversc.py). + diff --git a/docs/usage.md b/docs/usage.md new file mode 100644 index 0000000..bd2af98 --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,171 @@ +# LEVERSC: Cross-Platform Scriptable Multichannel 3-D Visualization for Fluorescence Microscopy Images (Usage Example) +# Usage Example +## Scripted Movie Rendering (in MATLAB) +In this section we will discuss in detail the usage of the script application programming interface ([API](#api)) for rendering high-quality presentation movies. +The full script ([```sampleVolumeMovie.m```](../src/MATLAB/sampleVolumeMovie.m)) is available in the ```src/MATLAB``` directory of the LEVERSC repository. + +### Movie setup +We begin by loading some image data, in this case from the sample .LEVER file distributed along with the LEVERSC repository. +```matlab +%% Load image (in this case from a LEVER file) +strDB='../../sampleImages/lscSampleImage.LEVER'; +[im,CONSTANTS]=leversc.loadImage(strDB); +``` + +A leversc class object must be initialized, here we initialize the leversc class with image data and metadata (metadata fields such as ```PixelPhysicalSize``` are important for correct data visualization). +```matlab +% Initialize leversc class with image and metadata +lsc=leversc(im,CONSTANTS); +``` + +A reproducible movie render should set the rendering parameters consistently at the beginning of rendering to properly visualize the data. +In this case we used the LEVERSC tool interface to interactively identify good visualization values, then used the ```/renderParams``` API call to read the current settings. +The image below shows the LEVERSC interface for selecting visualization (rendering) parameters: + + + + +The selected rendering parameters were hard-coded into our rendering script. +```matlab +%% Set up pre-selected render properties +lsc.renderParams(1).alpha = 1; +lsc.renderParams(1).dark = 0; +lsc.renderParams(1).medium = 0.78; +lsc.renderParams(1).bright = 0.96; +lsc.renderParams(1).color = [1;1;1]; +``` + +We disable the display of most UI elements +```matlab +%% Disable most UI elements +lsc.uiParams.sidebar='none'; +lsc.uiParams.clockButton='none'; +lsc.uiParams.webToolbar='none'; +``` + +We reset the view parameters to defaults for the start of the movie: +```matlab +%% Reset view parameters (also set background to black) +lsc.viewParams.clipMode = 0; +lsc.viewParams.worldRot = reshape([1,0,0,0; 0,1,0,0; 0,0,1,0; 0,0,0,1], 16,1); +lsc.viewParams.zoom = 0; +lsc.viewParams.bgColor = [0,0,0]; +``` + +The first step in this movie is to apply a quick animated zoom to fill the display with the actual data in the volume, capturing frames for each zoom level. +Since our movie will run at 10 frames per second (fps) we interpolate our zoom over 10 frames (a 1 second zoom): +```matlab +%% Quick zoom from 0 to 0.4 (1 sec = 10 frames) +zlevels = linspace(0,0.4, 10); +for i=1:length(zlevels) + lsc.viewParams.zoom=zlevels(i); + + imCap = get_rendered_frame(lsc); + if ( bPreview ) + imagesc(imCap); + axis image; + drawnow(); + else + writeVideo(vidWrite,imCap); + end +end +``` + +Next we apply a 5 second (50 frame) rotation of 180 degrees about the y-axis: +```matlab +%% Rotate halfway around in 5sec +angles = linspace(0,180,50); +for i=2:length(angles) + ry=[cosd(angles(i)), 0, sind(angles(i)),0; + 0,1,0,0; + -sind(angles(i)),0,cosd(angles(i)),0; + 0,0,0,1]; + + worldRot=ry; + lsc.viewParams.worldRot=worldRot(:); + + imCap = get_rendered_frame(lsc); + if ( bPreview ) + imagesc(imCap); + axis image; + drawnow(); + else + writeVideo(vidWrite,imCap); + end +end +``` + +Next we move the sampling plane to the edge of the volume and turn on planar clipping. +Then we animate moving the plane to just a little back from the volume center. +The plane animation is 2 seconds (20 frames) long: +```matlab +%% Put sample plane at the back of the volume and set to planar clipping mode, +%% then animate plane movement into just back from center +planeZs = linspace(85,50, 20); +lsc.viewParams.planeCenter(3) = planeZs(1); +lsc.viewParams.clipMode = 1; % Plane-clipping mode +for i=1:length(planeZs) + lsc.viewParams.planeCenter(3) = planeZs(i); + + imCap = get_rendered_frame(lsc); + if ( bPreview ) + imagesc(imCap); + axis image; + drawnow(); + else + writeVideo(vidWrite,imCap); + end +end +``` + +We apply another 180 degree rotation to rotate the volume the rest of the way back to the starting view. +This time we show matrix multiplication for the world rotation matrix by a delta rotation matrix: +```matlab +%% Rotate the rest of the way around with plane clipping on (5sec) +% This time we use a "delta" rotation matrix to show how matrix +% products can be used +frameRots = 50; +angleDelta = 180 / frameRots; +deltaRY = [cosd(angleDelta), 0, sind(angleDelta),0; + 0,1,0,0; + -sind(angleDelta),0,cosd(angleDelta),0; + 0,0,0,1]; +worldRot = reshape(lsc.viewParams.worldRot, 4,4); +for i=1:frameRots + worldRot = deltaRY * worldRot; + lsc.viewParams.worldRot = worldRot(:); + + imCap = get_rendered_frame(lsc); + if ( bPreview ) + imagesc(imCap); + axis image; + drawnow(); + else + writeVideo(vidWrite,imCap); + end +end +``` + +As a final animation, we change the plane clipping mode to slice sampling, and animate moving out of the volume towards the camera: +```matlab +%% Change to slice clipping mode and pull plane back toward camera +startZ = lsc.viewParams.planeCenter(3); +planeZs = linspace(startZ,1,20); +lsc.viewParams.clipMode = 2; % Slice-clipping mode +for i=1:length(planeZs) + lsc.viewParams.planeCenter(3) = planeZs(i); + + imCap = get_rendered_frame(lsc); + if ( bPreview ) + imagesc(imCap); + axis image; + drawnow(); + else + writeVideo(vidWrite,imCap); + end +end +``` +If run with the ```bPreview``` flag set to false, this will generate ```lscSampleMovie.mp4```. +**NOTE:** The LEVERSC window size will determine the resolution of the video produced, so it is important to set the window size appropriately before running the video script. + +Using the example shown here, as well as the full ```viewParams``` and ```renderParams``` API calls, complex camera and movie effects can be built through interpolation of multiple parameters at each frame. diff --git a/readme.md b/readme.md index 1fb94ea..2039e2b 100644 --- a/readme.md +++ b/readme.md @@ -68,6 +68,8 @@ debug output. ## Further Details -Details of the LEVERSC tool architecture and API can be found in the [methods](docs/methods.md "LEVERSC online methods") section. The source code for LEVERSC integrations are available in this repository ([ImageJ plugin](src/ImageJ "ImageJ plugin source code"), [Python module](src/Python "Python module source code"), [MATLAB class](src/MATLAB "MATLAB class and helper source code")). +Details of the LEVERSC tool architecture and API can be found in the online [API documentation](docs/api.md "LEVERSC API documentation"). A detailed usage example is available [here](docs/usage.md "LEVERSC usage example"), and a step-by-step guide for implementing a plugin to communicate with LEVERSC through the API is provided [here](docs/plugin_example.md "LEVERSC plugin guide"). + +The source code for LEVERSC integrations are available in this repository ([ImageJ plugin](src/ImageJ "ImageJ plugin source code"), [Python module](src/Python "Python module source code"), [MATLAB class](src/MATLAB "MATLAB class and helper source code")). Additionally, the node.js and webgl source code for the LEVERJS/LEVERSC tool, as well as build instructions are available in the main [leverjs repository](https://git-bioimage.coe.drexel.edu/opensource/leverjs "LEVERJS source code repository"). -- GitLab