VivoScript: Topographic Thinning – The Onion Tool

VivoScript: Onion Tool

A new VivoScript will be available with the release of VivoQuant 1.23: the Onion Tool. This tool allows the user to select a Region of Interest that he or she has segmented, and perform layer-based analysis. The tool operates on any ROI present in the 3D ROI Tool, and is configurable to fit your specific analysis needs.

Onion Tool for 3D ROI Analysis

The Onion Tool alters the ROI that has already been drawn by the user, thereby serving as an extension of the user’s own analysis. The user runs the tool, designed to be run straight from the VivoScript Toolbar, after drawing complete ROIs. If the tool finds that there are no ROIs segmented, it will prompt the user that he or she needs to draw the ROIs before continuing. Otherwise, the tool will ask the user which ROI the tool should use, then the tool handles the rest. The onion layers are generated from the outer edge of the ROI and work toward the center. The original ROI is repeatedly eroded, with the eroded voxels mapped to new layers of the Onion. Once the original ROI no longer contains any voxels, the loop stops, and the original ROI, now with a volume of 0, is deleted. The ROI layers are named based on the original ROI name, so the tool can be run multiple times within a single RMHA. Here, a movie shows the progression of a tumor ROI, originally in green.

OnionProgression

(click to play)

Onion Tool Code

The Onion Tool relies on two main functions of the VivoScript. The first is the ability to read the ROI information  from the manual segmentations. This allows for the flexibility to operate on any ROI. The following is the beginning of the script, where ROI values and names are assessed, and the user is prompted for input. Note, also, the ability to change the thickness of the onion layers, which can be changed in the script to match the user’s analysis goals.

// Establish onion layer thickness
	var thickness = 2;

// Determine number of ROIs
	VQ.mainWin().setViewMode("Slice View","3D ROI Tool");
	var roi = VQ.currentOp();
	var n_rois = roi.numROIs();	

// Make sure there are ROIs drawn (can remove line 14 and move message to line 15 when VQ 1.23 stable is being used)	
	if (n_rois == 1){
		VQ.showMessage("Please draw an ROI first");
		VQ.suspend();
	}

// Get ROI name to onion
	var n_rois = roi.numROIs();		
	var names = new Array();		
	for (n = 0; n < n_rois; n++){
		var stats = VQ.getROIStats(0, n);

			for (s in stats) { 
				if (s == "roiname") {
					names[n] = stats[s];
				}
			}
	}

	var roiName = VQ.getItem("Select ROI to onion", "Select ROI to onion", names, current=1)

// Translate ROI name back into ROI value	
	for (n = 0; n < n_rois; n++){
		var stats = VQ.getROIStats(0, n);

			for (s in stats) { 
				if (s == "roiname") {
					if (stats[s] == roiName) {

						for (k in stats) {
							if (k == "roiid") { 
								var roiID = stats[k];
							}	
						}

						for (k in stats) {
							if (k == "roicolor") { 
								var roiColor = stats[k];
							}	
						}
					}	
				}
			}
	}

 

The onion itself is generated from a “while” loop which adds the onion layer and erodes the original ROI, mapping to the new onion layer in an iterative process until the original ROI no longer has any volume. Note, also, certain steps, such as editing the original ROI to make sure it is not hidden or immutable, and centering on the original ROI, have been added to ensure the script runs smoothly and the user can watch as it occurs.

function onion_tool(roiID) { //generate onion effect of input roiid
    VQ.mainWin().setViewMode("Slice View","3D ROI Tool");
	var colorlist = ["red", "green", "blue", "cyan", "magenta", "yellow", "darkred", "darkgreen", "darkblue", "darkcyan", "darkmagenta", "tomato", "gold", "maroon", "midnightblue", "orchid", "peachpuff", "lightseagreen", "crimson"];
	var clength = colorlist.length;

	VQ.currentOp().editROI(roiID,roiName,roiColor, 0, 0, "125", "250");

	// Center on ROI
		var ctl = VQ.controler();
		VQ.debug("Centering on ROI of value: "+ roiID + " and color: " + roiColor)
		var centers = VQ.currentOp().getROICenterOfMass(roiID);
		var centers = centers.substr(1,centers.length-2).split(" ");;
		ctl.setPos(0, centers[0]);
		ctl.setPos(1, centers[1]);
		ctl.setPos(2, centers[2]);

	var v_new = 1;

	var cnt = 0;
	while (v_new >  0) {

	// Get number of ROIs
		var n_rois = roi.numROIs();	

		var layerName = roiName + "-Layer" + cnt;
		var cnt = cnt+1;

		var stats = VQ.getROIStats(0, roiID);

		for (s in stats) { 
			if (s == "voxels") {
				var v_orig = stats[s];
			}
		}

		//Make ROI Layers

			var colorchoice = colorlist[cnt-(Math.floor(cnt/clength)*clength)];
			var EDval = thickness + 4;	

			VQ.currentOp().addROI(layerName, colorchoice, 0, 0, "125", "250")
			VQ.getWidget("cbMagicEDRadius").setCurrentIndex(EDval);
			VQ.getWidget("cbErodeMapTo").setChecked(1);
			VQ.getWidget("cbLayerROI").setCurrentIndex(n_rois);
			VQ.getWidget("cbROIs").setCurrentIndex(roiID);
			VQ.getWidget("buttonMagicErode").click();
			VQ.getWidget("cbErodeMapTo").setChecked(0);
			VQ.currentOp().editROI(n_rois,layerName, colorchoice, 1, 0, "125", "250")

		var stats = VQ.getROIStats(0, roiID);

		for (s in stats) { 
			if (s == "voxels") {
				var v_new = stats[s];
			}
		}					
	}

	VQ.currentOp().deleteROI(roiID,0);
}

 

Onion Tool Analysis

The onion tool allows the user to analyze changes in tissue as a function of layer of tissue in the organ. For example, below is a plot of the concentration (μCi/mm^3) within the tumor shown in the movie above:

OnionConcentration

This type of analysis can be very useful, particularly for examining tumors.